40 bool norm_set =
false;
43 int order_quad = std::max(2, 2*order+1);
50 ParGridFunction *pgf =
dynamic_cast<ParGridFunction *
>(gf);
53 ParMesh *pmesh = pgf->ParFESpace()->GetParMesh();
80void ConvergenceStudy::AddL2Error(GridFunction *gf,
81 Coefficient *scalar_u, VectorCoefficient *vector_u)
84 int dim = gf->FESpace()->GetMesh()->Dimension();
87 ParGridFunction *pgf =
dynamic_cast<ParGridFunction *
>(gf);
90 MPI_Comm comm = pgf->ParFESpace()->GetComm();
92 MPI_Comm_rank(comm, &rank);
94 if (rank==0) { print_flag = 1; }
95 tdofs = pgf->ParFESpace()->GlobalTrueVSize();
98 if (!tdofs) { tdofs = gf->FESpace()->GetTrueVSize(); }
103 L2Err = gf->ComputeL2Error(*scalar_u);
104 CoeffNorm = GetNorm(gf,scalar_u,
nullptr);
108 L2Err = gf->ComputeL2Error(*vector_u);
109 CoeffNorm = GetNorm(gf,
nullptr,vector_u);
113 MFEM_ABORT(
"Exact Solution Coefficient pointer is NULL");
121 real_t num = log(L2Errors[counter-1]/L2Err);
122 real_t den = log((
real_t)ndofs[counter]/ndofs[counter-1]);
129void ConvergenceStudy::AddGf(GridFunction *gf, Coefficient *scalar_u,
130 VectorCoefficient *grad,
131 Coefficient *ell_coeff,
132 JumpScaling jump_scaling)
134 cont_type = gf->FESpace()->FEColl()->GetContType();
138 "This constructor is intended for H1 or L2 Elements")
140 AddL2Error(gf,scalar_u,
nullptr);
141 int dim = gf->FESpace()->
GetMesh()->Dimension();
145 real_t GradErr = gf->ComputeGradError(grad);
148 sqrt(L2Errors[counter-1]*L2Errors[counter-1]+GradErr*GradErr);
156 real_t num = log(DErrors[dcounter-1]/GradErr);
157 real_t den = log((
real_t)ndofs[dcounter]/ndofs[dcounter-1]);
159 num = log(EnErrors[dcounter-1]/error);
160 eval =
dim * num/den;
164 CoeffDNorm = GetNorm(gf,
nullptr,grad);
166 MFEM_VERIFY(counter == dcounter,
167 "Number of added solutions and derivatives do not match")
172 real_t DGErr = gf->ComputeDGFaceJumpError(scalar_u,ell_coeff,jump_scaling);
173 DGFaceErrors.
Append(DGErr);
179 real_t num = log(DGFaceErrors[fcounter-1]/DGErr);
180 real_t den = log((
real_t)ndofs[fcounter]/ndofs[fcounter-1]);
185 MFEM_VERIFY(fcounter == counter,
"Number of added solutions mismatch");
189void ConvergenceStudy::AddGf(GridFunction *gf, VectorCoefficient *vector_u,
190 VectorCoefficient *curl, Coefficient *div)
192 cont_type = gf->FESpace()->FEColl()->GetContType();
194 AddL2Error(gf,
nullptr,vector_u);
195 int dim = gf->FESpace()->GetMesh()->Dimension();
197 bool derivative =
false;
200 DErr = gf->ComputeCurlError(curl);
201 CoeffDNorm = GetNorm(gf,
nullptr,curl);
206 DErr = gf->ComputeDivError(div);
208 CoeffDNorm = GetNorm(gf,div,
nullptr);
213 real_t error = sqrt(L2Errors[counter-1]*L2Errors[counter-1] + DErr*DErr);
222 real_t num = log(DErrors[dcounter-1]/DErr);
223 real_t den = log((
real_t)ndofs[dcounter]/ndofs[dcounter-1]);
225 num = log(EnErrors[dcounter-1]/error);
226 eval =
dim * num/den;
231 MFEM_VERIFY(counter == dcounter,
232 "Number of added solutions and derivatives do not match")
240 std::string title = (relative) ?
"Relative " :
"Absolute ";
242 os <<
" -------------------------------------------" <<
"\n";
243 os << std::setw(21) << title <<
"L2 Error " <<
"\n";
244 os <<
" -------------------------------------------"
246 os << std::right<< std::setw(11)<<
"DOFs "<< std::setw(13) <<
"Error ";
247 os << std::setw(15) <<
"Rate " <<
"\n";
248 os <<
" -------------------------------------------"
250 os << std::setprecision(4);
251 real_t d = (relative) ? CoeffNorm : 1.0;
252 for (
int i =0; i<counter; i++)
254 os << std::right << std::setw(10)<< ndofs[i] << std::setw(16)
255 << std::scientific << L2Errors[i]/d << std::setw(13)
256 << std::fixed << L2Rates[i] <<
"\n";
259 if (dcounter == counter)
264 case 0: dname =
"Grad";
break;
265 case 1: dname =
"Curl";
break;
266 case 2: dname =
"Div";
break;
267 case 3: dname =
"DG Grad";
break;
270 os <<
" -------------------------------------------" <<
"\n";
271 os << std::setw(21) << title << dname <<
" Error " <<
"\n";
272 os <<
" -------------------------------------------" <<
"\n";
273 os << std::right<<std::setw(11)<<
"DOFs "<< std::setw(13) <<
"Error";
274 os << std::setw(15) <<
"Rate " <<
"\n";
275 os <<
" -------------------------------------------"
277 os << std::setprecision(4);
278 d = (relative) ? CoeffDNorm : 1.0;
279 for (
int i =0; i<dcounter; i++)
281 os << std::right << std::setw(10)<< ndofs[i] << std::setw(16)
282 << std::scientific << DErrors[i]/d << std::setw(13)
283 << std::fixed << DRates[i] <<
"\n";
288 case 0: dname =
"H1";
break;
289 case 1: dname =
"H(Curl)";
break;
290 case 2: dname =
"H(Div)";
break;
291 case 3: dname =
"DG H1";
break;
298 sqrt(CoeffNorm*CoeffNorm + CoeffDNorm*CoeffDNorm):1.0;
300 os <<
" -------------------------------------------" <<
"\n";
301 os << std::setw(21) << title << dname <<
" Error " <<
"\n";
302 os <<
" -------------------------------------------" <<
"\n";
303 os << std::right<< std::setw(11)<<
"DOFs "<< std::setw(13);
305 os << std::setw(15) <<
"Rate " <<
"\n";
306 os <<
" -------------------------------------------"
308 os << std::setprecision(4);
309 for (
int i =0; i<dcounter; i++)
311 os << std::right << std::setw(10)<< ndofs[i] << std::setw(16)
312 << std::scientific << EnErrors[i]/d << std::setw(13)
313 << std::fixed << EnRates[i] <<
"\n";
318 if (cont_type == 3 && fcounter)
320 os <<
" -------------------------------------------" <<
"\n";
321 os <<
" DG Face Jump Error " <<
"\n";
322 os <<
" -------------------------------------------"
324 os << std::right<< std::setw(11)<<
"DOFs "<< std::setw(13);
326 os << std::setw(15) <<
"Rate " <<
"\n";
327 os <<
" -------------------------------------------"
329 os << std::setprecision(4);
330 for (
int i =0; i<fcounter; i++)
332 os << std::right << std::setw(10)<< ndofs[i] << std::setw(16)
333 << std::scientific << DGFaceErrors[i] << std::setw(13)
334 << std::fixed << DGFaceRates[i] <<
"\n";
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
void Reset()
Clear any internal data.
void Print(bool relative=false, std::ostream &out=mfem::out)
Print rates and errors.
@ DISCONTINUOUS
Field is discontinuous across element interfaces.
@ CONTINUOUS
Field is continuous across element interfaces.
Mesh * GetMesh() const
Returns the mesh.
int GetMaxElementOrder() const
Return the maximum polynomial order.
Class for grid function - Vector with associated FE space.
FiniteElementSpace * FESpace()
Class for an integration rule - an Array of IntegrationPoint.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Base class for vector Coefficients that optionally depend on time and space.
real_t ComputeGlobalLpNorm(real_t p, Coefficient &coeff, ParMesh &pmesh, const IntegrationRule *irs[])
Compute the global Lp norm of a function f. .
real_t ComputeLpNorm(real_t p, Coefficient &coeff, Mesh &mesh, const IntegrationRule *irs[])
Compute the Lp norm of a function f. .
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)