12 #include "../config/config.hpp"
19 #include "../general/forall.hpp"
38 const int *partitioning)
54 int element_counter = 0;
56 const int glob_ne = glob_fes->
GetNE();
57 for (
int i = 0; i < glob_ne; i++)
59 if (partitioning[i] == MyRank)
92 MFEM_ASSERT(
pfes != NULL,
"not a ParFiniteElementSpace");
107 MFEM_ASSERT(
pfes != NULL,
"not a ParFiniteElementSpace");
122 MFEM_ASSERT(
pfes != NULL,
"not a ParFiniteElementSpace");
135 prolong->
Mult(*tv, *
this);
226 MPI_Request *requests =
new MPI_Request[2*num_face_nbrs];
227 MPI_Request *send_requests = requests;
228 MPI_Request *recv_requests = requests + num_face_nbrs;
229 MPI_Status *statuses =
new MPI_Status[num_face_nbrs];
231 auto d_data = this->
Read();
235 const int ldof = d_send_ldof[i];
236 d_send_data[i] = d_data[ldof >= 0 ? ldof : -1-ldof];
243 for (
int fn = 0; fn < num_face_nbrs; fn++)
248 MPI_Isend(&send_data_ptr[send_offset[fn]],
249 send_offset[fn+1] - send_offset[fn],
250 MPI_DOUBLE, nbr_rank, tag, MyComm, &send_requests[fn]);
252 MPI_Irecv(&face_nbr_data_ptr[recv_offset[fn]],
253 recv_offset[fn+1] - recv_offset[fn],
254 MPI_DOUBLE, nbr_rank, tag, MyComm, &recv_requests[fn]);
257 MPI_Waitall(num_face_nbrs, send_requests, statuses);
258 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
277 int s = dofs.
Size()/fes_vdim;
318 return (DofVal * LocVec);
332 int dof = FElem->
GetDof();
349 for (
int k = 0; k < vdim; k++)
351 val(k) = shape * ((
const double *)loc_data + dof * k);
374 int comp,
Vector *tr)
const
412 return (DofVal * LocVec);
459 for (
int k = 0; k < vdim; k++)
461 val(k) = shape * ((
const double *)loc_data + dof * k);
484 double loc_integral, glob_integral;
488 MPI_Allreduce(&loc_integral, &glob_integral, 1, MPI_DOUBLE, MPI_SUM,
491 (*this) *= (delta_c->
Scale() / glob_integral);
505 ldof_attr.
Copy(gdof_attr);
508 gcomm.
Bcast(gdof_attr);
514 if (gdof_attr[i] > ldof_attr[i])
528 gcomm.
Bcast(gdof_attr);
531 (*this)(i) /= gdof_attr[i];
551 gcomm.
Bcast(zones_per_vdof);
573 gcomm.
Bcast(zones_per_vdof);
589 for (
int i = 0; i < values.
Size(); i++)
591 values(i) = values_counter[i] ? (*this)(i) : 0.0;
600 for (
int i = 0; i < values.Size(); i++)
602 if (values_counter[i])
604 (*this)(i) = values(i)/values_counter[i];
611 for (
int i = 0; i < values_counter.Size(); i++)
614 bool(values_counter[i]) == bool(ess_vdofs_marker[i]),
627 for (
int i = 0; i < values.
Size(); i++)
629 values(i) = values_counter[i] ? (*this)(i) : 0.0;
638 for (
int i = 0; i < values.Size(); i++)
640 if (values_counter[i])
642 (*this)(i) = values(i)/values_counter[i];
649 for (
int i = 0; i < values_counter.Size(); i++)
652 bool(values_counter[i]) == bool(ess_vdofs_marker[i]),
665 int fdof,
dim, intorder, k;
667 Vector shape, el_dofs, err_val, ell_coeff_val;
675 std::map<int,int> local_to_shared;
679 local_to_shared[i_local] = i;
684 double shared_face_factor = 1.0;
685 bool shared_face =
false;
686 int iel1, iel2, info1, info2;
694 if (info2 >= 0 && iel2 < 0)
696 int ishared = local_to_shared[i];
700 if ( (k = fe2->
GetOrder()) > intorder )
705 shared_face_factor = 0.5;
714 if ( (k = fe2->
GetOrder()) > intorder )
725 intorder = 2 * intorder;
738 transf = face_elem_transf->
Elem1;
744 for (k = 0; k < fdof; k++)
747 el_dofs(k) = (*this)(vdofs[k]);
751 el_dofs(k) = - (*this)(-1-vdofs[k]);
758 ell_coeff_val(j) = ell_coeff->
Eval(*transf, eip);
759 err_val(j) = exsol->
Eval(*transf, eip) - (shape * el_dofs);
764 transf = face_elem_transf->
Elem2;
771 for (k = 0; k < fdof; k++)
784 for (k = 0; k < fdof; k++)
787 el_dofs(k) = (*this)(vdofs[k]);
791 el_dofs(k) = - (*this)(-1 - vdofs[k]);
799 ell_coeff_val(j) += ell_coeff->
Eval(*transf, eip);
800 ell_coeff_val(j) *= 0.5;
801 err_val(j) -= (exsol->
Eval(*transf, eip) - (shape * el_dofs));
804 transf = face_elem_transf;
809 error += shared_face_factor*(ip.
weight * Nu * ell_coeff_val(j) *
810 pow(transf->
Weight(), 1.0-1.0/(dim-1)) *
811 err_val(j) * err_val(j));
815 error = (error < 0.0) ? -sqrt(-error) : sqrt(error);
821 double *data_ =
const_cast<double*
>(
HostRead());
822 for (
int i = 0; i <
size; i++)
829 for (
int i = 0; i <
size; i++)
835 #ifdef MFEM_USE_ADIOS2
837 const std::string& variable_name,
840 double *data_ =
const_cast<double*
>(
HostRead());
841 for (
int i = 0; i <
size; i++)
848 for (
int i = 0; i <
size; i++)
863 MyComm =
pfes -> GetComm();
865 MPI_Comm_size(MyComm, &NRanks);
866 MPI_Comm_rank(MyComm, &MyRank);
868 double **values =
new double*[NRanks];
869 int *nv =
new int[NRanks];
870 int *nvdofs =
new int[NRanks];
871 int *nedofs =
new int[NRanks];
872 int *nfdofs =
new int[NRanks];
873 int *nrdofs =
new int[NRanks];
875 double * h_data =
const_cast<double *
>(this->
HostRead());
878 nv[0] =
pfes -> GetVSize();
879 nvdofs[0] =
pfes -> GetNVDofs();
880 nedofs[0] =
pfes -> GetNEDofs();
881 nfdofs[0] =
pfes -> GetNFDofs();
888 for (p = 1; p < NRanks; p++)
890 MPI_Recv(&nv[p], 1, MPI_INT, p, 455, MyComm, &status);
891 MPI_Recv(&nvdofs[p], 1, MPI_INT, p, 456, MyComm, &status);
892 MPI_Recv(&nedofs[p], 1, MPI_INT, p, 457, MyComm, &status);
893 MPI_Recv(&nfdofs[p], 1, MPI_INT, p, 458, MyComm, &status);
894 values[
p] =
new double[nv[
p]];
895 MPI_Recv(values[p], nv[p], MPI_DOUBLE, p, 460, MyComm, &status);
898 int vdim =
pfes -> GetVDim();
900 for (p = 0; p < NRanks; p++)
902 nrdofs[
p] = nv[
p]/vdim - nvdofs[
p] - nedofs[
p] - nfdofs[
p];
907 for (
int d = 0; d < vdim; d++)
909 for (p = 0; p < NRanks; p++)
910 for (i = 0; i < nvdofs[
p]; i++)
912 out << *values[
p]++ <<
'\n';
915 for (p = 0; p < NRanks; p++)
916 for (i = 0; i < nedofs[
p]; i++)
918 out << *values[
p]++ <<
'\n';
921 for (p = 0; p < NRanks; p++)
922 for (i = 0; i < nfdofs[
p]; i++)
924 out << *values[
p]++ <<
'\n';
927 for (p = 0; p < NRanks; p++)
928 for (i = 0; i < nrdofs[
p]; i++)
930 out << *values[
p]++ <<
'\n';
936 for (p = 0; p < NRanks; p++)
937 for (i = 0; i < nvdofs[
p]; i++)
938 for (
int d = 0; d < vdim; d++)
940 out << *values[
p]++ <<
'\n';
943 for (p = 0; p < NRanks; p++)
944 for (i = 0; i < nedofs[
p]; i++)
945 for (
int d = 0; d < vdim; d++)
947 out << *values[
p]++ <<
'\n';
950 for (p = 0; p < NRanks; p++)
951 for (i = 0; i < nfdofs[
p]; i++)
952 for (
int d = 0; d < vdim; d++)
954 out << *values[
p]++ <<
'\n';
957 for (p = 0; p < NRanks; p++)
958 for (i = 0; i < nrdofs[
p]; i++)
959 for (
int d = 0; d < vdim; d++)
961 out << *values[
p]++ <<
'\n';
965 for (p = 1; p < NRanks; p++)
974 MPI_Send(&nv[0], 1, MPI_INT, 0, 455, MyComm);
975 MPI_Send(&nvdofs[0], 1, MPI_INT, 0, 456, MyComm);
976 MPI_Send(&nedofs[0], 1, MPI_INT, 0, 457, MyComm);
977 MPI_Send(&nfdofs[0], 1, MPI_INT, 0, 458, MyComm);
978 MPI_Send(h_data, nv[0], MPI_DOUBLE, 0, 460, MyComm);
998 loc_norm = -pow(-loc_norm, p);
1002 loc_norm = pow(loc_norm, p);
1005 MPI_Allreduce(&loc_norm, &glob_norm, 1, MPI_DOUBLE, MPI_SUM, comm);
1007 if (glob_norm < 0.0)
1009 glob_norm = -pow(-glob_norm, 1.0/p);
1013 glob_norm = pow(glob_norm, 1.0/p);
1018 MPI_Allreduce(&loc_norm, &glob_norm, 1, MPI_DOUBLE, MPI_MAX, comm);
1030 MFEM_VERIFY(ffes,
"the flux FE space must be ParFiniteElementSpace");
1043 for (
int i = 0; i < count.Size(); i++)
1045 if (count[i] != 0) { flux(i) /= count[i]; }
1066 int norm_p,
double solver_tol,
int solver_max_it)
1076 for (
int i = 0; i < xfes->
GetNE(); i++)
1083 *flux_fes.
GetFE(i), el_f,
false);
1096 MFEM_VERIFY(smooth_flux_fes.
GetFE(0) != NULL,
1097 "Could not obtain FE of smooth flux space.");
1152 double total_error = 0.0;
1154 for (
int i = 0; i < xfes->
GetNE(); i++)
1157 total_error += pow(errors(i), norm_p);
1161 MPI_Allreduce(&total_error, &glob_error, 1, MPI_DOUBLE, MPI_SUM,
1164 return pow(glob_error, 1.0/norm_p);
1169 #endif // MFEM_USE_MPI
int GetNPoints() const
Returns the number of the points in the integration rule.
Abstract class for all finite elements.
int GetNFaceNeighbors() const
Ordering::Type GetOrdering() const
Return the ordering method.
int Size() const
Return the logical size of the array.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
void Reduce(T *ldata, void(*Op)(OpData< T >)) const
Reduce within each group where the master is the root.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Class for an integration rule - an Array of IntegrationPoint.
HypreParVector * NewTrueDofVector()
Class for grid function - Vector with associated FE space.
void Bcast(T *ldata, int layout) const
Broadcast within each group where the master is the root.
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
void ExchangeFaceNbrData()
void SumFluxAndCount(BilinearFormIntegrator &blfi, GridFunction &flux, Array< int > &counts, bool wcoef, int subdomain)
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
ParMesh * GetParMesh() const
HypreParVector * ParallelAssemble() const
Returns a new vector assembled on the true dofs.
Base class for vector Coefficients that optionally depend on time and space.
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_dofs, int component=-1) const
Determine the boundary degrees of freedom.
void ProjectDeltaCoefficient(DeltaCoefficient &delta_coeff, double &integral)
HypreParVector * ParallelProject() const
Returns a new vector restricted to the true dofs.
virtual void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
void SetSize(int s)
Resize the vector to size s.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
double Scale()
Return the scale factor times the optional time dependent function. Returns with when not set by th...
void ProjectDiscCoefficient(VectorCoefficient &coeff, Array< int > &dof_attr)
int GetNSharedFaces() const
Return the number of shared faces (3D), edges (2D), vertices (1D)
ParFiniteElementSpace * pfes
Points to the same object as fes.
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
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...
void SaveAsOne(std::ostream &out=mfem::out)
Merge the local grid functions.
Data type dense matrix using column-major storage.
Delta function coefficient optionally multiplied by a weight coefficient and a scaled time dependent ...
int Size() const
Returns the size of the vector.
int GetNE() const
Returns number of elements.
virtual double GetValue(int i, const IntegrationPoint &ip, int vdim=1) const
virtual void Save(std::ostream &out) const
void DivideByGroupSize(double *vec)
Scale a vector of true dofs.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void ProjectDiscCoefficient(VectorCoefficient &coeff)
Project a discontinuous vector coefficient as a grid function on a continuous finite element space...
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the ParGridFunction.
void AccumulateAndCountBdrTangentValues(VectorCoefficient &vcoeff, Array< int > &bdr_attr, Array< int > &values_counter)
Abstract parallel finite element space.
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
virtual void ProjectCoefficient(Coefficient &coeff)
Vector send_data
Vector used as an MPI buffer to send face-neighbor data in ExchangeFaceNbrData() to neighboring proce...
double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
int GetLocalTDofNumber(int ldof) const
void ComputeMeans(AvgType type, Array< int > &zones_per_vdof)
double * GetData() const
Return a pointer to the beginning of the Vector data.
virtual double ComputeDGFaceJumpError(Coefficient *exsol, Coefficient *ell_coeff, double Nu, const IntegrationRule *irs[]=NULL) const
Returns the Face Jumps error for L2 elements.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
int Size_of_connections() const
void SetPrintLevel(int print_lvl)
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 ...
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void GetFaceNbrElementVDofs(int i, Array< int > &vdofs) const
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the ParGridFunction reference external data on a new FiniteElementSpace.
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
int GetNE() const
Returns number of elements in the mesh.
const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
The BoomerAMG solver in hypre.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Communicator performing operations within groups defined by a GroupTopology with arbitrary-size data ...
const FiniteElement * GetFaceNbrFE(int i) const
void ExchangeFaceNbrData()
static void Sum(OpData< T >)
Reduce operation Sum, instantiated for int and double.
ElementTransformation * GetFaceNbrElementTransformation(int i) const
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Mesh * GetMesh() const
Returns the mesh.
int GetSharedFace(int sface) const
Return the local face index for the given shared face.
Memory< int > & GetJMemory()
void SetPrintLevel(int print_level)
FaceElementTransformations * GetSharedFaceTransformations(int sf, bool fill2=true)
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
virtual void GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void AccumulateAndCountZones(Coefficient &coeff, AvgType type, Array< int > &zones_per_vdof)
Accumulates (depending on type) the values of coeff at all shared vdofs and counts in how many zones ...
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the GridFunction reference external data on a new FiniteElementSpace.
int GetVDim() const
Returns vector dimension.
FiniteElementSpace * FESpace()
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true...
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...
void SetMaxIter(int max_iter)
virtual void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const
int SpaceDimension() const
Wrapper for hypre's parallel vector class.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
double GlobalLpNorm(const double p, double loc_norm, MPI_Comm comm)
Compute a global Lp norm from the local Lp norms computed by each processor.
void GetFaceElements(int Face, int *Elem1, int *Elem2) const
double p(const Vector &x, double t)
void GetFaceInfos(int Face, int *Inf1, int *Inf2) const
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, Array< int > &attr)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
FiniteElementSpace * fes
FE space on which the grid function lives. Owned if fec is not NULL.
virtual void ComputeFlux(BilinearFormIntegrator &blfi, GridFunction &flux, bool wcoef=true, int subdomain=-1)
static void Max(OpData< T >)
Reduce operation Max, instantiated for int and double.
void CalcPhysShape(ElementTransformation &Trans, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in physical space at the point ...
GroupCommunicator & GroupComm()
Return a reference to the internal GroupCommunicator (on VDofs)
static bool GetGPUAwareMPI()
FiniteElementCollection * fec
Used when the grid function is read from a file. It can also be set explicitly, see MakeOwner()...
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)
void Distribute(const Vector *tv)
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
double ComputeElementLpDistance(double p, int i, GridFunction &gf1, GridFunction &gf2)
Compute the Lp distance between two grid functions on the given element.
bool Nonconforming() const
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name...
void GetFaceNbrElementTransformation(int i, IsoparametricTransformation *ElTr)
Vector face_nbr_data
Vector used to store data from face-neighbor processors, initialized by ExchangeFaceNbrData().
virtual const char * Name() const
Class for integration point with weight.
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual const SparseMatrix * GetRestrictionMatrix() const
Get the R matrix which restricts a local dof vector to true dof vector.
virtual void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff, Array< int > &bdr_attr)
Project the tangential components of the given VectorCoefficient on the boundary. Only boundary attri...
HypreParVector * ParallelAverage() const
Returns a new vector averaged on the true dofs.
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
void Destroy()
Destroy a vector.
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
void AddDistribute(double a, const Vector *tv)
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
virtual void ProjectCoefficient(Coefficient &coeff)
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the GridFunction.
int GetFaceNbrVSize() const
double * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
for VectorFiniteElements (Nedelec, Raviart-Thomas)
const FiniteElementCollection * FEColl() const
Vector coefficient defined by a vector GridFunction.
Class for parallel grid function.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Wrapper for hypre's ParCSR matrix class.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
int GetRangeType() const
Returns the FiniteElement::RangeType of the element, one of {SCALAR, VECTOR}.
Class for parallel meshes.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
int GetFaceNbrRank(int fn) const
void AccumulateAndCountBdrValues(Coefficient *coeff[], VectorCoefficient *vcoeff, Array< int > &attr, Array< int > &values_counter)
virtual double GetValue(int i, const IntegrationPoint &ip, int vdim=1) const
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.
double f(const Vector &p)
ParFiniteElementSpace * ParFESpace() const
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const