MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
elastoperator.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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#include "elastoperator.hpp"
13
14namespace mfem
15{
16
17void ElasticityOperator::Init()
18{
19 int dim = pmesh->Dimension();
20 fec = new H1_FECollection(order,dim);
21 fes = new ParFiniteElementSpace(pmesh,fec,dim,Ordering::byVDIM);
22 globalntdofs = fes->GlobalTrueVSize();
23 pmesh->SetNodalFESpace(fes);
24
25 auto ref_func = [](const Vector & x, Vector & y) { y = x; };
26 VectorFunctionCoefficient ref_cf(dim,ref_func);
27 ParGridFunction xr(fes); xr.ProjectCoefficient(ref_cf);
28 xr.GetTrueDofs(xref);
29 SetEssentialBC();
30 SetUpOperator();
31}
32
33void ElasticityOperator::SetEssentialBC()
34{
35 ess_tdof_list.SetSize(0);
36 if (pmesh->bdr_attributes.Size())
37 {
38 ess_bdr.SetSize(pmesh->bdr_attributes.Max());
39 }
40 ess_bdr = 0;
41 Array<int> ess_tdof_list_temp;
42 for (int i = 0; i < ess_bdr_attr.Size(); i++ )
43 {
44 ess_bdr[ess_bdr_attr[i]-1] = 1;
45 fes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list_temp,ess_bdr_attr_comp[i]);
46 ess_tdof_list.Append(ess_tdof_list_temp);
47 ess_bdr[ess_bdr_attr[i]-1] = 0;
48 }
49}
50
51void ElasticityOperator::SetUpOperator()
52{
53 x.SetSpace(fes); x = 0.0;
54 b = new ParLinearForm(fes);
55 if (nonlinear)
56 {
57 material_model = new NeoHookeanModel(c1_cf, c2_cf);
58 op = new ParNonlinearForm(fes);
59 dynamic_cast<ParNonlinearForm*>(op)->AddDomainIntegrator(
60 new HyperelasticNLFIntegrator(material_model));
61 dynamic_cast<ParNonlinearForm*>(op)->SetEssentialTrueDofs(ess_tdof_list);
62 }
63 else
64 {
65 op = new ParBilinearForm(fes);
66 dynamic_cast<ParBilinearForm*>(op)->AddDomainIntegrator(
67 new ElasticityIntegrator(c1_cf,c2_cf));
68 K = new HypreParMatrix();
69 dynamic_cast<ParBilinearForm*>(op)->Assemble();
70 dynamic_cast<ParBilinearForm*>(op)->FormSystemMatrix(ess_tdof_list,*K);
71 }
72}
73
75 Array<int> & ess_bdr_attr_, Array<int> & ess_bdr_attr_comp_,
76 const Vector & E, const Vector & nu, bool nonlinear_)
77 : nonlinear(nonlinear_), pmesh(pmesh_), ess_bdr_attr(ess_bdr_attr_),
78 ess_bdr_attr_comp(ess_bdr_attr_comp_)
79{
80 comm = pmesh->GetComm();
81 SetParameters(E,nu);
82 Init();
83}
84
86{
87 int n = (pmesh->attributes.Size()) ? pmesh->attributes.Max() : 0;
88 MFEM_VERIFY(E.Size() == n, "Incorrect parameter size E");
89 MFEM_VERIFY(nu.Size() == n, "Incorrect parameter size nu");
90 c1.SetSize(n);
91 c2.SetSize(n);
92 if (nonlinear)
93 {
94 for (int i = 0; i<n; i++)
95 {
96 c1(i) = 0.5*E(i) / (1+nu(i));
97 c2(i) = E(i)/(1.0-2.0*nu(i))/3.0;
98 }
99 }
100 else
101 {
102 for (int i = 0; i<n; i++)
103 {
104 c1(i) = E(i) * nu(i) / ( (1+nu(i)) * (1-2*nu(i)) );
105 c2(i) = 0.5 * E(i)/(1+nu(i));
106 }
107 }
108 c1_cf.UpdateConstants(c1);
109 c2_cf.UpdateConstants(c2);
110}
111
113 Array<int> & bdr_marker)
114{
115 pressure_cf.constant = f.constant;
117 bdr_marker);
118}
119
121 Array<int> essbdr)
122{
124 x.ProjectBdrCoefficient(delta_cf,essbdr);
125}
126
128{
129 if (!formsystem)
130 {
131 formsystem = true;
132 b->Assemble();
133 B.SetSize(fes->GetTrueVSize());
134 b->ParallelAssemble(B);
135 B.SetSubVector(ess_tdof_list, 0.0);
136 if (!nonlinear)
137 {
138 x.GetTrueDofs(X);
139 dynamic_cast<ParBilinearForm*>(op)->ParallelEliminateTDofsInRHS(ess_tdof_list,
140 X, B);
141 }
142 }
143}
144
146{
147 formsystem = false;
148 delete b;
149 b = new ParLinearForm(fes);
150 x = 0.0;
151}
152
154{
155 if (nonlinear)
156 {
157 real_t energy = 0.0;
158 Vector tu(xref); tu += u;
159 ParGridFunction u_gf(fes);
160 u_gf.SetFromTrueDofs(tu);
161 energy += dynamic_cast<ParNonlinearForm*>(op)->GetEnergy(u_gf);
162 energy -= InnerProduct(comm, B, u);
163 return energy;
164 }
165 else
166 {
167 Vector ku(K->Height());
168 K->Mult(u,ku);
169 return 0.5 * InnerProduct(comm,u, ku) - InnerProduct(comm,u, B);
170 }
171}
172
173void ElasticityOperator::GetGradient(const Vector & u, Vector & gradE) const
174{
175 if (nonlinear)
176 {
177 Vector tu(xref); tu += u;
178 gradE.SetSize(op->Height());
179 dynamic_cast<ParNonlinearForm*>(op)->Mult(tu, gradE);
180 }
181 else
182 {
183 gradE.SetSize(K->Height());
184 K->Mult(u, gradE);
185 }
186 gradE.Add(-1.0, B);
187}
188
190{
191 if (nonlinear)
192 {
193 Vector tu(xref); tu += u;
194 return dynamic_cast<HypreParMatrix *>(&dynamic_cast<ParNonlinearForm*>
195 (op)->GetGradient(tu));
196 }
197 else
198 {
199 return K;
200 }
201}
202
204{
205 delete op;
206 delete b;
207 delete fes;
208 delete fec;
209 if (K) { delete K; }
210 if (material_model) { delete material_model; }
211}
212
213}
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition array.cpp:69
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:840
int Size() const
Return the logical size of the array.
Definition array.hpp:166
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:912
A coefficient that is constant across space and time.
ElasticityOperator(ParMesh *pmesh_, Array< int > &ess_bdr_attr_, Array< int > &ess_bdr_attr_comp_, const Vector &E, const Vector &nu, bool nonlinear_=false)
Construct an ElasticityOperator.
void FormLinearSystem()
Assemble and form the linear system (matrix and RHS).
void UpdateRHS()
Reset and reassemble the RHS linear form.
void SetNeumanPressureData(ConstantCoefficient &f, Array< int > &bdr_marker)
Apply Neumann (pressure) boundary condition on a set of boundary markers.
~ElasticityOperator()
Destructor (cleans up FE space, operator, and material model).
void GetGradient(const Vector &u, Vector &gradE) const
Compute the gradient of the energy functional at a given displacement vector.
void SetParameters(const Vector &E, const Vector &nu)
Set material parameters from vectors of Young’s modulus (E) and Poisson’s ratio (ν).
HypreParMatrix * GetHessian(const Vector &u)
Get the Hessian (stiffness matrix) at a given displacement vector.
virtual void Mult(const Vector &U, Vector &Y) const override
Compute the residual Y = R(U) representing the elasticity equation with a material model chosen by ca...
void SetDisplacementDirichletData(const Vector &delta, Array< int > essbdr)
Apply Dirichlet (displacement) boundary condition on a set of boundary markers.
real_t GetEnergy(const Vector &u) const
Compute the elastic energy functional at a given displacement vector.
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:419
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, real_t alpha=1.0, real_t beta=0.0) const
Computes y = alpha * A * x + beta * y.
Definition hypre.cpp:1863
A class to initialize the size of a Tensor.
Definition dtensor.hpp:57
void AddBoundaryIntegrator(LinearFormIntegrator *lfi)
Adds new Boundary Integrator. Assumes ownership of lfi.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition mesh.hpp:304
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1306
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition mesh.hpp:302
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
void UpdateConstants(Vector &c)
Update the constants with vector c.
Class for parallel bilinear form.
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
HYPRE_BigInt GlobalTrueVSize() const
Definition pfespace.hpp:349
int GetTrueVSize() const override
Return the number of local vector true dofs.
Definition pfespace.hpp:353
Class for parallel grid function.
Definition pgridfunc.hpp:50
void SetFromTrueDofs(const Vector &tv) override
Set the GridFunction from the given true-dof vector.
Class for parallel linear form.
void ParallelAssemble(Vector &tv)
Assemble the vector on the true dofs, i.e. P^t v.
void Assemble()
Assembles the ParLinearForm i.e. sums over all domain/bdr integrators.
Class for parallel meshes.
Definition pmesh.hpp:34
MPI_Comm GetComm() const
Definition pmesh.hpp:405
void SetNodalFESpace(FiniteElementSpace *nfes) override
Definition pmesh.cpp:2038
Parallel non-linear operator on the true dofs.
Vector coefficient that is constant in space and time.
Vector data type.
Definition vector.hpp:82
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
Definition vector.cpp:702
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Definition vector.cpp:326
int dim
Definition ex24.cpp:53
real_t delta
Definition lissajous.cpp:43
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
real_t InnerProduct(HypreParVector *x, HypreParVector *y)
Definition hypre.cpp:468
float real_t
Definition config.hpp:46
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30