1 // --------------------------------------------------------------------- 2 // 3 // Copyright (C) 2009 - 2019 by the deal.II authors 4 // 5 // This file is part of the deal.II library. 6 // 7 // The deal.II library is free software; you can use it, redistribute 8 // it, and/or modify it under the terms of the GNU Lesser General 9 // Public License as published by the Free Software Foundation; either 10 // version 2.1 of the License, or (at your option) any later version. 11 // The full text of the license can be found in the file LICENSE.md at 12 // the top level directory of deal.II. 13 // 14 // --------------------------------------------------------------------- 15 16 17 #ifndef dealii_slepc_spectral_transformation_h 18 # define dealii_slepc_spectral_transformation_h 19 20 21 # include <deal.II/base/config.h> 22 23 # ifdef DEAL_II_WITH_SLEPC 24 25 # include <deal.II/lac/exceptions.h> 26 # include <deal.II/lac/petsc_solver.h> 27 28 # include <petscksp.h> 29 30 # include <slepceps.h> 31 32 # include <memory> 33 34 DEAL_II_NAMESPACE_OPEN 35 36 // Forward declaration 37 # ifndef DOXYGEN 38 namespace PETScWrappers 39 { 40 // forward declarations 41 class SolverBase; 42 } // namespace PETScWrappers 43 # endif 44 45 namespace SLEPcWrappers 46 { 47 // forward declaration 48 class SolverBase; 49 50 /** 51 * Base class for spectral transformation classes using the SLEPc solvers 52 * which are selected based on flags passed to the spectral transformation. 53 * 54 * <code>SLEPcWrappers::TransformationXXX</code>, where <code>XXX</code> is 55 * your favourite transformation type, can then be implemented in 56 * application codes in the following way for <code>XXX=INVERT</code> with 57 * the solver object <code>eigensolver</code>: 58 * @code 59 * // Set a transformation, this one shifts the eigenspectrum by 3.142.. 60 * SLEPcWrappers::TransformationShift::AdditionalData 61 * additional_data(3.142); 62 * SLEPcWrappers::TransformationShift shift(mpi_communicator,additional_data); 63 * eigensolver.set_transformation(shift); 64 * @endcode 65 * and later calling the <code>solve()</code> function as usual: 66 * @code 67 * SolverControl solver_control (1000, 1e-9); 68 * SolverArnoldi system (solver_control, mpi_communicator); 69 * eigensolver.solve (A, B, lambda, x, size_of_spectrum); 70 * @endcode 71 * 72 * @note These options can also be set at the command line. 73 * 74 * @ingroup SLEPcWrappers 75 */ 76 class TransformationBase 77 { 78 protected: 79 /** 80 * Constructor. 81 */ 82 TransformationBase(const MPI_Comm &mpi_communicator); 83 84 public: 85 /** 86 * Destructor. 87 */ 88 virtual ~TransformationBase(); 89 90 /** 91 * Set a flag to indicate how the transformed matrices are being stored in 92 * the spectral transformations. 93 * 94 * The possible values are given by the enumerator STMatMode in the SLEPc 95 * library 96 * http://www.grycap.upv.es/slepc/documentation/current/docs/manualpages/ST/STMatMode.html 97 */ 98 void 99 set_matrix_mode(const STMatMode mode); 100 101 /** 102 * Set solver to be used when solving a system of linear algebraic 103 * equations inside the eigensolver. 104 */ 105 void 106 set_solver(const PETScWrappers::SolverBase &solver); 107 108 protected: 109 /** 110 * SLEPc spectral transformation object. 111 */ 112 ST st; 113 114 // Make the solver class a friend, since it needs to set spectral 115 // transformation object. 116 friend class SolverBase; 117 }; 118 119 /** 120 * An implementation of the transformation interface using the SLEPc Shift. 121 * 122 * @ingroup SLEPcWrappers 123 */ 124 class TransformationShift : public TransformationBase 125 { 126 public: 127 /** 128 * Standardized data struct to pipe additional data to the solver. 129 */ 130 struct AdditionalData 131 { 132 /** 133 * Constructor. By default, set the shift parameter to zero. 134 */ 135 AdditionalData(const double shift_parameter = 0); 136 137 /** 138 * Shift parameter. 139 */ 140 const double shift_parameter; 141 }; 142 143 144 /** 145 * Constructor. 146 */ 147 TransformationShift(const MPI_Comm & mpi_communicator, 148 const AdditionalData &data = AdditionalData()); 149 150 151 protected: 152 /** 153 * Store a copy of the flags for this particular solver. 154 */ 155 const AdditionalData additional_data; 156 }; 157 158 /** 159 * An implementation of the transformation interface using the SLEPc Shift 160 * and Invert. 161 * 162 * @ingroup SLEPcWrappers 163 */ 164 class TransformationShiftInvert : public TransformationBase 165 { 166 public: 167 /** 168 * Standardized data struct to pipe additional data to the solver. 169 */ 170 struct AdditionalData 171 { 172 /** 173 * Constructor. By default, set the shift parameter to zero. 174 */ 175 AdditionalData(const double shift_parameter = 0); 176 177 /** 178 * Shift parameter. 179 */ 180 const double shift_parameter; 181 }; 182 183 184 /** 185 * Constructor. 186 */ 187 TransformationShiftInvert(const MPI_Comm & mpi_communicator, 188 const AdditionalData &data = AdditionalData()); 189 190 protected: 191 /** 192 * Store a copy of the flags for this particular solver. 193 */ 194 const AdditionalData additional_data; 195 196 // Make the solver class a friend, since it may need to set target 197 // equal the provided shift value. 198 friend class SolverBase; 199 }; 200 201 /** 202 * An implementation of the transformation interface using the SLEPc 203 * Spectrum Folding. This transformation type has been removed in SLEPc 204 * 3.5.0 and thus cannot be used in the newer versions. 205 * 206 * @ingroup SLEPcWrappers 207 */ 208 class TransformationSpectrumFolding : public TransformationBase 209 { 210 public: 211 /** 212 * Standardized data struct to pipe additional data to the solver. 213 */ 214 struct AdditionalData 215 { 216 /** 217 * Constructor. By default, set the shift parameter to zero. 218 */ 219 AdditionalData(const double shift_parameter = 0); 220 221 /** 222 * Shift parameter. 223 */ 224 const double shift_parameter; 225 }; 226 227 228 /** 229 * Constructor. 230 */ 231 TransformationSpectrumFolding( 232 const MPI_Comm & mpi_communicator, 233 const AdditionalData &data = AdditionalData()); 234 235 protected: 236 /** 237 * Store a copy of the flags for this particular solver. 238 */ 239 const AdditionalData additional_data; 240 }; 241 242 /** 243 * An implementation of the transformation interface using the SLEPc Cayley. 244 * 245 * @ingroup SLEPcWrappers 246 */ 247 class TransformationCayley : public TransformationBase 248 { 249 public: 250 /** 251 * Standardized data struct to pipe additional data to the solver. 252 */ 253 struct AdditionalData 254 { 255 /** 256 * Constructor. Requires two shift parameters 257 */ 258 AdditionalData(const double shift_parameter = 0, 259 const double antishift_parameter = 0); 260 261 /** 262 * Shift parameter. 263 */ 264 const double shift_parameter; 265 266 /** 267 * Antishift parameter. 268 */ 269 const double antishift_parameter; 270 }; 271 272 273 /** 274 * Constructor. 275 */ 276 TransformationCayley(const MPI_Comm & mpi_communicator, 277 const AdditionalData &data = AdditionalData()); 278 279 protected: 280 /** 281 * Store a copy of the flags for this particular solver. 282 */ 283 const AdditionalData additional_data; 284 }; 285 286 } // namespace SLEPcWrappers 287 288 DEAL_II_NAMESPACE_CLOSE 289 290 # endif // DEAL_II_WITH_SLEPC 291 292 /*-------------------- slepc_spectral_transformation.h ------------------*/ 293 294 #endif 295 296 /*-------------------- slepc_spectral_transformation.h ------------------*/ 297