MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
mtop_solvers.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_MTOP_SOLVERS_HPP
13#define MFEM_MTOP_SOLVERS_HPP
14
15#include <memory>
16
17#include "mfem.hpp"
18
20
21///////////////////////////////////////////////////////////////////////////////
22/// \brief The IsoElasticityLambdaCoeff class converts E modulus of elasticity
23/// and Poisson's ratio to Lame's lambda coefficient
25{
26 mfem::Coefficient *E, *nu;
27
28public:
29 /// Constructor - takes as inputs E modulus and Poisson's ratio
33
34 /// Evaluates the Lame's lambda coefficient
36 const mfem::IntegrationPoint &ip) override
37 {
38 const real_t EE = E->Eval(T, ip);
39 const real_t nn = nu->Eval(T, ip);
40 constexpr auto Lambda = [](const real_t E, const real_t nu)
41 {
42 return E * nu / (1.0 + nu) / (1.0 - 2.0 * nu);
43 };
44 return Lambda(EE, nn);
45 }
46};
47
48///////////////////////////////////////////////////////////////////////////////
49/// \brief The IsoElasticityShearCoeff class converts E modulus of elasticity
50/// and Poisson's ratio to Shear coefficient
51///
53{
54 mfem::Coefficient *E, *nu;
55
56public:
57 /// Constructor - takes as inputs E modulus and Poisson's ratio
60
61 /// Evaluates the shear coefficient
63 const mfem::IntegrationPoint &ip) override
64 {
65 const real_t EE = E->Eval(T, ip);
66 const real_t nn = nu->Eval(T, ip);
67 constexpr auto Shear = [](const real_t E, const real_t nu)
68 {
69 return E / (2.0 * (1.0 + nu));
70 };
71 return Shear(EE, nn);
72 }
73};
74
75///////////////////////////////////////////////////////////////////////////////
76/// \brief The IsoLinElasticSolver class provides a solver for
77/// linear isotropic elasticity. The solver provides options for
78/// partial assembly, dFEM based integrators, and full assembly.
79/// The preconditioners are based on block LOR approximations.
81{
82public:
83 /// Construct the solver for a given mesh and discretization
84 /// order. The parameters pa and dfem define the utilization of
85 /// partial assembly or dFEM based integrators.
86 IsoLinElasticSolver(mfem::ParMesh *mesh, int vorder = 1,
87 bool pa = false, bool dfem = false);
88
89 /// Destructor of the solver.
91
92 /// Sets the linear solver relative tolerance (rtol),
93 /// absolute tolerance (atol) and maximum number of
94 /// iterations miter.
95 void SetLinearSolver(real_t rtol = 1e-8,
96 real_t atol = 1e-12,
97 int miter = 200);
98
99 /// Solves the forward problem.
100 void FSolve();
101
102 /// Adds displacement BC in direction 0(x), 1(y), 2(z), or -1(all).
103 void AddDispBC(int id, int dir, real_t val);
104
105 /// Adds displacement BC in direction 0(x), 1(y), 2(z), or -1(all).
106 void AddDispBC(int id, int dir, mfem::Coefficient &val);
107
108 /// Clear all displacement BC
109 void DelDispBC();
110
111 /// Set the values of the volumetric force.
112 void SetVolForce(real_t fx, real_t fy, real_t fz = 0.0);
113
114 /// Add surface load.
115 void AddSurfLoad(int id, real_t fx, real_t fy, real_t fz = 0.0)
116 {
117 mfem::Vector vec;
118 vec.SetSize(spaceDim);
119 vec[0] = fx;
120 vec[1] = fy;
121 if (spaceDim == 3) { vec[2] = fz; }
122 auto *vc = new mfem::VectorConstantCoefficient(vec);
123 if (load_coeff.find(id) != load_coeff.end()) { delete load_coeff[id]; }
124 load_coeff[id] = vc;
125 }
126
127 /// Add surface load
129 {
130 surf_loads[id] = &ff;
131 }
132
133 /// Associates coefficient to the volumetric force.
135
136 /// Returns the displacements.
138 {
139 fdisp.SetFromTrueDofs(sol);
140 return fdisp;
141 }
142
143 /// Returns the adjoint displacements.
145 {
146 adisp.SetFromTrueDofs(adj);
147 return adisp;
148 }
149
150 /// Returns the solution vector.
152
153 /// Returns the adjoint solution vector.
155
156 /// Returns the displacements.
158 {
159 sgf.SetSpace(vfes);
160 sgf.SetFromTrueDofs(sol);
161 }
162
163 /// Returns the adjoint displacements.
165 {
166 agf.SetSpace(vfes);
167 agf.SetFromTrueDofs(adj);
168 }
169
170 /// Sets BC dofs, bilinear form, preconditioner and solver.
171 /// Should be called before calling Mult or MultTranspose
172 virtual void Assemble();
173
174 /// Forward solve with given RHS. x is the RHS vector.
175 void Mult(const mfem::Vector &x, mfem::Vector &y) const override;
176
177 /// Adjoint solve with given RHS. x is the RHS vector.
178 /// The essential BCs are set to zero.
179 void MultTranspose(const mfem::Vector &x, mfem::Vector &y) const override;
180
181 /// Set material
183 {
184 E = &E_;
185 nu = &nu_;
186
187 delete lambda;
188 delete mu;
189 delete bf; bf=nullptr;
190 dop.release();
191
192 lambda = new IsoElasticityLambdaCoeff(E, nu);
193 mu = new IsoElasticityShearCoeff(E, nu);
194 }
195
198 {
199 public:
201 const mfem::IntegrationRule &ir,
202 int vdim) :
203 mfem::future::UniformParameterSpace(mesh, ir, vdim, false)
204 {
205 dtq.nqpt = ir.GetNPoints();
206 }
207 };
208
209 // creates a list with essential dofs
210 // sets the values in the bsol vector
211 // the list is written in ess_dofs
212 // The 'nvcc' compiler needs these SetEssTDofs functions to be public.
213 void SetEssTDofs(mfem::Vector &bsol, mfem::Array<int> &ess_dofs);
214 void SetEssTDofs(const int j, mfem::ParFiniteElementSpace &scalar_space,
215 mfem::Array<int> &ess_dofs);
216private:
217 mfem::ParMesh *pmesh;
218 const bool pa, dfem; // partial assembly, dFEM operator
219 const int dim, spaceDim;
220
221 // finite element collection for linear elasticity
223
224 // finite element space for linear elasticity
226
227 // solution true vector
228 mutable mfem::Vector sol;
229 // adjoint true vector
230 mutable mfem::Vector adj;
231 // RHS
232 mutable mfem::Vector rhs;
233
234 // forward solution
236 // adjoint solution
238
239 // Linear solver parameters
240 real_t linear_rtol;
241 real_t linear_atol;
242 int linear_iter;
243
244 mfem::HypreBoomerAMG *prec; // preconditioner
245 mfem::CGSolver *ls; // linear solver
246
247 // PA LOR preconditioner
248 mfem::Array<int> lor_block_offsets;
249 std::unique_ptr<mfem::Solver> lor_pa_prec;
250 std::unique_ptr<mfem::ParLORDiscretization> lor_disc;
251 std::unique_ptr<mfem::ElasticityIntegrator> lor_integrator;
252 std::unique_ptr<mfem::ParFiniteElementSpace> lor_scalar_fespace;
253 std::unique_ptr<mfem::BlockDiagonalPreconditioner> lor_blockDiag;
254 std::vector<std::unique_ptr<mfem::ParBilinearForm>> lor_bilinear_forms;
255 std::vector<std::unique_ptr<mfem::HypreParMatrix>> lor_block;
256 std::vector<std::unique_ptr<mfem::HypreBoomerAMG>> lor_amg_blocks;
257
258 /// Volumetric force created by the solver.
260 /// Volumetric force coefficient can point to the one
261 /// created by the solver or to external vector coefficient.
262 mfem::VectorCoefficient *volforce;
263
264 // surface loads
265 using VectorCoefficientPtrMap = std::map<int, mfem::VectorCoefficient *>;
266 VectorCoefficientPtrMap load_coeff; // internally generated load
267 VectorCoefficientPtrMap surf_loads; // external vector coefficients
268
269 class SurfaceLoad;
270 std::unique_ptr<SurfaceLoad> lcsurf_load; // locally generated surface loads
271 std::unique_ptr<SurfaceLoad> glsurf_load; // global surface loads
272
273 // boundary conditions for x,y, and z directions
274 using ConstantCoefficientMap = std::map<int, mfem::ConstantCoefficient>;
275 ConstantCoefficientMap bcx, bcy, bcz;
276
277 // holds BC in coefficient form
278 using CoefficientPtrMap = std::map<int, mfem::Coefficient *>;
279 CoefficientPtrMap bccx, bccy, bccz;
280
281 // holds the displacement constrained DOFs
282 mfem::Array<int> ess_tdofv;
283
284 mfem::Coefficient *E, *nu;
285 mfem::Coefficient *lambda, *mu;
286
289 std::unique_ptr<mfem::OperatorHandle> Kh;
290 std::unique_ptr<mfem::HypreParMatrix> K, Ke;
291
292 // beginning of dFEM definitions
293 // U - displacements, Coords - nodal coordinates
294 // E modulus sampled on integration points
295 // Nu Poisson's ratio sampled on integration points
296 static constexpr int U = 0, Coords = 1, LCoeff = 2, MuCoeff = 3;
297 const mfem::FiniteElement *fe;
300 mfem::Array<int> domain_attributes;
301 const mfem::IntegrationRule &ir;
303 NqptUniformParameterSpace Lambda_ps, Mu_ps;
304 std::unique_ptr<mfem::CoefficientVector> Lambda_cv, Mu_cv;
305 std::unique_ptr<mfem::future::DifferentiableOperator> dop;
306 // end of dFEM definitions
307
309
310 class SurfaceLoad: public mfem::VectorCoefficient
311 {
312 VectorCoefficientPtrMap *map;
313 public:
314 SurfaceLoad(int dim, VectorCoefficientPtrMap &cmap):
316 {
317 map = &cmap;
318 }
320
322 const mfem::IntegrationPoint &ip) override
323 {
324 V.SetSize(GetVDim());
325 V = 0.0;
326 auto it = map->find(T.Attribute);
327 if (it != map->end()) { it->second->Eval(V, T, ip); }
328 }
329 };
330};
331
332#endif // MFEM_MTOP_SOLVERS_HPP
The IsoElasticityLambdaCoeff class converts E modulus of elasticity and Poisson's ratio to Lame's lam...
IsoElasticityLambdaCoeff(mfem::Coefficient *E, mfem::Coefficient *nu)
Constructor - takes as inputs E modulus and Poisson's ratio.
real_t Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override
Evaluates the Lame's lambda coefficient.
The IsoElasticityShearCoeff class converts E modulus of elasticity and Poisson's ratio to Shear coeff...
real_t Eval(mfem::ElementTransformation &T, const mfem::IntegrationPoint &ip) override
Evaluates the shear coefficient.
IsoElasticityShearCoeff(mfem::Coefficient *E_, mfem::Coefficient *nu_)
Constructor - takes as inputs E modulus and Poisson's ratio.
NqptUniformParameterSpace(mfem::ParMesh &mesh, const mfem::IntegrationRule &ir, int vdim)
The IsoLinElasticSolver class provides a solver for linear isotropic elasticity. The solver provides ...
void SetEssTDofs(mfem::Vector &bsol, mfem::Array< int > &ess_dofs)
void AddDispBC(int id, int dir, real_t val)
Adds displacement BC in direction 0(x), 1(y), 2(z), or -1(all).
mfem::Vector & GetAdjointSolutionVector()
Returns the adjoint solution vector.
void FSolve()
Solves the forward problem.
void SetVolForce(real_t fx, real_t fy, real_t fz=0.0)
Set the values of the volumetric force.
void Mult(const mfem::Vector &x, mfem::Vector &y) const override
Forward solve with given RHS. x is the RHS vector.
void SetMaterial(mfem::Coefficient &E_, mfem::Coefficient &nu_)
Set material.
void GetAdj(mfem::ParGridFunction &agf)
Returns the adjoint displacements.
mfem::ParGridFunction & GetDisplacements()
Returns the displacements.
void GetSol(mfem::ParGridFunction &sgf)
Returns the displacements.
void SetLinearSolver(real_t rtol=1e-8, real_t atol=1e-12, int miter=200)
void AddSurfLoad(int id, real_t fx, real_t fy, real_t fz=0.0)
Add surface load.
IsoLinElasticSolver(mfem::ParMesh *mesh, int vorder=1, bool pa=false, bool dfem=false)
mfem::Vector & GetSolutionVector()
Returns the solution vector.
~IsoLinElasticSolver()
Destructor of the solver.
mfem::ParGridFunction & GetADisplacements()
Returns the adjoint displacements.
void AddSurfLoad(int id, mfem::VectorCoefficient &ff)
Add surface load.
virtual void Assemble()
void MultTranspose(const mfem::Vector &x, mfem::Vector &y) const override
void DelDispBC()
Clear all displacement BC.
Conjugate gradient method.
Definition solvers.hpp:627
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
Square Operator for imposing essential boundary conditions using only the action, Mult(),...
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Definition fe_base.hpp:190
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
Abstract class for all finite elements.
Definition fe_base.hpp:294
The BoomerAMG solver in hypre.
Definition hypre.hpp:1829
Class for integration point with weight.
Definition intrules.hpp:35
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:96
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:255
Abstract operator.
Definition operator.hpp:27
Class for parallel bilinear form.
Abstract parallel finite element space.
Definition pfespace.hpp:31
Class for parallel grid function.
Definition pgridfunc.hpp:50
void SetFromTrueDofs(const Vector &tv) override
Set the GridFunction from the given true-dof vector.
void SetSpace(FiniteElementSpace *f) override
Associate a new FiniteElementSpace with the ParGridFunction.
Class for parallel linear form.
Class for parallel meshes.
Definition pmesh.hpp:35
Class representing the storage layout of a QuadratureFunction.
Definition qspace.hpp:164
Base class for vector Coefficients that optionally depend on time and space.
int GetVDim()
Returns dimension of the vector.
VectorCoefficient(int vd)
Initialize the VectorCoefficient with vector dimension vd.
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
Vector coefficient that is constant in space and time.
Vector data type.
Definition vector.hpp:82
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:633
UniformParameterSpace(Mesh &mesh, const IntegrationRule &ir, int vdim, bool used_in_tensor_product=true)
Constructor for a uniform parameter space.
int dim
Definition ex24.cpp:53
real_t mu
Definition ex25.cpp:140
mfem::real_t real_t
float real_t
Definition config.hpp:46
std::array< int, NCMesh::MaxFaceNodes > nodes