예제 #1
0
파일: geom.cpp 프로젝트: Kyushick/sight
void Geometry::GetPerfPointMat (int GeomType, DenseMatrix &pm)
{
   switch (GeomType)
   {
   case Geometry::SEGMENT:
   {
      pm.SetSize (1, 2);
      pm(0,0) = 0.0;
      pm(0,1) = 1.0;
   }
   break;

   case Geometry::TRIANGLE:
   {
      pm.SetSize (2, 3);
      pm(0,0) = 0.0;  pm(1,0) = 0.0;
      pm(0,1) = 1.0;  pm(1,1) = 0.0;
      pm(0,2) = 0.5;  pm(1,2) = 0.86602540378443864676;
   }
   break;

   case Geometry::SQUARE:
   {
      pm.SetSize (2, 4);
      pm(0,0) = 0.0;  pm(1,0) = 0.0;
      pm(0,1) = 1.0;  pm(1,1) = 0.0;
      pm(0,2) = 1.0;  pm(1,2) = 1.0;
      pm(0,3) = 0.0;  pm(1,3) = 1.0;
   }
   break;

   case Geometry::TETRAHEDRON:
   {
      pm.SetSize (3, 4);
      pm(0,0) = 0.0;  pm(1,0) = 0.0;  pm(2,0) = 0.0;
      pm(0,1) = 1.0;  pm(1,1) = 0.0;  pm(2,1) = 0.0;
      pm(0,2) = 0.5;  pm(1,2) = 0.86602540378443864676;  pm(2,2) = 0.0;
      pm(0,3) = 0.5;  pm(1,3) = 0.28867513459481288225;
      pm(2,3) = 0.81649658092772603273;
   }
   break;

   case Geometry::CUBE:
   {
      pm.SetSize (3, 8);
      pm(0,0) = 0.0;  pm(1,0) = 0.0;  pm(2,0) = 0.0;
      pm(0,1) = 1.0;  pm(1,1) = 0.0;  pm(2,1) = 0.0;
      pm(0,2) = 1.0;  pm(1,2) = 1.0;  pm(2,2) = 0.0;
      pm(0,3) = 0.0;  pm(1,3) = 1.0;  pm(2,3) = 0.0;
      pm(0,4) = 0.0;  pm(1,4) = 0.0;  pm(2,4) = 1.0;
      pm(0,5) = 1.0;  pm(1,5) = 0.0;  pm(2,5) = 1.0;
      pm(0,6) = 1.0;  pm(1,6) = 1.0;  pm(2,6) = 1.0;
      pm(0,7) = 0.0;  pm(1,7) = 1.0;  pm(2,7) = 1.0;
   }
   break;

   default:
      mfem_error ("Geometry::GetPerfPointMat (...)");
   }
}
예제 #2
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void BoundaryFlowIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    mfem_error("BoundaryFlowIntegrator::AssembleRHSElementVect\n"
               "  is not implemented as boundary integrator!\n"
               "  Use LinearForm::AddBdrFaceIntegrator instead of\n"
               "  LinearForm::AddBoundaryIntegrator.");
}
예제 #3
0
파일: blockvector.cpp 프로젝트: LLNL/mfem
BlockVector & BlockVector::operator=(const BlockVector & original)
{
   if (numBlocks!=original.numBlocks)
   {
      mfem_error("Number of Blocks don't match in BlockVector::operator=");
   }

   for (int i(0); i <= numBlocks; ++i)
      if (blockOffsets[i]!=original.blockOffsets[i])
      {
         mfem_error("Size of Blocks don't match in BlockVector::operator=");
      }

   Vector::operator=(original.GetData());

   return *this;
}
예제 #4
0
파일: vector.cpp 프로젝트: LLNL/mfem
double Vector::operator*(const Vector &v) const
{
#ifdef MFEM_DEBUG
   if (v.size != size)
   {
      mfem_error("Vector::operator*(const Vector &) const");
   }
#endif

   return operator*(v.data);
}
예제 #5
0
파일: sets.cpp 프로젝트: LLNL/mfem
int ListOfIntegerSets::Lookup(IntegerSet &s)
{
   for (int i = 0; i < TheList.Size(); i++)
      if (*TheList[i] == s)
      {
         return i;
      }

   mfem_error("ListOfIntegerSets::Lookup (), integer set not found.");
   return -1;
}
예제 #6
0
int IsoparametricTransformation::OrderW()
{
   switch (FElem->Space())
   {
      case FunctionSpace::Pk:
         return (FElem->GetOrder() - 1) * FElem->GetDim();
      case FunctionSpace::Qk:
         return (FElem->GetOrder() * FElem->GetDim() - 1);
      default:
         mfem_error("IsoparametricTransformation::OrderW()");
   }
   return 0;
}
예제 #7
0
파일: blockmatrix.hpp 프로젝트: jdahm/mfem
inline void BlockMatrix::findGlobalRow(int iglobal, int & iblock,
                                       int & iloc) const
{
    if (iglobal > row_offsets[nRowBlocks])
    {
        mfem_error("BlockMatrix::findGlobalRow");
    }

    for (iblock = 0; iblock < nRowBlocks; ++iblock)
        if (row_offsets[iblock+1] > iglobal)
        {
            break;
        }

    iloc = iglobal - row_offsets[iblock];
}
예제 #8
0
파일: geom.cpp 프로젝트: Kyushick/sight
const IntegrationRule * Geometry::GetVertices(int GeomType)
{
   switch (GeomType)
   {
   case Geometry::POINT:       return GeomVert[0];
   case Geometry::SEGMENT:     return GeomVert[1];
   case Geometry::TRIANGLE:    return GeomVert[2];
   case Geometry::SQUARE:      return GeomVert[3];
   case Geometry::TETRAHEDRON: return GeomVert[4];
   case Geometry::CUBE:        return GeomVert[5];
   default:
      mfem_error ("Geometry::GetVertices(...)");
   }
   // make some compilers happy.
   return GeomVert[0];
}
예제 #9
0
파일: blockmatrix.hpp 프로젝트: jdahm/mfem
inline void BlockMatrix::findGlobalCol(int jglobal, int & jblock,
                                       int & jloc) const
{
    if (jglobal > col_offsets[nColBlocks])
    {
        mfem_error("BlockMatrix::findGlobalCol");
    }

    for (jblock = 0; jblock < nColBlocks; ++jblock)
        if (col_offsets[jblock+1] > jglobal)
        {
            break;
        }

    jloc = jglobal - col_offsets[jblock];
}
예제 #10
0
int IsoparametricTransformation::OrderGrad(const FiniteElement *fe)
{
   if (FElem->Space() == fe->Space())
   {
      int k = FElem->GetOrder();
      int d = FElem->GetDim();
      int l = fe->GetOrder();
      switch (fe->Space())
      {
         case FunctionSpace::Pk:
            return ((k-1)*(d-1)+(l-1));
         case FunctionSpace::Qk:
            return (k*(d-1)+(l-1));
      }
   }
   mfem_error("IsoparametricTransformation::OrderGrad(...)");
   return 0;
}
예제 #11
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void BoundaryTangentialLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dim = el.GetDim()+1;
    int dof = el.GetDof();
    Vector tangent(dim), Qvec;

    shape.SetSize(dof);
    elvect.SetSize(dof);
    elvect = 0.0;

    if (dim != 2)
        mfem_error("These methods make sense only in 2D problems.");

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        int intorder = oa * el.GetOrder() + ob;  // <----------
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Tr.SetIntPoint(&ip);
        const DenseMatrix &Jac = Tr.Jacobian();
        tangent(0) =  Jac(0,0);
        tangent(1) = Jac(1,0);

        Q.Eval(Qvec, Tr, ip);

        el.CalcShape(ip, shape);

        add(elvect, ip.weight*(Qvec*tangent), shape, elvect);
    }
}
예제 #12
0
파일: geom.cpp 프로젝트: Kyushick/sight
const IntegrationRule *GeometryRefiner::RefineInterior(int Geom, int Times)
{
   int g = Geom;

   switch (g)
   {
   case Geometry::SEGMENT:
   {
      if (Times < 2)
         return NULL;
      if (IntPts[g] == NULL || IntPts[g]->GetNPoints() != Times-1)
      {
         delete IntPts[g];
         IntPts[g] = new IntegrationRule(Times-1);
         for (int i = 1; i < Times; i++)
         {
            IntegrationPoint &ip = IntPts[g]->IntPoint(i-1);
            ip.x = double(i) / Times;
            ip.y = ip.z = 0.0;
         }
      }
   }
   break;

   case Geometry::TRIANGLE:
   {
      if (Times < 3)
         return NULL;
      if (IntPts[g] == NULL ||
          IntPts[g]->GetNPoints() != ((Times-1)*(Times-2))/2)
      {
         delete IntPts[g];
         IntPts[g] = new IntegrationRule(((Times-1)*(Times-2))/2);
         for (int k = 0, j = 1; j < Times-1; j++)
            for (int i = 1; i < Times-j; i++, k++)
            {
               IntegrationPoint &ip = IntPts[g]->IntPoint(k);
               ip.x = double(i) / Times;
               ip.y = double(j) / Times;
               ip.z = 0.0;
            }
      }
   }
   break;

   case Geometry::SQUARE:
   {
      if (Times < 2)
         return NULL;
      if (IntPts[g] == NULL || IntPts[g]->GetNPoints() != (Times-1)*(Times-1))
      {
         delete IntPts[g];
         IntPts[g] = new IntegrationRule((Times-1)*(Times-1));
         for (int k = 0, j = 1; j < Times; j++)
            for (int i = 1; i < Times; i++, k++)
            {
               IntegrationPoint &ip = IntPts[g]->IntPoint(k);
               ip.x = double(i) / Times;
               ip.y = double(j) / Times;
               ip.z = 0.0;
            }
      }
   }
   break;

   default:
      mfem_error("GeometryRefiner::RefineInterior(...)");
   }

   return IntPts[g];
}
예제 #13
0
파일: geom.cpp 프로젝트: Kyushick/sight
RefinedGeometry * GeometryRefiner::Refine (int Geom, int Times, int ETimes)
{
   int i, j, k, l;

   const double *cp = NULL;
   if (type)
      cp = poly1d.ClosedPoints(Times);

   switch (Geom)
   {
   case Geometry::SEGMENT:
   {
      const int g = Geometry::SEGMENT;
      if (RGeom[g] != NULL && RGeom[g]->Times == Times)
         return RGeom[g];
      delete RGeom[g];
      RGeom[g] = new RefinedGeometry(Times+1, 2*Times, 0);
      RGeom[g]->Times = Times;
      RGeom[g]->ETimes = 0;
      for (i = 0; i <= Times; i++)
      {
         IntegrationPoint &ip = RGeom[g]->RefPts.IntPoint(i);
         ip.x = (type == 0) ? double(i) / Times : cp[i];
      }
      Array<int> &G = RGeom[g]->RefGeoms;
      for (i = 0; i < Times; i++)
      {
         G[2*i+0] = i;
         G[2*i+1] = i+1;
      }

      return RGeom[g];
   }

   case Geometry::TRIANGLE:
   {
      if (RGeom[2] != NULL && RGeom[2]->Times == Times &&
          RGeom[2]->ETimes == ETimes)
         return RGeom[2];

      if (RGeom[2] != NULL)
         delete RGeom[2];
      RGeom[2] = new RefinedGeometry ((Times+1)*(Times+2)/2, 3*Times*Times,
                                      3*Times*(ETimes+1));
      RGeom[2]->Times = Times;
      RGeom[2]->ETimes = ETimes;
      for (k = j = 0; j <= Times; j++)
         for (i = 0; i <= Times-j; i++, k++)
         {
            IntegrationPoint &ip = RGeom[2]->RefPts.IntPoint(k);
            if (type == 0)
            {
               ip.x = double(i) / Times;
               ip.y = double(j) / Times;
            }
            else
            {
               ip.x = cp[i]/(cp[i] + cp[j] + cp[Times-i-j]);
               ip.y = cp[j]/(cp[i] + cp[j] + cp[Times-i-j]);
            }
         }
      Array<int> &G = RGeom[2]->RefGeoms;
      for (l = k = j = 0; j < Times; j++, k++)
         for (i = 0; i < Times-j; i++, k++)
         {
            G[l++] = k;
            G[l++] = k+1;
            G[l++] = k+Times-j+1;
            if (i+j+1 < Times)
            {
               G[l++] = k+1;
               G[l++] = k+Times-j+2;
               G[l++] = k+Times-j+1;
            }
         }
      Array<int> &E = RGeom[2]->RefEdges;
      // horizontal edges
      for (l = k = 0; k < Times; k += Times/ETimes)
      {
         j = k*(Times+1)-((k-1)*k)/2;
         for (i = 0; i < Times-k; i++)
         {
            E[l++] = j; j++;
            E[l++] = j;
         }
      }
      // diagonal edges
      for (k = Times; k > 0; k -= Times/ETimes)
      {
         j = k;
         for (i = 0; i < k; i++)
         {
            E[l++] = j; j += Times-i;
            E[l++] = j;
         }
      }
      // vertical edges
      for (k = 0; k < Times; k += Times/ETimes)
      {
         j = k;
         for (i = 0; i < Times-k; i++)
         {
            E[l++] = j; j += Times-i+1;
            E[l++] = j;
         }
      }

      return RGeom[2];
   }

   case Geometry::SQUARE:
   {
      if (RGeom[3] != NULL && RGeom[3]->Times == Times &&
          RGeom[3]->ETimes == ETimes)
         return RGeom[3];

      if (RGeom[3] != NULL)
         delete RGeom[3];
      RGeom[3] = new RefinedGeometry ((Times+1)*(Times+1), 4*Times*Times,
                                      4*(ETimes+1)*Times);
      RGeom[3]->Times = Times;
      RGeom[3]->ETimes = ETimes;
      for (k = j = 0; j <= Times; j++)
         for (i = 0; i <= Times; i++, k++)
         {
            IntegrationPoint &ip = RGeom[3]->RefPts.IntPoint(k);
            if (type == 0)
            {
               ip.x = double(i) / Times;
               ip.y = double(j) / Times;
            }
            else
            {
               ip.x = cp[i];
               ip.y = cp[j];
            }
         }
      Array<int> &G = RGeom[3]->RefGeoms;
      for (l = k = j = 0; j < Times; j++, k++)
         for (i = 0; i < Times; i++, k++)
         {
            G[l++] = k;
            G[l++] = k+1;
            G[l++] = k+Times+2;
            G[l++] = k+Times+1;
         }
      Array<int> &E = RGeom[3]->RefEdges;
      // horizontal edges
      for (l = k = 0; k <= Times; k += Times/ETimes)
      {
         for (i = 0, j = k*(Times+1); i < Times; i++)
         {
            E[l++] = j; j++;
            E[l++] = j;
         }
      }
      // vertical edges (in right-to-left order)
      for (k = Times; k >= 0; k -= Times/ETimes)
      {
         for (i = 0, j = k; i < Times; i++)
         {
            E[l++] = j; j += Times+1;
            E[l++] = j;
         }
      }

      return RGeom[3];
   }

   case Geometry::CUBE:
   {
      const int g = Geometry::CUBE;
      if (RGeom[g] != NULL && RGeom[g]->Times == Times &&
          RGeom[g]->ETimes == ETimes)
         return RGeom[g];

      if (RGeom[g] != NULL)
         delete RGeom[g];
      RGeom[g] = new RefinedGeometry ((Times+1)*(Times+1)*(Times+1),
                                      8*Times*Times*Times, 0);
      RGeom[g]->Times = Times;
      RGeom[g]->ETimes = ETimes;
      for (l = k = 0; k <= Times; k++)
         for (j = 0; j <= Times; j++)
            for (i = 0; i <= Times; i++, l++)
            {
               IntegrationPoint &ip = RGeom[g]->RefPts.IntPoint(l);
               if (type == 0)
               {
                  ip.x = double(i) / Times;
                  ip.y = double(j) / Times;
                  ip.z = double(k) / Times;
               }
               else
               {
                  ip.x = cp[i];
                  ip.y = cp[j];
                  ip.z = cp[k];
               }
            }
      Array<int> &G = RGeom[g]->RefGeoms;
      for (l = k = 0; k < Times; k++)
         for (j = 0; j < Times; j++)
            for (i = 0; i < Times; i++)
            {
               G[l++] = i+0 + (j+0 + (k+0) * (Times+1)) * (Times+1);
               G[l++] = i+1 + (j+0 + (k+0) * (Times+1)) * (Times+1);
               G[l++] = i+1 + (j+1 + (k+0) * (Times+1)) * (Times+1);
               G[l++] = i+0 + (j+1 + (k+0) * (Times+1)) * (Times+1);
               G[l++] = i+0 + (j+0 + (k+1) * (Times+1)) * (Times+1);
               G[l++] = i+1 + (j+0 + (k+1) * (Times+1)) * (Times+1);
               G[l++] = i+1 + (j+1 + (k+1) * (Times+1)) * (Times+1);
               G[l++] = i+0 + (j+1 + (k+1) * (Times+1)) * (Times+1);
            }

      return RGeom[g];
   }

   case Geometry::TETRAHEDRON:
   {
      const int g = Geometry::TETRAHEDRON;
      if (RGeom[g] != NULL && RGeom[g]->Times == Times &&
          RGeom[g]->ETimes == ETimes)
         return RGeom[g];

      if (RGeom[g] != NULL)
         delete RGeom[g];

      // subdivide the tetrahedron with vertices
      // (0,0,0), (0,0,1), (1,1,1), (0,1,1)

      // vertices: 0 <= i <= j <= k <= Times
      // (3-combination with repetitions)
      // number of vertices: (n+3)*(n+2)*(n+1)/6, n = Times

      // elements: the vertices are: v1=(i,j,k), v2=v1+u1, v3=v2+u2, v4=v3+u3
      // where 0 <= i <= j <= k <= n-1 and
      // u1,u2,u3 is a permutation of (1,0,0),(0,1,0),(0,0,1)
      // such that all v2,v3,v4 have non-decreasing components
      // number of elements: n^3

      const int n = Times;
      RGeom[g] = new RefinedGeometry((n+3)*(n+2)*(n+1)/6, 4*n*n*n, 0);
      // enumerate and define the vertices
      Array<int> vi((n+1)*(n+1)*(n+1));
      vi = -1;
      int m = 0;
      for (k = 0; k <= n; k++)
         for (j = 0; j <= k; j++)
            for (i = 0; i <= j; i++)
            {
               IntegrationPoint &ip = RGeom[g]->RefPts.IntPoint(m);
               // map the coordinates to the reference tetrahedron
               // (0,0,0) -> (0,0,0)
               // (0,0,1) -> (1,0,0)
               // (1,1,1) -> (0,1,0)
               // (0,1,1) -> (0,0,1)
               if (type == 0)
               {
                  ip.x = double(k - j) / n;
                  ip.y = double(i) / n;
                  ip.z = double(j - i) / n;
               }
               else
               {
                  double w = cp[k-j] + cp[i] + cp[j-i] + cp[Times-k];
                  ip.x = cp[k-j]/w;
                  ip.y = cp[i]/w;
                  ip.z = cp[j-i]/w;
               }
               l = i + (j + k * (n+1)) * (n+1);
               vi[l] = m;
               m++;
            }
      if (m != (n+3)*(n+2)*(n+1)/6)
         mfem_error("GeometryRefiner::Refine() for TETRAHEDRON #1");
      // elements
      Array<int> &G = RGeom[g]->RefGeoms;
      m = 0;
      for (k = 0; k < n; k++)
         for (j = 0; j <= k; j++)
            for (i = 0; i <= j; i++)
            {
               // the ordering of the vertices is chosen to ensure:
               // 1) correct orientation
               // 2) the x,y,z edges are in the set of edges
               //    {(0,1),(2,3), (0,2),(1,3)}
               //    (goal is to ensure that subsequent refinement using
               //    this procedure preserves the six tetrahedral shapes)

               // zyx: (i,j,k)-(i,j,k+1)-(i+1,j+1,k+1)-(i,j+1,k+1)
               G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
               G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
               G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
               G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
               if (j < k)
               {
                  // yzx: (i,j,k)-(i+1,j+1,k+1)-(i,j+1,k)-(i,j+1,k+1)
                  G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
                  G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
                  G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
                  // yxz: (i,j,k)-(i,j+1,k)-(i+1,j+1,k+1)-(i+1,j+1,k)
                  G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
                  G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
               }
               if (i < j)
               {
                  // xzy: (i,j,k)-(i+1,j,k)-(i+1,j+1,k+1)-(i+1,j,k+1)
                  G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
                  if (j < k)
                  {
                     // xyz: (i,j,k)-(i+1,j+1,k+1)-(i+1,j,k)-(i+1,j+1,k)
                     G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
                     G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
                     G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
                     G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
                  }
                  // zxy: (i,j,k)-(i+1,j+1,k+1)-(i,j,k+1)-(i+1,j,k+1)
                  G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
                  G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
                  G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
               }
            }
      if (m != 4*n*n*n)
         mfem_error("GeometryRefiner::Refine() for TETRAHEDRON #2");
      for (i = 0; i < m; i++)
         if (G[i] < 0)
            mfem_error("GeometryRefiner::Refine() for TETRAHEDRON #3");

      return RGeom[g];
   }

   default:

      return RGeom[0];
   }
}
예제 #14
0
 void Mult(const Vector &x, Vector &y) const
 {
    mfem_error("SuperLURowLocMatrix::Mult(...)\n"
               "  matrix vector products are not supported.");
 }
