87static const char *enum_str[] =
111int main(
int argc,
char *argv[])
118 const char *mesh_file =
"../../data/inline-quad.mesh";
124 bool static_cond =
false;
128 real_t relax_factor = 2.0/3;
130 bool visualization =
true;
132 bool paraview =
false;
135 args.
AddOption(&mesh_file,
"-m",
"--mesh",
136 "Mesh file to use.");
138 "Finite element order (polynomial degree).");
139 args.
AddOption(&delta_order,
"-do",
"--delta-order",
140 "Order enrichment for DPG test space.");
142 "Epsilon coefficient");
143 args.
AddOption(&ref,
"-ref",
"--num-refinements",
144 "Number of uniform refinements");
145 args.
AddOption(&theta,
"-theta",
"--theta",
146 "Theta parameter for AMR");
147 args.
AddOption(&iprob,
"-prob",
"--problem",
"Problem case"
148 " 0: lshape, 1: General");
150 "Vector Coefficient beta");
151 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
152 "--no-static-condensation",
"Enable static condensation.");
153 args.
AddOption(&pmg,
"-pmg",
"--p-refinement-multigrid",
"-no-pmg",
154 "--no-p-refinement-multigrid",
"Enable P-Refinement Multigrid.");
155 args.
AddOption(&pmg_levels,
"-pmgl",
"--p-refinement-multigrid-levels",
156 "Number of levels for P-Refinement Multigrid.");
157 args.
AddOption(&relax_factor,
"-rf",
"--relaxation-factor",
158 "Relaxation factor for the p-multigrid smoother.");
159 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
160 "--no-visualization",
161 "Enable or disable GLVis visualization.");
162 args.
AddOption(¶view,
"-paraview",
"--paraview",
"-no-paraview",
164 "Enable or disable ParaView visualization.");
165 args.
AddOption(&visport,
"-p",
"--send-port",
"Socket for GLVis.");
176 if (iprob > 3) { iprob = 3; }
179 if (
prob == prob_type::EJ ||
prob == prob_type::curved_streamlines ||
180 prob == prob_type::bdr_layer)
182 mesh_file =
"../../data/inline-quad.mesh";
185 Mesh mesh(mesh_file, 1, 1);
187 MFEM_VERIFY(
dim > 1,
"Dimension = 1 is not supported in this example");
223 ParMesh pmesh(MPI_COMM_WORLD, mesh);
257 int test_order = order+delta_order;
279 trial_fes.
Append(sigma_fes);
280 trial_fes.
Append(hatu_fes);
281 trial_fes.
Append(hatf_fes);
286 a->StoreMatrices(
true);
290 TrialSpace::u_space, TestSpace::v_space);
294 TrialSpace::sigma_space, TestSpace::v_space);
298 TrialSpace::u_space, TestSpace::tau_space);
302 TrialSpace::sigma_space, TestSpace::tau_space);
306 TrialSpace::hatu_space, TestSpace::tau_space);
310 TrialSpace::hatf_space, TestSpace::v_space);
325 TestSpace::v_space, TestSpace::v_space);
328 TestSpace::v_space, TestSpace::v_space);
331 TestSpace::v_space, TestSpace::v_space);
334 TestSpace::tau_space, TestSpace::tau_space);
337 TestSpace::tau_space, TestSpace::tau_space);
340 if (
prob == prob_type::sinusoidal ||
341 prob == prob_type::curved_streamlines)
363 std::cout <<
" Ref |"
367 std::cout <<
" L2 Error |"
370 std::cout <<
" Residual |"
372 <<
" CG it |" << std::endl;
373 std::cout << std::string((
exact_known) ? 72 : 50,
'-')
377 if (static_cond) {
a->EnableStaticCondensation(); }
397 for (
int it = 0; it<=ref; it++)
410 if (
prob == prob_type::EJ)
428 int n = ess_tdof_list_uhat.
Size();
429 int m = ess_tdof_list_fhat.
Size();
431 for (
int j = 0; j < n; j++)
437 for (
int j = 0; j < m; j++)
467 Solver * preconditioner =
nullptr;
471 a->GetTraceFESpaces(prec_fes);
475 prec_fes = trial_fes;
480 bool mumps_coarse_solver =
true;
482 bool mumps_coarse_solver =
false;
484 std::vector<Array<int>> ess_bdr_marker(prec_fes.
Size());
485 for (
int b = 0;
b<prec_fes.
Size();
b++)
490 int ess_block = (static_cond) ? 0 : 2;
493 ess_bdr_marker[
b] = ess_bdr_uhat;
495 else if (
b == ess_block+1)
497 ess_bdr_marker[
b] = ess_bdr_fhat;
501 ess_bdr_marker[
b] = 0;
506 pmg_levels, relax_factor, mumps_coarse_solver);
516 prec->SetOperator(A->
GetBlock(i,i));
517 block_diag->SetDiagonalBlock(i,prec);
526 cg.SetPreconditioner(*preconditioner);
528 delete preconditioner;
530 int num_iter = cg.GetNumIterations();
532 a->RecoverFEMSolution(X,x);
533 Vector & residuals =
a->ComputeResidual(x);
538 real_t gresidual = residual * residual;
541 MPI_MAX, MPI_COMM_WORLD);
543 MPI_SUM, MPI_COMM_WORLD);
545 gresidual = sqrt(gresidual);
548 for (
int iel = 0; iel<pmesh.
GetNE(); iel++)
550 if (residuals[iel] > theta * maxresidual)
552 elements_to_refine.
Append(iel);
570 L2Error = sqrt(u_err*u_err + sigma_err*sigma_err);
571 rate_err = (it) ?
dim*log(err0/L2Error)/log((
real_t)dof0/dofs) : 0.0;
574 real_t rate_res = (it) ?
dim*log(res0/gresidual)/log((
real_t)dof0/dofs) : 0.0;
581 std::ios oldState(
nullptr);
582 oldState.copyfmt(std::cout);
583 std::cout << std::right << std::setw(5) << it <<
" | "
584 << std::setw(10) << dof0 <<
" | ";
587 std::cout << std::setprecision(3) << std::setw(10)
588 << std::scientific << err0 <<
" | "
589 << std::setprecision(2)
590 << std::setw(6) << std::fixed << rate_err <<
" | " ;
592 std::cout << std::setprecision(3)
593 << std::setw(10) << std::scientific << res0 <<
" | "
594 << std::setprecision(2)
595 << std::setw(6) << std::fixed << rate_res <<
" | "
596 << std::setw(6) << std::fixed << num_iter <<
" | "
598 std::cout.copyfmt(oldState);
603 const char * keys = (it == 0 &&
dim == 2) ?
"cgRjmlk\n" :
nullptr;
606 "Numerical u", 0,0, 500, 500, keys);
608 "Numerical flux", 501,0,500, 500, keys);
624 for (
int i =0; i<trial_fes.
Size(); i++)
626 trial_fes[i]->Update(
false);
663 if (X.
Size() == 3) { z = X[2]; }
682 return g * cos(M_PI * y)/denom;
692 MFEM_ABORT(
"Wrong code path");
703 if (X.
Size() == 3) { z = X[2]; }
711 for (
int i = 0; i<du.
Size(); i++)
713 du[i] = M_PI * cos(
alpha);
731 real_t u_x = g_x * cos(M_PI * y)/denom;
732 real_t u_y = -M_PI * g * sin(M_PI*y)/denom;
747 MFEM_ABORT(
"Wrong code path");
757 if (X.
Size() == 3) { z = X[2]; }
764 return - M_PI*M_PI *
u * X.
Size();
781 real_t g_xx = g1_xx - g2_xx;
783 real_t u = g * cos(M_PI * y)/denom;
784 real_t u_xx = g_xx * cos(M_PI * y)/denom;
785 real_t u_yy = -M_PI * M_PI *
u;
797 MFEM_ABORT(
"Wrong code path");
823 for (
int i = 0; i<hatf.
Size(); i++)
825 hatf[i] = beta_val[i] *
u -
sigma[i];
840 for (
int i = 0; i<du.
Size(); i++)
842 s += beta_val[i] * du[i];
849 if (
prob == prob_type::bdr_layer)
876 if (
prob == prob_type::curved_streamlines)
880 beta_val(0) =
exp(x)*sin(y);
881 beta_val(1) =
exp(x)*cos(y);
894 for (
int i = 0; i < pmesh->
GetNE(); i++)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
A class to handle Block diagonal preconditioners in a matrix-free implementation.
A class to handle Block systems in a matrix-free implementation.
Array< int > & RowOffsets()
Return the row offsets for block starts.
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
int NumRowBlocks() const
Return the number of row blocks.
A class to handle Vectors in a block fashion.
Vector & GetBlock(int i)
Get the i-th vector in the block.
Conjugate gradient method.
A coefficient that is constant across space and time.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
for Raviart-Thomas elements
Class for domain integration .
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
A general function coefficient.
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
void ProjectBdrCoefficientNormal(Coefficient *coeff, VectorCoefficient *vcoeff, const Array< int > &attr)
Arbitrary order H1-conforming (continuous) finite elements.
Arbitrary order "H^{1/2}-conforming" trace finite elements defined on the interface between mesh elem...
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Arbitrary order "L2-conforming" discontinuous finite elements.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
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.
real_t GetElementVolume(int i)
void EnsureNCMesh(bool simplices_nonconforming=false)
static int WorldRank()
Return the MPI rank in 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.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
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.
Matrix coefficient defined as the outer product of two vector coefficients.
Creates a p-refinement multigrid preconditioner for a given set of parallel finite element spaces and...
Abstract parallel finite element space.
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.
void GetElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetElementDofs(), but with a user-provided DofTransformation object.
ParMesh * GetParMesh() const
void Update(bool want_transform=true) override
Class for parallel grid function.
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.
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, const Array< int > &attr)
ParFiniteElementSpace * ParFESpace() const
void MakeRef(FiniteElementSpace *f, real_t *v) override
Make the ParGridFunction reference external data on a new FiniteElementSpace.
void Update() override
Transform by the Space UpdateMatrix (e.g., on Mesh change).
void SetSpace(FiniteElementSpace *f) override
Associate a new FiniteElementSpace with the ParGridFunction.
Class for parallel meshes.
void SetLevelsOfDetail(int levels_of_detail_)
Set the refinement level.
void SetHighOrderOutput(bool high_order_output_)
Sets whether or not to output the data as high-order elements (false by default).
void SetDataFormat(VTKFormat fmt)
Set the data format for the ParaView output files.
Writer for ParaView visualization (PVD and VTU format)
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Arbitrary order "H^{-1/2}-conforming" face finite elements defined on the interface between mesh elem...
Vector coefficient defined as a product of scalar and vector coefficients.
A general vector function coefficient.
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
real_t Norml2() const
Returns the l2 norm of the vector.
real_t Max() const
Returns the maximal element of the vector.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
const int * ess_tdof_list
real_t sigma(const Vector &x)
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, const char *keys, bool vec)
real_t u(const Vector &xvec)
Solver * MakeFESpaceDefaultSolver(const ParFiniteElementSpace *pfespace, int print_level)
Creates a default solver for a given parallel FE space. The default solvers are the following:
std::function< real_t(const Vector &)> f(real_t mass_coeff)
real_t exact_hatu(const Vector &X)
real_t exact_laplacian_u(const Vector &X)
void exact_gradu(const Vector &X, Vector &du)
real_t bdr_data(const Vector &X)
void exact_hatf(const Vector &X, Vector &hatf)
real_t exact_u(const Vector &X)
void beta_function(const Vector &X, Vector &beta_val)
void exact_sigma(const Vector &X, Vector &sigma)
real_t f_exact(const Vector &X)
void setup_test_norm_coeffs(ParGridFunction &c1_gf, ParGridFunction &c2_gf)
MFEM_HOST_DEVICE Complex exp(const Complex &q)
Helper struct to convert a C++ type to an MPI type.