MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
mtop_integrators.hpp
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#ifndef MTOPINTEGRATORS_HPP
13#define MTOPINTEGRATORS_HPP
14
15#include "mfem.hpp"
17
18#include <map>
19
20namespace mfem
21{
22
23/// Base class for representing function at integration points.
25{
26public:
27 virtual ~BaseQFunction() {}
28
29 /// Returns a user defined string identifying the function.
30 virtual std::string GetType()=0;
31
32 // Returns the energy at an integration point.
33 virtual
36 {
37 return 0.0;
38 }
39
40 // Returns the residual at an integration point.
41 virtual
43 mfem::Vector &dd, mfem::Vector &uu, mfem::Vector &rr)=0;
44
45 /// Returns the gradient of the residual at a integration point.
46 virtual
49
50 /// Returns the gradient of the residual with respect to the design
51 /// parameters, multiplied by the adjoint.
52 virtual
55 mfem::Vector &aa, mfem::Vector &rr)=0;
56
57};
58
59/* QLinearDiffusion implements methods for computing the energy, the residual,
60 * gradient of the residual and the product of the adjoint fields with the
61 * derivative of the residual with respect to the parameters. All computations
62 * are performed at a integration point. Therefore the vectors (vv,uu,aa,rr ..)
63 * hold the fields' values and the fields' derivatives at the integration
64 * point. For example for a single scalar parametric field representing the
65 * density in topology optimization the vector dd will have size one and the
66 * element will be the density at the integration point. The map between state
67 * and parameter is not fixed and depends on the implementation of the QFunction
68 * class. */
70{
71public:
73 real_t pp=1.0, real_t minrho=1e-7, real_t betac=4.0, real_t etac=0.5):
74 diff(diffco),load(hsrco), powerc(pp), rhomin(minrho), beta(betac), eta(etac)
75 {
76
77 }
78
79 std::string GetType() override
80 {
81 return "QLinearDiffusion";
82 }
83
85 Vector &dd, Vector &uu) override
86 {
87 // dd[0] - density
88 // uu[0] - grad_x
89 // uu[1] - grad_y
90 // uu[2] - grad_z
91 // uu[3] - temperature/scalar field
92
93 real_t di=diff.Eval(T,ip);
94 real_t ll=load.Eval(T,ip);
95 // Computes the physical density using projection.
96 real_t rz=0.5+0.5*std::tanh(beta*(dd[0]-eta)); //projection
97 // Computes the diffusion coefficient at the integration point.
98 real_t fd=di*(std::pow(rz,powerc)+rhomin);
99 // Computes the sum of the energy and the product of the temperature and
100 // the external input at the integration point.
101 real_t rez = 0.5*(uu[0]*uu[0]+uu[1]*uu[1]+uu[2]*uu[2])*fd-uu[3]*ll;
102 return rez;
103 }
104
105 /// Returns the derivative of QEnergy with respect to the state vector uu.
107 Vector &dd, Vector &uu, Vector &rr) override
108 {
109 real_t di=diff.Eval(T,ip);
110 real_t ll=load.Eval(T,ip);
111 real_t rz=0.5+0.5*std::tanh(beta*(dd[0]-eta));
112 real_t fd=di*(std::pow(rz,powerc)+rhomin);
113
114 rr[0]=uu[0]*fd;
115 rr[1]=uu[1]*fd;
116 rr[2]=uu[2]*fd;
117 rr[3]=-ll;
118 }
119
120
121 // Returns the derivative, with respect to the density, of the product of
122 // the adjoint field with the residual at the integration point ip.
124 Vector &dd, Vector &uu, Vector &aa, Vector &rr) override
125 {
126 real_t di=diff.Eval(T,ip);
127 real_t tt=std::tanh(beta*(dd[0]-eta));
128 real_t rz=0.5+0.5*tt;
129 real_t fd=di*powerc*std::pow(rz,powerc-1.0)*0.5*(1.0-tt*tt)*beta;
130
131 rr[0] = -(aa[0]*uu[0]+aa[1]*uu[1]+aa[2]*uu[2])*fd;
132 }
133
134 // Returns the gradient of the residual with respect to the state vector at
135 // the integration point ip.
137 Vector &dd, Vector &uu, DenseMatrix &hh) override
138 {
139 real_t di=diff.Eval(T,ip);
140 real_t tt=std::tanh(beta*(dd[0]-eta));
141 real_t rz=0.5+0.5*tt;
142 real_t fd=di*(std::pow(rz,powerc)+rhomin);
143 hh=0.0;
144
145 hh(0,0)=fd;
146 hh(1,1)=fd;
147 hh(2,2)=fd;
148 hh(3,3)=0.0;
149 }
150
151private:
152 mfem::Coefficient& diff; //diffusion coefficient
153 mfem::Coefficient& load; //load coefficient
154 real_t powerc; //penalization coefficient
155 real_t rhomin; //lower bound for the density
156 real_t beta; //controls the sharpness of the projection
157 real_t eta; //projection threshold for tanh
158};
159
160/// Provides implementation of an integrator for linear diffusion with
161/// parametrization provided by a density field. The setup is standard for
162/// topology optimization problems.
164{
165public:
167 {
168
169 }
170
171 /// Computes the local energy.
175 const Array<const Vector *> &elfun,
176 const Array<const Vector *> &pelfun) override;
177
178 /// Computes the element's residual.
182 const Array<const Vector *> &elfun,
183 const Array<const Vector *> &pelfun,
184 const Array<Vector *> &elvec) override;
185
186 /// Computes the stiffness/tangent matrix.
190 const Array<const Vector *> &elfun,
191 const Array<const Vector *> &pelfun,
192 const Array2D<DenseMatrix *> &elmats) override;
193
194 /// Computes the product of the adjoint solution and the derivative of the
195 /// residual with respect to the parametric fields.
199 const Array<const Vector *> &elfun,
200 const Array<const Vector *> &alfun,
201 const Array<const Vector *> &pelfun,
202 const Array<Vector *> &elvec) override;
203private:
204 BaseQFunction& qfun;
205};
206
207
208/// Computes an example of nonlinear objective
209/// $\int \rm{field}*\rm{field}*\rm{weight})\rm{d}\Omega_e$.
211{
212public:
213
215 {
216
217 }
218
219 /// Returns the objective contribution at element level.
222 const Array<const Vector *> &elfun) override;
223
224 /// Returns the gradient of the objective contribution at element level.
227 const Array<const Vector *> &elfun,
228 const Array<Vector *> &elvec) override;
229};
230
231}
232
233#endif
Dynamic 2D array using row-major layout.
Definition array.hpp:392
Base class for representing function at integration points.
virtual void QResidual(ElementTransformation &T, const IntegrationPoint &ip, mfem::Vector &dd, mfem::Vector &uu, mfem::Vector &rr)=0
virtual void AQResidual(ElementTransformation &T, const IntegrationPoint &ip, mfem::Vector &dd, mfem::Vector &uu, mfem::Vector &aa, mfem::Vector &rr)=0
virtual std::string GetType()=0
Returns a user defined string identifying the function.
virtual real_t QEnergy(ElementTransformation &T, const IntegrationPoint &ip, mfem::Vector &dd, mfem::Vector &uu)
virtual void QGradResidual(ElementTransformation &T, const IntegrationPoint &ip, mfem::Vector &dd, mfem::Vector &uu, mfem::DenseMatrix &hh)=0
Returns the gradient of the residual at a integration point.
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.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void AssembleElementVector(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array< Vector * > &elvec) override
Returns the gradient of the objective contribution at element level.
real_t GetElementEnergy(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun) override
Returns the objective contribution at element level.
Class for integration point with weight.
Definition intrules.hpp:35
void AssembleElementVector(const Array< const FiniteElement * > &el, const Array< const FiniteElement * > &pel, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array< const Vector * > &pelfun, const Array< Vector * > &elvec) override
Computes the element's residual.
ParametricLinearDiffusion(BaseQFunction &qfunm)
real_t GetElementEnergy(const Array< const FiniteElement * > &el, const Array< const FiniteElement * > &pel, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array< const Vector * > &pelfun) override
Computes the local energy.
void AssemblePrmElementVector(const Array< const FiniteElement * > &el, const Array< const FiniteElement * > &pel, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array< const Vector * > &alfun, const Array< const Vector * > &pelfun, const Array< Vector * > &elvec) override
void AssembleElementGrad(const Array< const FiniteElement * > &el, const Array< const FiniteElement * > &pel, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array< const Vector * > &pelfun, const Array2D< DenseMatrix * > &elmats) override
Computes the stiffness/tangent matrix.
QLinearDiffusion(mfem::Coefficient &diffco, mfem::Coefficient &hsrco, real_t pp=1.0, real_t minrho=1e-7, real_t betac=4.0, real_t etac=0.5)
real_t QEnergy(ElementTransformation &T, const IntegrationPoint &ip, Vector &dd, Vector &uu) override
void QGradResidual(ElementTransformation &T, const IntegrationPoint &ip, Vector &dd, Vector &uu, DenseMatrix &hh) override
Returns the gradient of the residual at a integration point.
void QResidual(ElementTransformation &T, const IntegrationPoint &ip, Vector &dd, Vector &uu, Vector &rr) override
Returns the derivative of QEnergy with respect to the state vector uu.
void AQResidual(ElementTransformation &T, const IntegrationPoint &ip, Vector &dd, Vector &uu, Vector &aa, Vector &rr) override
std::string GetType() override
Returns a user defined string identifying the function.
Vector data type.
Definition vector.hpp:82
float real_t
Definition config.hpp:43