예제 #15
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void LinearFormIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect)
{
    mfem_error("LinearFormIntegrator::AssembleRHSElementVect(...)");
}
예제 #16
0
파일: element.hpp 프로젝트: YPCC/mfem
 virtual Element *Duplicate(Mesh *m) const
 { mfem_error("OctasectedElement::Duplicate()"); return NULL; }
예제 #17
0
void GroupTopology::Create(ListOfIntegerSets &groups, int mpitag)
{
   groups.AsTable(group_lproc); // group_lproc = group_proc

   Table group_mgroupandproc;
   group_mgroupandproc.SetDims(NGroups(),
                               group_lproc.Size_of_connections() + NGroups());
   for (int i = 0; i < NGroups(); i++)
   {
      int j = group_mgroupandproc.GetI()[i];
      group_mgroupandproc.GetI()[i+1] = j + group_lproc.RowSize(i) + 1;
      group_mgroupandproc.GetJ()[j] = i;
      j++;
      for (int k = group_lproc.GetI()[i];
           j < group_mgroupandproc.GetI()[i+1]; j++, k++)
      {
         group_mgroupandproc.GetJ()[j] = group_lproc.GetJ()[k];
      }
   }

   // build groupmaster_lproc with lproc = proc
   groupmaster_lproc.SetSize(NGroups());

   // simplest choice of the group owner
   for (int i = 0; i < NGroups(); i++)
   {
      groupmaster_lproc[i] = groups.PickElementInSet(i);
   }

   // load-balanced choice of the group owner, which however can lead to
   // isolated dofs
   // for (i = 0; i < NGroups(); i++)
   //    groupmaster_lproc[i] = groups.PickRandomElementInSet(i);

   ProcToLProc();

   // build group_mgroup
   group_mgroup.SetSize(NGroups());

   int send_counter = 0;
   int recv_counter = 0;
   for (int i = 1; i < NGroups(); i++)
      if (groupmaster_lproc[i] != 0) // we are not the master
      {
         recv_counter++;
      }
      else
      {
         send_counter += group_lproc.RowSize(i)-1;
      }

   MPI_Request *requests = new MPI_Request[send_counter];
   MPI_Status  *statuses = new MPI_Status[send_counter];

   int max_recv_size = 0;
   send_counter = 0;
   for (int i = 1; i < NGroups(); i++)
   {
      if (groupmaster_lproc[i] == 0) // we are the master
      {
         group_mgroup[i] = i;

         for (int j = group_lproc.GetI()[i];
              j < group_lproc.GetI()[i+1]; j++)
         {
            if (group_lproc.GetJ()[j] != 0)
            {
               MPI_Isend(group_mgroupandproc.GetRow(i),
                         group_mgroupandproc.RowSize(i),
                         MPI_INT,
                         lproc_proc[group_lproc.GetJ()[j]],
                         mpitag,
                         MyComm,
                         &requests[send_counter]);
               send_counter++;
            }
         }
      }
      else // we are not the master
         if (max_recv_size < group_lproc.RowSize(i))
         {
            max_recv_size = group_lproc.RowSize(i);
         }
   }
   max_recv_size++;

   IntegerSet group;
   if (recv_counter > 0)
   {
      int count;
      MPI_Status status;
      int *recv_buf = new int[max_recv_size];
      for ( ; recv_counter > 0; recv_counter--)
      {
         MPI_Recv(recv_buf, max_recv_size, MPI_INT,
                  MPI_ANY_SOURCE, mpitag, MyComm, &status);

         MPI_Get_count(&status, MPI_INT, &count);

         group.Recreate(count-1, recv_buf+1);
         int g = groups.Lookup(group);
         group_mgroup[g] = recv_buf[0];

         if (lproc_proc[groupmaster_lproc[g]] != status.MPI_SOURCE)
         {
            cerr << "\n\n\nGroupTopology::GroupTopology: "
                 << MyRank() << ": ERROR\n\n\n" << endl;
            mfem_error();
         }
      }
      delete [] recv_buf;
   }

   MPI_Waitall(send_counter, requests, statuses);

   delete [] statuses;
   delete [] requests;
}
예제 #18
0
파일: blockmatrix.hpp 프로젝트: jdahm/mfem
 /// Returns a pointer to (approximation) of the matrix inverse.
 virtual MatrixInverse * Inverse() const
 {
     mfem_error("BlockMatrix::Inverse not implemented \n");
     return static_cast<MatrixInverse*>(NULL);
 }
예제 #19
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void DGDirichletLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    mfem_error("DGDirichletLFIntegrator::AssembleRHSElementVect");
}