PRISMS-PF Manual v3.0-pre
Loading...
Searching...
No Matches
matrixFreePDE.h
1#ifndef MATRIXFREEPDE_H
2#define MATRIXFREEPDE_H
3
4// dealii headers
5#include <deal.II/base/config.h>
6#include <deal.II/base/quadrature.h>
7#include <deal.II/base/timer.h>
8#include <deal.II/distributed/solution_transfer.h>
9#include <deal.II/distributed/tria.h>
10#include <deal.II/dofs/dof_handler.h>
11#include <deal.II/dofs/dof_tools.h>
12#include <deal.II/fe/fe_q.h>
13#include <deal.II/fe/fe_system.h>
14#include <deal.II/fe/fe_values.h>
15#include <deal.II/fe/mapping_fe.h>
16#include <deal.II/grid/grid_tools.h>
17#include <deal.II/grid/manifold_lib.h>
18#include <deal.II/grid/tria.h>
19#include <deal.II/grid/tria_accessor.h>
20#include <deal.II/grid/tria_iterator.h>
21#include <deal.II/lac/affine_constraints.h>
22#include <deal.II/lac/la_parallel_vector.h>
23#include <deal.II/lac/vector.h>
24#include <deal.II/matrix_free/fe_evaluation.h>
25#include <deal.II/matrix_free/matrix_free.h>
26#include <deal.II/numerics/vector_tools.h>
27
28// PRISMS headers
29#include <core/fields.h>
30#include <core/refinement/AdaptiveRefinement.h>
31#include <core/userInputParameters.h>
32#include <core/variableContainer.h>
33#include <core/variableValueContainer.h>
34#include <grains/SimplifiedGrainRepresentation.h>
35#include <nucleation/nucleus.h>
36#include <utilities/computeStress.h>
37#include <utilities/utilities.h>
38
39using namespace dealii;
40
52template <int dim, int degree>
53class MatrixFreePDE : public Subscriptor
54{
55public:
60
64 ~MatrixFreePDE() override;
65
70 virtual void
71 init();
72
78 virtual void
79 create_triangulation(parallel::distributed::Triangulation<dim> &tria) const;
80
90 void
91 initForTests(std::vector<Field<dim>> _fields);
92
97 void
98 solve();
99
108 void
109 vmult(dealii::LinearAlgebra::distributed::Vector<double> &dst,
110 const dealii::LinearAlgebra::distributed::Vector<double> &src) const;
111
118 std::vector<Field<dim>> fields;
119
123 void
124 buildFields();
125
129 ConditionalOStream pcout;
130
140 virtual void
141 setInitialCondition([[maybe_unused]] const Point<dim> &p,
142 [[maybe_unused]] const unsigned int index,
143 [[maybe_unused]] double &scalar_IC,
144 [[maybe_unused]] Vector<double> &vector_IC) = 0;
145
157 virtual void
158 setNonUniformDirichletBCs([[maybe_unused]] const Point<dim> &p,
159 [[maybe_unused]] const unsigned int index,
160 [[maybe_unused]] const unsigned int direction,
161 [[maybe_unused]] const double time,
162 [[maybe_unused]] double &scalar_BC,
163 [[maybe_unused]] Vector<double> &vector_BC) = 0;
164
165protected:
166 userInputParameters<dim> userInputs;
167
168 unsigned int totalDOFs;
169
170 // The attributes of the primary field variables and
171 // the postprocessing field variables
172 const AttributesList &var_attributes;
173 const AttributesList &pp_attributes;
174
175 // Elasticity matrix variables
176 const static unsigned int CIJ_tensor_size = 2 * dim - 1 + dim / 3;
177
178 // Method to reinitialize the mesh, degrees of freedom, constraints and data
179 // structures when the mesh is adapted
180 void
181 reinit();
182
187 void
189
190 std::vector<SimplifiedGrainRepresentation<dim>> simplified_grain_representations;
191
199 virtual void
200 solveIncrement(bool skip_time_dependent);
201 /* Method to write solution fields to vtu and pvtu (parallel) files.
202 *
203 * This method can be enabled/disabled by setting the flag writeOutput to
204 * true/false. Also, the user can select how often the solution files are
205 * written by setting the flag skipOutputSteps in the parameters file.
206 */
207 void
208 outputResults();
209
210 /*Parallel mesh object which holds information about the FE nodes, elements
211 * and parallel domain decomposition
212 */
213 parallel::distributed::Triangulation<dim> triangulation;
214 /*A vector of finite element objects used in a model. For problems with only
215 *one primal field, the size of this vector is one,otherwise the size is the
216 *number of primal fields in the problem.
217 */
218 std::vector<FESystem<dim> *> FESet;
219 /*A vector of all the constraint sets in the problem. A constraint set is a
220 *map which holds the mapping between the degrees of freedom and the
221 *corresponding degree of freedom constraints. Currently the type of
222 *constraints stored are either Dirichlet boundary conditions or hanging node
223 *constraints for adaptive meshes.
224 */
225 std::vector<const AffineConstraints<double> *> constraintsDirichletSet,
226 constraintsOtherSet;
227 /*A vector of all the degree of freedom objects is the problem. A degree of
228 *freedom object handles the serial/parallel distribution of the degrees of
229 *freedom for all the primal fields in the problem.*/
230 std::vector<const DoFHandler<dim> *> dofHandlersSet;
231
232 /*A vector of the locally relevant degrees of freedom. Locally relevant degrees of
233 *freedom in a parallel implementation is a collection of the degrees of freedom owned
234 *by the current processor and the surrounding ghost nodes which are required for the
235 *field computations in this processor.
236 */
237 std::vector<const IndexSet *> locally_relevant_dofsSet;
238 /*Copies of constraintSet elements, but stored as non-const to enable application of
239 * constraints.*/
240 std::vector<AffineConstraints<double> *> constraintsDirichletSet_nonconst,
241 constraintsOtherSet_nonconst;
242 /*Copies of dofHandlerSet elements, but stored as non-const.*/
243 std::vector<DoFHandler<dim> *> dofHandlersSet_nonconst;
244 /*Copies of locally_relevant_dofsSet elements, but stored as non-const.*/
245 std::vector<IndexSet *> locally_relevant_dofsSet_nonconst;
246 /*Vector all the solution vectors in the problem. In a multi-field problem, each primal
247 * field has a solution vector associated with it.*/
248 std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> solutionSet;
249 /*Vector all the residual (RHS) vectors in the problem. In a multi-field problem, each
250 * primal field has a residual vector associated with it.*/
251 std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> residualSet;
252 /*Vector of parallel solution transfer objects. This is used only when adaptive meshing
253 * is enabled.*/
254 std::vector<parallel::distributed::SolutionTransfer<
255 dim,
256 dealii::LinearAlgebra::distributed::Vector<double>> *>
257 soltransSet;
258
259 // matrix free objects
260 /*Object of class MatrixFree<dim>. This is primarily responsible for all the
261 *base matrix free functionality of this MatrixFreePDE<dim> class. Refer to
262 *deal.ii documentation of MatrixFree<dim> class for details.
263 */
264 MatrixFree<dim, double> matrixFreeObject;
265 /*Vector to store the inverse of the mass matrix diagonal for scalar fields.
266 * Due to the choice of spectral elements with Guass-Lobatto quadrature, the
267 * mass matrix is diagonal.*/
268 dealii::LinearAlgebra::distributed::Vector<double> invMscalar;
269 /*Vector to store the inverse of the mass matrix diagonal for vector fields.
270 * Due to the choice of spectral elements with Guass-Lobatto quadrature, the
271 * mass matrix is diagonal.*/
272 dealii::LinearAlgebra::distributed::Vector<double> invMvector;
273 /*Vector to store the solution increment. This is a temporary vector used
274 * during implicit solves of the Elliptic fields.*/
275 dealii::LinearAlgebra::distributed::Vector<double> dU_vector, dU_scalar;
276
277 // matrix free methods
278 /*Current field index*/
279 unsigned int currentFieldIndex;
280 /*Method to compute the inverse of the mass matrix*/
281 void
282 computeInvM();
283
284 /*Method to compute an explicit timestep*/
285 void
286 updateExplicitSolution(unsigned int fieldIndex);
287
288 /*Method to compute an implicit timestep*/
289 bool
290 updateImplicitSolution(unsigned int fieldIndex, unsigned int nonlinear_iteration_index);
291
292 /*Method to apply boundary conditions*/
293 void
294 applyBCs(unsigned int fieldIndex);
295
299 void
301
305 dealii::AlignedVector<dealii::VectorizedArray<double>> element_volume;
306
307 /*Method to compute the right hand side (RHS) residual vectors*/
308 void
309 computeExplicitRHS();
310 void
311 computeNonexplicitRHS();
312
313 // virtual methods to be implemented in the derived class
314 /*Method to calculate LHS(implicit solve)*/
315 void
316 getLHS(const MatrixFree<dim, double> &data,
317 dealii::LinearAlgebra::distributed::Vector<double> &dst,
318 const dealii::LinearAlgebra::distributed::Vector<double> &src,
319 const std::pair<unsigned int, unsigned int> &cell_range) const;
320
321 bool generatingInitialGuess;
322 void
323 getLaplaceLHS(const MatrixFree<dim, double> &data,
324 dealii::LinearAlgebra::distributed::Vector<double> &dst,
325 const dealii::LinearAlgebra::distributed::Vector<double> &src,
326 const std::pair<unsigned int, unsigned int> &cell_range) const;
327
328 void
329 setNonlinearEqInitialGuess();
330 void
331 computeLaplaceRHS(unsigned int fieldIndex);
332 void
333 getLaplaceRHS(const MatrixFree<dim, double> &data,
334 dealii::LinearAlgebra::distributed::Vector<double> &dst,
335 const dealii::LinearAlgebra::distributed::Vector<double> &src,
336 const std::pair<unsigned int, unsigned int> &cell_range) const;
337
338 /*Method to calculate RHS (implicit/explicit). This is an abstract method, so
339 * every model which inherits MatrixFreePDE<dim> has to implement this
340 * method.*/
341 void
342 getExplicitRHS(
343 const MatrixFree<dim, double> &data,
344 std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> &dst,
345 const std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> &src,
346 const std::pair<unsigned int, unsigned int> &cell_range) const;
347
348 void
349 getNonexplicitRHS(
350 const MatrixFree<dim, double> &data,
351 std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> &dst,
352 const std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> &src,
353 const std::pair<unsigned int, unsigned int> &cell_range) const;
354
355 virtual void
356 explicitEquationRHS(
357 [[maybe_unused]] variableContainer<dim, degree, VectorizedArray<double>>
358 &variable_list,
359 [[maybe_unused]] const Point<dim, VectorizedArray<double>> q_point_loc,
360 [[maybe_unused]] const VectorizedArray<double> element_volume) const = 0;
361
362 virtual void
363 nonExplicitEquationRHS(
364 [[maybe_unused]] variableContainer<dim, degree, VectorizedArray<double>>
365 &variable_list,
366 [[maybe_unused]] const Point<dim, VectorizedArray<double>> q_point_loc,
367 [[maybe_unused]] const VectorizedArray<double> element_volume) const = 0;
368
369 virtual void
370 equationLHS([[maybe_unused]] variableContainer<dim, degree, VectorizedArray<double>>
371 &variable_list,
372 [[maybe_unused]] const Point<dim, VectorizedArray<double>> q_point_loc,
373 [[maybe_unused]] const VectorizedArray<double> element_volume) const = 0;
374
375 virtual void
376 postProcessedFields(
377 [[maybe_unused]] const variableContainer<dim, degree, VectorizedArray<double>>
378 &variable_list,
379 [[maybe_unused]] variableContainer<dim, degree, VectorizedArray<double>>
380 &pp_variable_list,
381 [[maybe_unused]] const Point<dim, VectorizedArray<double>> q_point_loc,
382 [[maybe_unused]] const VectorizedArray<double> element_volume) const {};
383 void
384 computePostProcessedFields(
385 std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> &postProcessedSet);
386
387 void
388 getPostProcessedFields(
389 const MatrixFree<dim, double> &data,
390 std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> &dst,
391 const std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> &src,
392 const std::pair<unsigned int, unsigned int> &cell_range);
393
394 // methods to apply dirichlet BC's
395 /*Map of degrees of freedom to the corresponding Dirichlet boundary
396 * conditions, if any.*/
397 std::vector<std::map<types::global_dof_index, double> *> valuesDirichletSet;
398 /*Virtual method to mark the boundaries for applying Dirichlet boundary
399 * conditions. This is usually expected to be provided by the user.*/
400 void
401 markBoundaries(parallel::distributed::Triangulation<dim> &) const;
403 void
405
407 void
409
410 // Methods to apply periodic BCs
411 void
412 setPeriodicity();
413 void
414 setPeriodicityConstraints(AffineConstraints<double> *, const DoFHandler<dim> *) const;
415
426 void
427 set_rigid_body_mode_constraints(AffineConstraints<double> *constraints,
428 const DoFHandler<dim> *dof_handler,
429 const Point<dim> target_point = Point<dim>()) const;
430
431 // methods to apply initial conditions
432 /*Virtual method to apply initial conditions. This is usually expected to be
433 * provided by the user in IBVP (Initial Boundary Value Problems).*/
434
435 void
436 applyInitialConditions();
437
438 // --------------------------------------------------------------------------
439 // Methods for saving and loading checkpoints
440 // --------------------------------------------------------------------------
441
442 void
443 save_checkpoint();
444
445 void
446 load_checkpoint_triangulation();
447 void
448 load_checkpoint_fields();
449 void
450 load_checkpoint_time_info();
451
452 void
453 move_file(const std::string &, const std::string &);
454
455 void
456 verify_checkpoint_file_exists(const std::string &filename);
457
458 // --------------------------------------------------------------------------
459 // Nucleation methods and variables
460 // --------------------------------------------------------------------------
461 // Vector of all the nuclei seeded in the problem
462 std::vector<nucleus<dim>> nuclei;
463
464 // Method to get a list of new nuclei to be seeded
465 void
466 updateNucleiList();
467 std::vector<nucleus<dim>>
468 getNewNuclei();
469 void
470 getLocalNucleiList(std::vector<nucleus<dim>> &newnuclei) const;
471 void
472 safetyCheckNewNuclei(std::vector<nucleus<dim>> newnuclei,
473 std::vector<unsigned int> &conflict_ids);
474 void
475 refineMeshNearNuclei(std::vector<nucleus<dim>> newnuclei);
476 double
477 weightedDistanceFromNucleusCenter(const Point<dim, double> center,
478 const std::vector<double> &semiaxes,
479 const Point<dim, double> q_point_loc,
480 const unsigned int var_index) const;
481 VectorizedArray<double>
482 weightedDistanceFromNucleusCenter(const Point<dim, double> center,
483 const std::vector<double> &semiaxes,
484 const Point<dim, VectorizedArray<double>> q_point_loc,
485 const unsigned int var_index) const;
486
487 // Method to obtain the nucleation probability for an element, nontrival case
488 // must be implemented in the subsclass
489 [[nodiscard]] virtual double
490 getNucleationProbability(variableValueContainer,
491 double,
492 Point<dim>,
493 [[maybe_unused]] unsigned int variable_index) const
494 {
495 return 0.0;
496 };
497
498 // utility functions
499 /*Returns index of given field name if exists, else throw error.*/
500 unsigned int
501 getFieldIndex(std::string _name);
502
503 /*Method to compute the integral of a field.*/
504 void
505 computeIntegral(
506 double &integratedField,
507 int index,
508 std::vector<dealii::LinearAlgebra::distributed::Vector<double> *> variableSet);
509
510 // variables for time dependent problems
511 /*Flag used to see if invM, time stepping in run(), etc are necessary*/
512 bool isTimeDependentBVP;
513 /*Flag used to mark problems with Elliptic fields.*/
514 bool isEllipticBVP;
515
516 bool hasExplicitEquation;
517 bool hasNonExplicitEquation;
518 //
519 double currentTime;
520 unsigned int currentIncrement, currentOutput, currentCheckpoint,
521 current_grain_reassignment;
522
523 /*Timer and logging object*/
524 mutable TimerOutput computing_timer;
525
526 bool first_integrated_var_output_complete;
527
528 // Methods and variables for integration
529 double integrated_var;
530 unsigned int integral_index;
531 std::mutex assembler_lock;
532
533 /*AMR methods*/
535};
536
537template class MatrixFreePDE<2, 1>;
538template class MatrixFreePDE<3, 1>;
539
540template class MatrixFreePDE<2, 2>;
541template class MatrixFreePDE<3, 2>;
542
543template class MatrixFreePDE<3, 3>;
544template class MatrixFreePDE<2, 3>;
545
546template class MatrixFreePDE<3, 4>;
547template class MatrixFreePDE<2, 4>;
548
549template class MatrixFreePDE<3, 5>;
550template class MatrixFreePDE<2, 5>;
551
552template class MatrixFreePDE<3, 6>;
553template class MatrixFreePDE<2, 6>;
554
555#endif
Definition AdaptiveRefinement.h:23
Field class that handles the attributes of each field.
Definition fields.h:16
This is the abstract base class for the matrix free implementation of parabolic and elliptic BVP's,...
Definition matrixFreePDE.h:54
void applyDirichletBCs()
Definition boundaryConditions.cc:98
virtual void setInitialCondition(const Point< dim > &p, const unsigned int index, double &scalar_IC, Vector< double > &vector_IC)=0
Set the initial condition for all fields. This function is overriden in each application.
void applyNeumannBCs()
Definition boundaryConditions.cc:13
virtual void create_triangulation(parallel::distributed::Triangulation< dim > &tria) const
Create the mesh with the user provided domain sizes.
Definition init.cc:368
virtual void init()
Initializes the mesh, degrees of freedom, constraints and data structures using the user provided inp...
Definition init.cc:11
void compute_element_volume()
Compute element volume for the triangulation.
Definition init.cc:402
ConditionalOStream pcout
Parallel message stream.
Definition matrixFreePDE.h:129
void initForTests(std::vector< Field< dim > > _fields)
Initializes the data structures for enabling unit tests.
std::vector< Field< dim > > fields
Vector of all the physical fields in the problem. Fields are identified by dimentionality (SCALAR/VEC...
Definition matrixFreePDE.h:118
void set_rigid_body_mode_constraints(AffineConstraints< double > *constraints, const DoFHandler< dim > *dof_handler, const Point< dim > target_point=Point< dim >()) const
Set constraints to pin the solution to 0 at a certain vertex. This is automatically done at the origi...
Definition boundaryConditions.cc:282
virtual void solveIncrement(bool skip_time_dependent)
Definition solveIncrement.cc:10
~MatrixFreePDE() override
Class destructor.
Definition matrixFreePDE.cc:39
virtual void setNonUniformDirichletBCs(const Point< dim > &p, const unsigned int index, const unsigned int direction, const double time, double &scalar_BC, Vector< double > &vector_BC)=0
Set the spatially or temporally non-uniform boundary conditions. This function is overriden in each a...
void buildFields()
Create the vector of all physical fields in the problem.
Definition buildFields.cc:16
void reassignGrains()
Definition reassignGrains.cc:9
void solve()
This method implements the time stepping algorithm and invokes the solveIncrement() method.
Definition solve.cc:8
dealii::AlignedVector< dealii::VectorizedArray< double > > element_volume
Vector that stores element volumes.
Definition matrixFreePDE.h:305
void vmult(dealii::LinearAlgebra::distributed::Vector< double > &dst, const dealii::LinearAlgebra::distributed::Vector< double > &src) const
This method essentially converts the MatrixFreePDE object into a matrix object which can be used with...
Definition computeLHS.cc:9
Definition userInputParameters.h:47
Definition variableContainer.h:17
Definition variableValueContainer.h:7
Definition nucleus.h:18