Beispiel #1
0
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 {
  }
  

}