ExprFieldWrapper::ExprFieldWrapper(const Expr& expr) : expr_(expr), df_(), discreteSpace_(), //map_(), indices_(), Expr_size_(1), isPointData_(true) { int index = 0; Expr_size_ = expr.size(); // Now it is independent of the size of the size of the Expression for(index = 0 ; index < Expr_size_ ; index++) { const DiscreteFunction* df = dynamic_cast<const DiscreteFunction*>(expr[index].ptr().get()); const DiscreteFuncElement* dfe = dynamic_cast<const DiscreteFuncElement*>(expr[index].ptr().get()); if (df != 0) { discreteSpace_ = df->discreteSpace(); //map_ = df->map(); indices_.append(tuple(0)); BasisFamily basis = discreteSpace_.basis()[0]; const Lagrange* lagr = dynamic_cast<const Lagrange*>(basis.ptr().get()); if (lagr != 0 && lagr->order()==0) isPointData_ = false; const EdgeLocalizedBasis* elb = dynamic_cast<const EdgeLocalizedBasis*>(basis.ptr().get()); if (elb!=0) isPointData_ = false; df_ = df->data(); } else if (dfe != 0) { const DiscreteFunctionData* f = DiscreteFunctionData::getData(dfe); TEST_FOR_EXCEPTION(f == 0, RuntimeError, "ExprFieldWrapper ctor argument " << expr << " is not a discrete function"); discreteSpace_ = f->discreteSpace(); //map_ = f->map(); indices_.append(tuple(dfe->myIndex())); BasisFamily basis = discreteSpace_.basis()[indices_[index][0]]; const Lagrange* lagr = dynamic_cast<const Lagrange*>(basis.ptr().get()); if (lagr != 0 && lagr->order()==0) isPointData_ = false; const EdgeLocalizedBasis* elb = dynamic_cast<const EdgeLocalizedBasis*>(basis.ptr().get()); if (elb!=0) isPointData_ = false; df_ = f; } else { TEST_FOR_EXCEPTION(df == 0 && dfe == 0, RuntimeError, "ExprFieldWrapper ctor argument is not a discrete " "function"); } } }
int main(int argc, char** argv) { try { GlobalMPISession session(&argc, &argv); TimeMonitor t(totalTimer()); int pMax = 1; int dim=2; CellType cellType = TriangleCell; Point a = Point(0.0, 0.0); Point b = Point(1.0, 0.0); Point c = Point(0.0, 1.0); CellJacobianBatch JBatch; JBatch.resize(1, 2, 2); double* J = JBatch.jVals(0); J[0] = b[0] - a[0]; J[1] = c[0] - a[0]; J[2] = b[1] - a[1]; J[3] = c[1] - a[1]; bool isInternalBdry=false; /* ------ evaluate Lagrange and FIAT-Lagrange at the vertices */ Array<Point> verts = tuple(a,b,c); BasisFamily lagrange = new Lagrange(1); BasisFamily fiatLagrange = new Lagrange(1); MultiIndex d0(0,0,0); MultiIndex dx(1,0,0); MultiIndex dy(0,1,0); Array<Array<Array<double> > > result; Array<int> dummy; std::cerr << "------ Evaluating bases at vertices ----------" << std::endl << std::endl; std::cerr << "Evaluating phi(vert) with FIAT-Lagrange" << std::endl; fiatLagrange.ptr()->refEval(cellType, verts, d0, result); std::cerr << "results = " << result << std::endl << std::endl; std::cerr << "Evaluating phi(vert) with Lagrange" << std::endl; lagrange.ptr()->refEval(cellType, verts, d0, result); std::cerr << "results = " << result << std::endl << std::endl; std::cerr << std::endl ; std::cerr << "Evaluating Dx*phi(vert) with FIAT-Lagrange" << std::endl; fiatLagrange.ptr()->refEval(cellType, verts, dx, result); std::cerr << "results = " << result << std::endl << std::endl; std::cerr << "Evaluating Dx*phi(vert) with Lagrange" << std::endl; lagrange.ptr()->refEval(cellType, verts, dx, result); std::cerr << "results = " << result << std::endl << std::endl; std::cerr << std::endl ; std::cerr << "Evaluating Dy*phi(vert) with FIAT-Lagrange" << std::endl; fiatLagrange.ptr()->refEval(cellType, verts, dy, result); std::cerr << "results = " << result << std::endl << std::endl; std::cerr << "Evaluating Dy*phi(vert) with Lagrange" << std::endl; lagrange.ptr()->refEval(cellType, verts, dy, result); std::cerr << "results = " << result << std::endl << std::endl; /* --------- evaluate integrals over elements ----------- */ RCP<Array<double> > A = rcp(new Array<double>()); QuadratureFamily quad = new GaussianQuadrature(4); Array<double> quadWeights; Array<Point> quadPts; quad.getPoints(cellType, quadPts, quadWeights); int nQuad = quadPts.size(); Array<double> coeff(nQuad); for (int i=0; i<nQuad; i++) { double s = quadPts[i][0]; double t = quadPts[i][1]; double x = a[0] + J[0]*s + J[1]*t; double y = a[1] + J[2]*s + J[3]*t; coeff[i] = x*y; } const double* const f = &(coeff[0]); std::cerr << std::endl << std::endl << "---------------- One-forms --------------------" << std::endl << std::endl; for (int p=1; p<=pMax; p++) { BasisFamily P = new Lagrange(p); for (int dp=0; dp<=1; dp++) { if (dp > p) continue; Tabs tab0; std::cerr << tab0 << "test function deriv order = " << dp << std::endl; int numTestDir = 1; if (dp==1) numTestDir = dim; for (int t=0; t<numTestDir; t++) { int alpha = t; Tabs tab; QuadratureIntegral ref(dim, cellType, dim, cellType, P, alpha, dp, quad, isInternalBdry); A->resize(ref.nNodesTest()); ref.transformOneForm(JBatch, JBatch, dummy, f, A); std::cerr << tab << "test deriv direction =" << t << std::endl; std::cerr << tab << "transformed local vector: " << std::endl; std::cerr << tab << "{"; for (int r=0; r<ref.nNodesTest(); r++) { if (r!=0) std::cerr << ", "; std::cerr << (*A)[r]; } std::cerr << "}" << std::endl << std::endl; } } } std::cerr << std::endl << std::endl << "---------------- Two-forms --------------------" << std::endl << std::endl; for (int p=1; p<=pMax; p++) { BasisFamily P = new Lagrange(p); for (int q=1; q<=pMax; q++) { BasisFamily Q = new Lagrange(q); for (int dp=0; dp<=1; dp++) { if (dp > p) continue; Tabs tab0; std::cerr << tab0 << "test function deriv order = " << dp << std::endl; for (int dq=0; dq<=1; dq++) { if (dq > q) continue; Tabs tab1; std::cerr << tab1 << "unk function deriv order = " << dq << std::endl; int numTestDir = 1; if (dp==1) numTestDir = dim; for (int t=0; t<numTestDir; t++) { int alpha = t; int numUnkDir = 1; if (dq==1) numUnkDir = dim; for (int u=0; u<numUnkDir; u++) { Tabs tab; int beta = u; QuadratureIntegral ref(dim, cellType, dim, cellType, P, alpha, dp, Q, beta, dq, quadd, isInternalBdry); A->resize(ref.nNodesTest()*ref.nNodesUnk()); ref.transformTwoForm(JBatch, JBatch, dummy, f, A); std::cerr << tab << "test deriv direction =" << t << ", unk deriv direction =" << u << std::endl; std::cerr << tab << "transformed local stiffness matrix" << std::endl; std::cerr << tab << "{"; for (int r=0; r<ref.nNodesTest(); r++) { if (r!=0) std::cerr << ", "; std::cerr << "{"; for (int c=0; c<ref.nNodesUnk(); c++) { if (c!=0) std::cerr << ", "; std::cerr << chop((*A)[r + ref.nNodesTest()*c]); } std::cerr << "}"; } std::cerr << "}" << std::endl << std::endl; } } } } } } TimeMonitor::summarize(); } catch(std::exception& e) { std::cerr << e.what() << std::endl; } }
void HomogeneousDOFMap::allocate(const Mesh& mesh, const BasisFamily& basis, int numFuncs) { Tabs tab; SUNDANCE_MSG1(setupVerb(), tab << "allocating DOF map for nFuncs=" << numFuncs); Array<int> fid(numFuncs); for (int f=0; f<numFuncs; f++) fid[f] = f; funcIDOnCellSets().append(fid); for (int d=0; d<=dim_; d++) { Tabs tab1; SUNDANCE_MSG2(setupVerb(), tab1 << "allocating d=" << d); /* record the number of facets for each cell type so we're * not making a bunch of mesh calls */ numFacets_[d].resize(d); for (int fd=0; fd<d; fd++) numFacets_[d][fd]=mesh.numFacets(d, 0, fd); SUNDANCE_MSG3(setupVerb(), tab1 << "num facets for dimension " << d << " is " << numFacets_[d]); /* look up the node pointer for this cell and for all of its * facets */ basis.ptr()->getLocalDOFs(mesh.cellType(d), localNodePtrs_[d]); SUNDANCE_MSG3(setupVerb(), tab1 << "node ptrs for dimension " << d << " are " << localNodePtrs_[d]); /* with the node pointers in hand, we can work out the number * of nodes per cell in this dimension */ if (localNodePtrs_[d][d].size() > 0) { nNodesPerCell_[d] = localNodePtrs_[d][d][0].size(); } else { nNodesPerCell_[d] = 0; } SUNDANCE_MSG3(setupVerb(), tab1 << "num nodes for dimension " << d << " is " << nNodesPerCell_[d]); totalNNodesPerCell_[d] = nNodesPerCell_[d]; for (int dd=0; dd<d; dd++) { totalNNodesPerCell_[d] += numFacets_[d][dd]*nNodesPerCell_[dd]; } /* we know from the mesh the number of cells in this dimension */ if (nNodesPerCell_[d] > 0) { dofs_[d].resize(mesh.numCells(d)); } else { dofs_[d].resize(0); } if (d > 0 && d < dim_) originalFacetOrientation_[d-1].resize(mesh.numCells(d)); /* If any nodes are associated with the facets, then we know we have * a continuous basis function */ if (d < dim_ && nNodesPerCell_[d] > 0) basisIsContinuous_ = true; /* now that we know the number of nodes per cell for this dimension, * we can allocate space for the DOFs in this dimension */ int numCells = dofs_[d].size(); for (int c=0; c<numCells; c++) { dofs_[d][c].resize(funcIDList().size() * nNodesPerCell_[d]); /* set everything to uninitializedVal() */ for (int i=0; i<dofs_[d][c].size(); i++) { dofs_[d][c][i] = uninitializedVal(); } } } SUNDANCE_MSG1(setupVerb(), tab << "done allocating DOF map"); }
void checkbasis( BasisFamily &b1 , BasisFamily &b2 ) { int maxDim=3; double tol = 1.0e-13; int maxDiffOrder = 0; int numErrors = 0; QuadratureFamily quad = new GaussianQuadrature(4); for (int spatialDim=1; spatialDim<=maxDim; spatialDim++) { std::cerr << "\t" << "spatial dimension =" << spatialDim << std::endl; for (int cellDim=0; cellDim<=spatialDim; cellDim++) { std::cerr << "\t\t" << "cell dimension =" << cellDim << std::endl; CellType cellType; if (cellDim==0) cellType=PointCell; if (cellDim==1) cellType=LineCell; if (cellDim==2) cellType=TriangleCell; if (cellDim==3) cellType=TetCell; Array<Point> qPts; Array<double> qWts; quad.getPoints(cellType, qPts, qWts); for (int d=0; d<=maxDiffOrder; d++) { if (cellDim==0 && d>0) continue; cerr << "\t\t\t" << "differentiation order = " << d << std::endl; for (int dir=0; dir<iPow(cellDim, d); dir++) { std::cerr << "\t\t\t\t" << "direction = " << dir << std::endl; MultiIndex mi; mi[dir]=d; Array<Array<double> > values1; Array<Array<double> > values2; std::cerr << "\t\t\t\t" << "computing basis1..."; b1.ptr()->refEval(spatialDim, cellType, qPts, mi, values1); std::cerr << "done" << std::endl << "\t\t\t\t" << "computing basis2..."; b2.ptr()->refEval(spatialDim, cellType, qPts, mi, values2); std::cerr << "done" << std::endl; int nNodes1 = b1.ptr()->nNodes(spatialDim, cellType); int nNodes2 = b2.ptr()->nNodes(spatialDim, cellType); std::cerr << "\t\t\t\t" << "num nodes: basis1=" << nNodes1 << " basis2=" << nNodes2 << std::endl; if (nNodes1 != nNodes2) { std::cerr << "******** ERROR: node counts should be equal" << std::endl; numErrors++; continue; } if (values1.size() != values2.size()) { std::cerr << "******** ERROR: value array outer sizes should be equal" << std::endl; numErrors++; continue; } if (values1.size() != qPts.size()) { std::cerr << "******** ERROR: value array outer size should be equal to number of quad points" << std::endl; numErrors++; continue; } for (int q=0; q<qPts.length(); q++) { if (values1[q].length() != nNodes1) { std::cerr << "******** ERROR: value array inner size should be equal to number of nodes" << std::endl; numErrors++; continue; } std::cerr << "\t\t\t\t\t" << "quad point q=" << q << " pt=" << qPts[q] << std::endl; for (int n=0; n<nNodes1; n++) { std::cerr << "\t\t\t\t\t\t" << "node n=" << n << " phi1=" << values1[q][n] << " phi2=" << values2[q][n] << " |phi1-phi2|=" << fabs(values1[q][n]-values2[q][n]) << std::endl; if (fabs(values1[q][n]-values2[q][n]) > tol) { cout << "ERROR" << std::endl; numErrors++; } } } } } } } std::cerr << std::endl << std::endl << "Summary: detected " << numErrors << " errors " << std::endl; }
SubmaximalNodalDOFMap ::SubmaximalNodalDOFMap(const Mesh& mesh, const CellFilter& cf, int nFuncs, int setupVerb) : DOFMapBase(mesh, setupVerb), dim_(0), nTotalFuncs_(nFuncs), domain_(cf), domains_(tuple(cf)), nodeLIDs_(), nodeDOFs_(), lidToPtrMap_(), mapStructure_() { Tabs tab0(0); SUNDANCE_MSG1(setupVerb, tab0 << "in SubmaximalNodalDOFMap ctor"); Tabs tab1; SUNDANCE_MSG2(setupVerb, tab1 << "domain " << domain_); SUNDANCE_MSG2(setupVerb, tab1 << "N funcs " << nFuncs); const MPIComm& comm = mesh.comm(); int rank = comm.getRank(); int nProc = comm.getNProc(); dim_ = cf.dimension(mesh); TEUCHOS_TEST_FOR_EXCEPT(dim_ != 0); CellSet nodes = cf.getCells(mesh); int nc = nodes.numCells(); nodeLIDs_.reserve(nc); nodeDOFs_.reserve(nc); Array<Array<int> > remoteNodes(nProc); int nextDOF = 0; int k=0; for (CellIterator c=nodes.begin(); c!=nodes.end(); c++, k++) { int nodeLID = *c; lidToPtrMap_.put(nodeLID, k); nodeLIDs_.append(nodeLID); int remoteOwner = rank; if (isRemote(0, nodeLID, remoteOwner)) { int GID = mesh.mapLIDToGID(0, nodeLID); remoteNodes[remoteOwner].append(GID); for (int f=0; f<nFuncs; f++) nodeDOFs_.append(-1); } else { for (int f=0; f<nFuncs; f++) nodeDOFs_.append(nextDOF++); } } /* Compute offsets for each processor */ int localCount = nextDOF; computeOffsets(localCount); /* Resolve remote DOF numbers */ shareRemoteDOFs(remoteNodes); BasisFamily basis = new Lagrange(1); mapStructure_ = rcp(new MapStructure(nTotalFuncs_, basis.ptr())); }