34 return int(std::abs(1.0e5 * sin(seed * 1.1234 * M_PI)));
39int main(
int argc,
char *argv[])
49 const char *device_config =
"cpu";
50 bool visualization =
true;
53 bool anisotropic =
false;
54 bool fixedOrder =
false;
55 bool deterministic =
true;
56 bool projectSolution =
false;
60 "Finite element order (polynomial degree) or -1 for"
61 " isoparametric space.");
62 args.
AddOption(&device_config,
"-d",
"--device",
63 "Device configuration string, see Device::Configure().");
64 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
66 "Enable or disable GLVis visualization.");
67 args.
AddOption(&numIter,
"-n",
"--num-iter",
"Number of hp-ref iterations");
68 args.
AddOption(&
dim,
"-dim",
"--dim",
"Mesh dimension (2 or 3)");
69 args.
AddOption(&anisotropic,
"-aniso",
"--anisotropic",
"-iso",
71 "Whether to use anisotropic refinements");
72 args.
AddOption(&fixedOrder,
"-fo",
"--fixed-order",
"-vo",
74 "Whether to fix the finite element order on all elements");
75 args.
AddOption(&deterministic,
"-det",
"--deterministic",
"-not-det",
76 "--not-deterministic",
77 "Use deterministic random refinements");
78 args.
AddOption(&projectSolution,
"-proj",
"--project-solution",
"-no-proj",
80 "Project a coefficient to solution");
96 MFEM_VERIFY(!anisotropic || fixedOrder,
97 "Variable-order is not supported with anisotropic refinement");
101 Device device(device_config);
102 if (myid == 0) { device.
Print(); }
120 ParMesh pmesh(MPI_COMM_WORLD, mesh);
123 int par_ref_levels = 0;
124 for (
int l = 0; l < par_ref_levels; l++)
146 cout <<
"Using isoparametric FEs: " << fec->
Name() << endl;
155 const int fespaceDim = projectSolution ?
dim : 1;
164 const std::vector<char> hp_char = {
'h',
'p'};
166 for (
int iter=0; iter<numIter; ++iter)
168 const int r1 = deterministic ?
DetRand(seed) : rand();
169 const int r2 = deterministic ?
DetRand(seed) : rand();
170 const int elem = r1 % pmesh.
GetNE();
173 MPI_Bcast(&hp, 1, MPI_INT, 0, MPI_COMM_WORLD);
175 if (fixedOrder) { hp = 0; }
178 const int r3 = deterministic ?
DetRand(seed) : rand();
179 htype = (r3 % 7) + 1;
183 cout <<
"hp-refinement iteration " << iter <<
": "
184 << hp_char[hp] <<
"-refinement\n";
201 std::set<int> conflicts;
206 cout <<
"Anisotropic conflict on iteration " << iter
223 cout <<
"Number of finite element unknowns: " << size << endl;
224 cout <<
"Total number of h-refinements: " << numH
225 <<
"\nTotal number of p-refinements: " << numP
226 <<
"\nMaximum order " << maxP <<
"\n";
246 cout <<
"\n|| E_h - E ||_{L^2} = " << error <<
'\n' << endl;
290 a.FormLinearSystem(ess_tdof_list, x,
b, A, X, B);
313 if (myid == 0) { cout <<
"H1 continuity error " << h1error << endl; }
314 MFEM_VERIFY(h1error < 1.0e-12,
"H1 continuity is not satisfied");
322 for (
int e=0; e<pmesh.
GetNE(); ++e)
327 MFEM_VERIFY(dofs.
Size() == 1,
"");
328 xo[dofs[0]] = p_elem;
335 ostringstream mesh_name, sol_name, order_name;
336 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
337 sol_name <<
"sol." << setfill(
'0') << setw(6) << myid;
338 order_name <<
"order." << setfill(
'0') << setw(6) << myid;
340 ofstream mesh_ofs(mesh_name.str().c_str());
341 mesh_ofs.precision(8);
344 ofstream sol_ofs(sol_name.str().c_str());
345 sol_ofs.precision(8);
347 vis_x->Save(sol_ofs);
349 ofstream order_ofs(order_name.str().c_str());
350 order_ofs.precision(8);
360 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
361 sol_sock.precision(8);
362 sol_sock <<
"solution\n" << pmesh << *vis_x << flush;
392 int Inf1, Inf2, NCFace;
399 auto &int_rule =
IntRules.
Get(FT->FaceGeom, 2 * faceOrder);
407 bool isNCSlave = FT->Elem2No >= 0 && NCFace >= 0;
408 bool isConforming = FT->Elem2No >= 0 && NCFace == -1;
409 if ((FT->Elem1No < FT->Elem2No && isConforming) || isNCSlave)
411 for (
int i = 0; i < nip; i++)
413 const auto &fip = int_rule.IntPoint(i);
416 FT->Loc1.Transform(fip, ip);
419 FT->Loc2.Transform(fip, ip);
422 const real_t err_i = std::abs(v1 - v2);
423 errorMax = std::max(errorMax, err_i);
434 if (!trueInterior) {
continue; }
438 const auto &int_rule =
IntRules.
Get(FT->FaceGeom, 2 * faceOrder);
441 for (
int i = 0; i < nip; i++)
443 const auto &fip = int_rule.IntPoint(i);
446 FT->Loc1.Transform(fip, ip);
449 FT->Loc2.Transform(fip, ip);
452 const real_t err_i = std::abs(v1 - v2);
453 errorMax = std::max(errorMax, err_i);
457 real_t errorMaxGlobal = 0.0;
458 MPI_Allreduce(&errorMax, &errorMaxGlobal, 1, MFEM_MPI_REAL_T, MPI_MAX,
460 return errorMaxGlobal;
478 if (x.
Size() == 3) {
f(2) = 0.0; }
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
int Size() const
Return the logical size of the array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Conjugate gradient method.
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
A coefficient that is constant across space and time.
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...
virtual const char * Name() const
int GetEdgeOrder(int edge, int variant=0) const
int GetFaceOrder(int face, int variant=0) const
Returns the polynomial degree of the i'th face finite element.
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
Arbitrary order H1-conforming (continuous) finite elements.
The BoomerAMG solver in hypre.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Class for integration point with weight.
int GetNPoints() const
Returns the number of the points in the integration rule.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void SetRelTol(real_t rtol)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
Arbitrary order "L2-conforming" discontinuous finite elements.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void GetFaceInfos(int Face, int *Inf1, int *Inf2) const
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void GeneralRefinement(const Array< Refinement > &refinements, int nonconforming=-1, int nc_limit=0)
void Clear()
Clear the contents of the Mesh.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
bool FaceIsInterior(int FaceNo) const
Return true if the given face is interior.
static Mesh MakeCartesian3D(int nx, int ny, int nz, Element::Type type, real_t sx=1.0, real_t sy=1.0, real_t sz=1.0, bool sfc_ordering=true)
Creates a mesh for the parallelepiped [0,sx]x[0,sy]x[0,sz], divided into nx*ny*nz hexahedra if type =...
void GetNodes(Vector &node_coord) const
void EnsureNCMesh(bool simplices_nonconforming=false)
static Mesh MakeCartesian2D(int nx, int ny, Element::Type type, bool generate_edges=false, real_t sx=1.0, real_t sy=1.0, bool sfc_ordering=true)
Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny quadrilaterals if type = QUADRILATER...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
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).
Pointer to an Operator of a specified type.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x)
Reconstruct a solution vector x (e.g. a GridFunction) from the solution X of a constrained linear sys...
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
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...
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
int GetMaxElementOrder() const override
Returns the maximum polynomial order over all elements globally.
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
HYPRE_BigInt GlobalTrueVSize() const
int GetTrueVSize() const override
Return the number of local vector true dofs.
const Operator * GetProlongationMatrix() const override
void GetElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetElementDofs(), but with a user-provided DofTransformation object.
void PRefineAndUpdate(const Array< pRefinement > &refs, bool want_transfer=true) override
const SparseMatrix * GetRestrictionMatrix() const override
Get the R matrix which restricts a local dof vector to true dof vector.
ParMesh * GetParMesh() const
void Update(bool want_transform=true) override
Class for parallel grid function.
void ExchangeFaceNbrData()
void Save(std::ostream &out) const override
real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const override
Returns ||u_ex - u_h||_L2 in parallel for H1 or L2 elements.
real_t GetValue(int i, const IntegrationPoint &ip, int vdim=1) const override
ParFiniteElementSpace * ParFESpace() const
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
std::unique_ptr< ParGridFunction > ProlongateToMaxOrder() const
Return a GridFunction with the values of this, prolongated to the maximum order of all elements in th...
Class for parallel meshes.
void ParPrint(std::ostream &out, const std::string &comments="") const
int GetNSharedFaces() const
Return the number of shared faces (3D), edges (2D), vertices (1D)
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31) override
bool AnisotropicConflict(const Array< Refinement > &refinements, std::set< int > &conflicts) const
Return true if the input array of refinements to be performed would result in conflicting anisotropic...
bool FaceIsTrueInterior(int FaceNo) const
int GetSharedFace(int sface) const
Return the local face index for the given shared face.
FaceElementTransformations * GetSharedFaceTransformations(int sf, bool fill2=true)
Get the FaceElementTransformations for the given shared face (edge 2D) using the shared face index sf...
void Mult(const Vector &x, Vector &y) const override
Matrix vector multiplication.
A general vector function coefficient.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
void f_exact(const Vector &x, Vector &f)
real_t CheckH1Continuity(ParGridFunction &x)