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
SurfaceDiffusionResidual<EvalT, Traits>::evaluateFields(
    typename Traits::EvalData workset)
{
  for (int cell(0); cell < workset.numCells; ++cell) {
    for (int node(0); node < numPlaneNodes; ++node) {
      scalarResidual(cell, node) = 0;
      for (int pt = 0; pt < numQPs; ++pt) {
        scalarResidual(cell, node) += refValues(node, pt) *
                                      scalarJump(cell, pt) * thickness *
                                      refArea(cell, pt);
      }
    }
  }
}
  void SurfaceL2ProjectionResidual<EvalT, Traits>::
  evaluateFields(typename Traits::EvalData workset)
  {
    // THESE NEED TO BE REMOVED!!!
    typedef Intrepid::FunctionSpaceTools FST;
    typedef Intrepid::RealSpaceTools<ScalarT> RST;

    ScalarT tau(0);

   // Initialize the residual
    for (int cell(0); cell < workset.numCells; ++cell) {
      for (int node(0); node < numPlaneNodes; ++node) {
        int topNode = node + numPlaneNodes;
        	 projection_residual_(cell, node) = 0;
        	 projection_residual_(cell, topNode) = 0;
      }
    }

    for (int cell(0); cell < workset.numCells; ++cell) {
      for (int node(0); node < numPlaneNodes; ++node) {
        int topNode = node + numPlaneNodes;
        	 for (int pt=0; pt < numQPs; ++pt) {
        		 tau = 0.0;
 
                 for (int dim=0; dim <numDims; ++dim){
                	 tau += detF_(cell,pt)*Cauchy_stress_(cell, pt, dim, dim)/numDims;
                 }

        	  projection_residual_(cell, node) += refValues(node,pt)*
                	       	                            (projected_tau_(cell,pt) -  tau)*
                                                               refArea(cell,pt);

        	 }
        	 projection_residual_(cell, topNode) =  projection_residual_(cell, node);

      }
    }

  }
  void SurfaceTLPoroMassResidual<EvalT, Traits>::
  evaluateFields(typename Traits::EvalData workset)
  {
    typedef Intrepid::FunctionSpaceTools FST;
    typedef Intrepid::RealSpaceTools<ScalarT> RST;

    Albany::MDArray porePressureold = (*workset.stateArrayPtr)[porePressureName];
    Albany::MDArray Jold;
    if (haveMech) {
      Jold = (*workset.stateArrayPtr)[JName];
    }

    ScalarT dt = deltaTime(0);

        // Compute pore fluid flux
       if (haveMech) {
       	// Put back the permeability tensor to the reference configuration
    	    RST::inverse(F_inv, defGrad);
           RST::transpose(F_invT, F_inv);
           FST::scalarMultiplyDataData<ScalarT>(JF_invT, J, F_invT);
           FST::scalarMultiplyDataData<ScalarT>(KJF_invT, kcPermeability, JF_invT);
           FST::tensorMultiplyDataData<ScalarT>(Kref, F_inv, KJF_invT);
           FST::tensorMultiplyDataData<ScalarT> (flux, Kref, scalarGrad); // flux_i = k I_ij p_j
       } else {
           FST::scalarMultiplyDataData<ScalarT> (flux, kcPermeability, scalarGrad); // flux_i = kc p_i
       }

       for (std::size_t cell=0; cell < workset.numCells; ++cell){
             for (std::size_t qp=0; qp < numQPs; ++qp) {
               for (std::size_t dim=0; dim <numDims; ++dim){

                 fluxdt(cell, qp, dim) = -flux(cell,qp,dim)*dt*refArea(cell,qp)*thickness;
               }
             }
       }
          FST::integrate<ScalarT>(poroMassResidual, fluxdt,
          		surface_Grad_BF, Intrepid::COMP_CPP, false); // "true" sums into

    for (std::size_t cell(0); cell < workset.numCells; ++cell) {
      for (std::size_t node(0); node < numPlaneNodes; ++node) {
        // initialize the residual
        int topNode = node + numPlaneNodes;

        for (std::size_t pt=0; pt < numQPs; ++pt) {

          // If there is no diffusion, then the residual defines only on the mid-plane value

          // Local Rate of Change volumetric constraint term
           poroMassResidual(cell, node) -=
                         refValues(node,pt)*(
                         std::log(J(cell,pt)/Jold(cell, pt))*
                         biotCoefficient(cell,pt) +
                          (porePressure(cell, pt) - porePressureold(cell, pt))/ biotModulus(cell,pt)
                          ) *refArea(cell,pt)*thickness;

           poroMassResidual(cell, topNode) -=
        		           refValues(node,pt)*(
        		           std::log(J(cell,pt)/Jold(cell, pt))*
        		           biotCoefficient(cell,pt) +
        		           (porePressure(cell, pt) - porePressureold(cell, pt))/ biotModulus(cell,pt)
        		           ) *refArea(cell,pt)*thickness;



        } // end integrartion point loop
      } //  end plane node loop

      // Stabilization term (if needed)
    } // end cell loop




  }
