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 (...)"); } }
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."); }
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; }
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); }
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; }
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; }
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]; }
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]; }
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]; }
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; }
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); } }
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]; }
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]; } }
void Mult(const Vector &x, Vector &y) const { mfem_error("SuperLURowLocMatrix::Mult(...)\n" " matrix vector products are not supported."); }
void LinearFormIntegrator::AssembleRHSElementVect( const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect) { mfem_error("LinearFormIntegrator::AssembleRHSElementVect(...)"); }
virtual Element *Duplicate(Mesh *m) const { mfem_error("OctasectedElement::Duplicate()"); return NULL; }
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; }
/// 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); }
void DGDirichletLFIntegrator::AssembleRHSElementVect( const FiniteElement &el, ElementTransformation &Tr, Vector &elvect) { mfem_error("DGDirichletLFIntegrator::AssembleRHSElementVect"); }