MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
lsf_integral.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// ---------------------------------------------------------------------
13// Miniapp: Integral of implicit domains defined by a level set function
14// ---------------------------------------------------------------------
15//
16// The miniapp demonstrates an interface to the Algoim library for computing
17// volumetric and surface integrals over domains and surfaces defined
18// implicitly by a level set function. The miniapp requires MFEM to be built
19// with Blitz and Algoim libraries (see INSTALL).
20//
21// Compile with: make lsf_integral
22//
23// Sample runs:
24//
25// Evaluates surface and volumetric integral for a circle with radius 1
26// lsf_integral -m ../../data/star-q3.mesh
27//
28// Evaluates surface and volumetric integral for a level set defined
29// by y=0.5-(0.1*sin(3*pi*x+pi/2))
30// lsf_integral -ls 2 -m ../../data/inline-quad.mesh -rs 2 -o 3 -ao 3
31
32#include "mfem.hpp"
33
34using namespace mfem;
35using namespace std;
36
37// Level set function for sphere in 3D and circle in 2D
39{
40 real_t r2= x*x;
41 return -sqrt(r2)+1.0;//the radius is 1.0
42}
43
44// Level set function for a sinusoidal wave.
45// Resulting zero isocontour is at y=0.5-(0.1*sin(3*pi*x+pi/2))
47{
48 real_t a1 = 20., a2 = 2., a3 = 3.;
49 return tanh(a1*(x(1)-0.5) + a2*sin(a3*(x(0)-0.5)*M_PI));
50}
51
52int main(int argc, char *argv[])
53{
54 // Parse command-line options
55 const char *mesh_file = "../../data/star-q3.mesh";
56 int ser_ref_levels = 1;
57 int order = 2;
58 int iorder = 2; // MFEM integration points
59 int aorder = 2; // Algoim integration points
60 bool visualization = true;
61 int print_level = 0;
62 int ls_type = 1;
63
64 OptionsParser args(argc, argv);
65 args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use.");
66 args.AddOption(&ser_ref_levels,
67 "-rs",
68 "--refine-serial",
69 "Number of times to refine the mesh uniformly in serial.");
70 args.AddOption(&order,
71 "-o",
72 "--order",
73 "Order (degree) of the finite elements.");
74 args.AddOption(&iorder,
75 "-io",
76 "--iorder",
77 "MFEM Integration order.");
78 args.AddOption(&aorder,
79 "-ao",
80 "--aorder",
81 "Algoim Integration order.");
82 args.AddOption(&ls_type,
83 "-ls",
84 "--ls-type",
85 "Level set type: 1: circle, 2 sinusoidal wave");
86 args.AddOption(&visualization,
87 "-vis",
88 "--visualization",
89 "-no-vis",
90 "--no-visualization",
91 "Enable or disable GLVis visualization.");
92 args.AddOption((&print_level), "-prt", "--print-level", "Print level.");
93 args.Parse();
94 if (!args.Good())
95 {
96 args.PrintUsage(std::cout);
97 return 1;
98 }
99 args.PrintOptions(std::cout);
100
101 // Read the (serial) mesh from the given mesh file.
102 Mesh *mesh = new Mesh(mesh_file, 1, 1);
103 int dim = mesh->Dimension();
104 // Refine the mesh in serial to increase the resolution. In this example
105 // we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
106 // a command-line parameter.
107 for (int lev = 0; lev < ser_ref_levels; lev++)
108 {
109 mesh->UniformRefinement();
110 }
111
112 // Define the finite element space for the level-set function.
113 H1_FECollection fec(order, dim);
114 FiniteElementSpace fespace(mesh, &fec, 1, Ordering::byVDIM);
115 int glob_size = fespace.GetTrueVSize();
116 std::cout << "Number of finite element unknowns: " << glob_size << std::endl;
117
118 // Define the level set grid function
119 GridFunction x(&fespace);
120
121 // Define the level set coefficient
122 Coefficient *ls_coeff = nullptr;
123 if (ls_type == 1)
124 {
125 ls_coeff=new FunctionCoefficient(sphere_ls);
126 }
127 else if (ls_type == 2)
128 {
130 }
131 else
132 {
133 MFEM_ABORT("Level set coefficient not defined");
134 }
135
136 // Project the coefficient onto the LS grid function
137 x.ProjectCoefficient(*ls_coeff);
138
139 if (visualization)
140 {
141 osockstream sock(19916, "localhost");
142 sock << "solution\n";
143 mesh->Print(sock);
144 x.Save(sock);
145 sock.send();
146 sock << "window_title 'Level set'\n"
147 << "window_geometry "
148 << 1200 << " " << 0 << " " << 600 << " " << 600 << "\n"
149 << "keys jRmmclA" << endl;
150 }
151
152 // Exact volume and area
153 real_t exact_volume = -10, exact_area = -10;
154 if (ls_type == 1)
155 {
156 if (strncmp(mesh_file,"../../data/star-q3.mesh",100) == 0)
157 {
158 exact_volume = M_PI;
159 exact_area = M_PI*2;
160 }
161 else if (strncmp(mesh_file, "../../data/inline-quad.mesh",100) == 0)
162 {
163 exact_volume = M_PI/4;
164 exact_area = M_PI/2;
165 }
166 }
167 else if (ls_type == 2)
168 {
169 if (strncmp(mesh_file, "../../data/inline-quad.mesh",100) == 0)
170 {
171 exact_volume = 0.5;
172 exact_area = 1.194452300992437;
173 }
174 }
175 (void)(&exact_area); // suppress a warning
176
178 const IntegrationRule* ir=nullptr;
179
180 // Integration with Algoim
181 real_t vol=0.0;
182
183#ifdef MFEM_USE_ALGOIM
184 real_t area=0.0;
185
186 AlgoimIntegrationRules* air=new AlgoimIntegrationRules(aorder,*ls_coeff,order);
187
188 IntegrationRule eir;
189 Vector sweights;
190
191 for (int i=0; i<fespace.GetNE(); i++)
192 {
193 // get the element transformation
194 trans = fespace.GetElementTransformation(i);
195
197 for (int j = 0; j < eir.GetNPoints(); j++)
198 {
199 const IntegrationPoint &ip = eir.IntPoint(j);
200 trans->SetIntPoint(&ip);
201 vol += ip.weight * trans->Weight();
202 }
203
204 // compute the perimeter/area contribution from the element
206 air->GetSurfaceWeights(*trans,eir,sweights);
207 for (int j = 0; j < eir.GetNPoints(); j++)
208 {
209 const IntegrationPoint &ip = eir.IntPoint(j);
210 trans->SetIntPoint(&ip);
211 area += ip.weight * sweights(j) * trans->Weight();
212 }
213 }
214
215 delete air;
216
217 if (exact_volume > 0)
218 {
219 std::cout<<"Algoim Volume="<<vol<<" Error="<<vol-exact_volume<<std::endl;
220 std::cout<<"Algoim Area="<<area<<" Error="<<area-exact_area<<std::endl;
221 }
222 else
223 {
224 std::cout<<"Algoim Volume="<<vol<<std::endl;
225 std::cout<<"Algoim Area="<<area<<std::endl;
226 }
227#endif
228
229 // Perform standard MFEM integration
230 vol=0.0;
231 for (int i=0; i<fespace.GetNE(); i++)
232 {
233 const FiniteElement* el=fespace.GetFE(i);
234 // get the element transformation
235 trans = fespace.GetElementTransformation(i);
236
237 // compute the volume contribution from the element
238 ir=&IntRules.Get(el->GetGeomType(), iorder);
239 for (int j = 0; j < ir->GetNPoints(); j++)
240 {
241 const IntegrationPoint &ip = ir->IntPoint(j);
242 trans->SetIntPoint(&ip);
243 real_t vlsf=x.GetValue(*trans,ip);
244 if (vlsf>=0.0)
245 {
246 vol += ip.weight * trans->Weight();
247 }
248 }
249 }
250
251 if (exact_volume > 0.0)
252 {
253 std::cout<<"MFEM Volume="<<vol<<" Error="<<vol-exact_volume<<std::endl;
254 }
255 else
256 {
257 std::cout<<"MFEM Volume="<<vol<<std::endl;
258 }
259
260 ParaViewDataCollection dacol("ParaViewLSF", mesh);
261 dacol.SetLevelsOfDetail(order);
262 dacol.RegisterField("LSF",&x);
263 dacol.SetTime(1.0);
264 dacol.SetCycle(1);
265 dacol.Save();
266
267 delete ls_coeff;
268 delete mesh;
269
270 return 0;
271}
virtual void GetVolumeIntegrationRule(ElementTransformation &Tr, IntegrationRule &result, const IntegrationRule *sir=nullptr) override
Construct a cut-volume IntegrationRule.
virtual void GetSurfaceIntegrationRule(ElementTransformation &Tr, IntegrationRule &result) override
Construct a cut-surface IntegrationRule.
virtual void GetSurfaceWeights(ElementTransformation &Tr, const IntegrationRule &sir, Vector &weights) override
Compute transformation quadrature weights for surface integration.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Definition fespace.hpp:851
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
Definition fespace.hpp:924
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Definition fespace.cpp:3835
int GetNE() const
Returns number of elements in the mesh.
Definition fespace.hpp:891
Abstract class for all finite elements.
Definition fe_base.hpp:244
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition fe_base.hpp:331
A general function coefficient.
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
virtual real_t GetValue(int i, const IntegrationPoint &ip, int vdim=1) const
Definition gridfunc.cpp:446
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:275
Class for integration point with weight.
Definition intrules.hpp:35
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition intrules.hpp:259
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Mesh data type.
Definition mesh.hpp:64
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Definition mesh.hpp:2433
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1216
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:11295
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
Definition optparser.hpp:82
bool Good() const
Return true if the command line options were parsed successfully.
Helper class for ParaView visualization data.
void SetLevelsOfDetail(int levels_of_detail_)
Vector data type.
Definition vector.hpp:82
int dim
Definition ex24.cpp:53
void trans(const Vector &u, Vector &x)
Definition ex27.cpp:412
int main()
real_t sinusoidal_ls(const Vector &x)
real_t sphere_ls(const Vector &x)
float real_t
Definition config.hpp:43
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:492