void values(FieldContainer<double> &values, BasisCachePtr sliceBasisCache) { vector<GlobalIndexType> sliceCellIDs = sliceBasisCache->cellIDs(); Teuchos::Array<int> dim; values.dimensions(dim); dim[0] = 1; // one cell Teuchos::Array<int> offset(dim.size()); for (int cellOrdinal = 0; cellOrdinal < sliceCellIDs.size(); cellOrdinal++) { offset[0] = cellOrdinal; int enumeration = values.getEnumeration(offset); FieldContainer<double>valuesForCell(dim,&values[enumeration]); GlobalIndexType sliceCellID = sliceCellIDs[cellOrdinal]; int numPoints = sliceBasisCache->getPhysicalCubaturePoints().dimension(1); int spaceDim = sliceBasisCache->getPhysicalCubaturePoints().dimension(2); FieldContainer<double> spaceTimePhysicalPoints(1,numPoints,spaceDim+1); for (int ptOrdinal=0; ptOrdinal<numPoints; ptOrdinal++) { for (int d=0; d<spaceDim; d++) { spaceTimePhysicalPoints(0,ptOrdinal,d) = sliceBasisCache->getPhysicalCubaturePoints()(cellOrdinal,ptOrdinal,d); } spaceTimePhysicalPoints(0,ptOrdinal,spaceDim) = _t; } GlobalIndexType cellID = _cellIDMap[sliceCellID]; BasisCachePtr spaceTimeBasisCache = BasisCache::basisCacheForCell(_spaceTimeMesh, cellID); FieldContainer<double> spaceTimeRefPoints(1,numPoints,spaceDim+1); CamelliaCellTools::mapToReferenceFrame(spaceTimeRefPoints, spaceTimePhysicalPoints, _spaceTimeMesh, cellID); spaceTimeRefPoints.resize(numPoints,spaceDim+1); spaceTimeBasisCache->setRefCellPoints(spaceTimeRefPoints); _spaceTimeFunction->values(valuesForCell, spaceTimeBasisCache); } }
void FunctionTests::checkFunctionsAgree(FunctionPtr f1, FunctionPtr f2, BasisCachePtr basisCache) { ASSERT_EQ(f1->rank(), f2->rank()) << "f1->rank() " << f1->rank() << " != f2->rank() " << f2->rank() << endl; int rank = f1->rank(); int numCells = basisCache->getPhysicalCubaturePoints().dimension(0); int numPoints = basisCache->getPhysicalCubaturePoints().dimension(1); int spaceDim = basisCache->getPhysicalCubaturePoints().dimension(2); Teuchos::Array<int> dim; dim.append(numCells); dim.append(numPoints); for (int i=0; i<rank; i++) { dim.append(spaceDim); } FieldContainer<double> f1Values(dim); FieldContainer<double> f2Values(dim); f1->values(f1Values,basisCache); f2->values(f2Values,basisCache); double tol = 1e-14; double maxDiff; EXPECT_TRUE(fcsAgree(f1Values,f2Values,tol,maxDiff)) << "Test failed: f1 and f2 disagree; maxDiff " << maxDiff << ".\n" << "f1Values: \n" << f1Values << "f2Values: \n" << f2Values; }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { double xCenter = 0; double yCenter = 0; int nPts = 0; for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); xCenter += x; yCenter += y; nPts++; } xCenter /= nPts; yCenter /= nPts; for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); if (abs(y) <= halfWidth && abs(yCenter) < halfWidth) values(cellIndex, ptIndex) = 1.0; else values(cellIndex, ptIndex) = 0.0; } } }
// bool matchesPoint(double x, double y) { // return true; // } bool matchesPoints(FieldContainer<bool> &pointsMatch, BasisCachePtr basisCache) { const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); const FieldContainer<double> *normals = &(basisCache->getSideNormals()); int numCells = (*points).dimension(0); int numPoints = (*points).dimension(1); FieldContainer<double> beta_pts(numCells,numPoints,2); _beta->values(beta_pts,basisCache); double tol=1e-14; bool somePointMatches = false; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double n1 = (*normals)(cellIndex,ptIndex,0); double n2 = (*normals)(cellIndex,ptIndex,1); double beta_n = beta_pts(cellIndex,ptIndex,0)*n1 + beta_pts(cellIndex,ptIndex,1)*n2 ; // cout << "beta = (" << beta_pts(cellIndex,ptIndex,0)<<", "<< // beta_pts(cellIndex,ptIndex,1)<<"), n = ("<<n1<<", "<<n2<<")"<<endl; pointsMatch(cellIndex,ptIndex) = false; if (beta_n < 0) { pointsMatch(cellIndex,ptIndex) = true; somePointMatches = true; } } } return somePointMatches; }
bool matchesPoints(FieldContainer<bool> &pointsMatch, BasisCachePtr basisCache) { const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); const FieldContainer<double> *normals = &(basisCache->getSideNormals()); int numCells = (*points).dimension(0); int numPoints = (*points).dimension(1); double tol = 1e-3; bool somePointMatches = false; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); double n1 = (*normals)(cellIndex,ptIndex,0); double n2 = (*normals)(cellIndex,ptIndex,1); double beta_n = _beta[0]*n1 + _beta[1]*n2 ; pointsMatch(cellIndex,ptIndex) = false; if (abs((x-.5)*(x-.5)+y*y) < 0.75+tol && beta_n < 0) { pointsMatch(cellIndex,ptIndex) = true; somePointMatches = true; } } } return somePointMatches; }
void PreviousSolutionFunction::values(FieldContainer<double> &values, BasisCachePtr basisCache) { int rank = Teuchos::GlobalMPISession::getRank(); if (_overrideMeshCheck) { _solnExpression->evaluate(values, _soln, basisCache); return; } if (!basisCache.get()) cout << "basisCache is nil!\n"; if (!_soln.get()) cout << "_soln is nil!\n"; // values are stored in (C,P,D) order if (basisCache->mesh().get() == _soln->mesh().get()) { _solnExpression->evaluate(values, _soln, basisCache); } else { static bool warningIssued = false; if (!warningIssued) { if (rank==0) cout << "NOTE: In PreviousSolutionFunction, basisCache's mesh doesn't match solution's. If this is not what you intended, it would be a good idea to make sure that the mesh is passed in on BasisCache construction; the evaluation will be a lot slower without it...\n"; warningIssued = true; } // get the physicalPoints, and make a basisCache for each... FieldContainer<double> physicalPoints = basisCache->getPhysicalCubaturePoints(); FieldContainer<double> value(1,1); // assumes scalar-valued solution function. int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); int spaceDim = physicalPoints.dimension(2); physicalPoints.resize(numCells*numPoints,spaceDim); vector< ElementPtr > elements = _soln->mesh()->elementsForPoints(physicalPoints, false); // false: don't make elements null just because they're off-rank. FieldContainer<double> point(1,spaceDim); FieldContainer<double> refPoint(1,spaceDim); int combinedIndex = 0; vector<GlobalIndexType> cellID; cellID.push_back(-1); BasisCachePtr basisCacheOnePoint; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++, combinedIndex++) { if (elements[combinedIndex].get()==NULL) continue; // no element found for point; skip it… ElementTypePtr elemType = elements[combinedIndex]->elementType(); for (int d=0; d<spaceDim; d++) { point(0,d) = physicalPoints(combinedIndex,d); } if (elements[combinedIndex]->cellID() != cellID[0]) { cellID[0] = elements[combinedIndex]->cellID(); basisCacheOnePoint = Teuchos::rcp( new BasisCache(elemType, _soln->mesh()) ); basisCacheOnePoint->setPhysicalCellNodes(_soln->mesh()->physicalCellNodesForCell(cellID[0]),cellID,false); // false: don't createSideCacheToo } // compute the refPoint: typedef CellTools<double> CellTools; int whichCell = 0; CellTools::mapToReferenceFrame(refPoint,point,_soln->mesh()->physicalCellNodesForCell(cellID[0]), *(elemType->cellTopoPtr),whichCell); basisCacheOnePoint->setRefCellPoints(refPoint); // cout << "refCellPoints:\n " << refPoint; // cout << "physicalCubaturePoints:\n " << basisCacheOnePoint->getPhysicalCubaturePoints(); _solnExpression->evaluate(value, _soln, basisCacheOnePoint); // cout << "value at point (" << point(0,0) << ", " << point(0,1) << ") = " << value(0,0) << endl; values(cellIndex,ptIndex) = value(0,0); } } } }
void MeshTransformationFunction::values(FieldContainer<double> &values, BasisCachePtr basisCache) { CHECK_VALUES_RANK(values); vector<GlobalIndexType> cellIDs = basisCache->cellIDs(); // identity map is the right thing most of the time // we'll do something different only where necessary int spaceDim = values.dimension(2); TEUCHOS_TEST_FOR_EXCEPTION(basisCache->cellTopology()->getDimension() != spaceDim, std::invalid_argument, "cellTopology dimension does not match the shape of the values container"); if (_op == OP_VALUE) { values = basisCache->getPhysicalCubaturePoints(); // identity } else if (_op == OP_DX) { // identity map is 1 in all the x slots, 0 in all others int mod_value = 0; // the x slots are the mod spaceDim = 0 slots; for (int i=0; i<values.size(); i++) { values[i] = (i%spaceDim == mod_value) ? 1.0 : 0.0; } } else if (_op == OP_DY) { // identity map is 1 in all the y slots, 0 in all others int mod_value = 1; // the y slots are the mod spaceDim = 1 slots; for (int i=0; i<values.size(); i++) { values[i] = (i%spaceDim == mod_value) ? 1.0 : 0.0; } } else if (_op == OP_DZ) { // identity map is 1 in all the z slots, 0 in all others int mod_value = 2; // the z slots are the mod spaceDim = 2 slots; for (int i=0; i<values.size(); i++) { values[i] = (i%spaceDim == mod_value) ? 1.0 : 0.0; } } // if (_op == OP_DX) { // cout << "values before cellTransformation:\n" << values; // } for (int cellIndex=0; cellIndex < cellIDs.size(); cellIndex++) { GlobalIndexType cellID = cellIDs[cellIndex]; if (_cellTransforms.find(cellID) == _cellTransforms.end()) continue; TFunctionPtr<double> cellTransformation = _cellTransforms[cellID]; ((CellTransformationFunction*)cellTransformation.get())->setCellIndex(cellIndex); cellTransformation->values(values, basisCache); } // if (_op == OP_DX) { // cout << "values after cellTransformation:\n" << values; // } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); values(cellIndex, ptIndex) = 0; } } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { vector<GlobalIndexType> cellIDs = basisCache->cellIDs(); int numPoints = values.dimension(1); FieldContainer<double> points = basisCache->getPhysicalCubaturePoints(); for (int i = 0; i<cellIDs.size(); i++) { for (int j = 0; j<numPoints; j++) { values(i,j) = cellIDs[i]; } } }
bool FunctionTests::functionsAgree(FunctionPtr f1, FunctionPtr f2, BasisCachePtr basisCache) { if (f2->rank() != f1->rank() ) { cout << "f1->rank() " << f1->rank() << " != f2->rank() " << f2->rank() << endl; return false; } int rank = f1->rank(); int numCells = basisCache->getPhysicalCubaturePoints().dimension(0); int numPoints = basisCache->getPhysicalCubaturePoints().dimension(1); int spaceDim = basisCache->getSpaceDim(); Teuchos::Array<int> dim; dim.append(numCells); dim.append(numPoints); for (int i=0; i<rank; i++) { dim.append(spaceDim); } FieldContainer<double> f1Values(dim); FieldContainer<double> f2Values(dim); f1->values(f1Values,basisCache); f2->values(f2Values,basisCache); double tol = 1e-14; double maxDiff; bool functionsAgree = TestSuite::fcsAgree(f1Values,f2Values,tol,maxDiff); if ( ! functionsAgree ) { functionsAgree = false; cout << "Test failed: f1 and f2 disagree; maxDiff " << maxDiff << ".\n"; cout << "f1Values: \n" << f1Values; cout << "f2Values: \n" << f2Values; } else { // cout << "f1 and f2 agree!" << endl; } return functionsAgree; }
void ExactSolution::solutionValues(FieldContainer<double> &values, int trialID, BasisCachePtr basisCache) { if (_exactFunctions.find(trialID) != _exactFunctions.end() ) { _exactFunctions[trialID]->values(values,basisCache); return; } // TODO: change ExactSolution::solutionValues (below) to take a *const* points FieldContainer, to avoid this copy: FieldContainer<double> points = basisCache->getPhysicalCubaturePoints(); if (basisCache->getSideIndex() >= 0) { FieldContainer<double> unitNormals = basisCache->getSideNormals(); this->solutionValues(values,trialID,points,unitNormals); } else { this->solutionValues(values,trialID,points); } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { FieldContainer<double> points = basisCache->getPhysicalCubaturePoints(); FieldContainer<double> normals = basisCache->getSideNormals(); int numCells = points.dimension(0); int numPoints = points.dimension(1); FieldContainer<double> Tv(numCells,numPoints); FieldContainer<double> u1v(numCells,numPoints);; _u1->values(u1v,basisCache); _T->values(Tv,basisCache); bool isSubsonic = false; double min_y = YTOP; double max_y = 0.0; values.initialize(0.0); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = points(cellIndex,ptIndex,0); double y = points(cellIndex,ptIndex,1); double T = Tv(cellIndex,ptIndex); double un = u1v(cellIndex,ptIndex); // WARNING: ASSUMES NORMAL AT OUTFLOW = (1,0) double c = sqrt(_gamma * (_gamma-1.0) * _cv * T); bool outflowMatch = ((abs(x-2.0) < _tol) && (y > 0.0) && (y < YTOP)); bool subsonicMatch = (un < c) && (un > 0.0); if (subsonicMatch && outflowMatch) { values(cellIndex,ptIndex) = 1.0; isSubsonic = true; min_y = min(y,min_y); max_y = max(y,max_y); // cout << "y = " << y << endl; } } } if (isSubsonic) { // cout << "subsonic in interval y =(" << min_y << "," << max_y << ")" << endl; } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); int spaceDim = values.dimension(2); const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { for (int d = 0; d < spaceDim; d++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); if ((x+.5)*(x+.5)+y*y < .25*.25) values(cellIndex,ptIndex) = 1.0; else values(cellIndex,ptIndex) = 0.0; } } } }
bool FunctionTests::testVectorFunctionValuesOrdering() { bool success = true; FunctionPtr x = Function::xn(1); FunctionPtr x_vector = Function::vectorize(x, Function::zero()); BasisCachePtr basisCache = BasisCache::parametricQuadCache(10); FieldContainer<double> points = basisCache->getPhysicalCubaturePoints(); int numCells = points.dimension(0); int numPoints = points.dimension(1); int spaceDim = points.dimension(2); FieldContainer<double> values(numCells,numPoints,spaceDim); x_vector->values(values, basisCache); // cout << "(x,0) function values:\n" << values; double tol = 1e-14; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double xValueExpected = points(cellIndex,ptIndex,0); double yValueExpected = 0; double xValue = values(cellIndex,ptIndex,0); double yValue = values(cellIndex,ptIndex,1); double xErr = abs(xValue-xValueExpected); double yErr = abs(yValue-yValueExpected); if ( (xErr > tol) || (yErr > tol) ) { success = false; cout << "testVectorFunctionValuesOrdering(): vectorized function values incorrect (presumably out of order).\n"; cout << "x: " << xValueExpected << " ≠ " << xValue << endl; cout << "y: " << yValueExpected << " ≠ " << yValue << endl; } } } return success; }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); FieldContainer<double> beta_pts(numCells,numPoints,2); _beta->values(beta_pts,basisCache); const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); double tol=1e-14; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); double b1 = beta_pts(cellIndex,ptIndex,0); double b2 = beta_pts(cellIndex,ptIndex,1); double beta_norm =b1*b1 + b2*b2; values(cellIndex,ptIndex) = sqrt(beta_norm); } } }
bool matchesPoints(FieldContainer<bool> &pointsMatch, BasisCachePtr basisCache) { const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); int numCells = (*points).dimension(0); int numPoints = (*points).dimension(1); FieldContainer<double> T(numCells,numPoints); FieldContainer<double> u1(numCells,numPoints);; _u1->values(u1,basisCache); _T->values(T,basisCache); double tol=1e-14; bool somePointMatches = false; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); double T_val = T(cellIndex,ptIndex); double c = sqrt(_gamma * (_gamma-1.0) * _cv * T_val); double un = u1(cellIndex,ptIndex); // WARNING: ASSUMES NORMAL AT OUTFLOW = (1,0) cout << "un = " << un << ", T = " << T_val << endl; double tol = 1e-14; bool outflowMatch = ((abs(x-2.0) < tol) && (y > 0.0) && (y < YTOP)); bool subsonicMatch = (un < c) && (un > 0.0); pointsMatch(cellIndex,ptIndex) = false; if (outflowMatch && subsonicMatch) { pointsMatch(cellIndex,ptIndex) = true; somePointMatches = true; } } } return somePointMatches; }
void PolarizedFunction<Scalar>::values(Intrepid::FieldContainer<Scalar> &values, BasisCachePtr basisCache) { this->CHECK_VALUES_RANK(values); static const double PI = 3.141592653589793238462; int numCells = values.dimension(0); int numPoints = values.dimension(1); const Intrepid::FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); Intrepid::FieldContainer<double> polarPoints = *points; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); double r = sqrt(x * x + y * y); double theta = (r != 0) ? acos(x/r) : 0; // now x = r cos theta, but need to guarantee that y = r sin theta (might differ in sign) // according to the acos docs, theta will be in [0, pi], so the rule is: (y < 0) ==> theta := 2 pi - theta; if (y < 0) theta = 2*PI-theta; polarPoints(cellIndex, ptIndex, 0) = r; polarPoints(cellIndex, ptIndex, 1) = theta; // if (r == 0) { // cout << "r == 0!" << endl; // } } } BasisCachePtr dummyBasisCache = Teuchos::rcp( new PhysicalPointCache( polarPoints ) ); _f->values(values,dummyBasisCache); if (_f->isZero()) { cout << "Warning: in PolarizedFunction, we are being asked for values when _f is zero. This shouldn't happen.\n"; } // cout << "polarPoints: \n" << polarPoints; // cout << "PolarizedFunction, values: \n" << values; }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); double tol=1e-14; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); // solution with a boundary layer (section 5.2 in DPG Part II) // for x = 1, y = 1: u = 0 if ( ( abs(x-1.0) < tol ) || (abs(y-1.0) < tol ) ) { values(cellIndex,ptIndex) = 0; } else if ( abs(x) < tol ) { // for x=0: u = 1 - y values(cellIndex,ptIndex) = 1.0 - y; } else { // for y=0: u=1-x values(cellIndex,ptIndex) = 1.0 - x; } } } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { double tol = 1e-11; vector<GlobalIndexType> cellIDs = basisCache->cellIDs(); int numPoints = values.dimension(1); FieldContainer<double> points = basisCache->getPhysicalCubaturePoints(); for (int i = 0; i<cellIDs.size(); i++) { for (int j = 0; j<numPoints; j++) { double x = points(i,j,0); double y = points(i,j,1); if (abs(x-.5)<tol) { values(i,j) = 1.0; } else { values(i,j) = 0.0; } } } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); const FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); double tol=1e-14; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); if ((abs(x)<tol) || ((abs(y)<tol) && (x<.2))) { values(cellIndex,ptIndex) = 1.0; } else { values(cellIndex,ptIndex) = 0.0; } } } }
void SimpleVectorFunction<Scalar>::values(Intrepid::FieldContainer<Scalar> &values, BasisCachePtr basisCache) { this->CHECK_VALUES_RANK(values); int numCells = values.dimension(0); int numPoints = values.dimension(1); const Intrepid::FieldContainer<double> *points = &(basisCache->getPhysicalCubaturePoints()); int spaceDim = points->dimension(2); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { if (spaceDim == 1) { double x = (*points)(cellIndex,ptIndex,0); values(cellIndex,ptIndex,0) = value(x)[0]; } else if (spaceDim == 2) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); values(cellIndex,ptIndex,0) = value(x,y)[0]; values(cellIndex,ptIndex,1) = value(x,y)[1]; } else if (spaceDim == 3) { double x = (*points)(cellIndex,ptIndex,0); double y = (*points)(cellIndex,ptIndex,1); double z = (*points)(cellIndex,ptIndex,2); values(cellIndex,ptIndex,0) = value(x,y,z)[0]; values(cellIndex,ptIndex,1) = value(x,y,z)[1]; values(cellIndex,ptIndex,2) = value(x,y,z)[2]; } } } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { // sets values(_cellIndex,P,D) TEUCHOS_TEST_FOR_EXCEPTION(_cellIndex == -1, std::invalid_argument, "must call setCellIndex before calling values!"); // cout << "_basisCoefficients:\n" << _basisCoefficients; BasisCachePtr spaceTimeBasisCache; if (basisCache->cellTopologyIsSpaceTime()) { // then we require that the basisCache provided be a space-time basis cache SpaceTimeBasisCache* spaceTimeCache = dynamic_cast<SpaceTimeBasisCache*>(basisCache.get()); TEUCHOS_TEST_FOR_EXCEPTION(!spaceTimeCache, std::invalid_argument, "space-time requires a SpaceTimeBasisCache"); spaceTimeBasisCache = basisCache; basisCache = spaceTimeCache->getSpatialBasisCache(); } int numDofs = _basis->getCardinality(); int spaceDim = basisCache->getSpaceDim(); bool basisIsVolumeBasis = (spaceDim == _basis->domainTopology()->getDimension()); bool useCubPointsSideRefCell = basisIsVolumeBasis && basisCache->isSideCache(); int numPoints = values.dimension(1); // check if we're taking a temporal derivative int component; Intrepid::EOperator relatedOp = BasisEvaluation::relatedOperator(_op, _basis->functionSpace(), spaceDim, component); if ((relatedOp == Intrepid::OPERATOR_GRAD) && (component==spaceDim)) { // then we are taking the temporal part of the Jacobian of the reference to curvilinear-reference space // based on our assumptions that curvilinearity is just in the spatial direction (and is orthogonally extruded in the // temporal direction), this is always the identity. for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { for (int d=0; d<values.dimension(2); d++) { if (d < spaceDim) values(_cellIndex,ptIndex,d) = 0.0; else values(_cellIndex,ptIndex,d) = 1.0; } } return; } constFCPtr transformedValues = basisCache->getTransformedValues(_basis, _op, useCubPointsSideRefCell); // transformedValues has dimensions (C,F,P,[D,D]) // therefore, the rank of the sum is transformedValues->rank() - 3 int rank = transformedValues->rank() - 3; TEUCHOS_TEST_FOR_EXCEPTION(rank != values.rank()-2, std::invalid_argument, "values rank is incorrect."); int spaceTimeSideOrdinal = (spaceTimeBasisCache != Teuchos::null) ? spaceTimeBasisCache->getSideIndex() : -1; // I'm pretty sure much of this treatment of the time dimension could be simplified by taking advantage of SpaceTimeBasisCache::getTemporalBasisCache()... double t0 = -1, t1 = -1; if ((spaceTimeSideOrdinal != -1) && (!spaceTimeBasisCache->cellTopology()->sideIsSpatial(spaceTimeSideOrdinal))) { unsigned sideTime0 = spaceTimeBasisCache->cellTopology()->getTemporalSideOrdinal(0); unsigned sideTime1 = spaceTimeBasisCache->cellTopology()->getTemporalSideOrdinal(1); // get first node of each of the time-orthogonal sides, and use that to determine t0 and t1: unsigned spaceTimeNodeTime0 = spaceTimeBasisCache->cellTopology()->getNodeMap(spaceDim, sideTime0, 0); unsigned spaceTimeNodeTime1 = spaceTimeBasisCache->cellTopology()->getNodeMap(spaceDim, sideTime1, 0); t0 = spaceTimeBasisCache->getPhysicalCellNodes()(_cellIndex,spaceTimeNodeTime0,spaceDim); t1 = spaceTimeBasisCache->getPhysicalCellNodes()(_cellIndex,spaceTimeNodeTime1,spaceDim); } // initialize the values we're responsible for setting if (_op == OP_VALUE) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { for (int d=0; d<values.dimension(2); d++) { if (d < spaceDim) values(_cellIndex,ptIndex,d) = 0.0; else if ((spaceTimeBasisCache != Teuchos::null) && (spaceTimeSideOrdinal == -1)) values(_cellIndex,ptIndex,spaceDim) = spaceTimeBasisCache->getPhysicalCubaturePoints()(_cellIndex,ptIndex,spaceDim); else if ((spaceTimeBasisCache != Teuchos::null) && (spaceTimeSideOrdinal != -1)) { if (spaceTimeBasisCache->cellTopology()->sideIsSpatial(spaceTimeSideOrdinal)) { values(_cellIndex,ptIndex,spaceDim) = spaceTimeBasisCache->getPhysicalCubaturePoints()(_cellIndex,ptIndex,spaceDim-1); } else { double temporalPoint; unsigned temporalNode = spaceTimeBasisCache->cellTopology()->getTemporalComponentSideOrdinal(spaceTimeSideOrdinal); if (temporalNode==0) temporalPoint = t0; else temporalPoint = t1; values(_cellIndex,ptIndex,spaceDim) = temporalPoint; } } } } } else if ((_op == OP_DX) || (_op == OP_DY) || (_op == OP_DZ)) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { for (int d=0; d<values.dimension(2); d++) { if (d < spaceDim) values(_cellIndex,ptIndex,d) = 0.0; else if (_op == OP_DZ) values(_cellIndex,ptIndex,d) = 1.0; else values(_cellIndex,ptIndex,d) = 0.0; } } } else { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unhandled _op"); } int numSpatialPoints = transformedValues->dimension(2); int numTemporalPoints = numPoints / numSpatialPoints; TEUCHOS_TEST_FOR_EXCEPTION(numTemporalPoints * numSpatialPoints != numPoints, std::invalid_argument, "numPoints is not evenly divisible by numSpatialPoints"); for (int i=0; i<numDofs; i++) { double weight = _basisCoefficients(i); for (int timePointOrdinal=0; timePointOrdinal<numTemporalPoints; timePointOrdinal++) { for (int spacePointOrdinal=0; spacePointOrdinal<numSpatialPoints; spacePointOrdinal++) { int spaceTimePointOrdinal = TENSOR_POINT_ORDINAL(spacePointOrdinal, timePointOrdinal, numSpatialPoints); for (int d=0; d<spaceDim; d++) { values(_cellIndex,spaceTimePointOrdinal,d) += weight * (*transformedValues)(_cellIndex,i,spacePointOrdinal,d); } } } } }
bool MeshTestUtility::determineRefTestPointsForNeighbors(MeshTopologyViewPtr meshTopo, CellPtr fineCell, unsigned int sideOrdinal, FieldContainer<double> &fineSideRefPoints, FieldContainer<double> &fineCellRefPoints, FieldContainer<double> &coarseSideRefPoints, FieldContainer<double> &coarseCellRefPoints) { unsigned spaceDim = meshTopo->getDimension(); unsigned sideDim = spaceDim - 1; if (spaceDim == 1) { fineSideRefPoints.resize(0,0); coarseSideRefPoints.resize(0,0); fineCellRefPoints.resize(1,1); coarseCellRefPoints.resize(1,1); FieldContainer<double> lineRefNodes(2,1); CellTopoPtr line = CellTopology::line(); CamelliaCellTools::refCellNodesForTopology(lineRefNodes, line); fineCellRefPoints[0] = lineRefNodes[sideOrdinal]; unsigned neighborSideOrdinal = fineCell->getNeighborInfo(sideOrdinal, meshTopo).second; if (neighborSideOrdinal != -1) { coarseCellRefPoints[0] = lineRefNodes[neighborSideOrdinal]; return true; } else { return false; } } pair<GlobalIndexType, unsigned> neighborInfo = fineCell->getNeighborInfo(sideOrdinal, meshTopo); if (neighborInfo.first == -1) { // boundary return false; } CellPtr neighborCell = meshTopo->getCell(neighborInfo.first); if (neighborCell->isParent(meshTopo)) { return false; // fineCell isn't the finer of the two... } CellTopoPtr fineSideTopo = fineCell->topology()->getSubcell(sideDim, sideOrdinal); CubatureFactory cubFactory; int cubDegree = 4; // fairly arbitrary choice: enough to get a decent number of test points... Teuchos::RCP<Cubature<double> > fineSideTopoCub = cubFactory.create(fineSideTopo, cubDegree); int numCubPoints = fineSideTopoCub->getNumPoints(); FieldContainer<double> cubPoints(numCubPoints, sideDim); FieldContainer<double> cubWeights(numCubPoints); // we neglect these... fineSideTopoCub->getCubature(cubPoints, cubWeights); FieldContainer<double> sideRefCellNodes(fineSideTopo->getNodeCount(),sideDim); CamelliaCellTools::refCellNodesForTopology(sideRefCellNodes, fineSideTopo); int numTestPoints = numCubPoints + fineSideTopo->getNodeCount(); FieldContainer<double> testPoints(numTestPoints, sideDim); for (int ptOrdinal=0; ptOrdinal<testPoints.dimension(0); ptOrdinal++) { if (ptOrdinal<fineSideTopo->getNodeCount()) { for (int d=0; d<sideDim; d++) { testPoints(ptOrdinal,d) = sideRefCellNodes(ptOrdinal,d); } } else { for (int d=0; d<sideDim; d++) { testPoints(ptOrdinal,d) = cubPoints(ptOrdinal-fineSideTopo->getNodeCount(),d); } } } fineSideRefPoints = testPoints; fineCellRefPoints.resize(numTestPoints, spaceDim); CamelliaCellTools::mapToReferenceSubcell(fineCellRefPoints, testPoints, sideDim, sideOrdinal, fineCell->topology()); CellTopoPtr coarseSideTopo = neighborCell->topology()->getSubcell(sideDim, neighborInfo.second); unsigned fineSideAncestorPermutation = fineCell->ancestralPermutationForSubcell(sideDim, sideOrdinal, meshTopo); unsigned coarseSidePermutation = neighborCell->subcellPermutation(sideDim, neighborInfo.second); unsigned coarseSideAncestorPermutationInverse = CamelliaCellTools::permutationInverse(coarseSideTopo, coarseSidePermutation); unsigned composedPermutation = CamelliaCellTools::permutationComposition(coarseSideTopo, coarseSideAncestorPermutationInverse, fineSideAncestorPermutation); // goes from coarse ordering to fine. RefinementBranch fineRefBranch = fineCell->refinementBranchForSide(sideOrdinal, meshTopo); FieldContainer<double> fineSideNodes(fineSideTopo->getNodeCount(), sideDim); // relative to the ancestral cell whose neighbor is compatible if (fineRefBranch.size() == 0) { CamelliaCellTools::refCellNodesForTopology(fineSideNodes, coarseSideTopo, composedPermutation); } else { FieldContainer<double> ancestralSideNodes(coarseSideTopo->getNodeCount(), sideDim); CamelliaCellTools::refCellNodesForTopology(ancestralSideNodes, coarseSideTopo, composedPermutation); RefinementBranch fineSideRefBranch = RefinementPattern::sideRefinementBranch(fineRefBranch, sideOrdinal); fineSideNodes = RefinementPattern::descendantNodes(fineSideRefBranch, ancestralSideNodes); } BasisCachePtr sideTopoCache = Teuchos::rcp( new BasisCache(fineSideTopo, 1, false) ); sideTopoCache->setRefCellPoints(testPoints); // add cell dimension fineSideNodes.resize(1,fineSideNodes.dimension(0), fineSideNodes.dimension(1)); sideTopoCache->setPhysicalCellNodes(fineSideNodes, vector<GlobalIndexType>(), false); coarseSideRefPoints = sideTopoCache->getPhysicalCubaturePoints(); // strip off the cell dimension: coarseSideRefPoints.resize(coarseSideRefPoints.dimension(1),coarseSideRefPoints.dimension(2)); coarseCellRefPoints.resize(numTestPoints,spaceDim); CamelliaCellTools::mapToReferenceSubcell(coarseCellRefPoints, coarseSideRefPoints, sideDim, neighborInfo.second, neighborCell->topology()); return true; // containers filled.... }
bool LinearTermTests::testRieszInversionAsProjection() { bool success = true; //////////////////// DECLARE VARIABLES /////////////////////// // define test variables VarFactoryPtr varFactory = VarFactory::varFactory(); VarPtr tau = varFactory->testVar("\\tau", HDIV); VarPtr v = varFactory->testVar("v", HGRAD); // define trial variables VarPtr uhat = varFactory->traceVar("\\widehat{u}"); VarPtr beta_n_u_minus_sigma_n = varFactory->fluxVar("\\widehat{\\beta \\cdot n u - \\sigma_{n}}"); VarPtr u = varFactory->fieldVar("u"); VarPtr sigma1 = varFactory->fieldVar("\\sigma_1"); VarPtr sigma2 = varFactory->fieldVar("\\sigma_2"); vector<double> beta; beta.push_back(1.0); beta.push_back(0.0); double eps = .01; //////////////////// DEFINE BILINEAR FORM /////////////////////// BFPtr confusionBF = Teuchos::rcp( new BF(varFactory) ); // tau terms: confusionBF->addTerm(sigma1 / eps, tau->x()); confusionBF->addTerm(sigma2 / eps, tau->y()); confusionBF->addTerm(u, tau->div()); confusionBF->addTerm(uhat, -tau->dot_normal()); // v terms: confusionBF->addTerm( sigma1, v->dx() ); confusionBF->addTerm( sigma2, v->dy() ); confusionBF->addTerm( -u, beta * v->grad() ); confusionBF->addTerm( beta_n_u_minus_sigma_n, v); //////////////////// BUILD MESH /////////////////////// // define nodes for mesh int H1Order = 2; int pToAdd = 2; FieldContainer<double> quadPoints(4,2); quadPoints(0,0) = 0.0; // x1 quadPoints(0,1) = 0.0; // y1 quadPoints(1,0) = 1.0; quadPoints(1,1) = 0.0; quadPoints(2,0) = 1.0; quadPoints(2,1) = 1.0; quadPoints(3,0) = 0.0; quadPoints(3,1) = 1.0; int nCells = 2; int horizontalCells = nCells, verticalCells = nCells; // create a new mesh: MeshPtr myMesh = MeshFactory::buildQuadMesh(quadPoints, horizontalCells, verticalCells, confusionBF, H1Order, H1Order+pToAdd); ElementTypePtr elemType = myMesh->getElement(0)->elementType(); BasisCachePtr basisCache = Teuchos::rcp(new BasisCache(elemType, myMesh)); vector<GlobalIndexType> cellIDs = myMesh->cellIDsOfTypeGlobal(elemType); bool createSideCacheToo = true; basisCache->setPhysicalCellNodes(myMesh->physicalCellNodesGlobal(elemType), cellIDs, createSideCacheToo); LinearTermPtr integrand = Teuchos::rcp(new LinearTerm); // residual FunctionPtr x = Function::xn(1); FunctionPtr y = Function::yn(1); FunctionPtr testFxn1 = x; FunctionPtr testFxn2 = y; FunctionPtr fxnToProject = x * y + 1.0; integrand->addTerm(fxnToProject * v); IPPtr ip_L2 = Teuchos::rcp(new IP); ip_L2->addTerm(v); ip_L2->addTerm(tau); Teuchos::RCP<RieszRep> riesz = Teuchos::rcp(new RieszRep(myMesh, ip_L2, integrand)); riesz->computeRieszRep(); FunctionPtr rieszFxn = RieszRep::repFunction(v,riesz); int numCells = basisCache->getPhysicalCubaturePoints().dimension(0); int numPts = basisCache->getPhysicalCubaturePoints().dimension(1); FieldContainer<double> valProject( numCells, numPts ); FieldContainer<double> valExpected( numCells, numPts ); rieszFxn->values(valProject,basisCache); fxnToProject->values(valExpected,basisCache); // int rank = Teuchos::GlobalMPISession::getRank(); // if (rank==0) cout << "physicalCubaturePoints:\n" << basisCache->getPhysicalCubaturePoints(); double maxDiff; double tol = 1e-12; success = TestSuite::fcsAgree(valProject,valExpected,tol,maxDiff); if (success==false) { cout << "Failed Riesz Inversion Projection test with maxDiff = " << maxDiff << endl; serializeOutput("valExpected", valExpected); serializeOutput("valProject", valProject); serializeOutput("physicalPoints", basisCache->getPhysicalCubaturePoints()); } return allSuccess(success); }
bool FunctionTests::testBasisSumFunction() { bool success = true; // on a single-element mesh, the BasisSumFunction should be identical to // the Solution with those coefficients // define a new mesh: more interesting if we're not on the ref cell int spaceDim = 2; FieldContainer<double> quadPoints(4,2); quadPoints(0,0) = 0.0; // x1 quadPoints(0,1) = 0.0; // y1 quadPoints(1,0) = 2.0; quadPoints(1,1) = 0.0; quadPoints(2,0) = 1.0; quadPoints(2,1) = 1.0; quadPoints(3,0) = 0.0; quadPoints(3,1) = 1.0; int H1Order = 1, pToAdd = 0; int horizontalCells = 1, verticalCells = 1; // create a pointer to a new mesh: MeshPtr spectralConfusionMesh = MeshFactory::buildQuadMesh(quadPoints, horizontalCells, verticalCells, _confusionBF, H1Order, H1Order+pToAdd); BCPtr bc = BC::bc(); SolutionPtr soln = Teuchos::rcp( new Solution(spectralConfusionMesh, bc) ); soln->initializeLHSVector(); int cellID = 0; double tol = 1e-16; // overly restrictive, just for now. DofOrderingPtr trialSpace = spectralConfusionMesh->getElementType(cellID)->trialOrderPtr; set<int> trialIDs = trialSpace->getVarIDs(); BasisCachePtr volumeCache = BasisCache::basisCacheForCell(spectralConfusionMesh, cellID); for (set<int>::iterator trialIt=trialIDs.begin(); trialIt != trialIDs.end(); trialIt++) { int trialID = *trialIt; const vector<int>* sidesForVar = &trialSpace->getSidesForVarID(trialID); bool boundaryValued = sidesForVar->size() != 1; // note that for volume trialIDs, sideIndex = 0, and numSides = 1… for (vector<int>::const_iterator sideIt = sidesForVar->begin(); sideIt != sidesForVar->end(); sideIt++) { int sideIndex = *sideIt; BasisCachePtr sideCache = volumeCache->getSideBasisCache(sideIndex); BasisPtr basis = trialSpace->getBasis(trialID, sideIndex); int basisCardinality = basis->getCardinality(); for (int basisOrdinal = 0; basisOrdinal<basisCardinality; basisOrdinal++) { FieldContainer<double> basisCoefficients(basisCardinality); basisCoefficients(basisOrdinal) = 1.0; soln->setSolnCoeffsForCellID(basisCoefficients, cellID, trialID, sideIndex); VarPtr v = Var::varForTrialID(trialID, spectralConfusionMesh->bilinearForm()); FunctionPtr solnFxn = Function::solution(v, soln, false); FunctionPtr basisSumFxn = Teuchos::rcp( new BasisSumFunction(basis, basisCoefficients, Teuchos::rcp((BasisCache*)NULL), OP_VALUE, boundaryValued) ); if (!boundaryValued) { double l2diff = (solnFxn - basisSumFxn)->l2norm(spectralConfusionMesh); // cout << "l2diff = " << l2diff << endl; if (l2diff > tol) { success = false; cout << "testBasisSumFunction: l2diff of " << l2diff << " exceeds tol of " << tol << endl; cout << "l2norm of basisSumFxn: " << basisSumFxn->l2norm(spectralConfusionMesh) << endl; cout << "l2norm of solnFxn: " << solnFxn->l2norm(spectralConfusionMesh) << endl; } l2diff = (solnFxn->dx() - basisSumFxn->dx())->l2norm(spectralConfusionMesh); // cout << "l2diff = " << l2diff << endl; if (l2diff > tol) { success = false; cout << "testBasisSumFunction: l2diff of dx() " << l2diff << " exceeds tol of " << tol << endl; cout << "l2norm of basisSumFxn->dx(): " << basisSumFxn->dx()->l2norm(spectralConfusionMesh) << endl; cout << "l2norm of solnFxn->dx(): " << solnFxn->dx()->l2norm(spectralConfusionMesh) << endl; } // test that the restriction to a side works int numSides = volumeCache->cellTopology()->getSideCount(); for (int i=0; i<numSides; i++) { BasisCachePtr mySideCache = volumeCache->getSideBasisCache(i); if (! solnFxn->equals(basisSumFxn, mySideCache, tol)) { success = false; cout << "testBasisSumFunction: on side 0, l2diff of " << l2diff << " exceeds tol of " << tol << endl; reportFunctionValueDifferences(solnFxn, basisSumFxn, mySideCache, tol); } if (! solnFxn->grad(spaceDim)->equals(basisSumFxn->grad(spaceDim), mySideCache, tol)) { success = false; cout << "testBasisSumFunction: on side 0, l2diff of dx() " << l2diff << " exceeds tol of " << tol << endl; reportFunctionValueDifferences(solnFxn->grad(spaceDim), basisSumFxn->grad(spaceDim), mySideCache, tol); } } } else { FieldContainer<double> cellIntegral(1); // compute l2 diff of integral along the one side where we can legitimately assert equality: FunctionPtr diffFxn = solnFxn - basisSumFxn; (diffFxn*diffFxn)->integrate(cellIntegral, sideCache); double l2diff = sqrt(cellIntegral(0)); if (l2diff > tol) { success = false; cout << "testBasisSumFunction: on side " << sideIndex << ", l2diff of " << l2diff << " exceeds tol of " << tol << endl; int numCubPoints = sideCache->getPhysicalCubaturePoints().dimension(1); FieldContainer<double> solnFxnValues(1,numCubPoints); FieldContainer<double> basisFxnValues(1,numCubPoints); solnFxn->values(solnFxnValues, sideCache); basisSumFxn->values(basisFxnValues, sideCache); cout << "solnFxnValues:\n" << solnFxnValues; cout << "basisFxnValues:\n" << basisFxnValues; } else { // cout << "testBasisSumFunction: on side " << sideIndex << ", l2diff of " << l2diff << " is within tol of " << tol << endl; } } } } } return success; }
void Projector::projectFunctionOntoBasis(FieldContainer<double> &basisCoefficients, FunctionPtr fxn, BasisPtr basis, BasisCachePtr basisCache, IPPtr ip, VarPtr v, set<int> fieldIndicesToSkip) { CellTopoPtr cellTopo = basis->domainTopology(); DofOrderingPtr dofOrderPtr = Teuchos::rcp(new DofOrdering()); if (! fxn.get()) { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "fxn cannot be null!"); } int cardinality = basis->getCardinality(); int numCells = basisCache->getPhysicalCubaturePoints().dimension(0); int numDofs = cardinality - fieldIndicesToSkip.size(); if (numDofs==0) { // we're skipping all the fields, so just initialize basisCoefficients to 0 and return basisCoefficients.resize(numCells,cardinality); basisCoefficients.initialize(0); return; } FieldContainer<double> gramMatrix(numCells,cardinality,cardinality); FieldContainer<double> ipVector(numCells,cardinality); // fake a DofOrdering DofOrderingPtr dofOrdering = Teuchos::rcp( new DofOrdering ); if (! basisCache->isSideCache()) { dofOrdering->addEntry(v->ID(), basis, v->rank()); } else { dofOrdering->addEntry(v->ID(), basis, v->rank(), basisCache->getSideIndex()); } ip->computeInnerProductMatrix(gramMatrix, dofOrdering, basisCache); ip->computeInnerProductVector(ipVector, v, fxn, dofOrdering, basisCache); // cout << "physical points for projection:\n" << basisCache->getPhysicalCubaturePoints(); // cout << "gramMatrix:\n" << gramMatrix; // cout << "ipVector:\n" << ipVector; map<int,int> oldToNewIndices; if (fieldIndicesToSkip.size() > 0) { // the code to do with fieldIndicesToSkip might not be terribly efficient... // (but it's not likely to be called too frequently) int i_indices_skipped = 0; for (int i=0; i<cardinality; i++) { int new_index; if (fieldIndicesToSkip.find(i) != fieldIndicesToSkip.end()) { i_indices_skipped++; new_index = -1; } else { new_index = i - i_indices_skipped; } oldToNewIndices[i] = new_index; } FieldContainer<double> gramMatrixFiltered(numCells,numDofs,numDofs); FieldContainer<double> ipVectorFiltered(numCells,numDofs); // now filter out the values that we're to skip for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int i=0; i<cardinality; i++) { int i_filtered = oldToNewIndices[i]; if (i_filtered == -1) { continue; } ipVectorFiltered(cellIndex,i_filtered) = ipVector(cellIndex,i); for (int j=0; j<cardinality; j++) { int j_filtered = oldToNewIndices[j]; if (j_filtered == -1) { continue; } gramMatrixFiltered(cellIndex,i_filtered,j_filtered) = gramMatrix(cellIndex,i,j); } } } // cout << "gramMatrixFiltered:\n" << gramMatrixFiltered; // cout << "ipVectorFiltered:\n" << ipVectorFiltered; gramMatrix = gramMatrixFiltered; ipVector = ipVectorFiltered; } for (int cellIndex=0; cellIndex<numCells; cellIndex++){ // TODO: rewrite to take advantage of SerialDenseWrapper... Epetra_SerialDenseSolver solver; Epetra_SerialDenseMatrix A(Copy, &gramMatrix(cellIndex,0,0), gramMatrix.dimension(2), gramMatrix.dimension(2), gramMatrix.dimension(1)); // stride -- fc stores in row-major order (a.o.t. SDM) Epetra_SerialDenseVector b(Copy, &ipVector(cellIndex,0), ipVector.dimension(1)); Epetra_SerialDenseVector x(gramMatrix.dimension(1)); solver.SetMatrix(A); int info = solver.SetVectors(x,b); if (info!=0){ cout << "projectFunctionOntoBasis: failed to SetVectors with error " << info << endl; } bool equilibrated = false; if (solver.ShouldEquilibrate()){ solver.EquilibrateMatrix(); solver.EquilibrateRHS(); equilibrated = true; } info = solver.Solve(); if (info!=0){ cout << "projectFunctionOntoBasis: failed to solve with error " << info << endl; } if (equilibrated) { int successLocal = solver.UnequilibrateLHS(); if (successLocal != 0) { cout << "projection: unequilibration FAILED with error: " << successLocal << endl; } } basisCoefficients.resize(numCells,cardinality); for (int i=0;i<cardinality;i++) { if (fieldIndicesToSkip.size()==0) { basisCoefficients(cellIndex,i) = x(i); } else { int i_filtered = oldToNewIndices[i]; if (i_filtered==-1) { basisCoefficients(cellIndex,i) = 0.0; } else { basisCoefficients(cellIndex,i) = x(i_filtered); } } } } }
bool ParametricCurveTests::testTransfiniteInterpolant() { bool success = true; // to begin, just let's do a simple quad mesh double width=4, height=3; double x0 = 0, y0 = 0; double x1 = width, y1 = 0; double x2 = width, y2 = height; double x3 = 0, y3 = height; vector< ParametricCurvePtr > edges(4); edges[0] = ParametricCurve::line(x0, y0, x1, y1); edges[1] = ParametricCurve::line(x1, y1, x2, y2); edges[2] = ParametricCurve::line(x2, y2, x3, y3); edges[3] = ParametricCurve::line(x3, y3, x0, y0); ParametricSurfacePtr transfiniteInterpolant = ParametricSurface::transfiniteInterpolant(edges); double x0_actual, y0_actual, x2_actual, y2_actual; transfiniteInterpolant->value(0, 0, x0_actual, y0_actual); transfiniteInterpolant->value(1, 1, x2_actual, y2_actual); double tol=1e-14; if ((abs(x0_actual-x0) > tol) || (abs(y0_actual-y0) > tol)) { success = false; cout << "transfinite interpolant doesn't interpolate (x0,y0).\n"; } if ((abs(x2_actual-x2) > tol) || (abs(y2_actual-y2) > tol)) { success = false; cout << "transfinite interpolant doesn't interpolate (x2,y2).\n"; } // the transfinite interpolant should be just (4t1, 3t2) FunctionPtr t1 = Function::xn(1); FunctionPtr t2 = Function::yn(1); FunctionPtr xPart = 4 * t1; FunctionPtr yPart = 3 * t2; FunctionPtr expected_tfi = Function::vectorize(xPart, yPart); int cubatureDegree = 4; BasisCachePtr parametricCache = BasisCache::parametricQuadCache(cubatureDegree); // a couple quick sanity checks: if (! expected_tfi->equals(expected_tfi, parametricCache)) { success = false; cout << "ERROR in Function::equals(): vector Function does not equal itself.\n"; } if (! transfiniteInterpolant->equals(transfiniteInterpolant, parametricCache)) { success = false; cout << "Weird error: transfiniteInterpolant does not equal itself.\n"; } // check that the transfiniteInterpolant's value() method matches values() { int numCells = 1; int numPoints = parametricCache->getRefCellPoints().dimension(0); int spaceDim = 2; FieldContainer<double> values(numCells,numPoints,spaceDim); transfiniteInterpolant->values(values, parametricCache); int cellIndex = 0; for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double t1 = parametricCache->getPhysicalCubaturePoints()(cellIndex,ptIndex,0); double t2 = parametricCache->getPhysicalCubaturePoints()(cellIndex,ptIndex,1); double x, y; transfiniteInterpolant->value(t1, t2, x, y); double x_expected = values(cellIndex,ptIndex,0); double y_expected = values(cellIndex,ptIndex,1); if (abs(x-x_expected) > tol) { cout << "transfinite interpolant value() does not match values()\n"; success = false; } if (abs(y-y_expected) > tol) { cout << "transfinite interpolant value() does not match values()\n"; success = false; } } } if (! expected_tfi->equals(transfiniteInterpolant, parametricCache, tol)) { cout << "transfinite interpolant doesn't match expected.\n"; success = false; int numCells = 1; int numPoints = parametricCache->getRefCellPoints().dimension(0); int spaceDim = 2; FieldContainer<double> values(numCells,numPoints,spaceDim); FieldContainer<double> expected_values(numCells,numPoints,spaceDim); expected_tfi->values(expected_values, parametricCache); transfiniteInterpolant->values(values, parametricCache); reportFunctionValueDifferences(parametricCache->getPhysicalCubaturePoints(), expected_values, values, tol); } // derivatives FunctionPtr xPart_dt1 = Function::constant(4); FunctionPtr yPart_dt1 = Function::constant(0); FunctionPtr expected_tfi_dt1 = Function::vectorize(xPart_dt1, yPart_dt1); if (! expected_tfi_dt1->equals(transfiniteInterpolant->dt1(), parametricCache, tol)) { cout << "d/dt1 of transfinite interpolant doesn't match expected.\n"; success = false; int numCells = 1; int numPoints = parametricCache->getRefCellPoints().dimension(0); int spaceDim = 2; FieldContainer<double> values(numCells,numPoints,spaceDim); FieldContainer<double> expected_values(numCells,numPoints,spaceDim); expected_tfi_dt1->values(expected_values, parametricCache); transfiniteInterpolant->dt1()->values(values, parametricCache); reportFunctionValueDifferences(parametricCache->getPhysicalCubaturePoints(), expected_values, values, tol); } FunctionPtr xPart_dt2 = Function::constant(0); FunctionPtr yPart_dt2 = Function::constant(3); FunctionPtr expected_tfi_dt2 = Function::vectorize(xPart_dt2, yPart_dt2); if (! expected_tfi_dt2->equals(transfiniteInterpolant->dt2(), parametricCache, tol)) { cout << "d/dt2 of transfinite interpolant doesn't match expected.\n"; success = false; int numCells = 1; int numPoints = parametricCache->getRefCellPoints().dimension(0); int spaceDim = 2; FieldContainer<double> values(numCells,numPoints,spaceDim); FieldContainer<double> expected_values(numCells,numPoints,spaceDim); expected_tfi_dt2->values(expected_values, parametricCache); transfiniteInterpolant->dt2()->values(values, parametricCache); reportFunctionValueDifferences(parametricCache->getPhysicalCubaturePoints(), expected_values, values, tol); } BasisCachePtr physicalBasisCache = BasisCache::quadBasisCache(width, height, cubatureDegree); FunctionPtr one = Function::constant(1); FunctionPtr expected_tfi_dx = Function::vectorize(one, Function::zero()); FunctionPtr expected_tfi_dy = Function::vectorize(Function::zero(), one); FunctionPtr expected_tfi_grad = Function::vectorize(expected_tfi_dx, expected_tfi_dy); if (! expected_tfi_grad->equals(transfiniteInterpolant->grad(), physicalBasisCache, tol)) { cout << "grad of transfinite interpolant doesn't match expected.\n"; success = false; int numCells = 1; int numPoints = physicalBasisCache->getRefCellPoints().dimension(0); int spaceDim = 2; FieldContainer<double> values(numCells,numPoints,spaceDim,spaceDim); FieldContainer<double> expected_values(numCells,numPoints,spaceDim,spaceDim); expected_tfi_grad->values(expected_values, physicalBasisCache); transfiniteInterpolant->grad()->values(values, physicalBasisCache); reportFunctionValueDifferences(physicalBasisCache->getPhysicalCubaturePoints(), expected_values, values, tol); } return success; }
bool MeshTestUtility::neighborBasesAgreeOnSides(Teuchos::RCP<Mesh> mesh, Epetra_MultiVector &globalSolutionCoefficients) { bool success = true; MeshTopologyViewPtr meshTopo = mesh->getTopology(); int spaceDim = meshTopo->getDimension(); set<IndexType> activeCellIndices = meshTopo->getActiveCellIndices(); for (set<IndexType>::iterator cellIt=activeCellIndices.begin(); cellIt != activeCellIndices.end(); cellIt++) { IndexType cellIndex = *cellIt; CellPtr cell = meshTopo->getCell(cellIndex); BasisCachePtr fineCellBasisCache = BasisCache::basisCacheForCell(mesh, cellIndex); ElementTypePtr fineElemType = mesh->getElementType(cellIndex); DofOrderingPtr fineElemTrialOrder = fineElemType->trialOrderPtr; FieldContainer<double> fineSolutionCoefficients(fineElemTrialOrder->totalDofs()); mesh->globalDofAssignment()->interpretGlobalCoefficients(cellIndex, fineSolutionCoefficients, globalSolutionCoefficients); // if ((cellIndex==0) || (cellIndex==2)) { // cout << "MeshTestUtility: local coefficients for cell " << cellIndex << ":\n" << fineSolutionCoefficients; // } unsigned sideCount = cell->getSideCount(); for (unsigned sideOrdinal=0; sideOrdinal<sideCount; sideOrdinal++) { FieldContainer<double> fineSideRefPoints, fineCellRefPoints, coarseSideRefPoints, coarseCellRefPoints; bool hasCoarserNeighbor = determineRefTestPointsForNeighbors(meshTopo, cell, sideOrdinal, fineSideRefPoints, fineCellRefPoints, coarseSideRefPoints, coarseCellRefPoints); if (!hasCoarserNeighbor) continue; pair<GlobalIndexType, unsigned> neighborInfo = cell->getNeighborInfo(sideOrdinal, meshTopo); CellPtr neighborCell = meshTopo->getCell(neighborInfo.first); unsigned numTestPoints = coarseCellRefPoints.dimension(0); // cout << "testing neighbor agreement between cell " << cellIndex << " and " << neighborCell->cellIndex() << endl; // if we get here, the cell has a neighbor on this side, and is at least as fine as that neighbor. BasisCachePtr fineSideBasisCache = fineCellBasisCache->getSideBasisCache(sideOrdinal); fineCellBasisCache->setRefCellPoints(fineCellRefPoints); BasisCachePtr coarseCellBasisCache = BasisCache::basisCacheForCell(mesh, neighborInfo.first); BasisCachePtr coarseSideBasisCache = coarseCellBasisCache->getSideBasisCache(neighborInfo.second); coarseCellBasisCache->setRefCellPoints(coarseCellRefPoints); bool hasSidePoints = (fineSideRefPoints.size() > 0); if (hasSidePoints) { fineSideBasisCache->setRefCellPoints(fineSideRefPoints); coarseSideBasisCache->setRefCellPoints(coarseSideRefPoints); } // sanity check: do physical points match? FieldContainer<double> fineCellPhysicalCubaturePoints = fineCellBasisCache->getPhysicalCubaturePoints(); FieldContainer<double> coarseCellPhysicalCubaturePoints = coarseCellBasisCache->getPhysicalCubaturePoints(); double tol = 1e-14; double maxDiff = 0; if (! fcsAgree(coarseCellPhysicalCubaturePoints, fineCellPhysicalCubaturePoints, tol, maxDiff) ) { cout << "ERROR: MeshTestUtility::neighborBasesAgreeOnSides internal error: fine and coarse cell cubature points do not agree.\n"; success = false; continue; } if (hasSidePoints) { FieldContainer<double> fineSidePhysicalCubaturePoints = fineSideBasisCache->getPhysicalCubaturePoints(); FieldContainer<double> coarseSidePhysicalCubaturePoints = coarseSideBasisCache->getPhysicalCubaturePoints(); double tol = 1e-14; double maxDiff = 0; if (! fcsAgree(fineSidePhysicalCubaturePoints, fineCellPhysicalCubaturePoints, tol, maxDiff) ) { cout << "ERROR: MeshTestUtility::neighborBasesAgreeOnSides internal error: fine side and cell cubature points do not agree.\n"; success = false; continue; } if (! fcsAgree(coarseSidePhysicalCubaturePoints, coarseCellPhysicalCubaturePoints, tol, maxDiff) ) { cout << "ERROR: MeshTestUtility::neighborBasesAgreeOnSides internal error: coarse side and cell cubature points do not agree.\n"; success = false; continue; } if (! fcsAgree(coarseSidePhysicalCubaturePoints, fineSidePhysicalCubaturePoints, tol, maxDiff) ) { cout << "ERROR: MeshTestUtility::neighborBasesAgreeOnSides internal error: fine and coarse side cubature points do not agree.\n"; success = false; continue; } } ElementTypePtr coarseElementType = mesh->getElementType(neighborInfo.first); DofOrderingPtr coarseElemTrialOrder = coarseElementType->trialOrderPtr; FieldContainer<double> coarseSolutionCoefficients(coarseElemTrialOrder->totalDofs()); mesh->globalDofAssignment()->interpretGlobalCoefficients(neighborInfo.first, coarseSolutionCoefficients, globalSolutionCoefficients); set<int> varIDs = fineElemTrialOrder->getVarIDs(); for (set<int>::iterator varIt = varIDs.begin(); varIt != varIDs.end(); varIt++) { int varID = *varIt; // cout << "MeshTestUtility: varID " << varID << ":\n"; bool isTraceVar = mesh->bilinearForm()->isFluxOrTrace(varID); BasisPtr fineBasis, coarseBasis; BasisCachePtr fineCache, coarseCache; if (isTraceVar) { if (! hasSidePoints) continue; // then nothing to do for traces fineBasis = fineElemTrialOrder->getBasis(varID, sideOrdinal); coarseBasis = coarseElemTrialOrder->getBasis(varID, neighborInfo.second); fineCache = fineSideBasisCache; coarseCache = coarseSideBasisCache; } else { fineBasis = fineElemTrialOrder->getBasis(varID); coarseBasis = coarseElemTrialOrder->getBasis(varID); fineCache = fineCellBasisCache; coarseCache = coarseCellBasisCache; Camellia::EFunctionSpace fs = fineBasis->functionSpace(); if ((fs == Camellia::FUNCTION_SPACE_HVOL) || (fs == Camellia::FUNCTION_SPACE_VECTOR_HVOL) || (fs == Camellia::FUNCTION_SPACE_TENSOR_HVOL)) { // volume L^2 basis: no continuities expected... continue; } } FieldContainer<double> localValuesFine = *fineCache->getTransformedValues(fineBasis, OP_VALUE); FieldContainer<double> localValuesCoarse = *coarseCache->getTransformedValues(coarseBasis, OP_VALUE); bool scalarValued = (localValuesFine.rank() == 3); // the following used if vector or tensor-valued: Teuchos::Array<int> valueDim; unsigned componentsPerValue = 1; FieldContainer<double> valueContainer; // just used for enumeration computation... if (!scalarValued) { localValuesFine.dimensions(valueDim); // clear first three: valueDim.erase(valueDim.begin()); valueDim.erase(valueDim.begin()); valueDim.erase(valueDim.begin()); valueContainer.resize(valueDim); componentsPerValue = valueContainer.size(); } // if (localValuesFine.rank() != 3) { // cout << "WARNING: MeshTestUtility::neighborBasesAgreeOnSides() only supports scalar-valued bases right now. Skipping check for varID " << varID << endl; // continue; // } FieldContainer<double> localPointValuesFine(fineElemTrialOrder->totalDofs()); FieldContainer<double> localPointValuesCoarse(coarseElemTrialOrder->totalDofs()); for (int valueComponentOrdinal=0; valueComponentOrdinal<componentsPerValue; valueComponentOrdinal++) { Teuchos::Array<int> valueMultiIndex(valueContainer.rank()); if (!scalarValued) valueContainer.getMultiIndex(valueMultiIndex, valueComponentOrdinal); Teuchos::Array<int> localValuesMultiIndex(localValuesFine.rank()); for (int r=0; r<valueMultiIndex.size(); r++) { localValuesMultiIndex[r+3] = valueMultiIndex[r]; } for (int ptOrdinal=0; ptOrdinal<numTestPoints; ptOrdinal++) { localPointValuesCoarse.initialize(0); localPointValuesFine.initialize(0); localValuesMultiIndex[2] = ptOrdinal; double fineSolutionValue = 0, coarseSolutionValue = 0; for (int basisOrdinal=0; basisOrdinal < fineBasis->getCardinality(); basisOrdinal++) { int fineDofIndex; if (isTraceVar) fineDofIndex = fineElemTrialOrder->getDofIndex(varID, basisOrdinal, sideOrdinal); else fineDofIndex = fineElemTrialOrder->getDofIndex(varID, basisOrdinal); if (scalarValued) { localPointValuesFine(fineDofIndex) = localValuesFine(0,basisOrdinal,ptOrdinal); } else { localValuesMultiIndex[1] = basisOrdinal; localPointValuesFine(fineDofIndex) = localValuesFine.getValue(localValuesMultiIndex); } fineSolutionValue += fineSolutionCoefficients(fineDofIndex) * localPointValuesFine(fineDofIndex); } for (int basisOrdinal=0; basisOrdinal < coarseBasis->getCardinality(); basisOrdinal++) { int coarseDofIndex; if (isTraceVar) coarseDofIndex = coarseElemTrialOrder->getDofIndex(varID, basisOrdinal, neighborInfo.second); else coarseDofIndex = coarseElemTrialOrder->getDofIndex(varID, basisOrdinal); if (scalarValued) { localPointValuesCoarse(coarseDofIndex) = localValuesCoarse(0,basisOrdinal,ptOrdinal); } else { localValuesMultiIndex[1] = basisOrdinal; localPointValuesCoarse(coarseDofIndex) = localValuesCoarse.getValue(localValuesMultiIndex); } coarseSolutionValue += coarseSolutionCoefficients(coarseDofIndex) * localPointValuesCoarse(coarseDofIndex); } if (abs(coarseSolutionValue - fineSolutionValue) > 1e-13) { success = false; cout << "coarseSolutionValue (" << coarseSolutionValue << ") and fineSolutionValue (" << fineSolutionValue << ") differ by " << abs(coarseSolutionValue - fineSolutionValue); cout << " at point " << ptOrdinal << " for varID " << varID << ". "; cout << "This may be an indication that something is amiss with the global-to-local map.\n"; } else { // // DEBUGGING: // cout << "solution value at point ("; // for (int d=0; d<spaceDim-1; d++) { // cout << fineSidePhysicalCubaturePoints(0,ptOrdinal,d) << ", "; // } // cout << fineSidePhysicalCubaturePoints(0,ptOrdinal,spaceDim-1) << "): "; // cout << coarseSolutionValue << endl; } FieldContainer<double> globalValuesFromFine, globalValuesFromCoarse; FieldContainer<GlobalIndexType> globalDofIndicesFromFine, globalDofIndicesFromCoarse; mesh->globalDofAssignment()->interpretLocalData(cellIndex, localPointValuesFine, globalValuesFromFine, globalDofIndicesFromFine); mesh->globalDofAssignment()->interpretLocalData(neighborInfo.first, localPointValuesCoarse, globalValuesFromCoarse, globalDofIndicesFromCoarse); std::map<GlobalIndexType, double> fineValuesMap; std::map<GlobalIndexType, double> coarseValuesMap; for (int i=0; i<globalDofIndicesFromCoarse.size(); i++) { GlobalIndexType globalDofIndex = globalDofIndicesFromCoarse[i]; coarseValuesMap[globalDofIndex] = globalValuesFromCoarse[i]; } double maxDiff = 0; for (int i=0; i<globalDofIndicesFromFine.size(); i++) { GlobalIndexType globalDofIndex = globalDofIndicesFromFine[i]; fineValuesMap[globalDofIndex] = globalValuesFromFine[i]; double diff = abs( fineValuesMap[globalDofIndex] - coarseValuesMap[globalDofIndex]); maxDiff = std::max(diff, maxDiff); if (diff > tol) { success = false; cout << "interpreted fine and coarse disagree at point ("; for (int d=0; d<spaceDim; d++) { cout << fineCellPhysicalCubaturePoints(0,ptOrdinal,d); if (d==spaceDim-1) cout << ").\n"; else cout << ", "; } } } if (maxDiff > tol) { cout << "maxDiff: " << maxDiff << endl; cout << "globalValuesFromFine:\n" << globalValuesFromFine; cout << "globalValuesFromCoarse:\n" << globalValuesFromCoarse; cout << "globalDofIndicesFromFine:\n" << globalDofIndicesFromFine; cout << "globalDofIndicesFromCoarse:\n" << globalDofIndicesFromCoarse; continue; // only worth testing further if we passed the above } } } } } } // cout << "Completed neighborBasesAgreeOnSides.\n"; return success; }
// tests Riesz inversion by integration by parts bool LinearTermTests::testRieszInversion() { bool success = true; //////////////////// DECLARE VARIABLES /////////////////////// // define test variables VarFactoryPtr varFactory = VarFactory::varFactory(); VarPtr tau = varFactory->testVar("\\tau", HDIV); VarPtr v = varFactory->testVar("v", HGRAD); // define trial variables VarPtr uhat = varFactory->traceVar("\\widehat{u}"); VarPtr beta_n_u_minus_sigma_n = varFactory->fluxVar("\\widehat{\\beta \\cdot n u - \\sigma_{n}}"); VarPtr u = varFactory->fieldVar("u"); VarPtr sigma1 = varFactory->fieldVar("\\sigma_1"); VarPtr sigma2 = varFactory->fieldVar("\\sigma_2"); vector<double> beta; beta.push_back(1.0); beta.push_back(0.0); double eps = .01; //////////////////// DEFINE BILINEAR FORM /////////////////////// BFPtr confusionBF = Teuchos::rcp( new BF(varFactory) ); // tau terms: confusionBF->addTerm(sigma1 / eps, tau->x()); confusionBF->addTerm(sigma2 / eps, tau->y()); confusionBF->addTerm(u, tau->div()); confusionBF->addTerm(uhat, -tau->dot_normal()); // v terms: confusionBF->addTerm( sigma1, v->dx() ); confusionBF->addTerm( sigma2, v->dy() ); confusionBF->addTerm( -u, beta * v->grad() ); confusionBF->addTerm( beta_n_u_minus_sigma_n, v); //////////////////// BUILD MESH /////////////////////// // define nodes for mesh int H1Order = 1; int pToAdd = 1; FieldContainer<double> quadPoints(4,2); quadPoints(0,0) = 0.0; // x1 quadPoints(0,1) = 0.0; // y1 quadPoints(1,0) = 1.0; quadPoints(1,1) = 0.0; quadPoints(2,0) = 1.0; quadPoints(2,1) = 1.0; quadPoints(3,0) = 0.0; quadPoints(3,1) = 1.0; int nCells = 1; int horizontalCells = nCells, verticalCells = nCells; // create a pointer to a new mesh: Teuchos::RCP<Mesh> myMesh = MeshFactory::buildQuadMesh(quadPoints, horizontalCells, verticalCells, confusionBF, H1Order, H1Order+pToAdd); ElementTypePtr elemType = myMesh->getElement(0)->elementType(); BasisCachePtr basisCache = Teuchos::rcp(new BasisCache(elemType, myMesh)); vector<GlobalIndexType> cellIDs; vector<ElementPtr> elems = myMesh->activeElements(); vector<ElementPtr>::iterator elemIt; for (elemIt=elems.begin(); elemIt!=elems.end(); elemIt++) { int cellID = (*elemIt)->cellID(); cellIDs.push_back(cellID); } bool createSideCacheToo = true; basisCache->setPhysicalCellNodes(myMesh->physicalCellNodesGlobal(elemType), cellIDs, createSideCacheToo); LinearTermPtr integrand = Teuchos::rcp(new LinearTerm);// residual LinearTermPtr integrandIBP = Teuchos::rcp(new LinearTerm);// residual vector<double> e1(2); // (1,0) vector<double> e2(2); // (0,1) e1[0] = 1; e2[1] = 1; FunctionPtr n = Function::normal(); FunctionPtr X = Function::xn(1); FunctionPtr Y = Function::yn(1); FunctionPtr testFxn1 = X; FunctionPtr testFxn2 = Y; FunctionPtr divTestFxn = testFxn1->dx() + testFxn2->dy(); FunctionPtr vectorTest = testFxn1*e1 + testFxn2*e2; integrand->addTerm(divTestFxn*v); integrandIBP->addTerm(vectorTest*n*v - vectorTest*v->grad()); // boundary term IPPtr sobolevIP = Teuchos::rcp(new IP); sobolevIP->addTerm(v); sobolevIP->addTerm(tau); Teuchos::RCP<RieszRep> riesz = Teuchos::rcp(new RieszRep(myMesh, sobolevIP, integrand)); // riesz->setPrintOption(true); riesz->computeRieszRep(); Teuchos::RCP<RieszRep> rieszIBP = Teuchos::rcp(new RieszRep(myMesh, sobolevIP, integrandIBP)); riesz->setFunctional(integrandIBP); // rieszIBP->setPrintOption(true); rieszIBP->computeRieszRep(); FunctionPtr rieszOrigFxn = RieszRep::repFunction(v,riesz); FunctionPtr rieszIBPFxn = RieszRep::repFunction(v,rieszIBP); int numCells = basisCache->getPhysicalCubaturePoints().dimension(0); int numPts = basisCache->getPhysicalCubaturePoints().dimension(1); FieldContainer<double> valOriginal( numCells, numPts); FieldContainer<double> valIBP( numCells, numPts); rieszOrigFxn->values(valOriginal,basisCache); rieszIBPFxn->values(valIBP,basisCache); double maxDiff; double tol = 1e-14; success = TestSuite::fcsAgree(valOriginal,valIBP,tol,maxDiff); if (success==false) { cout << "Failed TestRieszInversion with maxDiff = " << maxDiff << endl; } return success; }
bool FunctionTests::testJacobianOrdering() { bool success = true; FunctionPtr y = Function::yn(1); FunctionPtr f = Function::vectorize(y, Function::zero()); // test 1: Jacobian ordering is f_i,j int spaceDim = 2; int cellID = 0; BasisCachePtr basisCache = BasisCache::basisCacheForCell(_spectralConfusionMesh, cellID); FieldContainer<double> physicalPoints = basisCache->getPhysicalCubaturePoints(); int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); FieldContainer<double> expectedValues(numCells, numPoints, spaceDim, spaceDim); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { expectedValues(cellIndex,ptIndex,0,0) = 0; expectedValues(cellIndex,ptIndex,0,1) = 1; expectedValues(cellIndex,ptIndex,1,0) = 0; expectedValues(cellIndex,ptIndex,1,1) = 0; } } FieldContainer<double> values(numCells, numPoints, spaceDim, spaceDim); f->grad(spaceDim)->values(values, basisCache); double maxDiff = 0; double tol = 1e-14; if (! fcsAgree(expectedValues, values, tol, maxDiff)) { cout << "expectedValues does not match values in testJacobianOrdering().\n"; reportFunctionValueDifferences(physicalPoints, expectedValues, values, tol); success = false; } // test 2: ordering of VectorizedBasis agrees // (actually implemented where it belongs, in Vectorized_BasisTestSuite) // test 3: ordering of CellTools::getJacobian FieldContainer<double> nodes(1,4,2); nodes(0,0,0) = 1; nodes(0,0,1) = -2; nodes(0,1,0) = 1; nodes(0,1,1) = 2; nodes(0,2,0) = -1; nodes(0,2,1) = 2; nodes(0,3,0) = -1; nodes(0,3,1) = -2; shards::CellTopology quad_4(shards::getCellTopologyData<shards::Quadrilateral<4> >() ); int cubDegree = 4; BasisCachePtr rotatedCache = Teuchos::rcp( new BasisCache(nodes, quad_4, cubDegree) ); physicalPoints = rotatedCache->getPhysicalCubaturePoints(); numCells = physicalPoints.dimension(0); numPoints = physicalPoints.dimension(1); FieldContainer<double> expectedJacobian(numCells,numPoints,spaceDim,spaceDim); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { expectedJacobian(cellIndex,ptIndex,0,0) = 0; expectedJacobian(cellIndex,ptIndex,0,1) = -1; expectedJacobian(cellIndex,ptIndex,1,0) = 2; expectedJacobian(cellIndex,ptIndex,1,1) = 0; } } FieldContainer<double> jacobianValues = rotatedCache->getJacobian(); maxDiff = 0; if (! fcsAgree(expectedJacobian, jacobianValues, tol, maxDiff)) { cout << "expectedJacobian does not match jacobianValues in testJacobianOrdering().\n"; reportFunctionValueDifferences(physicalPoints, expectedJacobian, jacobianValues, tol); success = false; } return success; }