37int main(
int argc,
char *argv[])
39 MPI_Init(&argc, &argv);
43 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
44 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
49 const char *source_mesh_file =
"../../data/inline-tri.mesh";
50 const char *destination_mesh_file =
"../../data/inline-quad.mesh";
52 int src_n_refinements = 0;
53 int dest_n_refinements = 0;
54 int source_fe_order = 1;
55 int dest_fe_order = 1;
56 bool visualization =
true;
57 bool use_vector_fe =
false;
59 bool use_vector_space =
false;
61 bool assemble_mass_and_coupling_together =
true;
64 args.
AddOption(&source_mesh_file,
"-s",
"--source_mesh",
65 "Mesh file to use for src.");
66 args.
AddOption(&destination_mesh_file,
"-d",
"--destination_mesh",
67 "Mesh file to use for dest.");
68 args.
AddOption(&src_n_refinements,
"-sr",
"--source_refinements",
69 "Number of src refinements");
70 args.
AddOption(&dest_n_refinements,
"-dr",
"--dest_refinements",
71 "Number of dest refinements");
72 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
74 "Enable or disable GLVis visualization.");
75 args.
AddOption(&source_fe_order,
"-so",
"--source_fe_order",
76 "Order of the src finite elements");
77 args.
AddOption(&dest_fe_order,
"-do",
"--dest_fe_order",
78 "Order of the dest finite elements");
79 args.
AddOption(&verbose,
"-verb",
"--verbose",
"--no-verb",
"--no-verbose",
80 "Enable/Disable verbose output");
81 args.
AddOption(&use_vector_fe,
"-vfe",
"--use_vector_fe",
"-no-vfe",
83 "Use RT|ND vector finite elements (Experimental)");
84 args.
AddOption(&use_vector_space,
"-vfs",
"--use_vector_space",
"-no-vfs",
86 "Use Lagrange vector finite elements (Experimental)");
87 args.
AddOption(&use_h1,
"-h1",
"--use-h1",
"-nh1",
"--no-h1",
89 args.
AddOption(&assemble_mass_and_coupling_together,
"-act",
90 "--assemble_mass_and_coupling_together",
"-no-act",
91 "--no-assemble_mass_and_coupling_together",
92 "Assemble mass and coupling operators together (better for "
93 "non-affine elements)");
97 if (use_vector_fe && use_vector_space)
100 "WARNING: use_vector_fe and use_vector_space options"
101 "are both true, ignoring use_vector_fe\n";
104 shared_ptr<Mesh> src_mesh, dest_mesh;
108 imesh.open(destination_mesh_file);
111 dest_mesh = make_shared<Mesh>(imesh, 1, 1);
117 mfem::err <<
"WARNING: Destination mesh file not found: "
118 << destination_mesh_file <<
"\n"
119 <<
"Using default 2D quad mesh.";
124 const int dim = dest_mesh->Dimension();
129 dest_mesh->GetBoundingBox(box_min, box_max);
133 imesh.open(source_mesh_file);
137 src_mesh = make_shared<Mesh>(imesh, 1, 1);
143 mfem::err <<
"WARNING: Source mesh file not found: " << source_mesh_file
145 <<
"Using default box mesh.\n";
158 for (
int i = 0; i < src_mesh->GetNV(); ++i)
160 double *v = src_mesh->GetVertex(i);
162 for (
int d = 0; d <
dim; ++d)
169 for (
int i = 0; i < src_n_refinements; ++i)
171 src_mesh->UniformRefinement();
174 for (
int i = 0; i < dest_n_refinements; ++i)
176 dest_mesh->UniformRefinement();
179 auto p_src_mesh = make_shared<ParMesh>(MPI_COMM_WORLD, *src_mesh);
180 auto p_dest_mesh = make_shared<ParMesh>(MPI_COMM_WORLD, *dest_mesh);
182 shared_ptr<FiniteElementCollection> src_fe_coll, dest_fe_coll;
187 make_shared<RT_FECollection>(source_fe_order, src_mesh->Dimension());
189 make_shared<RT_FECollection>(dest_fe_order, dest_mesh->Dimension());
197 make_shared<H1_FECollection>(source_fe_order, src_mesh->Dimension());
199 make_shared<H1_FECollection>(dest_fe_order, dest_mesh->Dimension());
204 make_shared<L2_FECollection>(source_fe_order, src_mesh->Dimension());
206 make_shared<L2_FECollection>(dest_fe_order, dest_mesh->Dimension());
210 auto src_fe = make_shared<ParFiniteElementSpace>(
211 p_src_mesh.get(), src_fe_coll.get(),
212 use_vector_space ? src_mesh->Dimension() : 1);
214 auto dest_fe = make_shared<ParFiniteElementSpace>(
215 p_dest_mesh.get(), dest_fe_coll.get(),
216 use_vector_space ? dest_mesh->Dimension() : 1);
226 if (use_vector_fe || use_vector_space)
228 src_fun.ProjectCoefficient(vector_coeff);
233 src_fun.ProjectCoefficient(coeff);
243 assemble_mass_and_coupling_together);
246 if (use_vector_space)
250 else if (use_vector_fe)
259 if (assembler.
Transfer(src_fun, dest_fun))
269 src_err = src_fun.ComputeL2Error(vector_coeff);
274 src_err = src_fun.ComputeL2Error(coeff);
280 mfem::out <<
"l2 error: src: " << src_err <<
", dest: " << dest_err
284 plot(*p_src_mesh, src_fun,
"source", 0);
285 plot(*p_dest_mesh, dest_fun,
"destination", 1);
290 mfem::out <<
"No intersection no transfer!" << std::endl;
295 return MPI_Finalize();
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...