MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
sbm_solver.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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_SBM_SOLVER_HPP
13#define MFEM_SBM_SOLVER_HPP
14
15#include "mfem.hpp"
16#include "marking.hpp"
17
18namespace mfem
19{
20
21/// ShiftedFunctionCoefficient, similar to FunctionCoefficient, but also takes
22/// into account a displacement vector if specified.
24{
25protected:
26 std::function<real_t(const Vector &)> Function;
29
30public:
31 ShiftedFunctionCoefficient(std::function<real_t(const Vector &v)> F)
32 : Function(std::move(F)), constantcoefficient(false) { }
34 : constant(constant_), constantcoefficient(true) { }
35
37 {
38 if (constantcoefficient) { return constant; }
39
40 Vector D(T.GetSpaceDim());
41 D = 0.;
42 return (this)->Eval(T, ip, D);
43 }
44
45 /// Evaluate the coefficient at @a ip + @a D.
47 const IntegrationPoint &ip,
48 const Vector &D);
49};
50
52{
53protected:
54 std::function<void(const Vector &, Vector &)> Function;
55
56public:
58 std::function<void(const Vector &, Vector &)> F)
59 : VectorCoefficient(dim), Function(std::move(F)) { }
60
62 virtual void Eval(Vector &V, ElementTransformation &T,
63 const IntegrationPoint &ip)
64 {
65 Vector D(vdim);
66 D = 0.;
67 return (this)->Eval(V, T, ip, D);
68 }
69
70 /// Evaluate the coefficient at @a ip + @a D.
71 void Eval(Vector &V,
73 const IntegrationPoint &ip,
74 const Vector &D);
75};
76
77/// BilinearFormIntegrator for the high-order extension of shifted boundary
78/// method.
79/// $$
80/// A(u, w) = -\langle \nabla u \cdot n, w \rangle
81/// -\langle u + \nabla u \cdot d + h.o.t, \nabla w.n \rangle
82/// +\langle \alpha h^{-1} (u + \nabla u \cdot d + h.o.t), w + \nabla w \cdot d + h.o.t \rangle
83/// $$
84/// where $h.o.t$ include higher-order derivatives ($\nabla^k u$) due to Taylor
85/// expansion. Since this interior face integrator is applied to the surrogate
86/// boundary (see marking.hpp for notes on how the surrogate faces are
87/// determined and elements are marked), this integrator adds contribution to
88/// only the element that is adjacent to that face (Trans.Elem1 or Trans.Elem2)
89/// and is part of the surrogate domain.
91{
92protected:
94 VectorCoefficient *vD; // Distance function coefficient
95 Array<int> *elem_marker; // marker indicating whether element is inside,
96 // cut, or outside the domain.
97 bool include_cut_cell; // include element cut by true boundary
98 int nterms; // Number of terms in addition to the gradient
99 // term from Taylor expansion that should be included. (0 by default).
100 int NEproc; // Number of elements on the current MPI rank
102 Array<int> cut_marker; // Array with marker values for cut-cell
103 // corresponding to the level set that BilinearForm applies to.
104
105 // these are not thread-safe!
108
109
110public:
112 const real_t a,
114 Array<int> &elem_marker_,
115 Array<int> &cut_marker_,
116 bool include_cut_cell_ = false,
117 int nterms_ = 0)
118 : alpha(a), vD(&vD_),
119 elem_marker(&elem_marker_),
120 include_cut_cell(include_cut_cell_),
121 nterms(nterms_),
122 NEproc(pmesh->GetNE()),
124 cut_marker(cut_marker_) { }
125
127 virtual void AssembleFaceMatrix(const FiniteElement &el1,
128 const FiniteElement &el2,
130 DenseMatrix &elmat);
131
133};
134
135/// LinearFormIntegrator for the high-order extension of shifted boundary
136/// method.
137/// $$
138/// (u, w) = -\langle u_D, \nabla w \cdot n \rangle
139/// +\langle \alpha h^{-1} u_D, w + \nabla w \cdot d + h.o.t \rangle
140/// $$
141/// where $h.o.t$ include higher-order derivatives ($\nabla^k u$) due to Taylor
142/// expansion. Since this interior face integrator is applied to the surrogate
143/// boundary (see marking.hpp for notes on how the surrogate faces are
144/// determined and elements are marked), this integrator adds contribution to
145/// only the element that is adjacent to that face (Trans.Elem1 or Trans.Elem2)
146/// and is part of the surrogate domain.
147/// Note that $u_D$ is evaluated at the true boundary using the distance function
148/// and ShiftedFunctionCoefficient, i.e. $u_D(x_{true}) = u_D(x_{surrogate} + D)$,
149/// where $x_{surrogate}$ is the location of the integration point on the surrogate
150/// boundary and $D$ is the distance vector from the surrogate boundary to the
151/// true boundary.
153{
154protected:
156 real_t alpha; // Nitsche parameter
157 VectorCoefficient *vD; // Distance function coefficient
158 Array<int> *elem_marker; // marker indicating whether element is inside,
159 // cut, or outside the domain.
160 bool include_cut_cell; // include element cut by true boundary
161 int nterms; // Number of terms in addition to the gradient
162 // term from Taylor expansion that should be included. (0 by default).
163 int NEproc; // Number of elements on the current MPI rank
165 int ls_cut_marker; // Flag used for the cut-cell corresponding to the
166 // level set.
167
168 // these are not thread-safe!
171
172public:
175 const real_t alpha_,
177 Array<int> &elem_marker_,
178 bool include_cut_cell_ = false,
179 int nterms_ = 0,
180 int ls_cut_marker_ = ShiftedFaceMarker::SBElementType::CUT)
181 : uD(&u), alpha(alpha_), vD(&vD_),
182 elem_marker(&elem_marker_),
183 include_cut_cell(include_cut_cell_),
184 nterms(nterms_),
185 NEproc(pmesh->GetNE()),
187 ls_cut_marker(ls_cut_marker_) { }
188
189 virtual void AssembleRHSElementVect(const FiniteElement &el,
191 Vector &elvect);
192 virtual void AssembleRHSElementVect(const FiniteElement &el,
194 Vector &elvect);
195 virtual void AssembleRHSElementVect(const FiniteElement &el1,
196 const FiniteElement &el2,
198 Vector &elvect);
199};
200
201
202/// BilinearFormIntegrator for Neumann boundaries using the shifted boundary
203/// method.
204/// $$
205/// A(u,w) = \langle [\nabla u + \nabla(\nabla u) \cdot d + h.o.t.] \cdot \hat{n} \, (n \cdot \hat{n}),w ⟩ - \langle \nabla u \cdot n,w \rangle
206/// $$
207/// where h.o.t are the high-order terms due to Taylor expansion for $\nabla u$,
208/// $\hat{n}$ is the normal vector at the true boundary, $n$ is the normal vector at
209/// the surrogate boundary. Since this interior face integrator is applied to
210/// the surrogate boundary (see marking.hpp for notes on how the surrogate faces
211/// are determined and elements are marked), this integrator adds contribution
212/// to only the element that is adjacent to that face (Trans.Elem1 or
213/// Trans.Elem2) and is part of the surrogate domain.
215{
216protected:
217 ShiftedVectorFunctionCoefficient *vN; // Normal function coefficient
218 VectorCoefficient *vD; // Distance function coefficient
219 Array<int> *elem_marker; // Marker indicating whether element is inside,
220 // cut, or outside the domain.
222 int nterms; // Number of terms in addition to the gradient
223 // term from Taylor expansion that should be included. (0 by default).
224 int NEproc; // Number of elements on the current MPI rank
227
228
229 // these are not thread-safe!
232
233
234public:
238 Array<int> &elem_marker_,
239 Array<int> &cut_marker_,
240 bool include_cut_cell_ = false,
241 int nterms_ = 1)
242 : vN(&vN_), vD(&vD_),
243 elem_marker(&elem_marker_),
244 include_cut_cell(include_cut_cell_),
245 nterms(nterms_),
246 NEproc(pmesh->GetNE()),
248 cut_marker(cut_marker_) { }
249
251 virtual void AssembleFaceMatrix(const FiniteElement &el1,
252 const FiniteElement &el2,
254 DenseMatrix &elmat);
255
256 bool GetTrimFlag() const { return include_cut_cell; }
257
259};
260
261/// LinearFormIntegrator for Neumann boundaries using the shifted boundary
262/// method.
263/// $$
264/// (u, w) = \langle \hat{n} \cdot n \, t_n, w \rangle
265/// $$
266/// where $\hat{n}$ is the normal vector at the true boundary, $n$ is the normal vector
267/// at the surrogate boundary, and $t_n$ is the traction boundary condition.
268/// Since this interior face integrator is applied to the surrogate boundary
269/// (see marking.hpp for notes on how the surrogate faces are determined and
270/// elements are marked), this integrator adds contribution to only the element
271/// that is adjacent to that face (Trans.Elem1 or Trans.Elem2) and is part of
272/// the surrogate domain.
273/// Note that $t_n$ is evaluated at the true boundary using the distance function
274/// and ShiftedFunctionCoefficient, i.e. $t_n(x_{true}) = t_N(x_{surrogate} + D)$,
275/// where $x_{surrogate}$ is the location of the integration point on the surrogate
276/// boundary and $D$ is the distance vector from the surrogate boundary to the
277/// true boundary.
279{
280protected:
281 ShiftedVectorFunctionCoefficient *vN; // Normal function coefficient
282 ShiftedFunctionCoefficient *uN; // Neumann condition on true boundary
283 VectorCoefficient *vD; // Distance function coefficient
284 Array<int> *elem_marker; // Marker indicating whether element is inside,
285 int nterms; // Number of terms in addition to the gradient
286 // term from Taylor expansion that should be included. (0 by default).
288 int NEproc; // Number of elements on the current MPI rank
291
292 // these are not thread-safe!
294
295public:
300 Array<int> &elem_marker_,
301 int nterms_ = 0,
302 bool include_cut_cell_ = false,
303 int ls_cut_marker_ = ShiftedFaceMarker::SBElementType::CUT)
304 : vN(&vN_), uN(&u), vD(&vD_),
305 elem_marker(&elem_marker_),
306 nterms(nterms_),
307 include_cut_cell(include_cut_cell_),
308 NEproc(pmesh->GetNE()),
310 ls_cut_marker(ls_cut_marker_) { }
311
312 virtual void AssembleRHSElementVect(const FiniteElement &el,
314 Vector &elvect);
315 virtual void AssembleRHSElementVect(const FiniteElement &el,
317 Vector &elvect);
318 virtual void AssembleRHSElementVect(const FiniteElement &el1,
319 const FiniteElement &el2,
321 Vector &elvect);
322 bool GetTrimFlag() const { return include_cut_cell; }
323};
324
325} // namespace mfem
326
327#endif
Abstract base class BilinearFormIntegrator.
virtual void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat)
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
virtual int GetSpaceDim() const =0
Get the dimension of the target (physical) space.
A specialized ElementTransformation class representing a face and its two neighboring elements.
Definition eltrans.hpp:484
Abstract class for all finite elements.
Definition fe_base.hpp:239
Class for integration point with weight.
Definition intrules.hpp:35
Abstract base class LinearFormIntegrator.
Definition lininteg.hpp:25
Class for parallel meshes.
Definition pmesh.hpp:34
SBM2DirichletIntegrator(const ParMesh *pmesh, const real_t a, VectorCoefficient &vD_, Array< int > &elem_marker_, Array< int > &cut_marker_, bool include_cut_cell_=false, int nterms_=0)
virtual void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat)
SBM2DirichletLFIntegrator(const ParMesh *pmesh, ShiftedFunctionCoefficient &u, const real_t alpha_, VectorCoefficient &vD_, Array< int > &elem_marker_, bool include_cut_cell_=false, int nterms_=0, int ls_cut_marker_=ShiftedFaceMarker::SBElementType::CUT)
ShiftedFunctionCoefficient * uD
virtual void AssembleRHSElementVect(const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
VectorCoefficient * vD
ShiftedVectorFunctionCoefficient * vN
SBM2NeumannIntegrator(const ParMesh *pmesh, VectorCoefficient &vD_, ShiftedVectorFunctionCoefficient &vN_, Array< int > &elem_marker_, Array< int > &cut_marker_, bool include_cut_cell_=false, int nterms_=1)
virtual void AssembleFaceMatrix(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Trans, DenseMatrix &elmat)
ShiftedFunctionCoefficient * uN
ShiftedVectorFunctionCoefficient * vN
SBM2NeumannLFIntegrator(const ParMesh *pmesh, ShiftedFunctionCoefficient &u, VectorCoefficient &vD_, ShiftedVectorFunctionCoefficient &vN_, Array< int > &elem_marker_, int nterms_=0, bool include_cut_cell_=false, int ls_cut_marker_=ShiftedFaceMarker::SBElementType::CUT)
virtual void AssembleRHSElementVect(const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
ShiftedFunctionCoefficient(real_t constant_)
ShiftedFunctionCoefficient(std::function< real_t(const Vector &v)> F)
std::function< real_t(const Vector &)> Function
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
Evaluate the coefficient in the element described by T at the point ip.
std::function< void(const Vector &, Vector &)> Function
ShiftedVectorFunctionCoefficient(int dim, std::function< void(const Vector &, Vector &)> F)
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
Base class for vector Coefficients that optionally depend on time and space.
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 data type.
Definition vector.hpp:80
int dim
Definition ex24.cpp:53
real_t a
Definition lissajous.cpp:41
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
float real_t
Definition config.hpp:43