Exemplo n.º 1
0
//**********************************************************************
PHX_EVALUATE_FIELDS(DOFCurl,workset)
{ 
  // Zero out arrays
  for (int i = 0; i < dof_curl.size(); ++i)
    dof_curl[i] = 0.0;

  if(workset.num_cells>0) {
    Intrepid::FieldContainer<double> curls = (workset.bases[basis_index])->curl_basis;

    // assign ScalarT "dof_orientation" to double "orientation"
    Intrepid::FieldContainer<double> orientation(dof_orientation.dimension(0),
                                                 dof_orientation.dimension(1));

    for(int i=0;i<dof_orientation.dimension(0);i++)
       for(int j=0;j<dof_orientation.dimension(1);j++)
          orientation(i,j) = Sacado::ScalarValue<ScalarT>::eval(dof_orientation(i,j));

    // make sure things are orientated correctly
    Intrepid::FunctionSpaceTools::
       applyFieldSigns<ScalarT>(curls,orientation);

    // evaluate at quadrature points
    Intrepid::FunctionSpaceTools::evaluate<ScalarT>(dof_curl,dof_value,curls);
  }
}
void panzer::GatherTangents<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{ 

  if(workset.num_cells<=0)
    return;
  else {
    const shards::CellTopology & parentCell = *basis->getCellTopology();
    int cellDim = parentCell.getDimension();
    int numEdges = gatherFieldTangents.dimension(1);

    refEdgeTan = Intrepid2::FieldContainer<ScalarT>(numEdges,cellDim);

    for(int i=0;i<numEdges;i++) {
      Intrepid2::FieldContainer<double> refEdgeTan_local(cellDim);
      Intrepid2::CellTools<double>::getReferenceEdgeTangent(refEdgeTan_local, i, parentCell);

      for(int d=0;d<cellDim;d++)
        refEdgeTan(i,d) = refEdgeTan_local(d);
    }

    // Loop over workset faces and edge points
    for(std::size_t c=0;c<workset.num_cells;c++) {
      for(int pt = 0; pt < numEdges; pt++) {

        // Apply parent cell Jacobian to ref. edge tangent
        for(int i = 0; i < cellDim; i++) {
          edgeTan(c, pt, i) = 0.0;
          for(int j = 0; j < cellDim; j++){
            edgeTan(c, pt, i) +=  pointValues.jac(c, pt, i, j)*refEdgeTan(pt,j);
          }// for j
        }// for i
      }// for pt
    }// for pCell

    // Multiply tangent by orientation
    for(std::size_t c=0;c<workset.num_cells;c++) {
      for(int b=0;b<gatherFieldTangents.dimension(1);b++) {
        for(int d=0;d<gatherFieldTangents.dimension(2);d++) {
          gatherFieldTangents(c,b,d) = edgeTan(c,b,d)*dof_orientation(c,b); 
        }
      }
    }
  }

}
//**********************************************************************
PHX_EVALUATE_FIELDS(DirichletResidual_EdgeBasis,workset)
{ 
  if(workset.num_cells<=0)
    return;

  residual.deep_copy(ScalarT(0.0));

  if(workset.subcell_dim==1) {
    Intrepid2::CellTools<ScalarT>::getPhysicalEdgeTangents(edgeTan,
                                            pointValues.jac,
                                            this->wda(workset).subcell_index, 
                                           *basis->getCellTopology());

    for(std::size_t c=0;c<workset.num_cells;c++) {
      for(int b=0;b<dof.dimension(1);b++) {
        for(int d=0;d<dof.dimension(2);d++)
          residual(c,b) += (dof(c,b,d)-value(c,b,d))*edgeTan(c,b,d);
      } 
    }
  }
  else if(workset.subcell_dim==2) {
    // we need to compute the tangents on each edge for each cell.
    // how do we do this????
    const shards::CellTopology & parentCell = *basis->getCellTopology();
    int cellDim = parentCell.getDimension();
    int numEdges = dof.dimension(1);

    refEdgeTan = Kokkos::createDynRankView(residual.get_kokkos_view(),"refEdgeTan",numEdges,cellDim);

    for(int i=0;i<numEdges;i++) {
      Kokkos::DynRankView<double,PHX::Device> refEdgeTan_local("refEdgeTan_local",cellDim);
      Intrepid2::CellTools<double>::getReferenceEdgeTangent(refEdgeTan_local, i, parentCell);

      for(int d=0;d<cellDim;d++) 
        refEdgeTan(i,d) = refEdgeTan_local(d);
    }

    // Loop over workset faces and edge points
    for(std::size_t c=0;c<workset.num_cells;c++) {
      for(int pt = 0; pt < numEdges; pt++) {

        // Apply parent cell Jacobian to ref. edge tangent
        for(int i = 0; i < cellDim; i++) {
          edgeTan(c, pt, i) = 0.0;
          for(int j = 0; j < cellDim; j++){
            edgeTan(c, pt, i) +=  pointValues.jac(c, pt, i, j)*refEdgeTan(pt,j);
          }// for j
        }// for i
      }// for pt
    }// for pCell

    for(std::size_t c=0;c<workset.num_cells;c++) {
      for(int b=0;b<dof.dimension(1);b++) {
        for(int d=0;d<dof.dimension(2);d++)
          residual(c,b) += (dof(c,b,d)-value(c,b,d))*edgeTan(c,b,d);
      } 
    }

  }
  else {
    // don't know what to do 
    TEUCHOS_ASSERT(false);
  }

  // loop over residuals scaling by orientation. This gurantees
  // everything is oriented in the "positive" direction, this allows
  // sums acrossed processor to be oriented in the same way (right?)
  for(std::size_t c=0;c<workset.num_cells;c++) {
    for(int b=0;b<dof.dimension(1);b++) {
      residual(c,b) *= dof_orientation(c,b);
    }
  }
}
void panzer::GatherNormals<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{ 

  if(workset.num_cells<=0)
    return;

  const shards::CellTopology & parentCell = *basis->getCellTopology();
  int cellDim = parentCell.getDimension();
  int numFaces = gatherFieldNormals.dimension(1);

  // Collect the tangents for the element faces in reference space.
  // These are scaled such that U x V returns a unit normal,
  // **contrary to the Intrepid documentation**.
  Kokkos::DynRankView<ScalarT,PHX::Device> refFaceTanU = Kokkos::createDynRankView(gatherFieldNormals.get_static_view(),"refFaceTanU",numFaces,cellDim);
  Kokkos::DynRankView<ScalarT,PHX::Device> refFaceTanV = Kokkos::createDynRankView(gatherFieldNormals.get_static_view(),"refFaceTanV",numFaces,cellDim);
  for(int i=0;i<numFaces;i++) {
    Kokkos::DynRankView<double,PHX::Device> refTanU = Kokkos::DynRankView<double,PHX::Device>("refTanU",cellDim);
    Kokkos::DynRankView<double,PHX::Device> refTanV = Kokkos::DynRankView<double,PHX::Device>("refTanV",cellDim);
    Intrepid2::CellTools<double>::getReferenceFaceTangents(refTanU, refTanV, i, parentCell);
    for(int d=0;d<cellDim;d++) {
      refFaceTanU(i,d) = refTanU(d);
      refFaceTanV(i,d) = refTanV(d);
    }
  }

  // The conversion to physical space must be done by converting each face tangent,
  // then computing the normal: see Intrepid2_CellToolsDef.hpp.
  // This code duplicates Intrepid2::getPhysicalFaceNormals to avoid converting local
  // data structures to and from Intrepid data structures.
  // Note that the magnitude of the normal is related to the area of the physical face.
  for(index_t c=0;c<workset.num_cells;c++) {
    for(int f = 0; f < numFaces; f++) {

      std::vector<double> faceTanU(3);
      std::vector<double> faceTanV(3);
      for(int i = 0; i < cellDim; i++) {
        faceTanU[i] = Sacado::ScalarValue<ScalarT>::eval(pointValues.jac(c,f,i,0)*refFaceTanU(f,0))
                    + Sacado::ScalarValue<ScalarT>::eval(pointValues.jac(c,f,i,1)*refFaceTanU(f,1))
                    + Sacado::ScalarValue<ScalarT>::eval(pointValues.jac(c,f,i,2)*refFaceTanU(f,2));
        faceTanV[i] = Sacado::ScalarValue<ScalarT>::eval(pointValues.jac(c,f,i,0)*refFaceTanV(f,0))
                    + Sacado::ScalarValue<ScalarT>::eval(pointValues.jac(c,f,i,1)*refFaceTanV(f,1))
                    + Sacado::ScalarValue<ScalarT>::eval(pointValues.jac(c,f,i,2)*refFaceTanV(f,2));
      }

      // normal = TanU x TanV
      gatherFieldNormals(c,f,0) = (faceTanU[1]*faceTanV[2] - faceTanU[2]*faceTanV[1])*dof_orientation(c,f);
      gatherFieldNormals(c,f,1) = (faceTanU[2]*faceTanV[0] - faceTanU[0]*faceTanV[2])*dof_orientation(c,f);
      gatherFieldNormals(c,f,2) = (faceTanU[0]*faceTanV[1] - faceTanU[1]*faceTanV[0])*dof_orientation(c,f);

    }
  }

}