From: Denis Davydov Date: Sat, 28 Oct 2017 09:42:50 +0000 (+0200) Subject: set target with SLEPc shift-and-invert to comply with 3.8.0 X-Git-Tag: v9.0.0-rc1~859^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F5347%2Fhead;p=dealii.git set target with SLEPc shift-and-invert to comply with 3.8.0 --- diff --git a/include/deal.II/base/config.h.in b/include/deal.II/base/config.h.in index 8a9ecc3e8e..0c083b3974 100644 --- a/include/deal.II/base/config.h.in +++ b/include/deal.II/base/config.h.in @@ -245,6 +245,17 @@ >= \ (major)*10000 + (minor)*100 + (subminor)) +/* + * SLEPC + * see slepcversion.h + */ +#define DEAL_II_SLEPC_VERSION_GTE(major,minor,subminor) \ + ((SLEPC_VERSION_MAJOR * 10000 + \ + SLEPC_VERSION_MINOR * 100 + \ + SLEPC_VERSION_SUBMINOR) \ + >= \ + (major)*10000 + (minor)*100 + (subminor)) + /* * Trilinos: */ diff --git a/include/deal.II/lac/slepc_spectral_transformation.h b/include/deal.II/lac/slepc_spectral_transformation.h index c421ef6e50..11760a4d46 100644 --- a/include/deal.II/lac/slepc_spectral_transformation.h +++ b/include/deal.II/lac/slepc_spectral_transformation.h @@ -196,6 +196,12 @@ namespace SLEPcWrappers * Store a copy of the flags for this particular solver. */ const AdditionalData additional_data; + + /** + * Make the solver class a friend, since it may need to set target + * equal the provided shift value. + */ + friend class SolverBase; }; /** diff --git a/source/lac/slepc_solver.cc b/source/lac/slepc_solver.cc index 2d72f29699..18fbc7e708 100644 --- a/source/lac/slepc_solver.cc +++ b/source/lac/slepc_solver.cc @@ -91,8 +91,21 @@ namespace SLEPcWrappers { // set transformation type if any // STSetShift is called inside - const PetscErrorCode ierr = EPSSetST(eps,transformation.st); + PetscErrorCode ierr = EPSSetST(eps,transformation.st); AssertThrow (ierr == 0, SolverBase::ExcSLEPcError(ierr)); + +#if DEAL_II_SLEPC_VERSION_GTE(3, 8, 0) + // see https://lists.mcs.anl.gov/mailman/htdig/petsc-users/2017-October/033649.html + // From 3.8.0 SLEPc insists that when looking for smallest eigenvalues with shift-and-invert + // users should (a) set target (b) use EPS_TARGET_MAGNITUDE + // The former, however, needs to be applied to eps object and not spectral transformation. + if (SLEPcWrappers::TransformationShiftInvert *sinv = dynamic_cast(&transformation)) + { + ierr = EPSSetTarget (eps, sinv->additional_data.shift_parameter); + AssertThrow (ierr == 0, SolverBase::ExcSLEPcError(ierr)); + } +#endif + } void diff --git a/tests/slepc/step-36_parallel.cc b/tests/slepc/step-36_parallel.cc index 3a270d25b4..ec31dabbdf 100644 --- a/tests/slepc/step-36_parallel.cc +++ b/tests/slepc/step-36_parallel.cc @@ -289,7 +289,7 @@ void test (std::string solver_name, // Set the initial vector. This is optional, if not done the initial vector is set to random values eigensolver->set_initial_space(eigenfunctions); - eigensolver->set_which_eigenpairs (EPS_SMALLEST_REAL); + eigensolver->set_which_eigenpairs (EPS_TARGET_MAGNITUDE); eigensolver->set_problem_type (EPS_GHEP); eigensolver->solve (stiffness_matrix,