void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); MeshPtr mesh = basisCache->mesh(); vector<int> cellIDs = basisCache->cellIDs(); double tol=1e-14; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { double h = 1.0; if (_spatialCoord==0) { h = mesh->getCellXSize(cellIDs[cellIndex]); } else if (_spatialCoord==1) { h = mesh->getCellYSize(cellIDs[cellIndex]); } for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { values(cellIndex,ptIndex) = sqrt(h); } } }
void BilinearFormUtility::weightCellBasisValues(FieldContainer<double> &basisValues, const FieldContainer<double> &weights, int offset) { // weights are (numCells, offset+numFields) // basisValues are (numCells, numFields, ...) int numCells = basisValues.dimension(0); int numFields = basisValues.dimension(1); Teuchos::Array<int> dimensions; basisValues.dimensions(dimensions); int numAffectedValues = 1; for (int dimIndex=2; dimIndex<dimensions.size(); dimIndex++) { numAffectedValues *= dimensions[dimIndex]; } Teuchos::Array<int> index(dimensions.size(),0); for (int cellIndex=0; cellIndex < numCells; cellIndex++) { index[0] = cellIndex; for (int fieldIndex=0; fieldIndex < numFields; fieldIndex++) { index[1] = fieldIndex; int enumIndex = basisValues.getEnumeration(index); for (int valIndex=enumIndex; valIndex < numAffectedValues + enumIndex; valIndex++) { basisValues[valIndex] *= weights(cellIndex,fieldIndex+offset); } } } }
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; } } }
// time slice utilities assume a tensor product cell in the time dimension // and further assume that if there are nodeCount vertices in the spatial element, then the nodes in space-time // will be ordered such that nodes(i) and nodes(i+nodeCount) correspond to each other vector< vector<double> > timeSliceForCell(FieldContainer<double> &physicalCellNodes, double t) { int nodeCount = physicalCellNodes.dimension(1) / 2; int spaceDim = physicalCellNodes.dimension(2) - 1; // # of true spatial dimensions int d_time = spaceDim; // the index for the time dimension // FieldContainer<double> slice(1,nodeCount,spaceDim); vector< vector<double> > sliceVertices; for (int i=0; i<nodeCount; i++) { double t0 = physicalCellNodes(0,i,d_time); double t1 = physicalCellNodes(0,i+nodeCount,d_time); double dt = t1 - t0; // TODO: worry about curvilinear elements here--for now, we assume straight edges double w0 = 1.0 - (t - t0) / dt; double w1 = 1.0 - (t1 - t) / dt; vector<double> vertex(spaceDim); for (int d=0; d<spaceDim; d++) { double x0 = physicalCellNodes(0,i,d); double x1 = physicalCellNodes(0,i+nodeCount,d); vertex[d] = x0 * w0 + x1 * w1; } sliceVertices.push_back(vertex); } return sliceVertices; }
// This is the rhs for (div tau,w) = (f,w), // which makes f the negative Laplacian of scalar solution void rhsFunc( FieldContainer<double> &result, const FieldContainer<double> &points, int xd, int yd , int zd) { for (int cell=0;cell<result.dimension(0);cell++) { for (int pt=0;pt<result.dimension(1);pt++) { result(cell,pt) = 0.0; if (xd >=2) { result(cell,pt) += xd*(xd-1)*pow(points(cell,pt,0),xd-2)*pow(points(cell,pt,1),yd) *pow(points(cell,pt,2),zd); } if (yd >=2) { result(cell,pt) += yd*(yd-1)*pow(points(cell,pt,0),xd)*pow(points(cell,pt,1),yd-2) *pow(points(cell,pt,2),zd); } if (zd>=2) { result(cell,pt) += zd*(zd-1)*pow(points(cell,pt,0),xd)*pow(points(cell,pt,1),yd) *pow(points(cell,pt,2),zd-2); } } } }
/// exact solution void u_exact(FieldContainer<double> & result, const FieldContainer<double> & points, int degree) { for (int cell=0; cell<result.dimension(0); cell++) { for (int pt=0; pt<result.dimension(1); pt++) { result(cell,pt) = pow(points(pt,0), degree); } } }
void EricksonManufacturedSolution::rhs(int testVarID, const FieldContainer<double> &physicalPoints, FieldContainer<double> &values) { int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); int spaceDim = physicalPoints.dimension(2); if (testVarID == ConfusionBilinearForm::V) { // f = - eps * (d^2/dx^2 + d^2/dy^2) ( u ) + beta_x du/dx + beta_y du/dy values.resize(numCells,numPoints); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double x = physicalPoints(cellIndex,ptIndex,0); double y = physicalPoints(cellIndex,ptIndex,1); F2_2 sx(2,0,x), sy(2,1,y), su; // s for Sacado sx.val() = F2(2,0,x); sy.val() = F2(2,1,y); su = u(sx,sy); /* these are values of convection-diffusion values(cellIndex,ptIndex) = - _epsilon * ( su.dx(0).dx(0) + su.dx(1).dx(1) ) + _beta_x * su.dx(0).val() + _beta_y * su.dx(1).val(); */ // this RHS corresponds to only convection //values(cellIndex,ptIndex) = _beta_x * su.dx(0).val() + _beta_y * su.dx(1).val(); // exact RHS double pi = acos(0.0)*2.0; double epsSquared = _epsilon*_epsilon; // values(cellIndex,ptIndex) = exp((1.0-x)/_epsilon)*(pi*pi - 2*epsSquared)*sin(pi*y/epsSquared)/(epsSquared*_epsilon); values(cellIndex,ptIndex) = 0.0; } } } }
FCPtr BasisEvaluation::getValuesTimesNormals(constFCPtr values,const FieldContainer<double> &sideNormals) { // values should have dimensions (C,basisCardinality,P) int numCells = sideNormals.dimension(0); int numPoints = sideNormals.dimension(1); int spaceDim = sideNormals.dimension(2); int basisCardinality = values->dimension(1); if ( (numCells != values->dimension(0)) || (basisCardinality != values->dimension(1)) || (numPoints != values->dimension(2))) { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "values should have dimensions (C,basisCardinality,P)"); } Teuchos::RCP< FieldContainer<double> > result = Teuchos::rcp(new FieldContainer<double>(numCells,basisCardinality,numPoints,spaceDim)); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int basisOrdinal=0; basisOrdinal<basisCardinality; basisOrdinal++) { for (int pointIndex=0; pointIndex<numPoints; pointIndex++) { for (int dim=0; dim<spaceDim; dim++) { double n_dim = sideNormals(cellIndex,pointIndex,dim); double value = (*values)(cellIndex,basisOrdinal,pointIndex); (*result)(cellIndex,basisOrdinal,pointIndex,dim) = value * n_dim; } } } } return result; }
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); } } } }
bool BilinearFormUtility::checkForZeroRowsAndColumns(string name, FieldContainer<double> &array, bool checkRows, bool checkCols) { // for now, only support rank 3 FCs double tol = 1e-15; static int warningsIssued = 0; // max of 20 if ( array.rank() != 3) { TEUCHOS_TEST_FOR_EXCEPTION( array.rank() != 3, std::invalid_argument, "checkForZeroRowsAndColumns only supports rank-3 FieldContainers."); } int numCells = array.dimension(0); int numRows = array.dimension(1); int numCols = array.dimension(2); bool zeroRowOrColFound = false; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { if (checkRows) { for (int i=0; i<numRows; i++) { bool nonZeroFound = false; int j=0; while ((!nonZeroFound) && (j<numCols)) { if (abs(array(cellIndex,i,j)) > tol) nonZeroFound = true; j++; } if ( ! nonZeroFound ) { if (_warnAboutZeroRowsAndColumns) { warningsIssued++; cout << "warning: in matrix " << name << " for cell " << cellIndex << ", row " << i << " is all zeros." << endl; if ( (warningsIssued == 20) && _warnAboutZeroRowsAndColumns ) { cout << "20 warnings issued. Suppressing future warnings about zero rows and columns\n"; _warnAboutZeroRowsAndColumns = false; } } zeroRowOrColFound = true; } } } if (checkCols) { for (int j=0; j<numCols; j++) { bool nonZeroFound = false; int i=0; while ((!nonZeroFound) && (i<numRows)) { if (abs(array(cellIndex,i,j)) > tol) nonZeroFound = true; i++; } if ( ! nonZeroFound ) { if (_warnAboutZeroRowsAndColumns) { warningsIssued++; cout << "warning: in matrix " << name << " for cell " << cellIndex << ", column " << j << " is all zeros." << endl; if ( (warningsIssued == 20) && _warnAboutZeroRowsAndColumns ) { cout << "20 warnings issued. Suppressing future warnings about zero rows and columns\n"; _warnAboutZeroRowsAndColumns = false; } } zeroRowOrColFound = true; } } } } return !zeroRowOrColFound; // return TRUE if no zero row or col found }
/// exact solution void u_exact(FieldContainer<double> & result, const FieldContainer<double> & points, int xd, int yd, int zd) { int x = 0, y = 1, z = 2; for (int cell=0; cell<result.dimension(0); cell++) { for (int pt=0; pt<result.dimension(1); pt++) { result(cell,pt) = std::pow(points(pt,x), xd)*std::pow(points(pt,y), yd)*std::pow(points(pt,z), zd); } } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { CHECK_VALUES_RANK(values); _f->values(values,basisCache); int numCells = values.dimension(0); int numPoints = values.dimension(1); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double value = values(cellIndex,ptIndex); values(cellIndex,ptIndex) = log(value); } } }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { CHECK_VALUES_RANK(values); _f->values(values,basisCache); int numCells = values.dimension(0); int numPoints = values.dimension(1); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { double value = values(cellIndex,ptIndex); values(cellIndex,ptIndex) = pow(max(value,_minVal),_power); // WARNING: MAX OPERATOR HACK FOR NEG TEMP } } }
// computes riesz representation over a single element - map is from int (testID) to FieldContainer of values (sized cellIndex, numPoints) void RieszRep::computeRepresentationValues(FieldContainer<double> &values, int testID, IntrepidExtendedTypes::EOperatorExtended op, BasisCachePtr basisCache){ if (_repsNotComputed){ cout << "Computing riesz rep dofs" << endl; computeRieszRep(); } int spaceDim = _mesh->getTopology()->getSpaceDim(); int numCells = values.dimension(0); int numPoints = values.dimension(1); vector<GlobalIndexType> cellIDs = basisCache->cellIDs(); // all elems coming in should be of same type ElementPtr elem = _mesh->getElement(cellIDs[0]); ElementTypePtr elemTypePtr = elem->elementType(); DofOrderingPtr testOrderingPtr = elemTypePtr->testOrderPtr; CellTopoPtrLegacy cellTopoPtr = elemTypePtr->cellTopoPtr; int numTestDofsForVarID = testOrderingPtr->getBasisCardinality(testID, 0); BasisPtr testBasis = testOrderingPtr->getBasis(testID); bool testBasisIsVolumeBasis = (spaceDim == testBasis->domainTopology()->getDimension()); bool useCubPointsSideRefCell = testBasisIsVolumeBasis && basisCache->isSideCache(); Teuchos::RCP< const FieldContainer<double> > transformedBasisValues = basisCache->getTransformedValues(testBasis,op,useCubPointsSideRefCell); int rank = values.rank() - 2; // if values are shaped as (C,P), scalar... if (rank > 1) { cout << "ranks greater than 1 not presently supported...\n"; TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "ranks greater than 1 not presently supported..."); } // Camellia::print("cellIDs",cellIDs); values.initialize(0.0); for (int cellIndex = 0;cellIndex<numCells;cellIndex++){ int cellID = cellIDs[cellIndex]; for (int j = 0;j<numTestDofsForVarID;j++) { int dofIndex = testOrderingPtr->getDofIndex(testID, j); for (int i = 0;i<numPoints;i++) { if (rank==0) { double basisValue = (*transformedBasisValues)(cellIndex,j,i); values(cellIndex,i) += basisValue*_rieszRepDofsGlobal[cellID](dofIndex); } else { for (int d = 0; d<spaceDim; d++) { double basisValue = (*transformedBasisValues)(cellIndex,j,i,d); values(cellIndex,i,d) += basisValue*_rieszRepDofsGlobal[cellID](dofIndex); } } } } } // TestSuite::serializeOutput("rep values", values); }
void EricksonManufacturedSolution::getConstraints(FieldContainer<double> &physicalPoints, FieldContainer<double> &unitNormals, vector<map<int,FieldContainer<double > > > &constraintCoeffs, vector<FieldContainer<double > > &constraintValues){ int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); int spaceDim = physicalPoints.dimension(2); map<int,FieldContainer<double> > outflowConstraint; FieldContainer<double> uCoeffs(numCells,numPoints); FieldContainer<double> beta_sigmaCoeffs(numCells,numPoints); FieldContainer<double> outflowValues(numCells,numPoints); double tol = 1e-12; // default to no constraints, apply on outflow only uCoeffs.initialize(0.0); beta_sigmaCoeffs.initialize(0.0); outflowValues.initialize(0.0); Teuchos::Array<int> pointDimensions; pointDimensions.push_back(2); for (int cellIndex=0;cellIndex<numCells;cellIndex++){ for (int pointIndex=0;pointIndex<numPoints;pointIndex++){ FieldContainer<double> physicalPoint(pointDimensions, &physicalPoints(cellIndex,pointIndex,0)); FieldContainer<double> unitNormal(pointDimensions, &unitNormals(cellIndex,pointIndex,0)); double x = physicalPoints(cellIndex,pointIndex,0); double y = physicalPoints(cellIndex,pointIndex,1); double beta_n = _beta_x*unitNormals(cellIndex,pointIndex,0)+_beta_y*unitNormals(cellIndex,pointIndex,1); if ( abs(x-1.0) < tol ) { // if on outflow boundary TEUCHOS_TEST_FOR_EXCEPTION(beta_n < 0,std::invalid_argument,"Inflow condition on boundary"); // this combo isolates sigma_n //uCoeffs(cellIndex,pointIndex) = 1.0; uCoeffs(cellIndex,pointIndex) = beta_n; beta_sigmaCoeffs(cellIndex,pointIndex) = -1.0; double beta_n_u_minus_sigma_n = solutionValue(ConfusionBilinearForm::BETA_N_U_MINUS_SIGMA_HAT, physicalPoint, unitNormal); double u_hat = solutionValue(ConfusionBilinearForm::U_HAT, physicalPoint, unitNormal); outflowValues(cellIndex,pointIndex) = beta_n*u_hat - beta_n_u_minus_sigma_n; // sigma_n } } } outflowConstraint[ConfusionBilinearForm::U_HAT] = uCoeffs; outflowConstraint[ConfusionBilinearForm::BETA_N_U_MINUS_SIGMA_HAT] = beta_sigmaCoeffs; if (!_useWallBC){ constraintCoeffs.push_back(outflowConstraint); // only one constraint on outflow constraintValues.push_back(outflowValues); // only one constraint on outflow } }
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; } } }
bool cellMatches(FieldContainer<double> physicalNodes, double t) { int nodeCount = physicalNodes.dimension(1); int spaceDim = physicalNodes.dimension(2) - 1; // # of true spatial dimensions int d_time = spaceDim; // the index for the time dimension double hasVerticesBelow = false, hasVerticesAbove = false; for (int node = 0; node < nodeCount; node++) { double t_node = physicalNodes(0,node,d_time); if (t_node <= t) hasVerticesBelow = true; if (t_node >= t) hasVerticesAbove = true; } return hasVerticesAbove && hasVerticesBelow; }
void BilinearFormUtility<Scalar>::transposeFCMatrices(FieldContainer<Scalar> &fcTranspose, const FieldContainer<Scalar> &fc) { // check dimensions TEUCHOS_TEST_FOR_EXCEPTION( ( fc.dimension(0) != fcTranspose.dimension(0) ), std::invalid_argument, "fc.dimension(0) and fcTranspose.dimension(0) (numCells) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( fc.dimension(1) != fcTranspose.dimension(2) ), std::invalid_argument, "fc.dimension(1) and fcTranspose.dimension(2) (numRows) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( fc.dimension(2) != fcTranspose.dimension(1) ), std::invalid_argument, "fc.dimension(2) and fcTranspose.dimension(1) (numCols) do not match."); // transposes (C,i,j) --> (C,j,i) int numCells = fc.dimension(0); int numRows = fc.dimension(1); int numCols = fc.dimension(2); for (int cellIndex=0; cellIndex < numCells; cellIndex++) { for (int i=0; i < numRows; i++) { for (int j=0; j < numCols; j++) { fcTranspose(cellIndex,j,i) = fc(cellIndex,i,j); } } } }
void assignBlock(FieldContainer & block,FieldContainer & vertices, double val) { TEUCHOS_ASSERT(block.dimension(0)==vertices.dimension(0)); TEUCHOS_ASSERT(block.dimension(1)==vertices.dimension(1)); std::size_t cellCnt = block.dimension(0); std::size_t nodeCnt = block.dimension(1); for(std::size_t cell=0;cell<cellCnt;cell++) { for(std::size_t node=0;node<nodeCnt;node++) { block(cell,node) = val; } } }
void u_exact( FieldContainer<double> &result, const FieldContainer<double> &points, int xd, int yd, int zd) { for (int cell=0;cell<result.dimension(0);cell++){ for (int pt=0;pt<result.dimension(1);pt++) { result(cell,pt) = std::pow(points(cell,pt,0),xd)*std::pow(points(cell,pt,1),yd) *std::pow(points(cell,pt,2),zd); } } return; }
void values(FieldContainer<double> &values, BasisCachePtr basisCache) { int numCells = values.dimension(0); int numPoints = values.dimension(1); FieldContainer<double> beta_pts(numCells,numPoints); _f->values(values,basisCache); for (int i = 0;i<numCells;i++){ for (int j = 0;j<numPoints;j++){ if (values(i,j)<0){ values(i,j) = 0.0; } } } }
virtual void values(FieldContainer<double> &values, BasisCachePtr basisCache) { // not the most efficient implementation _fxn->values(values,basisCache); vector<GlobalIndexType> contextCellIDs = basisCache->cellIDs(); int cellIndex=0; // keep track of index into values int entryCount = values.size(); int numCells = values.dimension(0); int numEntriesPerCell = entryCount / numCells; for (vector<GlobalIndexType>::iterator cellIt = contextCellIDs.begin(); cellIt != contextCellIDs.end(); cellIt++) { GlobalIndexType cellID = *cellIt; if (_cellIDs.find(cellID) == _cellIDs.end()) { // clear out the associated entries for (int j=0; j<numEntriesPerCell; j++) { values[cellIndex*numEntriesPerCell + j] = 0; } } cellIndex++; } }
set<double> diagonalContourLevels(FieldContainer<double> &pointData, int pointsPerLevel=1) { // traverse diagonal of (i*numPoints + j) data from solutionData() int numPoints = sqrt(pointData.dimension(0)); set<double> levels; for (int i=0; i<numPoints; i++) { levels.insert(pointData(i*numPoints + i,2)); // format for pointData has values at (ptIndex, 2) } // traverse the counter-diagonal for (int i=0; i<numPoints; i++) { levels.insert(pointData(i*numPoints + numPoints-1-i,2)); // format for pointData has values at (ptIndex, 2) } set<double> filteredLevels; int i=0; pointsPerLevel *= 2; for (set<double>::iterator levelIt = levels.begin(); levelIt != levels.end(); levelIt++) { if (i%pointsPerLevel==0) { filteredLevels.insert(*levelIt); } i++; } return filteredLevels; }
void assignBlock(FieldContainer & block,FieldContainer & vertices, double (* func)(double,double)) { TEUCHOS_ASSERT(block.dimension(0)==vertices.dimension(0)); TEUCHOS_ASSERT(block.dimension(1)==vertices.dimension(1)); std::size_t cellCnt = block.dimension(0); std::size_t nodeCnt = block.dimension(1); for(std::size_t cell=0;cell<cellCnt;cell++) { for(std::size_t node=0;node<nodeCnt;node++) { double x = vertices(cell,node,0); double y = vertices(cell,node,1); block(cell,node) = func(x,y); } } }
/// right-hand side function void rhsFunc(FieldContainer<double> & result, const FieldContainer<double> & points, int xd, int yd, int zd) { int x = 0, y = 1, z = 2; // second x-derivatives of u if (xd > 1) { for (int cell=0; cell<result.dimension(0); cell++) { for (int pt=0; pt<result.dimension(1); pt++) { result(cell,pt) = - xd*(xd-1)*std::pow(points(cell,pt,x), xd-2) * std::pow(points(cell,pt,y), yd) * std::pow(points(cell,pt,z), zd); } } } // second y-derivatives of u if (yd > 1) { for (int cell=0; cell<result.dimension(0); cell++) { for (int pt=0; pt<result.dimension(1); pt++) { result(cell,pt) -= yd*(yd-1)*std::pow(points(cell,pt,y), yd-2) * std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,z), zd); } } } // second z-derivatives of u if (zd > 1) { for (int cell=0; cell<result.dimension(0); cell++) { for (int pt=0; pt<result.dimension(1); pt++) { result(cell,pt) -= zd*(zd-1)*std::pow(points(cell,pt,z), zd-2) * std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,y), yd); } } } // add u for (int cell=0; cell<result.dimension(0); cell++) { for (int pt=0; pt<result.dimension(1); pt++) { result(cell,pt) += std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,y), yd) * std::pow(points(cell,pt,z), zd); } } }
/* Monomial evaluation. in 1D, for point p(x) : x^xDeg in 2D, for point p(x,y) : x^xDeg * y^yDeg in 3D, for point p(x,y,z): x^xDeg * y^yDeg * z^zDeg */ double computeMonomial(FieldContainer<double> & p, int xDeg, int yDeg=0, int zDeg=0) { double val = 1.0; int polydeg[3]; polydeg[0] = xDeg; polydeg[1] = yDeg; polydeg[2] = zDeg; for (int i=0; i<p.dimension(0); i++) { val *= std::pow(p(i),polydeg[i]); } return val; }
void func_u(FieldContainer<ScalarT> fu, FieldContainer<ScalarT> u) { int num_cells = u.dimension(0); int num_cub_p = u.dimension(1); for(int c=0; c<num_cells; c++){ for(int p=0; p<num_cub_p; p++){ fu(c,p) = std::pow(u(c,p),3) + std::exp(u(c,p)); } } }
void dfunc_u(FieldContainer<double> dfu, FieldContainer<double> u) { int num_cells = u.dimension(0); int num_cub_p = u.dimension(1); for(int c=0; c<num_cells; c++) { for(int p=0; p<num_cub_p; p++) { dfu(c,p) = 3*u(c,p)*u(c,p) + std::exp(u(c,p)); } } }
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 LinearTermTests::transposeFieldContainer(FieldContainer<double> &fc) { // this is NOT meant for production code. Could do the transpose in place if we were concerned with efficiency. FieldContainer<double> fcCopy = fc; int numCells = fc.dimension(0); int dim1 = fc.dimension(1); int dim2 = fc.dimension(2); fc.resize(numCells,dim2,dim1); for (int i=0; i<numCells; i++) { for (int j=0; j<dim1; j++) { for (int k=0; k<dim2; k++) { fc(i,k,j) = fcCopy(i,j,k); } } } }