70int main(
int argc,
char *argv[])
77 const char *mesh_file =
"../../data/star.mesh";
84 bool use_pointwise_transfer =
false;
85 bool use_weighted_transfer =
false;
86 const char *device_config =
"cpu";
90 args.
AddOption(&mesh_file,
"-m",
"--mesh",
93 "Problem type (see the RHO_exact function).");
95 "Finite element order (polynomial degree) or -1 for"
96 " isoparametric space.");
97 args.
AddOption(&lref,
"-lref",
"--lor-ref-level",
"LOR refinement level.");
98 args.
AddOption(&lorder,
"-lo",
"--lor-order",
99 "LOR space order (polynomial degree, zero by default).");
100 args.
AddOption(&vis,
"-vis",
"--visualization",
"-no-vis",
101 "--no-visualization",
102 "Enable or disable GLVis visualization.");
103 args.
AddOption(&useH1,
"-h1",
"--use-h1",
"-l2",
"--use-l2",
104 "Use H1 spaces instead of L2.");
105 args.
AddOption(&use_pointwise_transfer,
"-t",
"--use-pointwise-transfer",
106 "-no-t",
"--dont-use-pointwise-transfer",
107 "Use pointwise transfer operators instead of L2 projection.");
108 args.
AddOption(&use_weighted_transfer,
"-w",
"--use-weighted-transfer",
109 "-no-w",
"--dont-use-weighted-transfer",
110 "Use coefficient-weighted L2 projection.");
111 args.
AddOption(&device_config,
"-d",
"--device",
112 "Device configuration string, see Device::Configure().");
113 args.
AddOption(&use_ea,
"-ea",
"--ea-version",
"-no-ea",
114 "--no-ea-version",
"Use element assembly version.");
118 Device device(device_config);
121 if (use_weighted_transfer && !use_pointwise_transfer)
125 cout <<
"Switching to positive problem = 5 for weighted transfer.\n";
131 Mesh serial_mesh(mesh_file, 1, 1);
132 ParMesh mesh(MPI_COMM_WORLD, serial_mesh);
137 for (
int l = 0; l < 4; l++)
156 cerr <<
"Switching the H1 LOR space order from 0 to 1\n";
174 if (use_weighted_transfer)
176 weight_coeff.
coeff = &weight_fn_coeff;
177 weight_coeff.
order = 2;
213 if (use_pointwise_transfer)
230 R.
Mult(rho, rho_lor);
233 auto global_max = [](
const Vector& v)
235 real_t max = v.Normlinf();
237 MPI_MAX, MPI_COMM_WORLD);
241 if (use_weighted_transfer && !use_pointwise_transfer)
253 w.ProjectCoefficient(W);
260 vel_gt.
UseEA(use_ea);
262 compute_mass(w_lor, ho_momentum,
"rho w LOR", prod_lor_weight);
273 const real_t l_inf = global_max(w_prev_true);
277 cout <<
"|w - P(R(w))|_∞ = " << l_inf <<
"\n\n";
288 P.
Mult(rho_lor, rho);
295 real_t l_inf = global_max(rho_prev_true);
299 cout <<
"|HO - P(R(HO))|_∞ = " << l_inf << endl;
305 auto global_sum = [](
const Vector& v)
309 MPI_SUM, MPI_COMM_WORLD);
319 real_t ho_dual_mass = global_sum(M_rho);
320 real_t lor_dual_mass = global_sum(M_rho_lor);
323 cout <<
"HO -> LOR dual field: " <<
abs(ho_dual_mass - lor_dual_mass) <<
"\n\n";
339 P.
Mult(rho_lor, rho);
346 R.
Mult(rho, rho_lor);
347 compute_mass(rho_lor, lor_mass,
"R(P(LOR))", weight_coeff);
348 if (vis) {
visualize(LOR_dc,
"R(P(LOR))",
Wx,
Wy, visport); }
350 rho_lor_prev -= rho_lor;
353 real_t l_inf = global_max(rho_lor_prev_true);
357 cout <<
"|LOR - R(P(LOR))|_∞ = " << l_inf << endl;
362 if (!use_pointwise_transfer)
369 real_t ho_dual_mass = global_sum(M_rho);
370 real_t lor_dual_mass = global_sum(M_rho_lor);
374 cout <<
"lor dual mass = " << lor_dual_mass <<
'\n';
375 cout <<
"ho dual mass = " << ho_dual_mass <<
'\n';
376 cout <<
"LOR -> HO dual field: " <<
abs(ho_dual_mass - lor_dual_mass) <<
'\n';
395 return x(1)+0.25*cos(2*M_PI*x.
Norml2());
397 return x(1)*x(1)*x(1) + 2*x(0)*x(1) + x(0);
399 return M_PI/2-atan(5*(2*x.
Norml2()-1));
401 return (x.
Norml2() < 0.1) ? 1 : 0;
403 return 2.0 + 2*x(0)*x(0) + 3*x(1)*x(1) - x(0)*x(1) + 0.1*sin(x.
Norml2());
412 return x(1) + 0.25*cos(2*M_PI*x.
Norml2());
418 return x(0)*x(0) + x(1)*x(1) + 1.0;
432 sol_sockL2.precision(8);
434 <<
"window_geometry " << x <<
" " << y <<
" " << w <<
" " << h
435 <<
"plot_caption '" <<
space <<
" " << prefix <<
" Density'"
436 <<
"window_title '" <<
direction <<
"'" << flush;
459 const real_t newmass = lf(gf);
463 cout <<
space <<
" " << prefix <<
" mass = " << newmass;
467 cout <<
" (" << fabs(newmass-oldmass)*100/oldmass <<
"%)";
@ GaussLobatto
Closed type.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
A coefficient that is constant across space and time.
GridFunction * GetField(const std::string &field_name)
Get a pointer to a grid function in the collection.
Mesh * GetMesh()
Get a pointer to the mesh in the collection.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
void Print(std::ostream &os=mfem::out)
Print the configuration of the MFEM virtual device object.
Class for domain integration .
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Mesh * GetMesh() const
Returns the mesh.
A general function coefficient.
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
Base class for transfer algorithms that construct transfer Operators between two finite element (FE) ...
virtual bool SupportsBackwardsOperator() const
virtual const Operator & ForwardOperator()=0
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
virtual const Operator & BackwardOperator()=0
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
Arbitrary order H1-conforming (continuous) finite elements.
Wrapper for hypre's ParCSR matrix class.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, real_t alpha=1.0, real_t beta=0.0) const
Computes y = alpha * A * x + beta * y.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Transfer data between a coarse mesh and an embedded refined mesh using interpolation.
Transfer data in L2 and H1 finite element spaces between a coarse mesh and an embedded refined mesh u...
const Operator & BackwardOperator() override
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
bool SupportsBackwardsOperator() const override
const Operator & ForwardOperator() override
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
Arbitrary order "L2-conforming" discontinuous finite elements.
void Clear()
Clear the contents of the Mesh.
int Dimension() const
Dimension of the reference space used within the elements.
ElementTransformation * GetTypicalElementTransformation()
If the local mesh is not empty return GetElementTransformation(0); otherwise, return the identity tra...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static int WorldSize()
Return the size of MPI_COMM_WORLD.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
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 ...
void ParseCheck(std::ostream &out=mfem::out)
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...
Abstract parallel finite element space.
const Operator * GetRestrictionOperator() const override
int GetTrueVSize() const override
Return the number of local vector true dofs.
Class for parallel grid function.
void ProjectCoefficient(Coefficient &coeff, ProjectType type=ProjectType::DEFAULT) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
ParFiniteElementSpace * ParFESpace() const
Class for parallel meshes.
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
real_t Norml2() const
Returns the l2 norm of the vector.
Data collection with VisIt I/O routines.
void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
real_t weight(const Vector &x)
real_t compute_mass(ParGridFunction &, real_t, string, CoefficientWithOrder)
real_t W_exact(const Vector &x)
void visualize(VisItDataCollection &, string, int, int, int)
real_t RHO_exact(const Vector &x)
MFEM_HOST_DEVICE real_t abs(const Complex &z)
Helper struct to convert a C++ type to an MPI type.