コード例 #1
0
ファイル: eltrans.cpp プロジェクト: LLNL/mfem
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;
}
コード例 #2
0
ファイル: eltrans.cpp プロジェクト: LLNL/mfem
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;
}
コード例 #3
0
ファイル: device.cpp プロジェクト: LLNL/mfem
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); }
}
コード例 #4
0
ファイル: pnonlinearform.cpp プロジェクト: LLNL/mfem
ParNonlinearForm::ParNonlinearForm(ParFiniteElementSpace *pf)
   : NonlinearForm(pf), pGrad(Operator::Hypre_ParCSR)
{
   X.MakeRef(pf, NULL);
   Y.MakeRef(pf, NULL);
   MFEM_VERIFY(!Serial(), "internal MFEM error");
}
コード例 #5
0
ファイル: device.cpp プロジェクト: LLNL/mfem
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;
}
コード例 #6
0
ファイル: pgridfunc.cpp プロジェクト: LLNL/mfem
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);
   }
}
コード例 #7
0
ファイル: eltrans.cpp プロジェクト: LLNL/mfem
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);
}
コード例 #8
0
ファイル: device.cpp プロジェクト: LLNL/mfem
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));
}
コード例 #9
0
ファイル: pgridfunc.cpp プロジェクト: LLNL/mfem
void ParGridFunction::ParallelAverage(HypreParVector &tv) const
{
   MFEM_VERIFY(pfes->Conforming(), "not implemented for NC meshes");
   pfes->GetProlongationMatrix()->MultTranspose(*this, tv);
   pfes->DivideByGroupSize(tv);
}
コード例 #10
0
ファイル: blockoperator.hpp プロジェクト: ShiyangZhang/mfem
 //! Return a reference to block i,j
 Operator & GetBlock(int i, int j)
 { MFEM_VERIFY(op(i,j), ""); return *op(i,j); }
コード例 #11
0
ファイル: blockoperator.hpp プロジェクト: ShiyangZhang/mfem
 //! Return a reference to block i,i.
 Operator & GetDiagonalBlock(int iblock)
 { MFEM_VERIFY(op[iblock], ""); return *op[iblock]; }