42 const double solver_tol = 1e-12;
43 const int solver_max_it = 200;
51 #endif // MFEM_USE_MPI
57 : attributes(attributes_)
58 , flux_integrator(&di_)
60 , flux_space(&flux_fespace_)
61 , own_flux_fespace(false)
73 : attributes(attributes_)
74 , flux_integrator(&di_)
76 , flux_space(flux_fespace_)
77 , own_flux_fespace(true)
95 compute_element_coefficient = [](
Mesh* mesh,
const int e)
100 compute_face_coefficient = [](
Mesh* mesh,
const int f,
101 const bool shared_face)
108 return dynamic_cast<ParMesh*
>(mesh)->GetSharedFaceTransformations(f);
110 #endif // MFEM_USE_MPI
116 double diameter = 0.0;
126 for (
int i = 0; i < nip; i++)
129 auto fip1 = vtx_intrule->IntPoint(i);
130 FT->Transform(fip1, p1);
132 for (
int j = 0; j < nip; j++)
134 auto fip2 = vtx_intrule->IntPoint(j);
135 FT->Transform(fip2, p2);
137 diameter = std::max<double>(diameter, p2.DistanceTo(p1));
140 return diameter/(2.0*order);
144 void KellyErrorEstimator::ComputeEstimates()
158 flux_space->
Update(
false);
160 auto xfes = solution->
FESpace();
161 MFEM_ASSERT(xfes->GetVDim() == 1,
162 "Estimation for vector-valued problems not implemented yet.");
165 this->error_estimates.
SetSize(xfes->GetNE());
166 this->error_estimates = 0.0;
179 if (attributes.
Size())
184 Array<int> xdofs, fdofs;
186 for (
int e = 0; e < xfes->GetNE(); e++)
188 auto attr = xfes->GetAttribute(e);
194 xfes->GetElementVDofs(e, xdofs);
197 ElementTransformation* Transf = xfes->GetElementTransformation(e);
199 *flux_space->
GetFE(e), el_f,
true);
206 for (
int f = 0;
f < mesh->GetNumFaces();
f++)
208 auto FT = mesh->GetFaceElementTransformations(
f);
210 auto &int_rule =
IntRules.
Get(FT->FaceGeom, 2 * xfes->GetFaceOrder(
f));
213 if (mesh->FaceIsInterior(
f))
215 int Inf1, Inf2, NCFace;
216 mesh->GetFaceInfos(
f, &Inf1, &Inf2, &NCFace);
223 bool isNCSlave = FT->Elem2No >= 0 && NCFace >= 0;
224 bool isConforming = FT->Elem2No >= 0 && NCFace == -1;
225 if ((FT->Elem1No < FT->Elem2No && isConforming) || isNCSlave)
227 if (attributes.
Size() &&
228 (attributes.
FindSorted(FT->Elem1->Attribute) == -1
229 || attributes.
FindSorted(FT->Elem2->Attribute) == -1))
239 for (
int i = 0; i < nip; i++)
242 auto &fip = int_rule.IntPoint(i);
244 FT->Loc1.Transform(fip, ip);
246 Vector val(flux_space->
GetVDim());
250 Vector normal(mesh->SpaceDimension());
251 FT->Face->SetIntPoint(&fip);
252 if (mesh->Dimension() == mesh->SpaceDimension())
258 Vector ref_normal(mesh->Dimension());
259 FT->Loc1.Transf.SetIntPoint(&fip);
260 CalcOrtho(FT->Loc1.Transf.Jacobian(), ref_normal);
261 auto &e1 = FT->GetElement1Transformation();
262 e1.AdjugateJacobian().MultTranspose(ref_normal, normal);
263 normal /= e1.Weight();
265 jumps(i) = val * normal * fip.weight * FT->Face->Weight();
270 for (
int i = 0; i < nip; i++)
273 auto &fip = int_rule.IntPoint(i);
275 FT->Loc2.Transform(fip, ip);
277 Vector val(flux_space->
GetVDim());
281 Vector normal(mesh->SpaceDimension());
282 FT->Face->SetIntPoint(&fip);
283 if (mesh->Dimension() == mesh->SpaceDimension())
289 Vector ref_normal(mesh->Dimension());
290 FT->Loc1.Transf.SetIntPoint(&fip);
291 CalcOrtho(FT->Loc1.Transf.Jacobian(), ref_normal);
292 auto &e1 = FT->GetElement1Transformation();
293 e1.AdjugateJacobian().MultTranspose(ref_normal, normal);
294 normal /= e1.Weight();
297 jumps(i) -= val * normal * fip.weight * FT->Face->Weight();
301 for (
int i = 0; i < nip; i++)
303 jumps(i) *= jumps(i);
305 auto h_k_face = compute_face_coefficient(mesh,
f,
false);
306 double jump_integral = h_k_face*jumps.Sum();
312 error_estimates(FT->Elem1No) += jump_integral;
313 error_estimates(FT->Elem2No) += jump_integral;
322 #endif // MFEM_USE_MPI
325 for (
int e = 0; e < xfes->GetNE(); e++)
327 auto factor = compute_element_coefficient(mesh, e);
329 error_estimates(e) =
sqrt(factor * error_estimates(e));
332 total_error = error_estimates.
Norml2();
342 ParGridFunction *pflux =
dynamic_cast<ParGridFunction*
>(flux);
343 MFEM_VERIFY(pflux,
"flux is not a ParGridFunction pointer");
345 ParMesh *pmesh =
dynamic_cast<ParMesh*
>(mesh);
346 MFEM_VERIFY(pmesh,
"mesh is not a ParMesh pointer");
348 pflux->ExchangeFaceNbrData();
350 for (
int sf = 0; sf < pmesh->GetNSharedFaces(); sf++)
352 auto FT = pmesh->GetSharedFaceTransformations(sf,
true);
353 if (attributes.
Size() &&
354 (attributes.
FindSorted(FT->Elem1->Attribute) == -1
355 || attributes.
FindSorted(FT->Elem2->Attribute) == -1))
360 auto &int_rule =
IntRules.
Get(FT->FaceGeom, 2 * xfes->GetFaceOrder(0));
368 for (
int i = 0; i < nip; i++)
371 auto &fip = int_rule.IntPoint(i);
373 FT->Loc1.Transform(fip, ip);
375 Vector val(flux_space->
GetVDim());
378 Vector normal(mesh->SpaceDimension());
379 FT->Face->SetIntPoint(&fip);
380 if (mesh->Dimension() == mesh->SpaceDimension())
386 Vector ref_normal(mesh->Dimension());
387 FT->Loc1.Transf.SetIntPoint(&fip);
388 CalcOrtho(FT->Loc1.Transf.Jacobian(), ref_normal);
389 auto &e1 = FT->GetElement1Transformation();
390 e1.AdjugateJacobian().MultTranspose(ref_normal, normal);
391 normal /= e1.Weight();
394 jumps(i) = val * normal * fip.weight * FT->Face->Weight();
399 for (
int i = 0; i < nip; i++)
402 auto &fip = int_rule.IntPoint(i);
404 FT->Loc2.Transform(fip, ip);
406 Vector val(flux_space->
GetVDim());
410 Vector normal(mesh->SpaceDimension());
411 FT->Face->SetIntPoint(&fip);
412 if (mesh->Dimension() == mesh->SpaceDimension())
418 Vector ref_normal(mesh->Dimension());
419 CalcOrtho(FT->Loc1.Transf.Jacobian(), ref_normal);
420 auto &e1 = FT->GetElement1Transformation();
421 e1.AdjugateJacobian().MultTranspose(ref_normal, normal);
422 normal /= e1.Weight();
425 jumps(i) -= val * normal * fip.weight * FT->Face->Weight();
429 for (
int i = 0; i < nip; i++)
431 jumps(i) *= jumps(i);
433 auto h_k_face = compute_face_coefficient(mesh, sf,
true);
434 double jump_integral = h_k_face*jumps.Sum();
436 error_estimates(FT->Elem1No) += jump_integral;
444 for (
int e = 0; e < xfes->GetNE(); e++)
446 auto factor = compute_element_coefficient(mesh, e);
448 error_estimates(e) =
sqrt(factor * error_estimates(e));
452 auto pfes =
dynamic_cast<ParFiniteElementSpace*
>(xfes);
453 MFEM_VERIFY(pfes,
"xfes is not a ParFiniteElementSpace pointer");
455 double process_local_error =
pow(error_estimates.
Norml2(),2.0);
456 MPI_Allreduce(&process_local_error, &total_error, 1, MPI_DOUBLE,
457 MPI_SUM, pfes->GetComm());
458 total_error =
sqrt(total_error);
459 #endif // MFEM_USE_MPI
464 MFEM_VERIFY(
coef != NULL ||
vcoef != NULL,
465 "LpErrorEstimator has no coefficient! Call SetCoef first.");
482 MPI_Allreduce(&process_local_error, &
total_error, 1, MPI_DOUBLE,
483 MPI_SUM, pfes->GetComm());
485 #endif // MFEM_USE_MPI
int GetNPoints() const
Returns the number of the points in the integration rule.
int Size() const
Return the logical size of the array.
Class for grid function - Vector with associated FE space.
virtual void Update(bool want_transform=true)
Reflect changes in the mesh: update number of DOFs, etc. Also, calculate GridFunction transformation ...
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void ComputeEstimates()
Compute the element error estimates.
virtual void ComputeElementLpErrors(const double p, Coefficient &exsol, Vector &error, Coefficient *weight=NULL, const IntegrationRule *irs[]=NULL) const
virtual void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const
ParFiniteElementSpace * flux_space
Ownership based on the flag own_flux_fes. Its Update() method is called automatically by this class w...
void SetSize(int s)
Resize the vector to size s.
VectorCoefficient * vcoef
double Norml2() const
Returns the l2 norm of the vector.
virtual void Update(bool want_transform=true)
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
int GetNE() const
Returns number of elements.
Abstract parallel finite element space.
void CalcOrtho(const DenseMatrix &J, Vector &n)
virtual FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
const IntegrationRule * GetVertices(int GeomType)
Return an IntegrationRule consisting of all vertices of the given Geometry::Type, GeomType...
void ComputeEstimates()
Compute the element error estimates.
ParGridFunction * solution
Not owned.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
double f(const Vector &xvec)
Mesh * GetMesh() const
Returns the mesh.
void ResetCoefficientFunctions()
Change the coefficients back to default as described above.
GridFunction * solution
Not owned.
int local_norm_p
Local L_p norm to use, default is 1.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
int GetVDim() const
Returns vector dimension.
FiniteElementSpace * FESpace()
KellyErrorEstimator(BilinearFormIntegrator &di_, GridFunction &sol_, FiniteElementSpace &flux_fes_, const Array< int > &attributes_=Array< int >())
Construct a new KellyErrorEstimator object for a scalar field.
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
FDualNumber< tbase > pow(const FDualNumber< tbase > &a, const FDualNumber< tbase > &b)
pow([dual number],[dual number])
int SpaceDimension() const
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
double L2ZZErrorEstimator(BilinearFormIntegrator &flux_integrator, const ParGridFunction &x, ParFiniteElementSpace &smooth_flux_fes, ParFiniteElementSpace &flux_fes, Vector &errors, int norm_p, double solver_tol, int solver_max_it)
ParFiniteElementSpace * smooth_flux_space
Ownership based on the flag own_flux_fes. Its Update() method is called automatically by this class w...
double ZZErrorEstimator(BilinearFormIntegrator &blfi, GridFunction &u, GridFunction &flux, Vector &error_estimates, Array< int > *aniso_flags, int with_subdomains, bool with_coeff)
FiniteElementSpace * flux_space
Ownership based on own_flux_fes. Its Update() method is called automatically by this class when neede...
FDualNumber< tbase > sqrt(const FDualNumber< tbase > &f)
sqrt([dual number])
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
BilinearFormIntegrator * integ
Not owned.
void ComputeEstimates()
Compute the element error estimates.
Class for parallel grid function.
BilinearFormIntegrator * integ
Not owned.
Class for parallel meshes.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
double Sum() const
Return the sum of the vector entries.