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();
232 auto d_send_data = send_data.Write();
233 MFEM_FORALL(i, send_data.Size(),
235 d_send_data[i] = d_data[d_send_ldof[i]];
239 auto send_data_ptr = mpi_gpu_aware ? send_data.Read() : send_data.HostRead();
242 for (
int fn = 0; fn < num_face_nbrs; fn++)
247 MPI_Isend(&send_data_ptr[send_offset[fn]],
248 send_offset[fn+1] - send_offset[fn],
249 MPI_DOUBLE, nbr_rank, tag, MyComm, &send_requests[fn]);
251 MPI_Irecv(&face_nbr_data_ptr[recv_offset[fn]],
252 recv_offset[fn+1] - recv_offset[fn],
253 MPI_DOUBLE, nbr_rank, tag, MyComm, &recv_requests[fn]);
256 MPI_Waitall(num_face_nbrs, send_requests, statuses);
257 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
275 int s = dofs.
Size()/fes_vdim;
298 return (DofVal * LocVec);
311 double loc_integral, glob_integral;
315 MPI_Allreduce(&loc_integral, &glob_integral, 1, MPI_DOUBLE, MPI_SUM,
318 (*this) *= (delta_c->
Scale() / glob_integral);
332 ldof_attr.
Copy(gdof_attr);
335 gcomm.
Bcast(gdof_attr);
341 if (gdof_attr[i] > ldof_attr[i])
355 gcomm.
Bcast(gdof_attr);
358 (*this)(i) /= gdof_attr[i];
378 gcomm.
Bcast(zones_per_vdof);
400 gcomm.
Bcast(zones_per_vdof);
416 for (
int i = 0; i < values.
Size(); i++)
418 values(i) = values_counter[i] ? (*this)(i) : 0.0;
427 for (
int i = 0; i < values.Size(); i++)
429 if (values_counter[i])
431 (*this)(i) = values(i)/values_counter[i];
438 for (
int i = 0; i < values_counter.Size(); i++)
441 bool(values_counter[i]) == bool(ess_vdofs_marker[i]),
454 for (
int i = 0; i < values.
Size(); i++)
456 values(i) = values_counter[i] ? (*this)(i) : 0.0;
465 for (
int i = 0; i < values.Size(); i++)
467 if (values_counter[i])
469 (*this)(i) = values(i)/values_counter[i];
476 for (
int i = 0; i < values_counter.Size(); i++)
479 bool(values_counter[i]) == bool(ess_vdofs_marker[i]),
487 double *data_ =
const_cast<double*
>(
HostRead());
488 for (
int i = 0; i <
size; i++)
495 for (
int i = 0; i <
size; i++)
509 MyComm =
pfes -> GetComm();
511 MPI_Comm_size(MyComm, &NRanks);
512 MPI_Comm_rank(MyComm, &MyRank);
514 double **values =
new double*[NRanks];
515 int *nv =
new int[NRanks];
516 int *nvdofs =
new int[NRanks];
517 int *nedofs =
new int[NRanks];
518 int *nfdofs =
new int[NRanks];
519 int *nrdofs =
new int[NRanks];
522 nv[0] =
pfes -> GetVSize();
523 nvdofs[0] =
pfes -> GetNVDofs();
524 nedofs[0] =
pfes -> GetNEDofs();
525 nfdofs[0] =
pfes -> GetNFDofs();
532 for (p = 1; p < NRanks; p++)
534 MPI_Recv(&nv[p], 1, MPI_INT, p, 455, MyComm, &status);
535 MPI_Recv(&nvdofs[p], 1, MPI_INT, p, 456, MyComm, &status);
536 MPI_Recv(&nedofs[p], 1, MPI_INT, p, 457, MyComm, &status);
537 MPI_Recv(&nfdofs[p], 1, MPI_INT, p, 458, MyComm, &status);
538 values[p] =
new double[nv[p]];
539 MPI_Recv(values[p], nv[p], MPI_DOUBLE, p, 460, MyComm, &status);
542 int vdim =
pfes -> GetVDim();
544 for (p = 0; p < NRanks; p++)
546 nrdofs[p] = nv[p]/vdim - nvdofs[p] - nedofs[p] - nfdofs[p];
551 for (
int d = 0; d < vdim; d++)
553 for (p = 0; p < NRanks; p++)
554 for (i = 0; i < nvdofs[p]; i++)
556 out << *values[p]++ <<
'\n';
559 for (p = 0; p < NRanks; p++)
560 for (i = 0; i < nedofs[p]; i++)
562 out << *values[p]++ <<
'\n';
565 for (p = 0; p < NRanks; p++)
566 for (i = 0; i < nfdofs[p]; i++)
568 out << *values[p]++ <<
'\n';
571 for (p = 0; p < NRanks; p++)
572 for (i = 0; i < nrdofs[p]; i++)
574 out << *values[p]++ <<
'\n';
580 for (p = 0; p < NRanks; p++)
581 for (i = 0; i < nvdofs[p]; i++)
582 for (
int d = 0; d < vdim; d++)
584 out << *values[p]++ <<
'\n';
587 for (p = 0; p < NRanks; p++)
588 for (i = 0; i < nedofs[p]; i++)
589 for (
int d = 0; d < vdim; d++)
591 out << *values[p]++ <<
'\n';
594 for (p = 0; p < NRanks; p++)
595 for (i = 0; i < nfdofs[p]; i++)
596 for (
int d = 0; d < vdim; d++)
598 out << *values[p]++ <<
'\n';
601 for (p = 0; p < NRanks; p++)
602 for (i = 0; i < nrdofs[p]; i++)
603 for (
int d = 0; d < vdim; d++)
605 out << *values[p]++ <<
'\n';
609 for (p = 1; p < NRanks; p++)
618 MPI_Send(&nv[0], 1, MPI_INT, 0, 455, MyComm);
619 MPI_Send(&nvdofs[0], 1, MPI_INT, 0, 456, MyComm);
620 MPI_Send(&nedofs[0], 1, MPI_INT, 0, 457, MyComm);
621 MPI_Send(&nfdofs[0], 1, MPI_INT, 0, 458, MyComm);
622 MPI_Send(
data, nv[0], MPI_DOUBLE, 0, 460, MyComm);
642 loc_norm = -pow(-loc_norm, p);
646 loc_norm = pow(loc_norm, p);
649 MPI_Allreduce(&loc_norm, &glob_norm, 1, MPI_DOUBLE, MPI_SUM, comm);
653 glob_norm = -pow(-glob_norm, 1.0/p);
657 glob_norm = pow(glob_norm, 1.0/p);
662 MPI_Allreduce(&loc_norm, &glob_norm, 1, MPI_DOUBLE, MPI_MAX, comm);
675 MFEM_VERIFY(ffes,
"the flux FE space must be ParFiniteElementSpace");
688 for (
int i = 0; i < count.Size(); i++)
690 if (count[i] != 0) { flux(i) /= count[i]; }
711 int norm_p,
double solver_tol,
int solver_max_it)
721 for (
int i = 0; i < xfes->
GetNE(); i++)
728 *flux_fes.
GetFE(i), el_f,
false);
794 double total_error = 0.0;
796 for (
int i = 0; i < xfes->
GetNE(); i++)
799 total_error += pow(errors(i), norm_p);
803 MPI_Allreduce(&total_error, &glob_error, 1, MPI_DOUBLE, MPI_SUM,
806 return pow(glob_error, 1.0/norm_p);
811 #endif // MFEM_USE_MPI
Abstract class for Finite Elements.
int GetNFaceNeighbors() const
Ordering::Type GetOrdering() const
Return the ordering method.
int Size() const
Logical size of the array.
For scalar fields; preserves point values.
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().
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.
void ExchangeFaceNbrData()
void SumFluxAndCount(BilinearFormIntegrator &blfi, GridFunction &flux, Array< int > &counts, bool wcoef, int subdomain)
HypreParVector * ParallelAssemble() const
Returns a new vector assembled on the true dofs.
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 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 set by SetScale() multiplied by the time-dependent function specified by SetFunction...
void ProjectDiscCoefficient(VectorCoefficient &coeff, Array< int > &dof_attr)
ParFiniteElementSpace * pfes
Points to the same object as fes.
void Copy(Array ©) const
Create a copy of the current array.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
void SaveAsOne(std::ostream &out=mfem::out)
Merge the local grid functions.
Delta function coefficient.
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.
virtual void ProjectCoefficient(Coefficient &coeff)
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.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
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 ...
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.
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.
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Memory< int > & GetJMemory()
void SetPrintLevel(int print_level)
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 (element) subvector to the vector.
void SetMaxIter(int max_iter)
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 ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, Array< int > &attr)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Base class Coefficient that may optionally depend on time.
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.
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...
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 associated with i'th element.
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).
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.
Class for parallel meshes.
int GetFaceNbrRank(int fn) const
void AccumulateAndCountBdrValues(Coefficient *coeff[], VectorCoefficient *vcoeff, Array< int > &attr, Array< int > &values_counter)
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.
ParFiniteElementSpace * ParFESpace() const
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const