示例#5
0
    int Orientation_Test05(const bool verbose) {

      Teuchos::RCP<std::ostream> outStream;
      Teuchos::oblackholestream bhs; // outputs nothing

      if (verbose)
        outStream = Teuchos::rcp(&std::cout, false);
      else
        outStream = Teuchos::rcp(&bhs,       false);

      Teuchos::oblackholestream oldFormatState;
      oldFormatState.copyfmt(std::cout);

      typedef typename
        Kokkos::Impl::is_space<DeviceSpaceType>::host_mirror_space::execution_space HostSpaceType ;

      *outStream << "DeviceSpace::  "; DeviceSpaceType::print_configuration(*outStream, false);
      *outStream << "HostSpace::    ";   HostSpaceType::print_configuration(*outStream, false);
      *outStream << "\n";

      
      *outStream
        << "===============================================================================\n"
        << "|                                                                             |\n"
        << "|                 Unit Test (OrientationTools, getModifiedHcurl_I1_Basis)     |\n"
        << "|                                                                             |\n"
        << "===============================================================================\n";

      int errorFlag = 0;
      const double tol = tolerence();

      typedef OrientationTools<DeviceSpaceType> ots;
      try {

        {
          *outStream << "\n -- Testing Quadrilateral \n\n";

          Basis_HCURL_QUAD_I1_FEM<DeviceSpaceType> cellBasis;
          const auto cellTopo = cellBasis.getBaseCellTopology();
          const ordinal_type ndofBasis = cellBasis.getCardinality();
          
          // 
          // 9 12 13 16
          // 4  3 11 15
          // 5  2  8 14
          // 1  6  7 10
          ordinal_type refMesh[9][4] = { { 1, 6, 2, 5 },
                                         { 6, 7, 8, 2 },
                                         { 7,10,14, 8 },
                                         { 5, 2, 3, 4 },
                                         { 2, 8,11, 3 },
                                         { 8,14,15,11 },
                                         { 4, 3,12, 9 },
                                         { 3,11,13,12 },
                                         {11,15,16,13 } };
          const ordinal_type numCells = 9, numVerts = 4, numEdges = 4;

          // view to import refMesh from host          
          Kokkos::DynRankView<ordinal_type,Kokkos::LayoutRight,HostSpaceType> 
            elemNodesHost(&refMesh[0][0], numCells, numVerts);
          auto elemNodes = Kokkos::create_mirror_view(typename DeviceSpaceType::memory_space(), elemNodesHost);
          Kokkos::deep_copy(elemNodes, elemNodesHost);
          
          // compute orientations for cells (one time computation)
          Kokkos::DynRankView<Orientation,DeviceSpaceType> elemOrts("elemOrts", numCells);
          ots::getOrientation(elemOrts, elemNodes, cellTopo);

          auto elemOrtsHost = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), elemOrts);
          Kokkos::deep_copy(elemOrtsHost, elemOrts);
          
          // cell specific modified basis 
          Kokkos::DynRankView<double,DeviceSpaceType> outValues("outValues", numCells, ndofBasis);
          Kokkos::DynRankView<double,DeviceSpaceType> refValues("refValues", numCells, ndofBasis);
          
          auto refValuesHost = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), refValues);
          for (auto cell=0;cell<numCells;++cell)           
            for (auto bf=0;bf<ndofBasis;++bf) 
              refValuesHost(cell, bf) = bf;
          Kokkos::deep_copy(refValues, refValuesHost);

          // modify refValues accounting for orientations
          ots::modifyBasisByOrientation(outValues,
                                        refValues,
                                        elemOrts,
                                        &cellBasis);

          auto outValuesHost = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), outValues);
          Kokkos::deep_copy(outValuesHost, outValues);

          for (auto cell=0;cell<numCells;++cell) {
            int flag = 0 ;
            std::stringstream s1, s2;
            
            ordinal_type orts[numEdges];
            elemOrtsHost(cell).getEdgeOrientation(orts, numEdges);
            
            const double ortVal[2] = { 1.0 , - 1.0 };

            s1 << " :: edge(0000) = " ;
            s2 << " :: edge(" << orts[0] << orts[1] << orts[2] << orts[3] << ") = ";
            for (auto edgeId=0;edgeId<numEdges;++edgeId) {
              const auto ndof = cellBasis.getDofTag(cellBasis.getDofOrdinal(1, edgeId, 0))(3);
              for (auto i=0;i<ndof;++i) {
                const auto refOrd = cellBasis.getDofOrdinal(1, edgeId, i);
                const auto outOrd = cellBasis.getDofOrdinal(1, edgeId, i);
                s1 << std::setw(4) << refValuesHost(cell, outOrd);              
                s2 << std::setw(4) << outValuesHost(cell, outOrd);              

                flag += (std::abs(ortVal[orts[edgeId]]*outValuesHost(cell, outOrd) - refValuesHost(cell, refOrd)) > tol);
              }

              s1 << " // ";
              s2 << " // ";
            }

            *outStream << "\n cell = " << cell << "\n"
                       << " - refValues = " << s1.str() << "\n"
                       << " - outValues = " << s2.str() << "\n";
            if (flag) {
              *outStream << "                      ^^^^^^^^^^^^ FAILURE\n";
              errorFlag += flag;
            }
          }
          ots::clearCoeffMatrix();
        }

      } catch (std::exception err) {
        std::cout << " Exeption\n";
        *outStream << err.what() << "\n\n";
        errorFlag = -1000;
      }

      if (errorFlag != 0)
        std::cout << "End Result: TEST FAILED = " << errorFlag << "\n";
      else
        std::cout << "End Result: TEST PASSED\n";
      
      // reset format state of std::cout
      std::cout.copyfmt(oldFormatState);
      
      return errorFlag;
    }
  void SurfaceScalarJump<EvalT, Traits>::
  evaluateFields(typename Traits::EvalData workset)
  {
    ScalarT scalarA(0.0), scalarB(0.0);
    /*
    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int pt=0; pt < numQPs; ++pt) {
        scalarA = 0.0;
        scalarB = 0.0;
        for (int node=0; node < numPlaneNodes; ++node) {
          int topNode = node + numPlaneNodes;
          	  scalarA += refValues(node, pt) * scalar(cell, node);
          	  scalarB += refValues(node, pt) * scalar(cell, topNode);
        }
        scalarJump(cell,pt) = scalarB - scalarA;
        scalarAverage(cell,pt) = 0.5*(scalarB + scalarA);
      }
    }
    */
    if (havePorePressure) {
    	for (int cell=0; cell < workset.numCells; ++cell) {
    		for (int pt=0; pt < numQPs; ++pt) {
    			scalarA = 0.0;
    			scalarB = 0.0;
    			for (int node=0; node < numPlaneNodes; ++node) {
    				int topNode = node + numPlaneNodes;
    					scalarA += refValues(node, pt) * nodalPorePressure(cell, node);
    					scalarB += refValues(node, pt) * nodalPorePressure(cell, topNode);
        	}
        	jumpPorePressure(cell,pt) = scalarB - scalarA;
        	midPlanePorePressure(cell,pt) = 0.5*(scalarB + scalarA);
      	  }
    	}
    }
    if (haveTemperature) {
    	for (int cell=0; cell < workset.numCells; ++cell) {
    		for (int pt=0; pt < numQPs; ++pt) {
    			scalarA = 0.0;
    			scalarB = 0.0;
    			for (int node=0; node < numPlaneNodes; ++node) {
    				int topNode = node + numPlaneNodes;
    					scalarA += refValues(node, pt) * nodalTemperature(cell, node);
    					scalarB += refValues(node, pt) * nodalTemperature(cell, topNode);
        	}
        	jumpTemperature(cell,pt) = scalarB - scalarA;
        	midPlaneTemperature(cell,pt) = 0.5*(scalarB + scalarA);
      	  }
    	}
    }

    if (haveTransport) {
    	for (int cell=0; cell < workset.numCells; ++cell) {
    		for (int pt=0; pt < numQPs; ++pt) {
    			scalarA = 0.0;
    			scalarB = 0.0;
    			for (int node=0; node < numPlaneNodes; ++node) {
    				int topNode = node + numPlaneNodes;
    					scalarA += refValues(node, pt) * nodalTransport(cell, node);
    					scalarB += refValues(node, pt) * nodalTransport(cell, topNode);
        	}
        	jumpTransport(cell,pt) = scalarB - scalarA;
        	midPlaneTransport(cell,pt) = 0.5*(scalarB + scalarA);
      	  }
    	}
    }

    if (haveHydroStress) {
    	for (int cell=0; cell < workset.numCells; ++cell) {
    		for (int pt=0; pt < numQPs; ++pt) {
    			scalarA = 0.0;
    			scalarB = 0.0;
    			for (int node=0; node < numPlaneNodes; ++node) {
    				int topNode = node + numPlaneNodes;
    					scalarA += refValues(node, pt) * nodalHydroStress(cell, node);
    					scalarB += refValues(node, pt) * nodalHydroStress(cell, topNode);
        	}
        	jumpHydroStress(cell,pt) = scalarB - scalarA;
        	midPlaneHydroStress(cell,pt) = 0.5*(scalarB + scalarA);
      	  }
    	}
    }

  }
  void SurfaceTLPoroMassResidual<EvalT, Traits>::
  evaluateFields(typename Traits::EvalData workset)
  {
    typedef Intrepid::FunctionSpaceTools FST;
    typedef Intrepid::RealSpaceTools<ScalarT> RST;

    Albany::MDArray porePressureold = (*workset.stateArrayPtr)[porePressureName];
    Albany::MDArray Jold;
    if (haveMech) {
      Jold = (*workset.stateArrayPtr)[JName];
    }

    ScalarT dt = deltaTime(0);

    // THE INTREPID REALSPACE TOOLS AND FUNCTION SPACE TOOLS NEED TO BE REMOVED!!!
    // Compute pore fluid flux
    if (haveMech) {
      // Put back the permeability tensor to the reference configuration
      RST::inverse(F_inv, defGrad);
      RST::transpose(F_invT, F_inv);
       FST::scalarMultiplyDataData<ScalarT>(JF_invT, J, F_invT);
       FST::scalarMultiplyDataData<ScalarT>(KJF_invT, kcPermeability, JF_invT);
      FST::tensorMultiplyDataData<ScalarT>(Kref, F_inv, KJF_invT);
      FST::tensorMultiplyDataData<ScalarT> (flux, Kref, scalarGrad); // flux_i = k I_ij p_j
    } else {
       FST::scalarMultiplyDataData<ScalarT> (flux, kcPermeability, scalarGrad); // flux_i = kc p_i
    }

    for (int cell(0); cell < workset.numCells; ++cell) {
      for (int node(0); node < numPlaneNodes; ++node) {
        // initialize the residual
        int topNode = node + numPlaneNodes;
        poroMassResidual(cell, topNode)  = 0.0;
        poroMassResidual(cell, node)  = 0.0;
      }
    }
 
    for (int cell(0); cell < workset.numCells; ++cell) {
      for (int node(0); node < numPlaneNodes; ++node) {
        int topNode = node + numPlaneNodes;

        for (int pt=0; pt < numQPs; ++pt) {

          // If there is no diffusion, then the residual defines only on the mid-plane value

          // Local Rate of Change volumetric constraint term
          poroMassResidual(cell, node) -= refValues(node,pt)*
            (std::log(J(cell,pt)/Jold(cell, pt))*
                     biotCoefficient(cell,pt) +
                     (porePressure(cell, pt) - porePressureold(cell, pt))/
                     biotModulus(cell,pt))*refArea(cell,pt);

          poroMassResidual(cell, topNode) -= refValues(node,pt)*
            (std::log(J(cell,pt)/Jold(cell, pt))*
                     biotCoefficient(cell,pt) +
                     (porePressure(cell, pt) - porePressureold(cell, pt))/
                     biotModulus(cell,pt))*refArea(cell,pt);

        } // end integrartion point loop
      } //  end plane node loop
    } // end cell loop


    for (int cell(0); cell < workset.numCells; ++cell) {
      for (int node(0); node < numPlaneNodes; ++node) {

        int topNode = node + numPlaneNodes;

        for (int pt=0; pt < numQPs; ++pt) {
          for (int dim=0; dim <numDims; ++dim){

            poroMassResidual(cell,node) -=  flux(cell, pt, dim)*dt*
              surface_Grad_BF(cell, node, pt, dim)*
              refArea(cell,pt);

            poroMassResidual(cell, topNode) -= flux(cell, pt, dim)*dt*
              surface_Grad_BF(cell, topNode, pt, dim)*
              refArea(cell,pt);
          }
        }
      }
    }

  }