void PointValues_Evaluator<EvalT,TraitsT>::initialize(const Teuchos::RCP<const panzer::PointRule> & pointRule, const Intrepid::FieldContainer<double> & userArray) { TEUCHOS_ASSERT(userArray.rank()==2); panzer::MDFieldArrayFactory af(pointRule->getName()+"_"); // copy user array data refPointArray = Intrepid::FieldContainer<double>(userArray.dimension(0),userArray.dimension(1)); TEUCHOS_ASSERT(refPointArray.size()==userArray.size()); for(int i=0;i<userArray.size();i++) refPointArray[i] = userArray[i]; // setup all fields to be evaluated and constructed pointValues.setupArrays(pointRule,af); // the field manager will allocate all of these field this->addEvaluatedField(pointValues.coords_ref); this->addEvaluatedField(pointValues.node_coordinates); this->addEvaluatedField(pointValues.jac); this->addEvaluatedField(pointValues.jac_inv); this->addEvaluatedField(pointValues.jac_det); this->addEvaluatedField(pointValues.point_coords); std::string n = "PointValues_Evaluator: " + pointRule->getName(); this->setName(n); }
void UnitNormalFunction::values(Intrepid::FieldContainer<double> &values, BasisCachePtr basisCache) { this->CHECK_VALUES_RANK(values); int numCells = values.dimension(0); int numPoints = values.dimension(1); int spaceDim = basisCache->getSpaceDim(); if (_comp == -1) { // check the the "D" dimension of values is correct: if (_spaceTime) { TEUCHOS_TEST_FOR_EXCEPTION(values.dimension(2) != spaceDim+1, std::invalid_argument, "For space-time normals, values.dimension(2) should be spaceDim + 1."); } else { TEUCHOS_TEST_FOR_EXCEPTION(values.dimension(2) != spaceDim, std::invalid_argument, "For spatial normals, values.dimension(2) should be spaceDim."); } } const Intrepid::FieldContainer<double> *sideNormals = _spaceTime ? &(basisCache->getSideNormalsSpaceTime()) : &(basisCache->getSideNormals()); int comp = _comp; if (comp == -2) { // want to select the temporal component, t() comp = spaceDim; } for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { if (comp == -1) { for (int d=0; d<spaceDim; d++) { double nd = (*sideNormals)(cellIndex,ptIndex,d); values(cellIndex,ptIndex,d) = nd; } if (_spaceTime) { double nd = (*sideNormals)(cellIndex,ptIndex,spaceDim); values(cellIndex,ptIndex,spaceDim) = nd; } } else { double ni = (*sideNormals)(cellIndex,ptIndex,comp); values(cellIndex,ptIndex) = ni; } } } }
void SideParityFunction::values(Intrepid::FieldContainer<double> &values, BasisCachePtr sideBasisCache) { this->CHECK_VALUES_RANK(values); int numCells = values.dimension(0); int numPoints = values.dimension(1); int sideIndex = sideBasisCache->getSideIndex(); if (sideIndex == -1) { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "non-sideBasisCache passed into SideParityFunction"); } if (sideBasisCache->getCellSideParities().size() > 0) { // then we'll use this, and won't require that mesh and cellIDs are set if (sideBasisCache->getCellSideParities().dimension(0) != numCells) { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "sideBasisCache->getCellSideParities() is non-empty, but the cell dimension doesn't match that of the values FieldContainer."); } for (int cellOrdinal=0; cellOrdinal<numCells; cellOrdinal++) { int parity = sideBasisCache->getCellSideParities()(cellOrdinal,sideIndex); for (int ptOrdinal=0; ptOrdinal<numPoints; ptOrdinal++) { values(cellOrdinal,ptOrdinal) = parity; } } } else { vector<GlobalIndexType> cellIDs = sideBasisCache->cellIDs(); if (cellIDs.size() != numCells) { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "cellIDs.size() != numCells"); } Teuchos::RCP<Mesh> mesh = sideBasisCache->mesh(); if (! mesh.get()) { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "mesh unset in BasisCache."); } for (int cellIndex=0; cellIndex<numCells; cellIndex++) { int parity = mesh->cellSideParitiesForCell(cellIDs[cellIndex])(0,sideIndex); for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { values(cellIndex,ptIndex) = parity; } } } }
double conditionNumberLAPACK(const Epetra_RowMatrix &stiffnessMatrix, bool diagScaling) { Intrepid::FieldContainer<double> A; SerialDenseWrapper::extractFCFromEpetra_RowMatrix(stiffnessMatrix, A); if (diagScaling) { for (int i=0; i<A.dimension(0); i++) { double diag = A(i,i); for (int j=0; j<A.dimension(1); j++) { A(i,j) /= diag; } } } return SerialDenseWrapper::condest(A); }
/** Get the local coordinates for this field. This is independent of element * locations. * * \param[in,out] coords Coordinates associated with this field type. */ void IntrepidFieldPattern::getInterpolatoryCoordinates(const Intrepid::FieldContainer<double> & cellVertices, Intrepid::FieldContainer<double> & coords) const { TEUCHOS_ASSERT(cellVertices.rank()==3); int numCells = cellVertices.dimension(0); // grab the local coordinates Intrepid::FieldContainer<double> localCoords; getInterpolatoryCoordinates(localCoords); // resize the coordinates field container coords.resize(numCells,localCoords.dimension(0),getDimension()); if(numCells>0) { // map to phsyical coordinates Intrepid::CellTools<double> cellTools; cellTools.mapToPhysicalFrame(coords,localCoords,cellVertices,intrepidBasis_->getBaseCellTopology()); } }
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 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 ConstantVectorFunction<Scalar>::values(Intrepid::FieldContainer<Scalar> &values, BasisCachePtr basisCache) { this->CHECK_VALUES_RANK(values); int spaceDim = values.dimension(2); if (spaceDim > _value.size()) { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "spaceDim is greater than length of vector..."); } // values are stored in (C,P,D) order, the important thing here being that we can do this: for (int i=0; i < values.size(); ) { for (int d=0; d < spaceDim; d++) { values[i++] = _value[d]; } } }
void ATO::Integrator<T>::getMeasure( T& measure, const Intrepid::FieldContainer<T>& topoVals, const Intrepid::FieldContainer<T>& coordCon, T zeroVal, C compare) //******************************************************************************// { typedef unsigned int uint; int nDims = coordCon.dimension(1); if(nDims == 2){ std::vector< Vector3D > points; std::vector< Tri > tris; // if there are topoVals that are exactly equal to or very near zeroVal, // there will be all sorts of special cases. If necessary, nudge values // away from zeroVal. Intrepid::FieldContainer<T> vals(topoVals); int nvals = vals.dimension(0); for(int i=0; i<nvals; i++){ if( fabs(vals(i) - zeroVal) < 1e-9 ) vals(i) = zeroVal + 1e-9; } // compute surface mesh in physicsl coordinates getSurfaceTris(points,tris, vals,coordCon, zeroVal,compare); // foreach tri, add measure int ntris = tris.size(); for(int i=0; i<ntris; i++){ T minc = getTriMeasure(points,tris[i]); measure += minc; } } }
void ATO::Integrator<T>::getSurfaceTris( std::vector< Vector3D >& points, std::vector< Tri >& tris, const Intrepid::FieldContainer<T>& topoVals, const Intrepid::FieldContainer<T>& coordCon, T zeroVal, C compare) //******************************************************************************// { const CellTopologyData& cellData = *(cellTopology->getBaseCellTopologyData()); // find intersections std::vector<Intersection> intersections; uint nEdges = cellData.edge_count; int nDims = coordCon.dimension(1); for(int edge=0; edge<nEdges; edge++){ uint i = cellData.edge[edge].node[0], j = cellData.edge[edge].node[1]; if((topoVals(i)-zeroVal)*(topoVals(j)-zeroVal) < 0.0){ Vector3D newpoint(Intrepid::ZEROS); T factor = fabs(topoVals(i)-zeroVal)/(fabs(topoVals(i)-zeroVal)+fabs(topoVals(j)-zeroVal)); for(uint k=0; k<nDims; k++) newpoint(k) = (1.0-factor)*coordCon(i,k) + factor*coordCon(j,k); std::pair<int,int> newIntx(i,j); if(topoVals(i) > zeroVal){int tmp=newIntx.first; newIntx.first=newIntx.second; newIntx.second=tmp;} intersections.push_back(Intersection(newpoint,newIntx)); } } std::vector<std::pair<Vector3D,Vector3D> > segment; // if there are four intersections, then there are two interfaces: if( intersections.size() == 4 ){ segment.resize(2); int numNodes = basis->getCardinality(); RealType cntrVal = 0.0; for(int node=0; node<numNodes; node++) cntrVal += topoVals(node); cntrVal /= numNodes; // if topoVal at centroid is negative, interssected segments share a positive valued node if( cntrVal < zeroVal ){ int second = intersections[0].connect.second; if( second == intersections[1].connect.second ){ segment[0].first = intersections[0].point; segment[0].second = intersections[1].point; segment[1].first = intersections[2].point; segment[1].second = intersections[3].point; } else if( second == intersections[2].connect.second ){ segment[0].first = intersections[0].point; segment[0].second = intersections[2].point; segment[1].first = intersections[1].point; segment[1].second = intersections[3].point; } else if( second == intersections[3].connect.second ){ segment[0].first = intersections[0].point; segment[0].second = intersections[3].point; segment[1].first = intersections[1].point; segment[1].second = intersections[2].point; } } else { int first = intersections[0].connect.first; if( first == intersections[1].connect.first ){ segment[0].first = intersections[0].point; segment[0].second = intersections[1].point; segment[1].first = intersections[2].point; segment[1].second = intersections[3].point; } else if( first == intersections[2].connect.first ){ segment[0].first = intersections[0].point; segment[0].second = intersections[2].point; segment[1].first = intersections[1].point; segment[1].second = intersections[3].point; } else if( first == intersections[3].connect.first ){ segment[0].first = intersections[0].point; segment[0].second = intersections[3].point; segment[1].first = intersections[1].point; segment[1].second = intersections[2].point; } } } else if( intersections.size() == 2){ segment.resize(1); segment[0].first = intersections[0].point; segment[0].second = intersections[1].point; } std::vector< Teuchos::RCP<MiniPoly> > polys; int npoints = coordCon.dimension(0), ndims = coordCon.dimension(1); Teuchos::RCP<MiniPoly> poly = Teuchos::rcp(new MiniPoly(npoints)); std::vector<Vector3D>& pnts = poly->points; std::vector<int>& map = poly->mapToBase; for(int pt=0; pt<npoints; pt++){ for(int dim=0; dim<ndims; dim++) pnts[pt](dim) = coordCon(pt,dim); map[pt] = pt; } polys.push_back(poly); int nseg = segment.size(); for(int seg=0; seg<nseg; seg++) partitionBySegment(polys, segment[seg]); typename std::vector< Teuchos::RCP<MiniPoly> >::iterator itpoly; for(itpoly=polys.begin(); itpoly!=polys.end(); itpoly++) if( included(*itpoly,topoVals,zeroVal,compare) ) trisFromPoly(points, tris, *itpoly); }
void ATO::Integrator<T>::getCubature(std::vector<std::vector<T> >& refPoints, std::vector<T>& weights, const Intrepid::FieldContainer<T>& coordCon, const Intrepid::FieldContainer<T>& topoVals, T zeroVal) //******************************************************************************// { // check for degeneracy (any topoVals == zeroVal). These will have to be handled specially. int nTopoVals = topoVals.dimension(0); T mult = topoVals(0)-zeroVal; for(int i=1; i<nTopoVals; i++) mult *= (topoVals(i)-zeroVal); TEUCHOS_TEST_FOR_EXCEPTION(mult == 0.0, std::runtime_error, std::endl << "Degenerate topology: handling not yet implemented." << std::endl); // This function computes the weights and refPoints for the base topology, // i.e., it ignores subcells associated with an extended topology (see Shards // Doxygen for details on base versus extended topologies). For example, // the extra subcells associated with a Quad8 or Quad9 element will be // ignored, so it will be treated as a Quad4 element. typedef unsigned int uint; int nDims = coordCon.dimension(1); if(nDims == 2){ /* const CellTopologyData& cellData = *(cellTopology->getBaseCellTopologyData()); std::vector< Intrepid::Vector<T> > points; std::vector< Intrepid::Vector<int> > tris; getSurfaceTris(points,tris, cellData,coordCon,topoVals,zeroVal); std::vector<Intrepid::Vector<T> > Apoints, Bpoints; // add negative/positive points to Apoints/Bpoints vector Intrepid::Vector<T> point(nDims); for(int i=0; i<nTopoVals; i++){ for(int j=0; j<nDims; j++) point(j) = coordCon(i,j); if(topoVals(i) < zeroVal) Apoints.push_back(point); else Bpoints.push_back(point); } // find/count intersection points uint nIntersections = 0; uint nEdges = cellData.edge_count; for(int edge=0; edge<nEdges; edge++){ uint i = cellData.edge[edge].node[0], j = cellData.edge[edge].node[1]; if((topoVals(i)-zeroVal)*(topoVals(j)-zeroVal) < 0.0){ Intrepid::Vector<T> newpoint(nDims); T factor = fabs(topoVals(i))/(fabs(topoVals(i))+fabs(topoVals(j))); for(uint k=0; k<nDims; k++) newpoint(k) = (1.0-factor)*coordCon(i,k) + factor*coordCon(j,k); Apoints.push_back(newpoint); Bpoints.push_back(newpoint); nIntersections++; } } // if there are four intersections, then there are two interfaces: if( nIntersections == 4 ){ } else if( nIntersections == 2 ){ // find centerpoint Intrepid::Vector<T> Acenter(Apoints[0]), Bcenter(Bpoints[0]); uint nApoints = Apoints.size(), nBpoints = Bpoints.size(); for(uint i=1; i<nApoints; i++) Acenter += Apoints[i]; Acenter /= nApoints; for(uint i=1; i<nBpoints; i++) Bcenter += Bpoints[i]; Bcenter /= nBpoints; // sort by counterclockwise angle about surface normal T pi = acos(-1.0); Intrepid::Vector<T> Ax(Apoints[0]-Acenter); Intrepid::Vector<T> Ay(-Ax(1),Ax(0),0.0); T Arefnorm = Intrepid::norm(Ax); std::map<T, uint> Aangles; Aangles.insert( std::pair<T, uint>(0.0,0) ); for(int i=1; i<nApoints; i++){ Intrepid::Vector<T> comp = Apoints[i] - Acenter; T compnorm = Intrepid::norm(comp); T angle = acos(Ax * comp/(compnorm*Arefnorm)); if( Ay * comp < 0.0 ) angle = 2.0*pi - angle; Aangles.insert( std::pair<T, uint>(angle,i) ); } // create polygons nApoints = Aangles.size(); if(nApoints == 5){ Intrepid::Vector<T>& c0 = Acenter; typename std::map<T,uint>::iterator it=Aangles.begin(); while(it!=Aangles.end()){ Intrepid::Vector<T>& c1 = Apoints[it->second]; it++; Intrepid::Vector<T>& c2 = Apoints[it->second]; addCubature(refPoints, weights, c0, c1, c2); } it=Aangles.begin(); typename std::map<T,uint>::reverse_iterator rit=Aangles.rbegin(); Intrepid::Vector<T>& c2 = Apoints[it->second]; Intrepid::Vector<T>& c1 = Apoints[rit->second]; addCubature(refPoints, weights, c0, c1, c2); } } else { TEUCHOS_TEST_FOR_EXCEPTION(mult == 0.0, std::runtime_error, std::endl << "Degenerate topology: Topology intersects element in " << Apoints.size() << " places." << std::endl); } */ } else if(nDims == 3){ } else { } }