MFEM v4.9.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// For non-conforming meshes please have a look at example
20// "ex2p.cpp".
21
22#include "example_utils.hpp"
23#include "mfem.hpp"
24
25#ifndef MFEM_USE_MOONOLITH
26#error This example requires that MFEM is built with MFEM_USE_MOONOLITH=YES
27#endif
28
29using namespace mfem;
30using namespace std;
31
32int main(int argc, char *argv[])
33{
34 // Init transfer library context
35 InitTransfer(argc, argv);
36
37 const char *source_mesh_file = "../../data/inline-tri.mesh";
38 const char *destination_mesh_file = "../../data/inline-quad.mesh";
39
40 int src_n_refinements = 0;
41 int dest_n_refinements = 0;
42 int source_fe_order = 1;
43 int dest_fe_order = 1;
44 bool visualization = true;
45 bool use_vector_fe = false;
46 bool verbose = false;
47
48 OptionsParser args(argc, argv);
49 args.AddOption(&source_mesh_file, "-s", "--source_mesh",
50 "Mesh file to use for src.");
51 args.AddOption(&destination_mesh_file, "-d", "--destination_mesh",
52 "Mesh file to use for dest.");
53 args.AddOption(&src_n_refinements, "-sr", "--source_refinements",
54 "Number of src refinements");
55 args.AddOption(&dest_n_refinements, "-dr", "--dest_refinements",
56 "Number of dest refinements");
57 args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
58 "--no-visualization",
59 "Enable or disable GLVis visualization.");
60 args.AddOption(&source_fe_order, "-so", "--source_fe_order",
61 "Order of the src finite elements");
62 args.AddOption(&dest_fe_order, "-do", "--dest_fe_order",
63 "Order of the dest finite elements");
64 args.AddOption(&verbose, "-verb", "--verbose", "--no-verb", "--no-verbose",
65 "Enable/Disable verbose output");
66 args.AddOption(&use_vector_fe, "-vfe", "--use_vector_fe", "-no-vfe",
67 "--no-vector_fe", "Use vector finite elements");
68 args.Parse();
69 check_options(args);
70
71 shared_ptr<Mesh> src_mesh, dest_mesh;
72
73 ifstream imesh;
74
75 imesh.open(destination_mesh_file);
76 if (imesh)
77 {
78 dest_mesh = make_shared<Mesh>(imesh, 1, 1);
79 imesh.close();
80 }
81 else
82 {
83 mfem::err << "WARNING: Destination mesh file not found: "
84 << destination_mesh_file << "\n"
85 << "Using default 2D quad mesh.";
86
87 dest_mesh = make_shared<Mesh>(4, 4, Element::QUADRILATERAL);
88 }
89
90 const int dim = dest_mesh->Dimension();
91
92 Vector box_min(dim), box_max(dim), range(dim);
93 dest_mesh->GetBoundingBox(box_min, box_max);
94 range = box_max;
95 range -= box_min;
96
97 imesh.open(source_mesh_file);
98
99 if (imesh)
100 {
101 src_mesh = make_shared<Mesh>(imesh, 1, 1);
102 imesh.close();
103 }
104 else
105 {
106 mfem::err << "WARNING: Source mesh file not found: " << source_mesh_file
107 << "\n"
108 << "Using default box mesh.\n";
109
110 if (dim == 2)
111 {
112 src_mesh =
113 make_shared<Mesh>(4, 4, Element::TRIANGLE, 1, range[0], range[1]);
114 }
115 else if (dim == 3)
116 {
117 src_mesh = make_shared<Mesh>(4, 4, 4, Element::TETRAHEDRON, 1, range[0],
118 range[1], range[2]);
119 }
120
121 for (int i = 0; i < src_mesh->GetNV(); ++i)
122 {
123 double *v = src_mesh->GetVertex(i);
124
125 for (int d = 0; d < dim; ++d)
126 {
127 v[d] += box_min[d];
128 }
129 }
130 }
131
132 for (int i = 0; i < src_n_refinements; ++i)
133 {
134 src_mesh->UniformRefinement();
135 }
136
137 for (int i = 0; i < dest_n_refinements; ++i)
138 {
139 dest_mesh->UniformRefinement();
140 }
141
142 shared_ptr<FiniteElementCollection> src_fe_coll, dest_fe_coll;
143
144 if (use_vector_fe)
145 {
146 src_fe_coll =
147 make_shared<RT_FECollection>(source_fe_order, src_mesh->Dimension());
148 dest_fe_coll =
149 make_shared<RT_FECollection>(dest_fe_order, dest_mesh->Dimension());
150 }
151 else
152 {
153 src_fe_coll =
154 make_shared<L2_FECollection>(source_fe_order, src_mesh->Dimension());
155 dest_fe_coll =
156 make_shared<L2_FECollection>(dest_fe_order, dest_mesh->Dimension());
157 }
158
159 auto src_fe =
160 make_shared<FiniteElementSpace>(src_mesh.get(), src_fe_coll.get());
161
162 auto dest_fe =
163 make_shared<FiniteElementSpace>(dest_mesh.get(), dest_fe_coll.get());
164
165 GridFunction src_fun(src_fe.get());
166 GridFunction dest_fun(dest_fe.get());
167 src_fun = 1.0;
168
169 // To be used with standard fe
171
172 // To be used with vector fe
174
175 if (use_vector_fe)
176 {
177 src_fun.ProjectCoefficient(vector_coeff);
178 src_fun.Update();
179 }
180 else
181 {
182 src_fun.ProjectCoefficient(coeff);
183 src_fun.Update();
184 }
185
186 dest_fun = 0.0;
187 dest_fun.Update();
188
189 MortarAssembler assembler(src_fe, dest_fe);
190 assembler.SetVerbose(verbose);
191
192 if (use_vector_fe)
193 {
194 assembler.AddMortarIntegrator(make_shared<VectorL2MortarIntegrator>());
195 }
196 else
197 {
198 assembler.AddMortarIntegrator(make_shared<L2MortarIntegrator>());
199 }
200
201 if (assembler.Transfer(src_fun, dest_fun))
202 {
203 if (visualization)
204 {
205 dest_fun.Update();
206
207 double src_err = 0;
208 double dest_err = 0;
209
210 if (use_vector_fe)
211 {
212 src_err = src_fun.ComputeL2Error(vector_coeff);
213 dest_err = dest_fun.ComputeL2Error(vector_coeff);
214 }
215 else
216 {
217 src_err = src_fun.ComputeL2Error(coeff);
218 dest_err = dest_fun.ComputeL2Error(coeff);
219 }
220
221 mfem::out << "l2 error: src: " << src_err << ", dest: " << dest_err
222 << std::endl;
223
224 plot(*src_mesh, src_fun, "source", 0);
225 plot(*dest_mesh, dest_fun, "destination", 1);
226 }
227 }
228 else
229 {
230 mfem::out << "No intersection -> no transfer!" << std::endl;
231 }
232
233 // Finalize transfer library context
234 return FinalizeTransfer();
235}
A general function coefficient.
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:32
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Definition gridfunc.cpp:168
virtual real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
Returns ||exsol - u_h||_L2 for scalar or vector H1 or L2 elements.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
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 ...
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:82
int dim
Definition ex24.cpp:53
void vector_fun(const mfem::Vector &x, mfem::Vector &f)
void plot(mfem::Mesh &mesh, mfem::GridFunction &x, std::string title, const int plot_number=0)
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:23
int FinalizeTransfer()
Finalize the par_moonolith library.
Definition transfer.cpp:27