int InverseElementTransformation::FindClosestPhysPoint( const Vector& pt, const IntegrationRule &ir) { MFEM_VERIFY(T != NULL, "invalid ElementTransformation"); MFEM_VERIFY(pt.Size() == T->GetSpaceDim(), "invalid point"); DenseMatrix physPts; T->Transform(ir, physPts); // Initialize distance and index of closest point int minIndex = -1; double minDist = std::numeric_limits<double>::max(); // Check all integration points in ir const int npts = ir.GetNPoints(); for (int i = 0; i < npts; ++i) { double dist = pt.DistanceTo(physPts.GetColumn(i)); if (dist < minDist) { minDist = dist; minIndex = i; } } return minIndex; }
int InverseElementTransformation::FindClosestRefPoint( const Vector& pt, const IntegrationRule &ir) { MFEM_VERIFY(T != NULL, "invalid ElementTransformation"); MFEM_VERIFY(pt.Size() == T->GetSpaceDim(), "invalid point"); // Initialize distance and index of closest point int minIndex = -1; double minDist = std::numeric_limits<double>::max(); // Check all integration points in ir using the local metric at each point // induced by the transformation. Vector dp(T->GetSpaceDim()), dr(T->GetDimension()); const int npts = ir.GetNPoints(); for (int i = 0; i < npts; ++i) { const IntegrationPoint &ip = ir.IntPoint(i); T->Transform(ip, dp); dp -= pt; T->SetIntPoint(&ip); T->InverseJacobian().Mult(dp, dr); double dist = dr.Norml2(); // double dist = dr.Normlinf(); if (dist < minDist) { minDist = dist; minIndex = i; } } return minIndex; }
void Device::Setup(const int device) { MFEM_VERIFY(ngpu == -1, "the mfem::Device is already configured!"); ngpu = 0; dev = device; #ifndef MFEM_USE_CUDA MFEM_VERIFY(!Allows(Backend::CUDA_MASK), "the CUDA backends require MFEM built with MFEM_USE_CUDA=YES"); #endif #ifndef MFEM_USE_RAJA MFEM_VERIFY(!Allows(Backend::RAJA_MASK), "the RAJA backends require MFEM built with MFEM_USE_RAJA=YES"); #endif #ifndef MFEM_USE_OPENMP MFEM_VERIFY(!Allows(Backend::OMP|Backend::RAJA_OMP), "the OpenMP and RAJA OpenMP backends require MFEM built with" " MFEM_USE_OPENMP=YES"); #endif if (Allows(Backend::CUDA)) { CudaDeviceSetup(dev, ngpu); } if (Allows(Backend::RAJA_CUDA)) { RajaDeviceSetup(dev, ngpu); } // The check for MFEM_USE_OCCA is in the function OccaDeviceSetup(). if (Allows(Backend::OCCA_MASK)) { OccaDeviceSetup(dev); } }
ParNonlinearForm::ParNonlinearForm(ParFiniteElementSpace *pf) : NonlinearForm(pf), pGrad(Operator::Hypre_ParCSR) { X.MakeRef(pf, NULL); Y.MakeRef(pf, NULL); MFEM_VERIFY(!Serial(), "internal MFEM error"); }
void Device::Configure(const std::string &device, const int dev) { std::map<std::string, Backend::Id> bmap; for (int i = 0; i < Backend::NUM_BACKENDS; i++) { bmap[internal::backend_name[i]] = internal::backend_list[i]; } std::string::size_type beg = 0, end; while (1) { end = device.find(',', beg); end = (end != std::string::npos) ? end : device.size(); const std::string bname = device.substr(beg, end - beg); std::map<std::string, Backend::Id>::iterator it = bmap.find(bname); MFEM_VERIFY(it != bmap.end(), "invalid backend name: '" << bname << '\''); Get().MarkBackend(it->second); if (end == device.size()) { break; } beg = end + 1; } // OCCA_CUDA needs CUDA or RAJA_CUDA: Get().allowed_backends = Get().backends; if (Allows(Backend::OCCA_CUDA) && !Allows(Backend::RAJA_CUDA)) { Get().MarkBackend(Backend::CUDA); } // Activate all backends for Setup(). Get().allowed_backends = Get().backends; Get().Setup(dev); // Enable only the default host CPU backend. Get().allowed_backends = Backend::CPU; }
void ParGridFunction::ComputeFlux( BilinearFormIntegrator &blfi, GridFunction &flux, int wcoef, int subdomain) { ParFiniteElementSpace *ffes = dynamic_cast<ParFiniteElementSpace*>(flux.FESpace()); MFEM_VERIFY(ffes, "the flux FE space must be ParFiniteElementSpace"); Array<int> count(flux.Size()); SumFluxAndCount(blfi, flux, count, wcoef, subdomain); // Accumulate flux and counts in parallel ffes->GroupComm().Reduce<double>(flux, GroupCommunicator::Sum); ffes->GroupComm().Bcast<double>(flux); ffes->GroupComm().Reduce<int>(count, GroupCommunicator::Sum); ffes->GroupComm().Bcast<int>(count); // complete averaging for (int i = 0; i < count.Size(); i++) { if (count[i] != 0) { flux(i) /= count[i]; } } if (ffes->Nonconforming()) { // On a partially conforming flux space, project on the conforming space. // Using this code may lead to worse refinements in ex6, so we do not use // it by default. // Vector conf_flux; // flux.ConformingProject(conf_flux); // flux.ConformingProlongate(conf_flux); } }
int InverseElementTransformation::Transform(const Vector &pt, IntegrationPoint &ip) { MFEM_VERIFY(T != NULL, "invalid ElementTransformation"); // Select initial guess ... switch (init_guess_type) { case Center: ip0 = &Geometries.GetCenter(T->GetGeometryType()); break; case ClosestPhysNode: case ClosestRefNode: { const int order = std::max(T->Order()+rel_qpts_order, 0); if (order == 0) { ip0 = &Geometries.GetCenter(T->GetGeometryType()); } else { const int old_type = GlobGeometryRefiner.GetType(); GlobGeometryRefiner.SetType(qpts_type); RefinedGeometry &RefG = *GlobGeometryRefiner.Refine(T->GetGeometryType(), order); int closest_idx = (init_guess_type == ClosestPhysNode) ? FindClosestPhysPoint(pt, RefG.RefPts) : FindClosestRefPoint(pt, RefG.RefPts); ip0 = &RefG.RefPts.IntPoint(closest_idx); GlobGeometryRefiner.SetType(old_type); } break; } case GivenPoint: break; default: MFEM_ABORT("invalid initial guess type"); } // Call the solver ... return NewtonSolve(pt, ip); }
static void DeviceSetup(const int dev, int &ngpu) { MFEM_CUDA_CHECK(cudaGetDeviceCount(&ngpu)); MFEM_VERIFY(ngpu > 0, "No CUDA device found!"); MFEM_CUDA_CHECK(cudaSetDevice(dev)); }
void ParGridFunction::ParallelAverage(HypreParVector &tv) const { MFEM_VERIFY(pfes->Conforming(), "not implemented for NC meshes"); pfes->GetProlongationMatrix()->MultTranspose(*this, tv); pfes->DivideByGroupSize(tv); }
//! Return a reference to block i,j Operator & GetBlock(int i, int j) { MFEM_VERIFY(op(i,j), ""); return *op(i,j); }
//! Return a reference to block i,i. Operator & GetDiagonalBlock(int iblock) { MFEM_VERIFY(op[iblock], ""); return *op[iblock]; }