68 int main(
int argc,
char *argv[])
71 Mpi::Init(argc, argv);
75 const char *mesh_file =
"../../data/star.mesh";
81 bool use_pointwise_transfer =
false;
84 args.
AddOption(&mesh_file,
"-m",
"--mesh",
87 "Problem type (see the RHO_exact function).");
89 "Finite element order (polynomial degree) or -1 for" 90 " isoparametric space.");
91 args.
AddOption(&lref,
"-lref",
"--lor-ref-level",
"LOR refinement level.");
92 args.
AddOption(&lorder,
"-lo",
"--lor-order",
93 "LOR space order (polynomial degree, zero by default).");
94 args.
AddOption(&vis,
"-vis",
"--visualization",
"-no-vis",
96 "Enable or disable GLVis visualization.");
97 args.
AddOption(&useH1,
"-h1",
"--use-h1",
"-l2",
"--use-l2",
98 "Use H1 spaces instead of L2.");
99 args.
AddOption(&use_pointwise_transfer,
"-t",
"--use-pointwise-transfer",
100 "-no-t",
"--dont-use-pointwise-transfer",
101 "Use pointwise transfer operators instead of L2 projection.");
105 Mesh serial_mesh(mesh_file, 1, 1);
106 ParMesh mesh(MPI_COMM_WORLD, serial_mesh);
111 int basis_lor = BasisType::GaussLobatto;
112 ParMesh mesh_lor = ParMesh::MakeRefined(mesh, lref, basis_lor);
124 cerr <<
"Switching the H1 LOR space order from 0 to 1\n";
169 double ho_mass =
compute_mass(&fespace, -1.0, HO_dc,
"HO ");
173 if (use_pointwise_transfer)
185 R.
Mult(rho, rho_lor);
188 auto global_max = [](
const Vector& v)
190 double max = v.Normlinf();
191 MPI_Allreduce(MPI_IN_PLACE, &max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
201 P.
Mult(rho_lor, rho);
208 double l_inf = global_max(rho_prev_true);
212 cout <<
"|HO - P(R(HO))|_∞ = " << l_inf << endl;
218 auto global_sum = [](
const Vector& v)
220 double sum = v.Sum();
221 MPI_Allreduce(MPI_IN_PLACE, &sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
231 double ho_dual_mass = global_sum(M_rho);
232 double lor_dual_mass = global_sum(M_rho_lor);
235 cout <<
"HO -> LOR dual field: " << abs(ho_dual_mass - lor_dual_mass) <<
"\n\n";
243 double lor_mass =
compute_mass(&fespace_lor, -1.0, LOR_dc,
"LOR ");
251 P.
Mult(rho_lor, rho);
258 R.
Mult(rho, rho_lor);
259 compute_mass(&fespace_lor, lor_mass, LOR_dc,
"R(P(LOR))");
262 rho_lor_prev -= rho_lor;
265 double l_inf = global_max(rho_lor_prev_true);
269 cout <<
"|LOR - R(P(LOR))|_∞ = " << l_inf << endl;
274 if (!use_pointwise_transfer)
281 double ho_dual_mass = global_sum(M_rho);
282 double lor_dual_mass = global_sum(M_rho_lor);
284 cout << lor_dual_mass <<
'\n';
285 cout << ho_dual_mass <<
'\n';
289 cout <<
"LOR -> HO dual field: " << abs(ho_dual_mass - lor_dual_mass) <<
'\n';
308 return x(1)+0.25*cos(2*M_PI*x.
Norml2());
310 return x(1)*x(1)*x(1) + 2*x(0)*x(1) + x(0);
312 return M_PI/2-atan(5*(2*x.
Norml2()-1));
314 return (x.
Norml2() < 0.1) ? 1 : 0;
329 sol_sockL2 <<
"parallel " << Mpi::WorldSize() <<
" " << Mpi::WorldRank() <<
331 sol_sockL2.precision(8);
333 <<
"window_geometry " << x <<
" " << y <<
" " << w <<
" " << h
334 <<
"plot_caption '" <<
space <<
" " << prefix <<
" Density'" 335 <<
"window_title '" <<
direction <<
"'" << flush;
351 cout <<
space <<
" " << prefix <<
" mass = " << newmass;
355 cout <<
" (" << fabs(newmass-massL2)*100/massL2 <<
"%)";
void visualize(VisItDataCollection &, string, int, int)
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Class for domain integration L(v) := (f, v)
int main(int argc, char *argv[])
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
A coefficient that is constant across space and time.
int Dimension() const
Dimension of the reference space used within the elements.
virtual const Operator * GetRestrictionOperator() const
GridFunction * GetField(const std::string &field_name)
Get a pointer to a grid function in the collection.
virtual const Operator & BackwardOperator()=0
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
double RHO_exact(const Vector &x)
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
virtual const Operator & ForwardOperator()=0
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
Data collection with VisIt I/O routines.
virtual bool SupportsBackwardsOperator() const
Base class for transfer algorithms that construct transfer Operators between two finite element (FE) ...
ParGridFunction * GetParField(const std::string &field_name)
Get a pointer to a parallel grid function in the collection.
Transfer data between a coarse mesh and an embedded refined mesh using interpolation.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
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...
double compute_mass(ParFiniteElementSpace *, double, VisItDataCollection &, string)
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
Transfer data in L2 and H1 finite element spaces between a coarse mesh and an embedded refined mesh u...
double Norml2() const
Returns the l2 norm of the vector.
Mesh * GetMesh()
Get a pointer to the mesh in the collection.
void Clear()
Clear the contents of the Mesh.
A general function coefficient.
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
Arbitrary order H1-conforming (continuous) finite elements.
Class for parallel grid function.
Wrapper for hypre's ParCSR matrix class.
Class for parallel meshes.
void ParseCheck(std::ostream &out=mfem::out)
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0) const
Computes y = alpha * A * x + beta * y.
Arbitrary order "L2-conforming" discontinuous finite elements.
virtual void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.