MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
integ_algoim.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 INTEG_ALGOIM_HPP
13#define INTEG_ALGOIM_HPP
14
15#include <mfem.hpp>
16
17#ifdef MFEM_USE_ALGOIM
18#include <algoim_quad.hpp>
19
20namespace mfem
21{
22
23// define templated element bases
24namespace TmplPoly_1D
25{
26
27/// Templated version of CalcBinomTerms
28template<typename float_type>
29void CalcBinomTerms(const int p, const float_type x, const float_type y,
30 float_type* u)
31{
32 if (p == 0)
33 {
34 u[0] = float_type(1.);
35 }
36 else
37 {
38 int i;
39 const int *b = Poly_1D::Binom(p);
40 float_type z = x;
41 for (i = 1; i < p; i++)
42 {
43 u[i] = b[i]*z;
44 z *= x;
45 }
46 u[p] = z;
47 z = y;
48 for (i--; i > 0; i--)
49 {
50 u[i] *= z;
51 z *= y;
52 }
53 u[0] = z;
54 }
55}
56
57/// Templated version of CalcBinomTerms
58template<typename float_type>
59void CalcBinomTerms(const int p, const float_type x, const float_type y,
60 float_type* u, float_type* d)
61{
62 if (p == 0)
63 {
64 u[0] = float_type(1.);
65 d[0] = float_type(0.);
66 }
67 else
68 {
69 int i;
70 const int *b = Poly_1D::Binom(p);
71 const float_type xpy = x + y, ptx = p*x;
72 float_type z = float_type(1.);
73
74 for (i = 1; i < p; i++)
75 {
76 d[i] = b[i]*z*(i*xpy - ptx);
77 z *= x;
78 u[i] = b[i]*z;
79 }
80 d[p] = p*z;
81 u[p] = z*x;
82 z = float_type(1.);
83 for (i--; i > 0; i--)
84 {
85 d[i] *= z;
86 z *= y;
87 u[i] *= z;
88 }
89 d[0] = -p*z;
90 u[0] = z*y;
91 }
92
93}
94
95/// Templated evaluation of Bernstein basis
96template <typename float_type>
97void CalcBernstein(const int p, const float_type x, float_type *u)
98{
99 CalcBinomTerms(p, x, 1. - x, u);
100}
101
102
103/// Templated evaluation of Bernstein basis
104template <typename float_type>
105void CalcBernstein(const int p, const float_type x,
106 float_type *u, float_type *d)
107{
108 CalcBinomTerms(p, x, 1. - x, u, d);
109}
110
111
112}
113
114/// Construct volumetric and surface integration rules for a given element
115/// using the Algoim library. The volume is define as the positive part of
116/// a level-set function(LSF) (lsfun argument in the constructor). The surface
117/// is defined as the zero level-set of the LSF.
119{
120public:
121
122 /// Construct Algoim object using a finite element, its transformation
123 /// and level-set function defined over the element using Lagrangian
124 /// bases. The argument o provides the order of the of the 1D Gaussian
125 /// integration rule used for deriving the vol/surface integration rules.
126 AlgoimIntegrationRule(int o, const FiniteElement &el,
127 ElementTransformation &trans, const Vector &lsfun);
128
129
130 /// Destructor of the Algoim object
132 {
133 delete pe;
134 delete vir;
135 delete sir;
136 }
137
138 /// Returns volumetric integration rule based on the provided
139 /// level-set function.
141
142 /// Returns surface integration rule based on the provided
143 /// level-set function.
145
146
147private:
148
149 /// 3D level-set function object required by Algoim.
150 struct LevelSet3D
151 {
152 /// Constructor for 3D level-set function object required by Algoim.
153 LevelSet3D(PositiveTensorFiniteElement* el_, Vector& lsfun_)
154 : el(el_), lsfun(lsfun_) { }
155
156 /// Returns the value of the LSF for point x.
157 template<typename T>
158 T operator() (const blitz::TinyVector<T,3>& x) const
159 {
160 int el_order=el->GetOrder();
161 T u1[el_order+1];
162 T u2[el_order+1];
163 T u3[el_order+1];
164 TmplPoly_1D::CalcBernstein(el_order, x[0], u1);
165 TmplPoly_1D::CalcBernstein(el_order, x[1], u2);
166 TmplPoly_1D::CalcBernstein(el_order, x[2], u3);
167
168 const Array<int>& dof_map=el->GetDofMap();
169
170 T res=T(0.0);
171 for (int oo = 0, kk = 0; kk <= el_order; kk++)
172 for (int jj = 0; jj <= el_order; jj++)
173 for (int ii = 0; ii <= el_order; ii++)
174 {
175 res=res-u1[ii]*u2[jj]*u3[kk]*lsfun(dof_map[oo++]);
176 }
177 return res;
178 }
179
180 /// Returns the gradients of the LSF for point x.
181 template<typename T>
182 blitz::TinyVector<T,3> grad(const blitz::TinyVector<T,3>& x) const
183 {
184 int el_order=el->GetOrder();
185 T u1[el_order+1];
186 T u2[el_order+1];
187 T u3[el_order+1];
188 T d1[el_order+1];
189 T d2[el_order+1];
190 T d3[el_order+1];
191
192 TmplPoly_1D::CalcBernstein(el_order,x[0], u1, d1);
193 TmplPoly_1D::CalcBernstein(el_order,x[1], u2, d2);
194 TmplPoly_1D::CalcBernstein(el_order,x[2], u3, d3);
195
196 blitz::TinyVector<T,3> res(T(0.0),T(0.0),T(0.0));
197
198 const Array<int>& dof_map=el->GetDofMap();
199
200 for (int oo = 0, kk = 0; kk <= el_order; kk++)
201 for (int jj = 0; jj <= el_order; jj++)
202 for (int ii = 0; ii <= el_order; ii++)
203 {
204 res[0]=res[0]-d1[ii]*u2[jj]*u3[kk]*lsfun(dof_map[oo]);
205 res[1]=res[1]-u1[ii]*d2[jj]*u3[kk]*lsfun(dof_map[oo]);
206 res[2]=res[2]-u1[ii]*u2[jj]*d3[kk]*lsfun(dof_map[oo]);
207 oo++;
208 }
209
210 return res;
211 }
212
213 private:
214 PositiveTensorFiniteElement* el;
215 Vector& lsfun;
216 };
217
218 /// 2D level-set function object required by Algoim.
219 struct LevelSet2D
220 {
221 /// Constructor for 2D level-set function object required by Algoim.
222 LevelSet2D(PositiveTensorFiniteElement* el_, Vector& lsfun_)
223 :el(el_), lsfun(lsfun_) { }
224
225 /// Returns the value of the LSF for point x.
226 template<typename T>
227 T operator() (const blitz::TinyVector<T,2>& x) const
228 {
229 int el_order=el->GetOrder();
230 T u1[el_order+1];
231 T u2[el_order+1];
232 TmplPoly_1D::CalcBernstein(el_order, x[0], u1);
233 TmplPoly_1D::CalcBernstein(el_order, x[1], u2);
234
235 const Array<int>& dof_map=el->GetDofMap();
236
237 T res=T(0.0);
238
239 for (int oo = 0, jj = 0; jj <= el_order; jj++)
240 for (int ii = 0; ii <= el_order; ii++)
241 {
242 res=res-u1[ii]*u2[jj]*lsfun(dof_map[oo++]);
243 }
244 return res;
245 }
246
247 /// Returns the gradients of the LSF for point x.
248 template<typename T>
249 blitz::TinyVector<T,2> grad(const blitz::TinyVector<T,2>& x) const
250 {
251 int el_order=el->GetOrder();
252 T u1[el_order+1];
253 T u2[el_order+1];
254 T d1[el_order+1];
255 T d2[el_order+1];
256
257 TmplPoly_1D::CalcBernstein(el_order,x[0], u1, d1);
258 TmplPoly_1D::CalcBernstein(el_order,x[1], u2, d2);
259
260 blitz::TinyVector<T,2> res(T(0.0),T(0.0));
261
262 const Array<int>& dof_map=el->GetDofMap();
263
264 for (int oo = 0, jj = 0; jj <= el_order; jj++)
265 for (int ii = 0; ii <= el_order; ii++)
266 {
267 res[0]=res[0]-(d1[ii]*u2[jj])*lsfun(dof_map[oo]);
268 res[1]=res[1]-(u1[ii]*d2[jj])*lsfun(dof_map[oo]);
269 oo++;
270 }
271
272 return res;
273 }
274
275
276 private:
277 PositiveTensorFiniteElement* el;
278 Vector& lsfun;
279 };
280
281
282 IntegrationRule* sir; // Surface integration rule. Owned.
283 IntegrationRule* vir; // Volumetric integration rule. Owned.
284 PositiveTensorFiniteElement *pe;
285 Vector lsvec; // level-set in Bernstein bases
286 int int_order; // integration order
287};
288
289}
290#endif
291
292#endif
const IntegrationRule * GetVolumeIntegrationRule()
AlgoimIntegrationRule(int o, const FiniteElement &el, ElementTransformation &trans, const Vector &lsfun)
const IntegrationRule * GetSurfaceIntegrationRule()
~AlgoimIntegrationRule()
Destructor of the Algoim object.
Abstract class for all finite elements.
Definition fe_base.hpp:239
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition fe_base.hpp:333
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
static const int * Binom(const int p)
Get a pointer to an array containing the binomial coefficients "pchoose k" for k=0,...
Definition fe_base.cpp:2028
Vector data type.
Definition vector.hpp:80
void trans(const Vector &u, Vector &x)
Definition ex27.cpp:412
real_t b
Definition lissajous.cpp:42
void CalcBernstein(const int p, const float_type x, float_type *u)
Templated evaluation of Bernstein basis.
void CalcBinomTerms(const int p, const float_type x, const float_type y, float_type *u)
Templated version of CalcBinomTerms.
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
real_t p(const Vector &x, real_t t)