MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
ex1.cpp
Go to the documentation of this file.
1// MFEM + Moonolith Example 1
2//
3// Compile with: make ex1
4//
5// Moonolith sample runs:
6// ex1
7// ex1 --source_refinements 1 --dest_refinements 2
8// ex1 --source_refinements 1 --dest_refinements 2 --use_vector_fe
9// ex1 -s ../../data/inline-hex.mesh -d ../../data/inline-tet.mesh
10//
11// Description: This example code demonstrates the use of MFEM for transferring
12// discrete fields from one finite element mesh to another. The
13// meshes can be of arbitrary shape and completely unrelated with
14// each other. This feature can be used for implementing immersed
15// domain methods for fluid-structure interaction or general
16// multi-physics applications.
17//
18// This particular example is only for serial runtimes.
19
20#include "example_utils.hpp"
21#include "mfem.hpp"
22
23using namespace mfem;
24using namespace std;
25
26int main(int argc, char *argv[])
27{
28 // Init transfer library context
29 InitTransfer(argc, argv);
30
31 const char *source_mesh_file = "../../data/inline-tri.mesh";
32 const char *destination_mesh_file = "../../data/inline-quad.mesh";
33
34 int src_n_refinements = 0;
35 int dest_n_refinements = 0;
36 int source_fe_order = 1;
37 int dest_fe_order = 1;
38 bool visualization = true;
39 bool use_vector_fe = false;
40 bool verbose = false;
41
42 OptionsParser args(argc, argv);
43 args.AddOption(&source_mesh_file, "-s", "--source_mesh",
44 "Mesh file to use for src.");
45 args.AddOption(&destination_mesh_file, "-d", "--destination_mesh",
46 "Mesh file to use for dest.");
47 args.AddOption(&src_n_refinements, "-sr", "--source_refinements",
48 "Number of src refinements");
49 args.AddOption(&dest_n_refinements, "-dr", "--dest_refinements",
50 "Number of dest refinements");
51 args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
52 "--no-visualization",
53 "Enable or disable GLVis visualization.");
54 args.AddOption(&source_fe_order, "-so", "--source_fe_order",
55 "Order of the src finite elements");
56 args.AddOption(&dest_fe_order, "-do", "--dest_fe_order",
57 "Order of the dest finite elements");
58 args.AddOption(&verbose, "-verb", "--verbose", "--no-verb", "--no-verbose",
59 "Enable/Disable verbose output");
60 args.AddOption(&use_vector_fe, "-vfe", "--use_vector_fe", "-no-vfe",
61 "--no-vector_fe", "Use vector finite elements");
62 args.Parse();
63 check_options(args);
64
65 shared_ptr<Mesh> src_mesh, dest_mesh;
66
67 ifstream imesh;
68
69 imesh.open(destination_mesh_file);
70 if (imesh)
71 {
72 dest_mesh = make_shared<Mesh>(imesh, 1, 1);
73 imesh.close();
74 }
75 else
76 {
77 mfem::err << "WARNING: Destination mesh file not found: "
78 << destination_mesh_file << "\n"
79 << "Using default 2D quad mesh.";
80
81 dest_mesh = make_shared<Mesh>(4, 4, Element::QUADRILATERAL);
82 }
83
84 const int dim = dest_mesh->Dimension();
85
86 Vector box_min(dim), box_max(dim), range(dim);
87 dest_mesh->GetBoundingBox(box_min, box_max);
88 range = box_max;
89 range -= box_min;
90
91 imesh.open(source_mesh_file);
92
93 if (imesh)
94 {
95 src_mesh = make_shared<Mesh>(imesh, 1, 1);
96 imesh.close();
97 }
98 else
99 {
100 mfem::err << "WARNING: Source mesh file not found: " << source_mesh_file
101 << "\n"
102 << "Using default box mesh.\n";
103
104 if (dim == 2)
105 {
106 src_mesh =
107 make_shared<Mesh>(4, 4, Element::TRIANGLE, 1, range[0], range[1]);
108 }
109 else if (dim == 3)
110 {
111 src_mesh = make_shared<Mesh>(4, 4, 4, Element::TETRAHEDRON, 1, range[0],
112 range[1], range[2]);
113 }
114
115 for (int i = 0; i < src_mesh->GetNV(); ++i)
116 {
117 double *v = src_mesh->GetVertex(i);
118
119 for (int d = 0; d < dim; ++d)
120 {
121 v[d] += box_min[d];
122 }
123 }
124 }
125
126 for (int i = 0; i < src_n_refinements; ++i)
127 {
128 src_mesh->UniformRefinement();
129 }
130
131 for (int i = 0; i < dest_n_refinements; ++i)
132 {
133 dest_mesh->UniformRefinement();
134 }
135
136 shared_ptr<FiniteElementCollection> src_fe_coll, dest_fe_coll;
137
138 if (use_vector_fe)
139 {
140 src_fe_coll =
141 make_shared<RT_FECollection>(source_fe_order, src_mesh->Dimension());
142 dest_fe_coll =
143 make_shared<RT_FECollection>(dest_fe_order, dest_mesh->Dimension());
144 }
145 else
146 {
147 src_fe_coll =
148 make_shared<L2_FECollection>(source_fe_order, src_mesh->Dimension());
149 dest_fe_coll =
150 make_shared<L2_FECollection>(dest_fe_order, dest_mesh->Dimension());
151 }
152
153 auto src_fe =
154 make_shared<FiniteElementSpace>(src_mesh.get(), src_fe_coll.get());
155
156 auto dest_fe =
157 make_shared<FiniteElementSpace>(dest_mesh.get(), dest_fe_coll.get());
158
159 GridFunction src_fun(src_fe.get());
160 GridFunction dest_fun(dest_fe.get());
161 src_fun = 1.0;
162
163 // To be used with standard fe
165
166 // To be used with vector fe
168
169 if (use_vector_fe)
170 {
171 src_fun.ProjectCoefficient(vector_coeff);
172 src_fun.Update();
173 }
174 else
175 {
176 src_fun.ProjectCoefficient(coeff);
177 src_fun.Update();
178 }
179
180 dest_fun = 0.0;
181 dest_fun.Update();
182
183 MortarAssembler assembler(src_fe, dest_fe);
184 assembler.SetVerbose(verbose);
185
186 if (use_vector_fe)
187 {
188 assembler.AddMortarIntegrator(make_shared<VectorL2MortarIntegrator>());
189 }
190 else
191 {
192 assembler.AddMortarIntegrator(make_shared<L2MortarIntegrator>());
193 }
194
195 if (assembler.Transfer(src_fun, dest_fun))
196 {
197 if (visualization)
198 {
199 dest_fun.Update();
200
201 double src_err = 0;
202 double dest_err = 0;
203
204 if (use_vector_fe)
205 {
206 src_err = src_fun.ComputeL2Error(vector_coeff);
207 dest_err = dest_fun.ComputeL2Error(vector_coeff);
208 }
209 else
210 {
211 src_err = src_fun.ComputeL2Error(coeff);
212 dest_err = dest_fun.ComputeL2Error(coeff);
213 }
214
215 mfem::out << "l2 error: src: " << src_err << ", dest: " << dest_err
216 << std::endl;
217
218 plot(*src_mesh, src_fun, "source");
219 plot(*dest_mesh, dest_fun, "destination");
220 }
221 }
222 else
223 {
224 mfem::out << "No intersection -> no transfer!" << std::endl;
225 }
226
227 // Finalize transfer library context
228 return FinalizeTransfer();
229}
A general function coefficient.
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:31
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Definition: gridfunc.cpp:164
virtual real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
Definition: gridfunc.cpp:2718
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Definition: gridfunc.cpp:2346
This class implements the serial variational transfer between finite element spaces....
void SetVerbose(const bool verbose)
Expose process details with verbose output.
void AddMortarIntegrator(const std::shared_ptr< MortarIntegrator > &integrator)
This method must be called before Assemble or Transfer. It will assemble the operator in all intersec...
bool Transfer(const GridFunction &src_fun, GridFunction &dest_fun)
transfer a function from source to destination. if the transfer is to be performed multiple times use...
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
Definition: optparser.cpp:151
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
A general vector function coefficient.
Vector data type.
Definition: vector.hpp:80
int dim
Definition: ex24.cpp:53
void plot(mfem::Mesh &mesh, mfem::GridFunction &x, std::string title)
void vector_fun(const mfem::Vector &x, mfem::Vector &f)
double example_fun(const mfem::Vector &x)
void check_options(mfem::OptionsParser &args)
int main()
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:66
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Definition: globals.hpp:71
void InitTransfer(int argc, char *argv[])
Initializes the par_moonolith library. It also calls MPI_Init.
Definition: transfer.cpp:19
int FinalizeTransfer()
Finalize the par_moonolith library.
Definition: transfer.cpp:23