Ejemplo n.º 1
0
  void SurfaceBasis<EvalT, Traits>::
  computeCurrentBaseVectors(const SFC & midplaneCoords,
                            PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> basis)
  {
    for (int cell(0); cell < midplaneCoords.dimension(0); ++cell) {
      // get the midplane coordinates
      std::vector<Intrepid::Vector<ScalarT> > midplaneNodes(numPlaneNodes);
      for (std::size_t node(0); node < numPlaneNodes; ++node)
        midplaneNodes[node] = Intrepid::Vector<ScalarT>(3, &midplaneCoords(cell, node, 0));

      Intrepid::Vector<ScalarT> g_0(0, 0, 0), g_1(0, 0, 0), g_2(0, 0, 0);
      //compute the base vectors
      for (std::size_t pt(0); pt < numQPs; ++pt) {
        g_0.clear();
        g_1.clear();
        g_2.clear();
        for (std::size_t node(0); node < numPlaneNodes; ++node) {
          g_0 += refGrads(node, pt, 0) * midplaneNodes[node];
          g_1 += refGrads(node, pt, 1) * midplaneNodes[node];
        }
        g_2 = cross(g_0, g_1) / norm(cross(g_0, g_1));

        basis(cell, pt, 0, 0) = g_0(0);
        basis(cell, pt, 0, 1) = g_0(1);
        basis(cell, pt, 0, 2) = g_0(2);
        basis(cell, pt, 1, 0) = g_1(0);
        basis(cell, pt, 1, 1) = g_1(1);
        basis(cell, pt, 1, 2) = g_1(2);
        basis(cell, pt, 2, 0) = g_2(0);
        basis(cell, pt, 2, 1) = g_2(1);
        basis(cell, pt, 2, 2) = g_2(2);
      }
    }
  }
  void SurfaceScalarGradientOperator<EvalT, Traits>::
  evaluateFields(typename Traits::EvalData workset)
  {
    Intrepid2::Vector<MeshScalarT> Parent_Grad_plus(3);
    Intrepid2::Vector<MeshScalarT> Parent_Grad_minor(3);

    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int pt=0; pt < numQPs; ++pt) {

        Intrepid2::Tensor<MeshScalarT> gBasis(3, refDualBasis,cell, pt,0,0);

        Intrepid2::Vector<MeshScalarT> N(3, refNormal,cell, pt,0);

        gBasis = Intrepid2::transpose(gBasis);

        // in-plane (parallel) contribution
        for (int node(0); node < numPlaneNodes; ++node) {
          int topNode = node + numPlaneNodes;

          // the parallel-to-the-plane term
          for (int i(0); i < numPlaneDims; ++i ){
            Parent_Grad_plus(i) = 0.5*refGrads(node, pt, i);
            Parent_Grad_minor(i) = 0.5*refGrads(node, pt, i);
          }

          // the orthogonal-to-the-plane term
          MeshScalarT invh = 1./ thickness;
          Parent_Grad_plus(numPlaneDims) = invh * refValues(node,pt);
          Parent_Grad_minor(numPlaneDims) = -invh * refValues(node,pt);

          // Mapping from parent to the physical domain
          Intrepid2::Vector<MeshScalarT> Transformed_Grad_plus(Intrepid2::dot(gBasis, Parent_Grad_plus));
          Intrepid2::Vector<MeshScalarT> Transformed_Grad_minor(Intrepid2::dot(gBasis,Parent_Grad_minor));

          // assign components to MDfield ScalarGrad
          for (int j(0); j < numDims; ++j ){
            surface_Grad_BF(cell, topNode, pt, j) = Transformed_Grad_plus(j);
            surface_Grad_BF(cell, node, pt, j) = Transformed_Grad_minor(j);
          }
        }
      }
    }

    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int pt=0; pt < numQPs; ++pt) {
        for (int k(0); k< numDims; ++k){
          grad_val_qp(cell, pt, k) = 0;
          for (int node(0); node < numNodes; ++node) {
            grad_val_qp(cell, pt, k) += surface_Grad_BF(cell, node, pt, k)*
              val_node(cell,node);
          }
        }
      }
    }

  }
  void SurfaceScalarGradient<EvalT, Traits>::
  evaluateFields(typename Traits::EvalData workset)
  {
    ScalarT midPlaneAvg;
    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int pt=0; pt < numQPs; ++pt) {

        Intrepid2::Vector<MeshScalarT> G_0(3, refDualBasis, cell, pt, 0, 0);
        Intrepid2::Vector<MeshScalarT> G_1(3, refDualBasis, cell, pt, 1, 0);
        Intrepid2::Vector<MeshScalarT> G_2(3, refDualBasis, cell, pt, 2, 0);
        Intrepid2::Vector<MeshScalarT> N(3, refNormal,cell, pt, 0);

        Intrepid2::Vector<ScalarT> scalarGradPerpendicular(0, 0, 0);
        Intrepid2::Vector<ScalarT> scalarGradParallel(0, 0, 0);

       // Need to inverse basis [G_0 ; G_1; G_2] and none of them should be normalized
        Intrepid2::Tensor<MeshScalarT> gBasis(3, refDualBasis,cell, pt, 0, 0);
        Intrepid2::Tensor<MeshScalarT> invRefDualBasis(3);

        // This map the position vector from parent to current configuration in R^3
        gBasis = Intrepid2::transpose(gBasis);
       invRefDualBasis = Intrepid2::inverse(gBasis);

        Intrepid2::Vector<MeshScalarT> invG_0(3, &invRefDualBasis( 0, 0));
        Intrepid2::Vector<MeshScalarT> invG_1(3, &invRefDualBasis( 1, 0));
        Intrepid2::Vector<MeshScalarT> invG_2(3, &invRefDualBasis( 2, 0));

        // in-plane (parallel) contribution
        for (int node(0); node < numPlaneNodes; ++node) {
          int topNode = node + numPlaneNodes;
          midPlaneAvg = 0.5 * (nodalScalar(cell, node) + nodalScalar(cell, topNode));
          for (int i(0); i < numDims; ++i) {
            scalarGradParallel(i) += 
              refGrads(node, pt, 0) * midPlaneAvg * invG_0(i) +
              refGrads(node, pt, 1) * midPlaneAvg * invG_1(i);
          }
        }

        // normal (perpendicular) contribution
        for (int i(0); i < numDims; ++i) {
          scalarGradPerpendicular(i) = jump(cell,pt) / thickness *invG_2(i);
        }

        // assign components to MDfield ScalarGrad
        for (int i(0); i < numDims; ++i )
          scalarGrad(cell, pt, i) = scalarGradParallel(i) + scalarGradPerpendicular(i);
      }
    }
  }