diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 896de338ccd..b6311a7bead 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -374,8 +374,8 @@ jobs: GEOS_ENABLE_BOUNDS_CHECK: OFF DOCKER_REPOSITORY: geosx/rockylinux8-clang17-cuda12.9.1 RUNS_ON: streak - NPROC: 8 - DOCKER_RUN_ARGS: "--cpus=8 --memory=256g --runtime=nvidia --gpus all -v /etc/pki/ca-trust/source/anchors/:/usr/local/share/ca-certificates/llnl:ro" + NPROC: 16 + DOCKER_RUN_ARGS: "--cpus=16 --memory=448g --runtime=nvidia --gpus all -v /etc/pki/ca-trust/source/anchors/:/usr/local/share/ca-certificates/llnl:ro" DOCKER_CERTS_DIR: "/usr/local/share/ca-certificates" DOCKER_CERTS_UPDATE_COMMAND: "update-ca-trust" HOST_CONFIG: /spack-generated.cmake diff --git a/scripts/setupPythonEnvironment.bash b/scripts/setupPythonEnvironment.bash index 492a507d4e7..9868b75e1ab 100755 --- a/scripts/setupPythonEnvironment.bash +++ b/scripts/setupPythonEnvironment.bash @@ -71,7 +71,7 @@ case $key in echo "-p/--python-target \"Target parent python bin\"" echo "-b/--bin-dir \"Directory to link new scripts\"" echo "-d/--pkg-dir \"Directory containing target python packages\"" - echo "-t/--tool-branch \"Target branch for geosPythonPackages (default=main) \"" + echo "-r/--python-pkg-branch \"Target branch for geosPythonPackages (default=main) \"" echo "-v/--verbose \"Increase verbosity level\"" echo "" exit diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 285597c903b..36dc61610ac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,6 +139,11 @@ blt_add_executable( NAME geosx ${extraComponentsLinkList} ${externalComponentsLinkList} ) +if(APPLE) + target_link_options(geosx PRIVATE "-Wl,-export_dynamic") +endif() + + # Seems to be required on some CMake versions (e.g. 3.16) to get enforce device linking if( ${ENABLE_HYPRE_DEVICE} STREQUAL "CUDA" ) set_target_properties( geosx PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS TRUE ) @@ -220,8 +225,8 @@ install( FILES ${CMAKE_BINARY_DIR}/schema.xsd ################################ # Add python environment setup ################################ -#message(WARNING "Temporarily changing the geosPythonBranch to cusini/remove-relative-paths") -#set(GEOS_PYTHON_PACKAGES_BRANCH "cusini/remove-relative-paths" CACHE STRING "" FORCE) +message(WARNING "Temporarily changing the geosPythonBranch to feature/remove-dndx-detj") +set(GEOS_PYTHON_PACKAGES_BRANCH "feature/remove-dndx-detj" CACHE STRING "" FORCE) if ( Python3_EXECUTABLE ) diff --git a/src/cmake/thirdparty/SetupGeosxThirdParty.cmake b/src/cmake/thirdparty/SetupGeosxThirdParty.cmake index d1043f59939..24f29fb1799 100644 --- a/src/cmake/thirdparty/SetupGeosxThirdParty.cmake +++ b/src/cmake/thirdparty/SetupGeosxThirdParty.cmake @@ -887,7 +887,7 @@ if( ${CMAKE_VERSION} VERSION_LESS "3.19" ) set( PYTHON_AND_VERSION Python3 ) set( PYTHON_OPTIONAL_COMPONENTS) else() - set( PYTHON_AND_VERSION Python3 3.6.0...<4 ) + set( PYTHON_AND_VERSION Python3 3.6.0...<4.0.0 ) set( PYTHON_OPTIONAL_COMPONENTS OPTIONAL_COMPONENTS Development NumPy) endif() if(ENABLE_PYGEOSX) diff --git a/src/coreComponents/finiteElement/CMakeLists.txt b/src/coreComponents/finiteElement/CMakeLists.txt index 54e20920522..0fb9c8feff2 100644 --- a/src/coreComponents/finiteElement/CMakeLists.txt +++ b/src/coreComponents/finiteElement/CMakeLists.txt @@ -29,6 +29,7 @@ set( finiteElement_headers LinearFormUtilities.hpp PDEUtilities.hpp elementFormulations/FiniteElementBase.hpp + elementFormulations/FiniteElementOperators.hpp elementFormulations/H1_Hexahedron_Lagrange1_GaussLegendre2.hpp elementFormulations/H1_Pyramid_Lagrange1_Gauss5.hpp elementFormulations/H1_QuadrilateralFace_Lagrange1_GaussLegendre2.hpp diff --git a/src/coreComponents/finiteElement/FiniteElementDiscretization.hpp b/src/coreComponents/finiteElement/FiniteElementDiscretization.hpp index e242734a9e8..bad54dd36c4 100644 --- a/src/coreComponents/finiteElement/FiniteElementDiscretization.hpp +++ b/src/coreComponents/finiteElement/FiniteElementDiscretization.hpp @@ -27,23 +27,9 @@ #include "LvArray/src/tensorOps.hpp" #include "FiniteElementDispatch.hpp" - namespace geos { -// TODO remove when these quantities are placed inside the FiniteElementBase -// class. -namespace dataRepository -{ -namespace keys -{ -string const dNdX = "dNdX"; -string const detJ = "detJ"; -} -} - - - class FiniteElementDiscretization : public dataRepository::Group { public: @@ -71,14 +57,6 @@ class FiniteElementDiscretization : public dataRepository::Group ///@} - template< typename SUBREGION_TYPE, - typename FE_TYPE > - void calculateShapeFunctionGradients( arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X, - SUBREGION_TYPE * const elementSubRegion, - typename FE_TYPE::template MeshData< SUBREGION_TYPE > meshData, - FE_TYPE & fe ) const; - - /** * @brief Factory method to instantiate a type of finite element formulation. * @param parentElementShape String key that indicates the type of @@ -125,65 +103,6 @@ ENUM_STRINGS( FiniteElementDiscretization::Formulation, "SEM", "DG" ); -template< typename SUBREGION_TYPE, - typename FE_TYPE > -void -FiniteElementDiscretization:: - calculateShapeFunctionGradients( arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X, - SUBREGION_TYPE * const elementSubRegion, - typename FE_TYPE::template MeshData< SUBREGION_TYPE > meshData, - FE_TYPE & finiteElement ) const -{ - GEOS_MARK_FUNCTION; - - // do not precompute shape functions in case of SEM or DG formulation (not needed) - if( m_formulation == Formulation::SEM || m_formulation == Formulation::DG ) - return; - - array4d< real64 > & dNdX = elementSubRegion->dNdX(); - array2d< real64 > & detJ = elementSubRegion->detJ(); - auto const & elemsToNodes = elementSubRegion->nodeList().toViewConst(); - - constexpr localIndex numNodesPerElem = FE_TYPE::maxSupportPoints; - constexpr localIndex numQuadraturePointsPerElem = FE_TYPE::numQuadraturePoints; - dNdX.resizeWithoutInitializationOrDestruction( elementSubRegion->size(), numQuadraturePointsPerElem, numNodesPerElem, 3 ); - detJ.resize( elementSubRegion->size(), numQuadraturePointsPerElem ); - - finiteElement.setGradNView( dNdX.toViewConst() ); - finiteElement.setDetJView( detJ.toViewConst() ); - - for( localIndex k = 0; k < elementSubRegion->size(); ++k ) - { - typename FE_TYPE::StackVariables feStack; - finiteElement.template setup< FE_TYPE >( k, meshData, feStack ); - real64 xLocal[numNodesPerElem][3]; - localIndex numSupportPoints = finiteElement.template numSupportPoints< FE_TYPE >( feStack ); - for( localIndex a=0; a< numSupportPoints; ++a ) - { - localIndex const nodeIndex = elemsToNodes[ k][ a ]; - for( int i=0; i<3; ++i ) - { - xLocal[ a ][ i ] = X[ nodeIndex ][ i ]; - } - } - - - - for( localIndex q = 0; q < numQuadraturePointsPerElem; ++q ) - { - real64 dNdXLocal[numNodesPerElem][3]; - detJ( k, q ) = finiteElement.calcGradN( q, xLocal, feStack, dNdXLocal ); - - for( localIndex b = 0; b < numSupportPoints; ++b ) - { - LvArray::tensorOps::copy< 3 >( dNdX[ k ][ q ][ b ], dNdXLocal[b] ); - } - } - } - -} - - } /* namespace geos */ #endif /* GEOS_FINITEELEMENT_FINITEELEMENTDISCRETIZATION_HPP_ */ diff --git a/src/coreComponents/finiteElement/FiniteElementDispatch.hpp b/src/coreComponents/finiteElement/FiniteElementDispatch.hpp index ddfc3942ce2..bd11097bb7f 100644 --- a/src/coreComponents/finiteElement/FiniteElementDispatch.hpp +++ b/src/coreComponents/finiteElement/FiniteElementDispatch.hpp @@ -159,14 +159,13 @@ struct FiniteElementDispatchHandler< FE_TYPE, FE_TYPES... > dispatch3D( FiniteElementBase const & input, LAMBDA && lambda ) { - if( auto const * const ptr = dynamic_cast< FE_TYPE const * >(&input) ) + if( auto const * const wrapper = dynamic_cast< FE_TYPE const * >(&input) ) { - lambda( *ptr ); - } - else - { - FiniteElementDispatchHandler< FE_TYPES... >::dispatch3D( input, lambda ); + lambda( *wrapper->getImpl() ); + return; } + + FiniteElementDispatchHandler< FE_TYPES... >::dispatch3D( input, lambda ); } template< typename LAMBDA > @@ -174,14 +173,13 @@ struct FiniteElementDispatchHandler< FE_TYPE, FE_TYPES... > dispatch3D( FiniteElementBase & input, LAMBDA && lambda ) { - if( auto * const ptr = dynamic_cast< FE_TYPE * >(&input) ) + if( auto * const wrapper = dynamic_cast< FE_TYPE * >(&input) ) { - lambda( *ptr ); - } - else - { - FiniteElementDispatchHandler< FE_TYPES... >::dispatch3D( input, lambda ); + lambda( *wrapper->getImpl() ); + return; } + + FiniteElementDispatchHandler< FE_TYPES... >::dispatch3D( input, lambda ); } template< typename LAMBDA > @@ -189,14 +187,13 @@ struct FiniteElementDispatchHandler< FE_TYPE, FE_TYPES... > dispatch2D( FiniteElementBase const & input, LAMBDA && lambda ) { - if( auto const * const ptr = dynamic_cast< FE_TYPE const * >(&input) ) + if( auto const * const wrapper = dynamic_cast< FE_TYPE const * >(&input) ) { - lambda( *ptr ); - } - else - { - FiniteElementDispatchHandler< FE_TYPES... >::dispatch2D( input, lambda ); + lambda( *wrapper->getImpl() ); + return; } + + FiniteElementDispatchHandler< FE_TYPES... >::dispatch2D( input, lambda ); } }; @@ -207,21 +204,21 @@ void dispatchlowOrder3D( FiniteElementBase const & input, LAMBDA && lambda ) { - if( auto const * const ptr1 = dynamic_cast< H1_Hexahedron_Lagrange1_GaussLegendre2 const * >(&input) ) + if( auto const * const wrapper1 = dynamic_cast< H1_Hexahedron_Lagrange1_GaussLegendre2 const * >(&input) ) { - lambda( *ptr1 ); + lambda( *wrapper1->getImpl() ); } - else if( auto const * const ptr2 = dynamic_cast< H1_Wedge_Lagrange1_Gauss6 const * >(&input) ) + else if( auto const * const wrapper2 = dynamic_cast< H1_Wedge_Lagrange1_Gauss6 const * >(&input) ) { - lambda( *ptr2 ); + lambda( *wrapper2->getImpl() ); } - else if( auto const * const ptr3 = dynamic_cast< H1_Tetrahedron_Lagrange1_Gauss1 const * >(&input) ) + else if( auto const * const wrapper3 = dynamic_cast< H1_Tetrahedron_Lagrange1_Gauss1 const * >(&input) ) { - lambda( *ptr3 ); + lambda( *wrapper3->getImpl() ); } - else if( auto const * const ptr4 = dynamic_cast< H1_Pyramid_Lagrange1_Gauss5 const * >(&input) ) + else if( auto const * const wrapper4 = dynamic_cast< H1_Pyramid_Lagrange1_Gauss5 const * >(&input) ) { - lambda( *ptr4 ); + lambda( *wrapper4->getImpl() ); } else { @@ -233,6 +230,4 @@ dispatchlowOrder3D( FiniteElementBase const & input, } // namespace geos - - #endif /* GEOS_FINITEELEMENT_FINITEELEMENTDISPATCH_HPP_ */ diff --git a/src/coreComponents/finiteElement/elementFormulations/BB_Tetrahedron.hpp b/src/coreComponents/finiteElement/elementFormulations/BB_Tetrahedron.hpp index 9374122a958..7cf102dda8c 100644 --- a/src/coreComponents/finiteElement/elementFormulations/BB_Tetrahedron.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/BB_Tetrahedron.hpp @@ -30,6 +30,12 @@ namespace geos namespace finiteElement { +namespace +{ +template< int ORDER > +constexpr int BB_Tetrahedron_NumNodes = ( ORDER + 1 ) * ( ORDER + 2 ) * ( ORDER + 3 ) / 6; +} + /** * This class contains the kernel accessible functions specific to the * Bernstein-Bézier (BB) modal any-order tetrahedron finite element with @@ -42,33 +48,41 @@ namespace finiteElement * by 0<=l1,l2,l3,l3<=1, l1+l2+l3+l4=1 */ template< int ORDER > -class BB_Tetrahedron final : public FiniteElementBase +class BB_Tetrahedron_impl : public FiniteElementBase_impl< BB_Tetrahedron_NumNodes< ORDER >, + 4, + BB_Tetrahedron_NumNodes< ORDER > > { public: + /// Convenience alias for base class type. + using Base = FiniteElementBase_impl< BB_Tetrahedron_NumNodes< ORDER >, + 4, + BB_Tetrahedron_NumNodes< ORDER > >; - /// The order of the finite element. - static constexpr int order = ORDER; + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; + + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; /// The number of shape functions per element. - constexpr static localIndex numNodes = ( ORDER + 1 ) * ( ORDER + 2 ) * ( ORDER + 3 ) / 6; + using Base::numNodes; - /// The number of shape functions per face - constexpr static localIndex numNodesPerFace = ( ORDER + 1 ) * ( ORDER + 2 ) / 2; + /// The number of quadrature points per element. + using Base::numQuadraturePoints; /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; + using Base::maxSupportPoints; - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = numNodes; - - /** @cond Doxygen_Suppress */ - USING_FINITEELEMENTBASE - /** @endcond Doxygen_Suppress */ + /// The order of the finite element. + static constexpr int order = ORDER; - virtual ~BB_Tetrahedron() = default; + /// The number of shape functions per face + constexpr static localIndex numNodesPerFace = ( ORDER + 1 ) * ( ORDER + 2 ) / 2; + /// @copydoc FiniteElementBase_impl::getNumQuadraturePoints() GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override + static localIndex getNumQuadraturePoints() { return numQuadraturePoints; } @@ -86,16 +100,18 @@ class BB_Tetrahedron final : public FiniteElementBase return numQuadraturePoints; } + /// @copydoc FiniteElementBase_impl::getNumSupportPoints() GEOS_HOST_DEVICE GEOS_FORCE_INLINE - virtual localIndex getNumSupportPoints() const override + static localIndex getNumSupportPoints() { return numNodes; } + /// @copydoc FiniteElementBase_impl::getMaxSupportPoints() GEOS_HOST_DEVICE GEOS_FORCE_INLINE - virtual localIndex getMaxSupportPoints() const override + static localIndex getMaxSupportPoints() { return maxSupportPoints; } @@ -122,7 +138,6 @@ class BB_Tetrahedron final : public FiniteElementBase GEOS_HOST_DEVICE GEOS_FORCE_INLINE static real64 jacobianDeterminant( real64 const (&X)[4][3] ) - { real64 m[3][3] = {}; for( int i = 0; i < 3; i++ ) @@ -396,6 +411,57 @@ class BB_Tetrahedron final : public FiniteElementBase } } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& J)[3][3] ) + { + GEOS_UNUSED_VAR( q ); + for( int i = 0; i < 3; ++i ) + { + for( int j = 0; j < 3; ++j ) + { + J[i][j] = 0; + } + } + real64 m[3][3] = {}; + for( int i = 0; i < 3; i++ ) + { + for( int j = 0; j < 3; j++ ) + { + m[ i ][ j ] = X[ i + 1 ][ j ] - X[ 0 ][ j ]; + } + } + real64 const detJ = LvArray::math::abs( LvArray::tensorOps::determinant< 3 >( m ) ); + return detJ; + } + + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param stack Variables allocated on the stack as filled by @ref setupStack. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & stack, + real64 (& J)[3][3] ) + { + GEOS_UNUSED_VAR( stack ); + return calcJacobian( q, X, J ); + } /** * @brief Calculate the shape functions derivatives wrt the physical @@ -1320,21 +1386,72 @@ class BB_Tetrahedron final : public FiniteElementBase }; -/** - * Tetrahedron element with Bernstein-Bézier basis functions of order 1. - */ +/// @copydoc BB_Tetrahedron_impl +template< int ORDER > +class BB_Tetrahedron final : public BB_Tetrahedron_impl< ORDER >, public FiniteElementBase +{ +public: + + /// The Implementation type + using ImplType = BB_Tetrahedron_impl< ORDER >; + + BB_Tetrahedron(): + FiniteElementBase( ImplType::numNodes, + ImplType::maxSupportPoints, + ImplType::numQuadraturePoints ) + { } + +#ifdef __CUDACC__ + #pragma diag_push + #pragma nv_diag_suppress 20012 +#endif + GEOS_HOST_DEVICE + virtual ~BB_Tetrahedron() override final = default; +#ifdef __CUDACC__ + #pragma diag_pop +#endif + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + ImplType * getImpl() + { + return static_cast< ImplType * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + ImplType const * getImpl() const + { + return static_cast< ImplType const * >(this); + } + +}; + +/// Tetrahedron element with Bernstein-Bézier basis functions of order 1. using BB1_Tetrahedron = BB_Tetrahedron< 1 >; -/** - * Tetrahedron element with Bernstein-Bézier basis functions of order 2. - */ +/// Tetrahedron element with Bernstein-Bézier basis functions of order 2. using BB2_Tetrahedron = BB_Tetrahedron< 2 >; -/** - * Tetrahedron element with Bernstein-Bézier basis functions of order 3. - */ +/// Tetrahedron element with Bernstein-Bézier basis functions of order 3. using BB3_Tetrahedron = BB_Tetrahedron< 3 >; + //using BB4_Tetrahedron = BB_Tetrahedron< 4 >; //using BB5_Tetrahedron = BB_Tetrahedron< 5 >; + +/// Tetrahedron element with Bernstein-Bézier basis functions of order 1. +using BB1_Tetrahedron_impl = BB_Tetrahedron_impl< 1 >; +/// Tetrahedron element with Bernstein-Bézier basis functions of order 2. +using BB2_Tetrahedron_impl = BB_Tetrahedron_impl< 2 >; +/// Tetrahedron element with Bernstein-Bézier basis functions of order 3. +using BB3_Tetrahedron_impl = BB_Tetrahedron_impl< 3 >; + +// using BB2_Tetrahedron_impl = BB_Tetrahedron_impl< 4 >; +// using BB3_Tetrahedron_impl = BB_Tetrahedron_impl< 5 >; + } } diff --git a/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1.hpp b/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1.hpp index 344f2579dfa..0017773fde4 100644 --- a/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1.hpp @@ -36,7 +36,7 @@ namespace finiteElement * @tparam MAXFACENODES The maximum number of nodes per face that the class expects. */ template< localIndex MAXCELLNODES, localIndex MAXFACENODES > -class ConformingVirtualElementOrder1 final : public FiniteElementBase +class ConformingVirtualElementOrder1_impl : public FiniteElementBase_impl< MAXCELLNODES, MAXFACENODES, 1 > { public: /// Type of MeshData::nodesCoords. @@ -69,7 +69,7 @@ class ConformingVirtualElementOrder1 final : public FiniteElementBase * stabilization matrix. Arrays are pre-allocated using @p MAXCELLNODES. * @sa setupStack. */ - struct StackVariables : public FiniteElementBase::StackVariables + struct StackVariables { /// The number of support points. @@ -93,7 +93,7 @@ class ConformingVirtualElementOrder1 final : public FiniteElementBase * @tparam SUBREGION_TYPE The type of mesh sub-region. */ template< typename SUBREGION_TYPE > - struct MeshData : public FiniteElementBase::MeshData< SUBREGION_TYPE > + struct MeshData { /// View to the array containing nodes coordinates. InputNodeCoords nodesCoords; @@ -119,16 +119,18 @@ class ConformingVirtualElementOrder1 final : public FiniteElementBase arrayView1d< real64 const > cellVolumes; }; + /// @copydoc FiniteElementBase_impl::getNumQuadraturePoints() GEOS_HOST_DEVICE - inline - localIndex getNumQuadraturePoints() const override + inline static + localIndex getNumQuadraturePoints() { return numQuadraturePoints; } + /// @copydoc FiniteElementBase_impl::getMaxSupportPoints() GEOS_HOST_DEVICE - inline - virtual localIndex getMaxSupportPoints() const override + inline static + localIndex getMaxSupportPoints() { return maxSupportPoints; } @@ -145,6 +147,34 @@ class ConformingVirtualElementOrder1 final : public FiniteElementBase return stack.numSupportPoints; } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param stack Variables allocated on the stack as filled by @ref setupStack. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & stack, + real64 (& J)[3][3] ) + { + GEOS_UNUSED_VAR( q ); + GEOS_UNUSED_VAR( X ); + for( localIndex i = 0; i < 3; ++i ) + { + for( localIndex j = 0; j < 3; ++j ) + { + J[i][j] = ( i == j ) ? 1.0 : 0.0; + } + } + return stack.quadratureWeight; // * 1.0; + } + /** * @brief Calculate the shape functions projected derivatives wrt the physical * coordinates. @@ -357,8 +387,8 @@ class ConformingVirtualElementOrder1 final : public FiniteElementBase * @return Zero. */ GEOS_HOST_DEVICE - inline - localIndex getNumSupportPoints() const override + inline static + localIndex getNumSupportPoints() { GEOS_ERROR( "VEM functions have to be called with the StackVariables syntax" ); return 0; @@ -444,6 +474,31 @@ class ConformingVirtualElementOrder1 final : public FiniteElementBase return 0.0; } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& J)[3][3] ) + { + GEOS_ERROR( "VEM functions have to be called with the StackVariables syntax" ); + GEOS_UNUSED_VAR( q, X ); + for( localIndex i = 0; i < 3; ++i ) + { + for( localIndex j = 0; j < 3; ++j ) + { + J[i][j] = 0.0; + } + } + return 0.0; + } + /** * @brief This function returns an error, since to get projection of gradients with VEM you have * to use the StackVariables version of this function. @@ -592,10 +647,62 @@ class ConformingVirtualElementOrder1 final : public FiniteElementBase } }; + + +/// @copydoc ConformingVirtualElementOrder1_impl +template< localIndex MAXCELLNODES, localIndex MAXFACENODES > +class ConformingVirtualElementOrder1 final : public ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES >, + public FiniteElementBase +{ +public: + /// The Implementation type + using ImplType = ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES >; + + /// The number of nodes/support points per element. + constexpr static localIndex numNodes = ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES >::numNodes; + + /// The number of faces/support points per element. + constexpr static localIndex numFaces = ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES >::numFaces; + + /// The maximum number of support points per element. + constexpr static localIndex maxSupportPoints = numNodes; + + /// The number of quadrature points per element. + constexpr static localIndex numQuadraturePoints = ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES >::numQuadraturePoints; + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES > * getImpl() + { + return static_cast< ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES > * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + const ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES > * getImpl() const + { + return static_cast< const ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES > * >(this); + } + + ConformingVirtualElementOrder1(): + FiniteElementBase( numNodes, + maxSupportPoints, + numQuadraturePoints ) + {} + + virtual ~ConformingVirtualElementOrder1() override final = default; + + +}; + /// Convenience typedef for VEM on tetrahedra. using H1_Tetrahedron_VEM_Gauss1 = ConformingVirtualElementOrder1< 4, 3 >; #if !defined( GEOS_USE_HIP ) -/// Convenience typedef for VEM on hexahedra. +/// Convenience typedef for VEM on tetrahedra. using H1_Hexahedron_VEM_Gauss1 = ConformingVirtualElementOrder1< 8, 4 >; #endif /// Convenience typedef for VEM on pyramids. @@ -616,12 +723,43 @@ using H1_Prism8_VEM_Gauss1 = ConformingVirtualElementOrder1< 16, 8 >; using H1_Prism9_VEM_Gauss1 = ConformingVirtualElementOrder1< 18, 9 >; /// Convenience typedef for VEM on prism10. using H1_Prism10_VEM_Gauss1 = ConformingVirtualElementOrder1< 20, 10 >; -/// Convenience typedef for VEM on prism11. #if !defined( GEOS_USE_HIP ) +/// Convenience typedef for VEM on prism11. using H1_Prism11_VEM_Gauss1 = ConformingVirtualElementOrder1< 22, 11 >; #endif -} -} + + +/// Convenience typedef for VEM on tetrahedra. +using H1_Tetrahedron_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 4, 3 >; +#if !defined( GEOS_USE_HIP ) +/// Convenience typedef for VEM on hexahedra. +using H1_Hexahedron_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 8, 4 >; +#endif +/// Convenience typedef for VEM on pyramids. +using H1_Pyramid_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 5, 4 >; +#if !defined( GEOS_USE_HIP ) +/// Convenience typedef for VEM on wedges. +using H1_Wedge_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 6, 4 >; +#endif +/// Convenience typedef for VEM on prism5. +using H1_Prism5_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 10, 5 >; +/// Convenience typedef for VEM on prism6. +using H1_Prism6_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 12, 6 >; +/// Convenience typedef for VEM on prism7. +using H1_Prism7_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 14, 7 >; +/// Convenience typedef for VEM on prism8. +using H1_Prism8_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 16, 8 >; +/// Convenience typedef for VEM on prism9. +using H1_Prism9_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 18, 9 >; +/// Convenience typedef for VEM on prism10. +using H1_Prism10_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 20, 10 >; +#if !defined( GEOS_USE_HIP ) +/// Convenience typedef for VEM on prism11. +using H1_Prism11_VEM_Gauss1_impl = ConformingVirtualElementOrder1_impl< 22, 11 >; +#endif + +} // namespace finiteElement +} // namespace geos #include "ConformingVirtualElementOrder1_impl.hpp" diff --git a/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1_impl.hpp b/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1_impl.hpp index 932603a3b9c..7d4552d2cd6 100644 --- a/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1_impl.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/ConformingVirtualElementOrder1_impl.hpp @@ -29,7 +29,7 @@ namespace finiteElement template< localIndex MCN, localIndex MFN > template< typename SUBREGION_TYPE > GEOS_HOST_DEVICE -void ConformingVirtualElementOrder1< MCN, MFN >:: +void ConformingVirtualElementOrder1_impl< MCN, MFN >:: computeProjectors( localIndex const & cellIndex, InputNodeCoords const & nodesCoords, InputCellToNodeMap< SUBREGION_TYPE > const & cellToNodeMap, @@ -55,7 +55,7 @@ computeProjectors( localIndex const & cellIndex, quadratureWeight = cellVolume; // Compute cell diameter. - real64 cellDiameter = ConformingVirtualElementOrder1< MCN, MFN >:: + real64 cellDiameter = ConformingVirtualElementOrder1_impl< MCN, MFN >:: computeDiameter< 3 > ( nodesCoords, cellToNodeMap[cellIndex], numCellPoints ); real64 const invCellDiameter = 1.0/cellDiameter; @@ -280,7 +280,7 @@ computeProjectors( localIndex const & cellIndex, template< localIndex MCN, localIndex MFN > GEOS_HOST_DEVICE -void ConformingVirtualElementOrder1< MCN, MFN >:: +void ConformingVirtualElementOrder1_impl< MCN, MFN >:: computeFaceIntegrals( InputNodeCoords const & nodesCoords, localIndex const (&faceToNodes)[MFN], localIndex const (&faceToEdges)[MFN], @@ -315,7 +315,7 @@ computeFaceIntegrals( InputNodeCoords const & nodesCoords, faceRotationMatrix[ 1 ][ 2 ]*nodesCoords( faceToNodes[ numVertex ], 1 ) + faceRotationMatrix[ 2 ][ 2 ]*nodesCoords( faceToNodes[ numVertex ], 2 ); } - faceDiameter = ConformingVirtualElementOrder1< MCN, MFN >:: + faceDiameter = ConformingVirtualElementOrder1_impl< MCN, MFN >:: computeDiameter< 2 >( faceRotatedVertices, numFaceVertices ); real64 const invFaceDiameter = 1.0/faceDiameter; diff --git a/src/coreComponents/finiteElement/elementFormulations/FiniteElementBase.hpp b/src/coreComponents/finiteElement/elementFormulations/FiniteElementBase.hpp index b834a019513..ebe38852e8f 100644 --- a/src/coreComponents/finiteElement/elementFormulations/FiniteElementBase.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/FiniteElementBase.hpp @@ -17,11 +17,6 @@ * @file FiniteElementBase.hpp */ -#if defined(GEOS_USE_DEVICE) -#define CALC_FEM_SHAPE_IN_KERNEL -#endif - - #ifndef GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_FINITEELEMENTBASE_HPP_ #define GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_FINITEELEMENTBASE_HPP_ @@ -39,76 +34,150 @@ namespace geos namespace finiteElement { -/** - * @brief Base class for FEM element implementations. - */ -class FiniteElementBase +/// @brief Device-compatible (non virtual) Base class for all finite element formulations. +template< int NUM_SUPPORT_POINTS, + int NUM_FACES, + int NUM_QUADRATURE_POINTS > +class FiniteElementBase_impl { public: - /// Default Constructor - FiniteElementBase() = default; + /// The number of nodes per element. + constexpr static localIndex numNodes = NUM_SUPPORT_POINTS; + + /// The number of support points per element. + constexpr static localIndex numSupportPoints = NUM_SUPPORT_POINTS; + + /// The maximum number of support points per element. + constexpr static localIndex maxSupportPoints = numSupportPoints; + + /// The number of faces per element. + constexpr static localIndex numFaces = NUM_FACES; + /// The number of quadrature points per element. + constexpr static localIndex numQuadraturePoints = NUM_QUADRATURE_POINTS; /// Number of sampling points. constexpr static int numSamplingPointsPerDirection = 10; + /// The number of sampling points per element. + constexpr static int numSamplingPoints = numSamplingPointsPerDirection * numSamplingPointsPerDirection * numSamplingPointsPerDirection; + +#ifdef __CUDACC__ + #pragma diag_push + #pragma nv_diag_suppress 20012 +#endif + /// Default constructor. + GEOS_HOST_DEVICE FiniteElementBase_impl() = default; + /// Default destructor. + GEOS_HOST_DEVICE ~FiniteElementBase_impl() = default; + /// Default copy constructor. + GEOS_HOST_DEVICE FiniteElementBase_impl( FiniteElementBase_impl const & ) = default; + /** + * @brief Default copy assignment operator. + * @return A reference to this object. + */ + GEOS_HOST_DEVICE FiniteElementBase_impl & operator=( FiniteElementBase_impl const & ) = default; + /// Default move constructor. + GEOS_HOST_DEVICE FiniteElementBase_impl( FiniteElementBase_impl && ) = default; + /** + * @brief Default move assignment operator. + * @return A reference to this object. + */ + GEOS_HOST_DEVICE FiniteElementBase_impl & operator=( FiniteElementBase_impl && ) = default; +#ifdef __CUDACC__ + #pragma diag_pop +#endif + /** - * @brief Copy Constructor - * @param source The object to copy. + * @struct StackVariables + * @brief Kernel variables allocated on the stack. + * + * Contains variables that will be allocated on the stack. Used only by Virtual Element classes to + * hold the computed projections of basis functions + */ + struct StackVariables + {}; + + /** + * @struct MeshData + * @brief Variables used to initialize the class. + */ + template< typename SUBREGION_TYPE > + struct MeshData + {}; + + /** + * @brief Get the number of quadrature points. + * @return The number of quadrature points. */ GEOS_HOST_DEVICE - FiniteElementBase( FiniteElementBase const & source ): -#ifdef CALC_FEM_SHAPE_IN_KERNEL - m_viewGradN(), - m_viewDetJ() -#else - m_viewGradN( source.m_viewGradN ), - m_viewDetJ( source.m_viewDetJ ) -#endif + static localIndex getNumQuadraturePoints() { - GEOS_UNUSED_VAR( source ); // suppress warning when CALC_FEM_SHAPE_IN_KERNEL is defined + return numQuadraturePoints; } - /// Default Move constructor - FiniteElementBase( FiniteElementBase && ) = default; - /** - * @brief Deleted copy assignment operator - * @return deleted + * @brief Get the number of quadrature points. + * @param stack Stack variables as filled by @ref setupStack. + * @return The number of quadrature points. */ - FiniteElementBase & operator=( FiniteElementBase const & ) = delete; + template< typename STACK_VARIABLES_TYPE > + GEOS_HOST_DEVICE + static localIndex getNumQuadraturePoints( STACK_VARIABLES_TYPE const & stack ) + { + GEOS_UNUSED_VAR( stack ); + return numQuadraturePoints; + } /** - * @brief Deleted move assignment operator - * @return deleted + * @brief Get the number of support points. + * @return The number of support points. */ - FiniteElementBase & operator=( FiniteElementBase && ) = delete; + GEOS_HOST_DEVICE + static localIndex getNumSupportPoints() + { + return numNodes; + } /** - * @brief Destructor + * @brief Get the number of support points. + * @param stack Object that holds stack variables. + * @return The number of support points. */ + template< typename STACK_VARIABLES_TYPE > GEOS_HOST_DEVICE - virtual ~FiniteElementBase() - {} + static localIndex getNumSupportPoints( STACK_VARIABLES_TYPE const & stack ) + { + GEOS_UNUSED_VAR( stack ); + return numNodes; + } /** - * @struct StackVariables - * @brief Kernel variables allocated on the stack. - * - * Contains variables that will be allocated on the stack. Used only by Virtual Element classes to - * hold the computed projections of basis functions + * @brief Get the maximum number of support points. + * @return The maximum number of support points. */ - struct StackVariables - {}; + GEOS_HOST_DEVICE + static localIndex getMaxSupportPoints() + { + return maxSupportPoints; + } /** - * @struct MeshData - * @brief Variables used to initialize the class. + * @brief Get the Sampling Point Coord In the Parent Space + * + * @param linearIndex linear index of the sampling point + * @param samplingPointCoord coordinates of the sampling point */ - template< typename SUBREGION_TYPE > - struct MeshData - {}; + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static void getSamplingPointCoordInParentSpace( int const & linearIndex, + real64 (& samplingPointCoord)[3] ) + { + GEOS_UNUSED_VAR( linearIndex, samplingPointCoord ); + GEOS_ERROR( " Element type not supported." ); + } + /** @@ -119,12 +188,13 @@ class FiniteElementBase * @param cellSubRegion The cell sub-region for which the element has to be initialized. * @param meshData MeshData struct to be filled. */ - template< typename SUBREGION_TYPE > + template< typename SUBREGION_TYPE, + typename MESH_DATA_TYPE > static void fillMeshData( NodeManager const & nodeManager, EdgeManager const & edgeManager, FaceManager const & faceManager, SUBREGION_TYPE const & cellSubRegion, - MeshData< SUBREGION_TYPE > & meshData ) + MESH_DATA_TYPE & meshData ) { GEOS_UNUSED_VAR( nodeManager, edgeManager, @@ -143,12 +213,14 @@ class FiniteElementBase * @param cellSubRegion The cell sub-region for which the element has to be initialized. * @param meshData The struct to be filled according to the @p LEAF class needs. */ - template< typename LEAF, typename SUBREGION_TYPE > + template< typename LEAF, + typename SUBREGION_TYPE, + typename MESH_DATA_TYPE > static void initialize( NodeManager const & nodeManager, EdgeManager const & edgeManager, FaceManager const & faceManager, SUBREGION_TYPE const & cellSubRegion, - typename LEAF::template MeshData< SUBREGION_TYPE > & meshData + MESH_DATA_TYPE & meshData ) { LEAF::template fillMeshData< SUBREGION_TYPE >( nodeManager, @@ -165,12 +237,13 @@ class FiniteElementBase * @param meshData MeshData struct filled by @ref fillMeshData. * @param stack Object that holds stack variables. */ - template< typename SUBREGION_TYPE > + template< typename MESH_DATA_TYPE, + typename STACK_VARIABLES_TYPE > GEOS_HOST_DEVICE GEOS_FORCE_INLINE static void setupStack( localIndex const & cellIndex, - MeshData< SUBREGION_TYPE > const & meshData, - StackVariables & stack ) + MESH_DATA_TYPE const & meshData, + STACK_VARIABLES_TYPE & stack ) { GEOS_UNUSED_VAR( cellIndex, meshData, @@ -178,6 +251,7 @@ class FiniteElementBase } + /** * @brief Abstract setup method, possibly computing cell-dependent properties. * @tparam LEAF Type of the derived finite element implementation. @@ -186,37 +260,16 @@ class FiniteElementBase * @param meshData A MeshData object previously filled. * @param stack Object that holds stack variables. */ - template< typename LEAF, typename SUBREGION_TYPE > + template< typename LEAF, + typename MESH_DATA_TYPE > GEOS_HOST_DEVICE void setup( localIndex const & cellIndex, - typename LEAF::template MeshData< SUBREGION_TYPE > const & meshData, + MESH_DATA_TYPE const & meshData, typename LEAF::StackVariables & stack ) const { LEAF::setupStack( cellIndex, meshData, stack ); } - /** - * @brief Virtual getter for the number of quadrature points per element. - * @return The number of quadrature points per element. - */ - GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const = 0; - - /** - * @brief Virtual getter for the number of support points per element. - * @return The number of support points per element. - */ - GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const = 0; - - /** - * @brief An helper struct to determine the function space. - * @tparam N The number of components per support point (i.e., 1 if - * scalar variable, 3 if vector variable) - */ - template< int N > - struct FunctionSpaceHelper - {}; /** * @brief Getter for the function space. @@ -226,104 +279,22 @@ class FiniteElementBase */ template< int N > GEOS_HOST_DEVICE - constexpr static PDEUtilities::FunctionSpace getFunctionSpace(); - - /** - * @brief Getter for the number of support points per element. - * @tparam LEAF Type of the derived finite element implementation. - * @param stack Stack variables created by a call to @ref setup. - * @return The number of support points per element. - */ - template< typename LEAF > - GEOS_HOST_DEVICE - localIndex numSupportPoints( typename LEAF::StackVariables const & stack ) const + constexpr static PDEUtilities::FunctionSpace getFunctionSpace() { - return LEAF::getNumSupportPoints( stack ); + if constexpr ( N == 1 ) + { + return PDEUtilities::FunctionSpace::H1; + } + else if constexpr ( N == 3 ) + { + return PDEUtilities::FunctionSpace::H1vector; + } + else + { + static_assert( N == 1 || N == 3, "Unsupported number of components per support point" ); + } } - /** - * @brief Get the maximum number of support points for this element. - * @details This should be used to know the size of pre-allocated objects whose size depend on the - * number of support points. - * @return The number of maximum support points for this element. - */ - GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const = 0; - - /** - * @brief Get the shape function gradients. - * @tparam LEAF Type of the derived finite element implementation. - * @param k The element index. - * @param q The quadrature point index. - * @param X Array of coordinates as the reference for the gradients. - * @param gradN Return array of the shape function gradients. - * @return The determinant of the Jacobian transformation matrix. - * - * This function calls the function to calculate shape function gradients. - */ - template< typename LEAF > - GEOS_HOST_DEVICE - real64 getGradN( localIndex const k, - localIndex const q, - real64 const (&X)[LEAF::maxSupportPoints][3], - real64 ( &gradN )[LEAF::maxSupportPoints][3] ) const; - - /** - * @brief Get the shape function gradients. - * @tparam LEAF Type of the derived finite element implementation. - * @param k The element index. - * @param q The quadrature point index. - * @param X Array of coordinates as the reference for the gradients. - * @param stack Stack variables relative to the element @p k created by a call to @ref setup. - * @param gradN Return array of the shape function gradients. - * @return The determinant of the Jacobian transformation matrix. - * - * This function calls the function to calculate shape function gradients. - */ - template< typename LEAF > - GEOS_HOST_DEVICE - real64 getGradN( localIndex const k, - localIndex const q, - real64 const (&X)[LEAF::maxSupportPoints][3], - typename LEAF::StackVariables const & stack, - real64 ( &gradN )[LEAF::maxSupportPoints][3] ) const; - - /** - * @brief Get the shape function gradients. - * @tparam LEAF Type of the derived finite element implementation. - * @param k The element index. - * @param q The quadrature point index. - * @param X dummy variable. - * @param gradN Return array of the shape function gradients. - * @return The determinant of the Jacobian transformation matrix. - * - * This function returns pre-calculated shape function gradients. - */ - template< typename LEAF > - GEOS_HOST_DEVICE - real64 getGradN( localIndex const k, - localIndex const q, - int const X, - real64 ( &gradN )[LEAF::maxSupportPoints][3] ) const; - /** - * @brief Get the shape function gradients. - * @tparam LEAF Type of the derived finite element implementation. - * @param k The element index. - * @param q The quadrature point index. - * @param X dummy variable. - * @param stack Stack variables relative to the element @p k created by a call to @ref setup. - * @param gradN Return array of the shape function gradients. - * @return The determinant of the Jacobian transformation matrix. - * - * This function returns pre-calculated shape function gradients. - */ - template< typename LEAF > - GEOS_HOST_DEVICE - real64 getGradN( localIndex const k, - localIndex const q, - int const X, - typename LEAF::StackVariables const & stack, - real64 ( &gradN )[LEAF::maxSupportPoints][3] ) const; /** @@ -336,13 +307,14 @@ class FiniteElementBase * @param matrix The matrix that needs to be stabilized. * @param scaleFactor Scaling of the stabilization matrix. */ - template< localIndex NUMDOFSPERTRIALSUPPORTPOINT, localIndex MAXSUPPORTPOINTS, bool UPPER > + template< localIndex NUMDOFSPERTRIALSUPPORTPOINT, + localIndex MAXSUPPORTPOINTS, + bool UPPER, + typename STACK_VARIABLES_TYPE > GEOS_HOST_DEVICE GEOS_FORCE_INLINE - static void addGradGradStabilization( StackVariables const & stack, - real64 ( & matrix ) - [MAXSUPPORTPOINTS * NUMDOFSPERTRIALSUPPORTPOINT] - [MAXSUPPORTPOINTS * NUMDOFSPERTRIALSUPPORTPOINT], + static void addGradGradStabilization( STACK_VARIABLES_TYPE const & stack, + real64 ( & matrix )[MAXSUPPORTPOINTS * NUMDOFSPERTRIALSUPPORTPOINT][MAXSUPPORTPOINTS * NUMDOFSPERTRIALSUPPORTPOINT], real64 const & scaleFactor ) { GEOS_UNUSED_VAR( stack, @@ -351,6 +323,7 @@ class FiniteElementBase } + /** * @brief Add stabilization of grad-grad bilinear form to input matrix. * @tparam LEAF Type of the derived finite element implementation. @@ -363,9 +336,7 @@ class FiniteElementBase template< typename LEAF, localIndex NUMDOFSPERTRIALSUPPORTPOINT, bool UPPER = false > GEOS_HOST_DEVICE void addGradGradStabilizationMatrix( typename LEAF::StackVariables const & stack, - real64 ( & matrix ) - [LEAF::maxSupportPoints * NUMDOFSPERTRIALSUPPORTPOINT] - [LEAF::maxSupportPoints * NUMDOFSPERTRIALSUPPORTPOINT], + real64 ( & matrix )[LEAF::maxSupportPoints * NUMDOFSPERTRIALSUPPORTPOINT][LEAF::maxSupportPoints * NUMDOFSPERTRIALSUPPORTPOINT], real64 const scaleFactor = 1.0 ) const { LEAF::template addGradGradStabilization< NUMDOFSPERTRIALSUPPORTPOINT, @@ -388,10 +359,12 @@ class FiniteElementBase * @p NUMDOFSPERTRIALSUPPORTPOINT. * @param scaleFactor Scaling of the stabilization matrix. */ - template< localIndex NUMDOFSPERTRIALSUPPORTPOINT, localIndex MAXSUPPORTPOINTS > + template< localIndex NUMDOFSPERTRIALSUPPORTPOINT, + localIndex MAXSUPPORTPOINTS, + typename STACK_VARIABLES_TYPE > GEOS_HOST_DEVICE GEOS_FORCE_INLINE - static void addEvaluatedGradGradStabilization( StackVariables const & stack, + static void addEvaluatedGradGradStabilization( STACK_VARIABLES_TYPE const & stack, real64 const ( &dofs )[MAXSUPPORTPOINTS][NUMDOFSPERTRIALSUPPORTPOINT], real64 ( & targetVector )[MAXSUPPORTPOINTS][NUMDOFSPERTRIALSUPPORTPOINT], real64 const scaleFactor ) @@ -433,640 +406,66 @@ class FiniteElementBase scaleFactor ); } - /** - * @name Value Operator Functions - */ - ///@{ - - /** - * @brief Compute the interpolated value of a variable. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @param N Array (for each support point) of shape function values at the - * coordinate the variable is to be interpolated. - * @param var Array of variable values for each support point. - * @param value The interpolated value of @p var. - * - * This is the standard finite element interpolation operator of a discrete - * variable defined at the support points. - * The operator is expressed as: - * \f[ - * value = \sum_a^{numSupport} \left ( N_a var_a \right ), - * \f] - - * @note The shape function values @p N must be evaluated prior to calling this - * function. - * - */ - template< int NUM_SUPPORT_POINTS > - GEOS_HOST_DEVICE - static - void value( real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&var)[NUM_SUPPORT_POINTS], - real64 & value ); - - /** - * @brief Compute the interpolated value of a vector variable. - * @tparam NUM_COMPONENTS Number of components for the vector variable. - * @copydoc value - */ - template< int NUM_SUPPORT_POINTS, - int NUM_COMPONENTS > - GEOS_HOST_DEVICE - static - void value( real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&var)[NUM_SUPPORT_POINTS][NUM_COMPONENTS], - real64 ( &value )[NUM_COMPONENTS] ); - - ///@} - - /** - * @name Gradient Operator Functions - */ - ///@{ - - /** - * @brief Calculate the symmetric gradient of a vector valued support field - * at a point using the stored basis function gradients for all support - * points. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @tparam GRADIENT_TYPE The type of the array object holding the shape - * @param gradN The basis function gradients at a point in the element. - * @param var The vector valued support field that the gradient operator will - * be applied to. - * @param gradVar The symmetric gradient in Voigt notation. - * - * More precisely, the operator is defined as: - * \f[ - * grad^s_{ij} = \frac{1}{2} \sum_a^{nSupport} \left ( \frac{\partial N_a}{\partial X_j} var_{ai} + \frac{\partial N_a}{\partial X_i} - * var_{aj}\right ), - * \f] - * - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void symmetricGradient( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS][3], - real64 ( &gradVar )[6] ); - - /** - * @brief Calculate the trace of the symmetric gradient of a vector valued support - * field (i.e. the volumetric strain for the displacement field) at a point using - * the stored basis function gradients for all support points. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @tparam GRADIENT_TYPE The type of the array object holding the shape - * @param gradN The basis function gradients at a point in the element. - * @param var The vector valued support field that the gradient operator will - * be applied to. - * @return The trace of the symetric gradient tensor. - * - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static real64 symmetricGradientTrace( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS][3] ); - /** - * @brief Calculate the gradient of a scalar valued support field at a point - * using the input basis function gradients. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @tparam GRADIENT_TYPE The type of the array object holding the shape - * function gradients. - * @param gradN The basis function gradients at a point in the element. - * @param var The vector valued support field that the gradient operator will - * be applied to. - * @param gradVar The gradient. - * - * More precisely, the operator is defined as: - * \f[ - * grad_{j} = \sum_a^{nSupport} \left ( \frac{\partial N_a}{\partial X_j} var_{a}\right ), - * \f] - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void gradient( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS], - real64 ( &gradVar )[3] ); - - /** - * @brief Calculate the gradient of a vector valued support field at a point - * using the input basis function gradients. - * @copydoc gradient - * - * More precisely, the operator is defined as: - * \f[ - * grad_{ij} = \sum_a^{nSupport} \left ( \frac{\partial N_a}{\partial X_j} var_{ai}\right ), - * \f] - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void gradient( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS][3], - real64 ( &gradVar )[3][3] ); - ///@} - - /** - * @name Multi-Operator Functions - */ - ///@{ - - /** - * @brief Calculate the value and gradient of a scalar valued support field - * at a point using the input basis function gradients. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @tparam GRADIENT_TYPE The type of the array object holding the shape - * @param N Array (for each support point) of shape function values at the - * coordinate the variable is to be interpolated. - * @param gradN The basis function gradients at a point in the element. - * @param var The vector valued support field that the gradient operator will - * be applied to. - * @param value The value at the point for which N was specified. - * @param gradVar The gradient at the point for which gradN was specified. - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void valueAndGradient( real64 const (&N)[NUM_SUPPORT_POINTS], - GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS], - real64 & value, - real64 ( &gradVar )[3] ); - - ///@} - - /** - * @name Scattering Operator Functions - * - * These functions take quadrature data and map it to the support points - * through some operator. - */ - ///@{ - - /** - * @brief Inner product of each basis function gradient with a rank-2 - * symmetric tensor. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @tparam GRADIENT_TYPE The type of the array object holding the shape - * function gradients. - * @param gradN The basis function gradients at a point in the element. - * @param var_detJxW The rank-2 tensor at @p q scaled by J*W. - * @param R The vector at each support point which will hold the result from - * the tensor contraction. - * - * More precisely, the operator is defined as: - * - * \f[ - * R_i = \sum_a^{nSupport} \left( \frac{\partial N_a}{\partial X_j} var_{ij}\right), - * \f] - * - * where \f$\frac{\partial N_a}{\partial X_j}\f$ is the basis function gradient, - * \f$var_{ij}\f$ is the rank-2 symmetric tensor. - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void plusGradNajAij( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[6], - real64 ( &R )[NUM_SUPPORT_POINTS][3] ); - - /** - * @copydoc plusGradNajAij - * @brief Inner product of each basis function gradient with a rank-2 - * tensor. - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void plusGradNajAij( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[3][3], - real64 ( &R )[NUM_SUPPORT_POINTS][3] ); +}; - /** - * @brief Product of each shape function with a vector forcing term. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @param N The shape function value at a predetermined coordinate in the element. - * @param forcingTerm_detJxW A vector scaled by detJxW - * @param R The vector at each support point which will hold the result from - * the tensor contraction. - */ - template< int NUM_SUPPORT_POINTS > - GEOS_HOST_DEVICE - static void plusNaFi( real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&forcingTerm_detJxW)[3], - real64 ( &R )[NUM_SUPPORT_POINTS][3] ); - /** - * @brief Inner product of each basis function gradient with a rank-2 - * symmetric tensor added to the product each shape function with a vector. - * @tparam NUM_SUPPORT_POINTS The number of support points for the element. - * @tparam GRADIENT_TYPE The type of the array object holding the shape - * function gradients. - * @param gradN The basis function gradients at a point in the element. - * @param var_detJxW The rank-2 symmetric tensor at @p q scaled by J*W. - * @param N The shape function value at a predetermined coordinate in the element. - * @param forcingTerm_detJxW A vector scaled by detJxW - * @param R The vector at each support point which will hold the result from - * the tensor contraction. - * - * \f[ - * R_i = \sum_a^{nSupport} \left ( \frac{\partial N_a}{\partial X_j} var_{ij} + N_a f_i \right ), - * \f] - */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void plusGradNajAijPlusNaFi( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[3][3], - real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&forcingTerm_detJxW)[3], - real64 ( &R )[NUM_SUPPORT_POINTS][3] ); +/** + * @brief Base class for FEM element implementations. + */ +class FiniteElementBase +{ +public: /** - * @brief Inner product of each basis function gradient with a rank-2 - * tensor added to the product each shape function with a vector. - * @copydoc plusGradNajAijPlusNaFi + * @brief Default constructor. + * @param numSupportPoints The number of support points. + * @param maxSupportPoints The maximum number of support points. + * @param numQuadraturePoints The number of quadrature points. */ - template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > - GEOS_HOST_DEVICE - static void plusGradNajAijPlusNaFi( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[6], - real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&forcingTerm_detJxW)[3], - real64 ( &R )[NUM_SUPPORT_POINTS][3] ); - + FiniteElementBase( localIndex const numSupportPoints, + localIndex const maxSupportPoints, + localIndex const numQuadraturePoints ): + m_numSupportPoints( numSupportPoints ), + m_maxSupportPoints( maxSupportPoints ), + m_numQuadraturePoints( numQuadraturePoints ) + { } /** - * @brief Sets m_viewGradN equal to an input view. - * @param source The view to assign to m_viewGradN. + * @brief Destructor */ - void setGradNView( arrayView4d< real64 const > const & source ) - { - GEOS_ERROR_IF_NE_MSG( source.size( 1 ), - getNumQuadraturePoints(), - "2nd-dimension of gradN array does not match number of quadrature points" ); - GEOS_ERROR_IF_NE_MSG( source.size( 2 ), - getMaxSupportPoints(), - "3rd-dimension of gradN array does not match number of support points" ); - GEOS_ERROR_IF_NE_MSG( source.size( 3 ), - 3, - "4th-dimension of gradN array does not match 3" ); - - m_viewGradN = source; - } + virtual ~FiniteElementBase() = default; /** - * @brief Sets m_viewDetJ equal to an input view. - * @param source The view to assign to m_viewDetJ. + * @brief Getter for the number of quadrature points per element. + * @return The number of quadrature points per element. */ - void setDetJView( arrayView2d< real64 const > const & source ) + localIndex getNumQuadraturePoints() const { - GEOS_ERROR_IF_NE_MSG( source.size( 1 ), - getNumQuadraturePoints(), - "2nd-dimension of gradN array does not match number of quadrature points" ); - m_viewDetJ = source; + return m_numQuadraturePoints; } /** - * @brief Getter for m_viewGradN - * @return A new arrayView copy of m_viewGradN. + * @brief Getter for the number of support points per element. + * @return The number of support points per element. */ - arrayView4d< real64 const > getGradNView() const - { - return m_viewGradN; - } + localIndex getNumSupportPoints() const { return m_numSupportPoints; }; /** - * @brief Getter for m_viewDetJ - * @return A new arrayView copy of m_viewDetJ. + * @brief Get the maximum number of support points for this element. + * @details This should be used to know the size of pre-allocated objects whose size depend on the + * number of support points. + * @return The number of maximum support points for this element. */ - arrayView2d< real64 const > getDetJView() const - { - return m_viewDetJ; - } + localIndex getMaxSupportPoints() const { return m_maxSupportPoints; }; - -protected: - /// View to potentially hold pre-calculated shape function gradients. - arrayView4d< real64 const > m_viewGradN; - - /// View to potentially hold pre-calculated weighted jacobian transformation - /// determinants. - arrayView2d< real64 const > m_viewDetJ; -}; - -/// @cond Doxygen_Suppress - -//************************************************************************************************* -//***** Definitions ******************************************************************************* -//************************************************************************************************* - -template<> -struct FiniteElementBase::FunctionSpaceHelper< 1 > -{ - GEOS_HOST_DEVICE - constexpr static PDEUtilities::FunctionSpace getFunctionSpace() - { - return PDEUtilities::FunctionSpace::H1; - } -}; - -template<> -struct FiniteElementBase::FunctionSpaceHelper< 3 > -{ - GEOS_HOST_DEVICE - constexpr static PDEUtilities::FunctionSpace getFunctionSpace() - { - return PDEUtilities::FunctionSpace::H1vector; - } +private: + localIndex const m_numSupportPoints; + localIndex const m_maxSupportPoints; + localIndex const m_numQuadraturePoints; }; -template< int N > -GEOS_HOST_DEVICE -constexpr PDEUtilities::FunctionSpace FiniteElementBase::getFunctionSpace() -{ - return FunctionSpaceHelper< N >::getFunctionSpace(); -} - -template< typename LEAF > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -real64 FiniteElementBase::getGradN( localIndex const k, - localIndex const q, - real64 const (&X)[LEAF::maxSupportPoints][3], - real64 (& gradN)[LEAF::maxSupportPoints][3] ) const -{ - GEOS_UNUSED_VAR( k ); - return LEAF::calcGradN( q, X, gradN ); -} - -template< typename LEAF > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -real64 FiniteElementBase::getGradN( localIndex const k, - localIndex const q, - real64 const (&X)[LEAF::maxSupportPoints][3], - typename LEAF::StackVariables const & stack, - real64 ( & gradN )[LEAF::maxSupportPoints][3] ) const -{ - GEOS_UNUSED_VAR( k ); - return LEAF::calcGradN( q, X, stack, gradN ); -} - -template< typename LEAF > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -real64 FiniteElementBase::getGradN( localIndex const k, - localIndex const q, - int const X, - real64 (& gradN)[LEAF::maxSupportPoints][3] ) const -{ - GEOS_UNUSED_VAR( X ); - - LvArray::tensorOps::copy< LEAF::maxSupportPoints, 3 >( gradN, m_viewGradN[ k ][ q ] ); - - return m_viewDetJ( k, q ); -} - -template< typename LEAF > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -real64 FiniteElementBase::getGradN( localIndex const k, - localIndex const q, - int const X, - typename LEAF::StackVariables const & stack, - real64 (& gradN)[LEAF::maxSupportPoints][3] ) const -{ - GEOS_UNUSED_VAR( X ); - GEOS_UNUSED_VAR( stack ); - - LvArray::tensorOps::copy< LEAF::maxSupportPoints, 3 >( gradN, m_viewGradN[ k ][ q ] ); - - return m_viewDetJ( k, q ); -} - -//************************************************************************************************* -//***** Interpolated Value Functions ************************************************************** -//************************************************************************************************* - -template< int NUM_SUPPORT_POINTS > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::value( real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&var)[NUM_SUPPORT_POINTS], - real64 & value ) -{ - value = LvArray::tensorOps::AiBi< NUM_SUPPORT_POINTS >( N, var ); -} - -template< int NUM_SUPPORT_POINTS, - int NUM_COMPONENTS > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::value( real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&var)[NUM_SUPPORT_POINTS][NUM_COMPONENTS], - real64 (& value)[NUM_COMPONENTS] ) -{ - - LvArray::tensorOps::Ri_eq_AjiBj< 3, NUM_SUPPORT_POINTS >( value, var, N ); -} - - -//************************************************************************************************* -//***** Variable Gradient Functions *************************************************************** -//************************************************************************************************* - -template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::symmetricGradient( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS][3], - real64 (& gradVar)[6] ) -{ - gradVar[0] = gradN[0][0] * var[0][0]; - gradVar[1] = gradN[0][1] * var[0][1]; - gradVar[2] = gradN[0][2] * var[0][2]; - gradVar[3] = gradN[0][2] * var[0][1] + gradN[0][1] * var[0][2]; - gradVar[4] = gradN[0][2] * var[0][0] + gradN[0][0] * var[0][2]; - gradVar[5] = gradN[0][1] * var[0][0] + gradN[0][0] * var[0][1]; - - for( int a=1; a -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -real64 FiniteElementBase::symmetricGradientTrace( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS][3] ) -{ - real64 result = gradN[0][0] * var[0][0] + gradN[0][1] * var[0][1] + gradN[0][2] * var[0][2]; - - for( int a=1; a -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::gradient( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS], - real64 (& gradVar)[3] ) -{ - LvArray::tensorOps::Ri_eq_AjiBj< 3, NUM_SUPPORT_POINTS >( gradVar, gradN, var ); -} - -template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::gradient( GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS][3], - real64 (& gradVar)[3][3] ) -{ - LvArray::tensorOps::Rij_eq_AkiBkj< 3, 3, NUM_SUPPORT_POINTS >( gradVar, var, gradN ); -} - - - -template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::valueAndGradient( real64 const (&N)[NUM_SUPPORT_POINTS], - GRADIENT_TYPE const & gradN, - real64 const (&var)[NUM_SUPPORT_POINTS], - real64 & value, - real64 (& gradVar)[3] ) -{ - value = N[0] * var[0]; - for( int i = 0; i < 3; ++i ) - { - gradVar[i] = var[0] * gradN[0][i]; - } - - for( int a=1; a -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::plusGradNajAij( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[6], - real64 (& R)[NUM_SUPPORT_POINTS][3] ) -{ - for( int a=0; a -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::plusGradNajAij( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[3][3], - real64 (& R)[NUM_SUPPORT_POINTS][3] ) -{ - for( int a=0; a( R[a], var_detJxW, gradN[a] ); - } -} - -template< int NUM_SUPPORT_POINTS > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::plusNaFi( real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&var_detJxW)[3], - real64 ( & R )[NUM_SUPPORT_POINTS][3] ) -{ - for( int a=0; a( R[a], var_detJxW, N[a] ); - } -} - - -template< int NUM_SUPPORT_POINTS, - typename GRADIENT_TYPE > -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::plusGradNajAijPlusNaFi( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[6], - real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&forcingTerm_detJxW)[3], - real64 (& R)[NUM_SUPPORT_POINTS][3] ) -{ - for( int a=0; a -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void FiniteElementBase::plusGradNajAijPlusNaFi( GRADIENT_TYPE const & gradN, - real64 const (&var_detJxW)[3][3], - real64 const (&N)[NUM_SUPPORT_POINTS], - real64 const (&forcingTerm_detJxW)[3], - real64 (& R)[NUM_SUPPORT_POINTS][3] ) -{ - for( int a=0; a +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void value( real64 const (&N)[NUM_SUPPORT_POINTS], + real64 const (&var)[NUM_SUPPORT_POINTS], + real64 & value ) +{ + value = LvArray::tensorOps::AiBi< NUM_SUPPORT_POINTS >( N, var ); +} + +/** + * @brief Compute the interpolated value of a vector variable. + * @tparam NUM_COMPONENTS Number of components for the vector variable. + * @copydoc value + */ +template< int NUM_SUPPORT_POINTS, + int NUM_COMPONENTS > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void value( real64 const (&N)[NUM_SUPPORT_POINTS], + real64 const (&var)[NUM_SUPPORT_POINTS][NUM_COMPONENTS], + real64 (& value)[NUM_COMPONENTS] ) +{ + LvArray::tensorOps::Ri_eq_AjiBj< NUM_COMPONENTS, NUM_SUPPORT_POINTS >( value, var, N ); +} + +///@} + +/** + * @name Gradient Operator Functions + */ +///@{ + +/** + * @brief Calculate the symmetric gradient of a vector valued support field + * at a point using the stored basis function gradients for all support + * points. + * @tparam NUM_SUPPORT_POINTS The number of support points for the element. + * @tparam GRADIENT_TYPE The type of the array object holding the shape + * @param gradN The basis function gradients at a point in the element. + * @param var The vector valued support field that the gradient operator will + * be applied to. + * @param gradVar The symmetric gradient in Voigt notation. + * + * More precisely, the operator is defined as: + * \f[ + * grad^s_{ij} = \frac{1}{2} \sum_a^{nSupport} \left ( \frac{\partial N_a}{\partial X_j} var_{ai} + \frac{\partial N_a}{\partial X_i} + * var_{aj}\right ), + * \f] + * + */ +template< int NUM_SUPPORT_POINTS, + typename GRADIENT_TYPE > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void symmetricGradient( GRADIENT_TYPE const & gradN, + real64 const (&var)[NUM_SUPPORT_POINTS][3], + real64 (& gradVar)[6] ) +{ + gradVar[0] = gradN[0][0] * var[0][0]; + gradVar[1] = gradN[0][1] * var[0][1]; + gradVar[2] = gradN[0][2] * var[0][2]; + gradVar[3] = gradN[0][2] * var[0][1] + gradN[0][1] * var[0][2]; + gradVar[4] = gradN[0][2] * var[0][0] + gradN[0][0] * var[0][2]; + gradVar[5] = gradN[0][1] * var[0][0] + gradN[0][0] * var[0][1]; + + for( int a=1; a +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 symmetricGradientTrace( GRADIENT_TYPE const & gradN, + real64 const (&var)[NUM_SUPPORT_POINTS][3] ) +{ + real64 result = gradN[0][0] * var[0][0] + gradN[0][1] * var[0][1] + gradN[0][2] * var[0][2]; + + for( int a=1; a +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void gradient( GRADIENT_TYPE const & gradN, + real64 const (&var)[NUM_SUPPORT_POINTS], + real64 (& gradVar)[3] ) +{ + LvArray::tensorOps::Ri_eq_AjiBj< 3, NUM_SUPPORT_POINTS >( gradVar, gradN, var ); +} + +/** + * @brief Calculate the gradient of a vector valued support field at a point + * using the input basis function gradients. + * @copydoc gradient + * + * More precisely, the operator is defined as: + * \f[ + * grad_{ij} = \sum_a^{nSupport} \left ( \frac{\partial N_a}{\partial X_j} var_{ai}\right ), + * \f] + */ +template< int NUM_SUPPORT_POINTS, + typename GRADIENT_TYPE > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void gradient( GRADIENT_TYPE const & gradN, + real64 const (&var)[NUM_SUPPORT_POINTS][3], + real64 (& gradVar)[3][3] ) +{ + LvArray::tensorOps::Rij_eq_AkiBkj< 3, 3, NUM_SUPPORT_POINTS >( gradVar, var, gradN ); +} + +///@} + +/** + * @name Multi-Operator Functions + */ +///@{ + +/** + * @brief Calculate the value and gradient of a scalar valued support field + * at a point using the input basis function gradients. + * @tparam NUM_SUPPORT_POINTS The number of support points for the element. + * @tparam GRADIENT_TYPE The type of the array object holding the shape + * @param N Array (for each support point) of shape function values at the + * coordinate the variable is to be interpolated. + * @param gradN The basis function gradients at a point in the element. + * @param var The vector valued support field that the gradient operator will + * be applied to. + * @param value The value at the point for which N was specified. + * @param gradVar The gradient at the point for which gradN was specified. + */ +template< int NUM_SUPPORT_POINTS, + typename GRADIENT_TYPE > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void valueAndGradient( real64 const (&N)[NUM_SUPPORT_POINTS], + GRADIENT_TYPE const & gradN, + real64 const (&var)[NUM_SUPPORT_POINTS], + real64 & value, + real64 (& gradVar)[3] ) +{ + value = N[0] * var[0]; + for( int i = 0; i < 3; ++i ) + { + gradVar[i] = var[0] * gradN[0][i]; + } + + for( int a=1; a +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void plusGradNajAij( GRADIENT_TYPE const & gradN, + real64 const (&var_detJxW)[6], + real64 (& R)[NUM_SUPPORT_POINTS][3] ) +{ + for( int a=0; a +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void plusGradNajAij( GRADIENT_TYPE const & gradN, + real64 const (&var_detJxW)[3][3], + real64 (& R)[NUM_SUPPORT_POINTS][3] ) +{ + for( int a=0; a( R[a], var_detJxW, gradN[a] ); + } +} + +/** + * @brief Product of each shape function with a vector forcing term. + * @tparam NUM_SUPPORT_POINTS The number of support points for the element. + * @param N The shape function value at a predetermined coordinate in the element. + * @param forcingTerm_detJxW A vector scaled by detJxW + * @param R The vector at each support point which will hold the result from + * the tensor contraction. + */ +template< int NUM_SUPPORT_POINTS > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void plusNaFi( real64 const (&N)[NUM_SUPPORT_POINTS], + real64 const (&var_detJxW)[3], + real64 ( & R )[NUM_SUPPORT_POINTS][3] ) +{ + for( int a=0; a( R[a], var_detJxW, N[a] ); + } +} + +/** + * @brief Inner product of each basis function gradient with a rank-2 + * symmetric tensor added to the product each shape function with a vector. + * @tparam NUM_SUPPORT_POINTS The number of support points for the element. + * @tparam GRADIENT_TYPE The type of the array object holding the shape + * function gradients. + * @param gradN The basis function gradients at a point in the element. + * @param var_detJxW The rank-2 symmetric tensor at @p q scaled by J*W. + * @param N The shape function value at a predetermined coordinate in the element. + * @param forcingTerm_detJxW A vector scaled by detJxW + * @param R The vector at each support point which will hold the result from + * the tensor contraction. + * + * \f[ + * R_i = \sum_a^{nSupport} \left ( \frac{\partial N_a}{\partial X_j} var_{ij} + N_a f_i \right ), + * \f] + */ +template< int NUM_SUPPORT_POINTS, + typename GRADIENT_TYPE > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void plusGradNajAijPlusNaFi( GRADIENT_TYPE const & gradN, + real64 const (&var_detJxW)[6], + real64 const (&N)[NUM_SUPPORT_POINTS], + real64 const (&forcingTerm_detJxW)[3], + real64 (& R)[NUM_SUPPORT_POINTS][3] ) +{ + for( int a=0; a +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void plusGradNajAijPlusNaFi( GRADIENT_TYPE const & gradN, + real64 const (&var_detJxW)[3][3], + real64 const (&N)[NUM_SUPPORT_POINTS], + real64 const (&forcingTerm_detJxW)[3], + real64 (& R)[NUM_SUPPORT_POINTS][3] ) +{ + for( int a=0; a { public: - /// The number of nodes/support points per element. - constexpr static localIndex numNodes = LagrangeBasis1::TensorProduct3D::numSupportPoints; + /// Convenience type alias for the base class + using Base = FiniteElementBase_impl< 8, 6, 8 >; - /// The number of faces/support points for bubble functions per element. - constexpr static localIndex numFaces = LagrangeBasis1::TensorProduct3D::numSupportFaces; + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; - /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = 8; + /// Number of nodes in the element + using Base::numNodes; - /// The number of sampling points per element - constexpr static int numSamplingPoints = numSamplingPointsPerDirection * numSamplingPointsPerDirection * numSamplingPointsPerDirection; + /// Number of quadrature points in the element + using Base::numQuadraturePoints; - /** @cond Doxygen_Suppress */ - USING_FINITEELEMENTBASE - /** @endcond Doxygen_Suppress */ + /// Maximum number of support points in the element + using Base::maxSupportPoints; - GEOS_HOST_DEVICE - virtual ~H1_Hexahedron_Lagrange1_GaussLegendre2() override - {} + /// @cond DO_NOT_DOCUMENT + H1_Hexahedron_Lagrange1_GaussLegendre2_impl() = default; + ~H1_Hexahedron_Lagrange1_GaussLegendre2_impl() = default; + H1_Hexahedron_Lagrange1_GaussLegendre2_impl( H1_Hexahedron_Lagrange1_GaussLegendre2_impl const & ) = default; + H1_Hexahedron_Lagrange1_GaussLegendre2_impl & operator=( H1_Hexahedron_Lagrange1_GaussLegendre2_impl const & ) = default; + H1_Hexahedron_Lagrange1_GaussLegendre2_impl( H1_Hexahedron_Lagrange1_GaussLegendre2_impl && ) = default; + H1_Hexahedron_Lagrange1_GaussLegendre2_impl & operator=( H1_Hexahedron_Lagrange1_GaussLegendre2_impl && ) = default; + /// @endcond DO_NOT_DOCUMENT + /// @copydoc FiniteElementBase_impl::getNumQuadraturePoints() GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override + static localIndex getNumQuadraturePoints() { return numQuadraturePoints; } @@ -115,14 +121,16 @@ class H1_Hexahedron_Lagrange1_GaussLegendre2 final : public FiniteElementBase return numQuadraturePoints; } + /// @copydoc FiniteElementBase_impl::getNumSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const override + static localIndex getNumSupportPoints() { return numNodes; } + /// @copydoc FiniteElementBase_impl::getMaxSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const override + static localIndex getMaxSupportPoints() { return maxSupportPoints; } @@ -251,6 +259,36 @@ class H1_Hexahedron_Lagrange1_GaussLegendre2 final : public FiniteElementBase calcFaceBubbleN( qCoords, N ); } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 ( &J )[3][3] ); + + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param stack Variables allocated on the stack as filled by @ref setupStack. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & stack, + real64 ( &J )[3][3] ); + /** * @brief Calculate the shape functions derivatives wrt the physical * coordinates. @@ -504,11 +542,11 @@ class H1_Hexahedron_Lagrange1_GaussLegendre2 final : public FiniteElementBase template< typename FUNC, typename ... PARAMS > GEOS_HOST_DEVICE inline void -H1_Hexahedron_Lagrange1_GaussLegendre2::supportLoop( int const qa, - int const qb, - int const qc, - FUNC && func, - PARAMS &&... params ) +H1_Hexahedron_Lagrange1_GaussLegendre2_impl::supportLoop( int const qa, + int const qb, + int const qc, + FUNC && func, + PARAMS &&... params ) { /// Options for how to calculate the parent gradients. @@ -596,16 +634,47 @@ H1_Hexahedron_Lagrange1_GaussLegendre2::supportLoop( int const qa, } //************************************************************************************************* +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Hexahedron_Lagrange1_GaussLegendre2_impl::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& J)[3][3] ) +{ + for( int i = 0; i < 3; ++i ) + { + for( int j = 0; j < 3; ++j ) + { + J[i][j] = 0; + } + } + int qa, qb, qc; + LagrangeBasis1::TensorProduct3D::multiIndex( q, qa, qb, qc ); + jacobianTransformation( qa, qb, qc, X, J ); + real64 const detJ = LvArray::tensorOps::determinant< 3 >( J ); + return detJ*weight; +} + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Hexahedron_Lagrange1_GaussLegendre2_impl::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & GEOS_UNUSED_PARAM( stack ), + real64 (& J)[3][3] ) +{ + return calcJacobian( q, X, J ); +} + GEOS_HOST_DEVICE inline real64 -H1_Hexahedron_Lagrange1_GaussLegendre2::calcGradN( localIndex const q, - real64 const (&X)[numNodes][3], - real64 (& gradN)[numNodes][3] ) +H1_Hexahedron_Lagrange1_GaussLegendre2_impl::calcGradN( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& gradN)[numNodes][3] ) { real64 J[3][3] = {{0}}; - int qa, qb, qc; LagrangeBasis1::TensorProduct3D::multiIndex( q, qa, qb, qc ); @@ -620,7 +689,7 @@ H1_Hexahedron_Lagrange1_GaussLegendre2::calcGradN( localIndex const q, GEOS_HOST_DEVICE inline -real64 H1_Hexahedron_Lagrange1_GaussLegendre2:: +real64 H1_Hexahedron_Lagrange1_GaussLegendre2_impl:: calcGradN( localIndex const q, real64 const (&X)[numNodes][3], StackVariables const & GEOS_UNUSED_PARAM( stack ), @@ -632,9 +701,9 @@ real64 H1_Hexahedron_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline real64 -H1_Hexahedron_Lagrange1_GaussLegendre2::calcGradFaceBubbleN( localIndex const q, - real64 const (&X)[numNodes][3], - real64 (& gradN)[numFaces][3] ) +H1_Hexahedron_Lagrange1_GaussLegendre2_impl::calcGradFaceBubbleN( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& gradN)[numFaces][3] ) { real64 J[3][3] = {{0}}; @@ -673,7 +742,7 @@ H1_Hexahedron_Lagrange1_GaussLegendre2::calcGradFaceBubbleN( localIndex const q, GEOS_HOST_DEVICE inline void -H1_Hexahedron_Lagrange1_GaussLegendre2:: +H1_Hexahedron_Lagrange1_GaussLegendre2_impl:: jacobianTransformation( int const qa, int const qb, int const qc, @@ -712,7 +781,7 @@ H1_Hexahedron_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline void -H1_Hexahedron_Lagrange1_GaussLegendre2:: +H1_Hexahedron_Lagrange1_GaussLegendre2_impl:: applyTransformationToParentGradients( int const qa, int const qb, int const qc, @@ -745,7 +814,7 @@ H1_Hexahedron_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline real64 -H1_Hexahedron_Lagrange1_GaussLegendre2:: +H1_Hexahedron_Lagrange1_GaussLegendre2_impl:: transformedQuadratureWeight( localIndex const q, real64 const (&X)[numNodes][3] ) { @@ -763,10 +832,10 @@ H1_Hexahedron_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline -void H1_Hexahedron_Lagrange1_GaussLegendre2::symmetricGradient( int const q, - real64 const (&invJ)[3][3], - real64 const (&var)[numNodes][3], - real64 (& grad)[6] ) +void H1_Hexahedron_Lagrange1_GaussLegendre2_impl::symmetricGradient( int const q, + real64 const (&invJ)[3][3], + real64 const (&var)[numNodes][3], + real64 (& grad)[6] ) { int qa, qb, qc; LagrangeBasis1::TensorProduct3D::multiIndex( q, qa, qb, qc ); @@ -798,10 +867,10 @@ void H1_Hexahedron_Lagrange1_GaussLegendre2::symmetricGradient( int const q, GEOS_HOST_DEVICE inline -void H1_Hexahedron_Lagrange1_GaussLegendre2::plusGradNajAij( int const q, - real64 const (&invJ)[3][3], - real64 const (&var)[6], - real64 (& R)[numNodes][3] ) +void H1_Hexahedron_Lagrange1_GaussLegendre2_impl::plusGradNajAij( int const q, + real64 const (&invJ)[3][3], + real64 const (&var)[6], + real64 (& R)[numNodes][3] ) { int qa, qb, qc; LagrangeBasis1::TensorProduct3D::multiIndex( q, qa, qb, qc ); @@ -833,10 +902,10 @@ void H1_Hexahedron_Lagrange1_GaussLegendre2::plusGradNajAij( int const q, GEOS_HOST_DEVICE inline -void H1_Hexahedron_Lagrange1_GaussLegendre2::gradient( int const q, - real64 const (&invJ)[3][3], - real64 const (&var)[numNodes][3], - real64 (& grad)[3][3] ) +void H1_Hexahedron_Lagrange1_GaussLegendre2_impl::gradient( int const q, + real64 const (&invJ)[3][3], + real64 const (&var)[numNodes][3], + real64 (& grad)[3][3] ) { int qa, qb, qc; LagrangeBasis1::TensorProduct3D::multiIndex( q, qa, qb, qc ); @@ -868,6 +937,46 @@ void H1_Hexahedron_Lagrange1_GaussLegendre2::gradient( int const q, #pragma GCC diagnostic pop #endif +/// @copydoc H1_Hexahedron_Lagrange1_GaussLegendre2_impl +class H1_Hexahedron_Lagrange1_GaussLegendre2 final : public H1_Hexahedron_Lagrange1_GaussLegendre2_impl, public FiniteElementBase +{ +public: + + /// The type of basis used for this element + using BASIS = LagrangeBasis1; + + /// The Implementation type + using ImplType = H1_Hexahedron_Lagrange1_GaussLegendre2_impl; + + H1_Hexahedron_Lagrange1_GaussLegendre2(): + FiniteElementBase( ImplType::numNodes, + ImplType::maxSupportPoints, + ImplType::numQuadraturePoints ) + { } + + GEOS_HOST_DEVICE + virtual ~H1_Hexahedron_Lagrange1_GaussLegendre2() override final = default; + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Hexahedron_Lagrange1_GaussLegendre2_impl * getImpl() + { + return static_cast< H1_Hexahedron_Lagrange1_GaussLegendre2_impl * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Hexahedron_Lagrange1_GaussLegendre2_impl const * getImpl() const + { + return static_cast< H1_Hexahedron_Lagrange1_GaussLegendre2_impl const * >(this); + } + +}; + #undef PARENT_GRADIENT_METHOD } } diff --git a/src/coreComponents/finiteElement/elementFormulations/H1_Pyramid_Lagrange1_Gauss5.hpp b/src/coreComponents/finiteElement/elementFormulations/H1_Pyramid_Lagrange1_Gauss5.hpp index 3f89788e48b..7292b6d2352 100644 --- a/src/coreComponents/finiteElement/elementFormulations/H1_Pyramid_Lagrange1_Gauss5.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/H1_Pyramid_Lagrange1_Gauss5.hpp @@ -55,88 +55,30 @@ namespace finiteElement * * */ -class H1_Pyramid_Lagrange1_Gauss5 final : public FiniteElementBase +class H1_Pyramid_Lagrange1_Gauss5_impl : public FiniteElementBase_impl< 5, 5, 5 > { public: /// The type of basis used for this element using BASIS = LagrangeBasis1; - /// The number of nodes/support points per element. - constexpr static localIndex numNodes = 5; - /// The number of faces/support points per element. - constexpr static localIndex numFaces = 5; + /// struct to hold stack variables. + struct StackVariables + {}; - /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; + /// MeshData struct to hold mesh data. + template< typename SUBREGION_TYPE > + struct MeshData {}; - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = 5; - - /// The number of sampling points per element. - constexpr static int numSamplingPoints = numSamplingPointsPerDirection * numSamplingPointsPerDirection * numSamplingPointsPerDirection; - - GEOS_HOST_DEVICE - virtual ~H1_Pyramid_Lagrange1_Gauss5() override - {} - - GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override - { - return numQuadraturePoints; - } - - /** - * @brief Get the number of quadrature points. - * @param stack Stack variables as filled by @ref setupStack. - * @return The number of quadrature points. - */ - GEOS_HOST_DEVICE - static localIndex getNumQuadraturePoints( StackVariables const & stack ) - { - GEOS_UNUSED_VAR( stack ); - return numQuadraturePoints; - } - - GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const override - { - return numNodes; - } - - /** - * @brief Get the number of support points. - * @param stack Object that holds stack variables. - * @return The number of support points. - */ - GEOS_HOST_DEVICE - static localIndex getNumSupportPoints( StackVariables const & stack ) - { - GEOS_UNUSED_VAR( stack ); - return numNodes; - } - - GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const override - { - return maxSupportPoints; - } - - /** - * @brief Get the Sampling Point Coord In the Parent Space - * - * @param linearIndex linear index of the sampling point - * @param samplingPointCoord coordinates of the sampling point - */ - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - static void getSamplingPointCoordInParentSpace( int const & linearIndex, - real64 (& samplingPointCoord)[3] ) - { - GEOS_UNUSED_VAR( linearIndex, samplingPointCoord ); - GEOS_ERROR( " Element type not supported." ); - } + /// @cond DO_NOT_DOCUMENT + H1_Pyramid_Lagrange1_Gauss5_impl() = default; + ~H1_Pyramid_Lagrange1_Gauss5_impl() = default; + H1_Pyramid_Lagrange1_Gauss5_impl( H1_Pyramid_Lagrange1_Gauss5_impl const & ) = default; + H1_Pyramid_Lagrange1_Gauss5_impl & operator=( H1_Pyramid_Lagrange1_Gauss5_impl const & ) = default; + H1_Pyramid_Lagrange1_Gauss5_impl( H1_Pyramid_Lagrange1_Gauss5_impl && ) = default; + H1_Pyramid_Lagrange1_Gauss5_impl & operator=( H1_Pyramid_Lagrange1_Gauss5_impl && ) = default; + /// @endcond DO_NOT_DOCUMENT /** * @brief Calculate shape functions values at a single point. @@ -205,6 +147,36 @@ class H1_Pyramid_Lagrange1_Gauss5 final : public FiniteElementBase GEOS_ERROR( "Unsupported bubble functions for pyramid elements" ); } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 ( &J )[3][3] ); + + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param stack Variables allocated on the stack as filled by @ref setupStack. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const &stack, + real64 ( &J )[3][3] ); + /** * @brief Calculate the shape functions derivatives wrt the physical * coordinates. @@ -450,7 +422,7 @@ class H1_Pyramid_Lagrange1_Gauss5 final : public FiniteElementBase GEOS_HOST_DEVICE inline void -H1_Pyramid_Lagrange1_Gauss5:: +H1_Pyramid_Lagrange1_Gauss5_impl:: jacobianTransformation( int const q, real64 const (&X)[numNodes][3], real64 ( & J )[3][3] ) @@ -497,7 +469,7 @@ H1_Pyramid_Lagrange1_Gauss5:: GEOS_HOST_DEVICE inline void -H1_Pyramid_Lagrange1_Gauss5:: +H1_Pyramid_Lagrange1_Gauss5_impl:: applyJacobianTransformationToShapeFunctionsDerivatives( int const q, real64 const ( &invJ )[3][3], real64 (& gradN)[numNodes][3] ) @@ -545,7 +517,7 @@ H1_Pyramid_Lagrange1_Gauss5:: GEOS_HOST_DEVICE inline void -H1_Pyramid_Lagrange1_Gauss5:: +H1_Pyramid_Lagrange1_Gauss5_impl:: calcN( real64 const ( &pointCoord )[3], real64 ( & N )[numNodes] ) { @@ -559,7 +531,7 @@ H1_Pyramid_Lagrange1_Gauss5:: GEOS_HOST_DEVICE inline void -H1_Pyramid_Lagrange1_Gauss5:: +H1_Pyramid_Lagrange1_Gauss5_impl:: calcN( localIndex const q, real64 ( & N )[numNodes] ) { @@ -572,7 +544,7 @@ H1_Pyramid_Lagrange1_Gauss5:: GEOS_HOST_DEVICE inline -void H1_Pyramid_Lagrange1_Gauss5:: +void H1_Pyramid_Lagrange1_Gauss5_impl:: calcN( localIndex const q, StackVariables const & GEOS_UNUSED_PARAM( stack ), real64 ( & N )[numNodes] ) @@ -582,11 +554,41 @@ void H1_Pyramid_Lagrange1_Gauss5:: //************************************************************************************************* +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Pyramid_Lagrange1_Gauss5_impl::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& J)[3][3] ) +{ + for( int i = 0; i < 3; ++i ) + { + for( int j = 0; j < 3; ++j ) + { + J[i][j] = 0; + } + } + jacobianTransformation( q, X, J ); + real64 const detJ = LvArray::tensorOps::determinant< 3 >( J ); + return detJ * quadratureWeight( q ); +} + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Pyramid_Lagrange1_Gauss5_impl::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & GEOS_UNUSED_PARAM( stack ), + real64 (& J)[3][3] ) +{ + return calcJacobian( q, X, J ); +} + GEOS_HOST_DEVICE inline -real64 H1_Pyramid_Lagrange1_Gauss5::calcGradN( localIndex const q, - real64 const (&X)[numNodes][3], - real64 (& gradN)[numNodes][3] ) +real64 H1_Pyramid_Lagrange1_Gauss5_impl::calcGradN( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& gradN)[numNodes][3] ) { real64 J[3][3] = {{0}}; @@ -601,7 +603,7 @@ real64 H1_Pyramid_Lagrange1_Gauss5::calcGradN( localIndex const q, GEOS_HOST_DEVICE inline -real64 H1_Pyramid_Lagrange1_Gauss5:: +real64 H1_Pyramid_Lagrange1_Gauss5_impl:: calcGradN( localIndex const q, real64 const (&X)[numNodes][3], StackVariables const & GEOS_UNUSED_PARAM( stack ), @@ -613,9 +615,9 @@ real64 H1_Pyramid_Lagrange1_Gauss5:: GEOS_HOST_DEVICE inline real64 -H1_Pyramid_Lagrange1_Gauss5::calcGradFaceBubbleN( localIndex const q, - real64 const (&X)[numNodes][3], - real64 (& gradN)[numFaces][3] ) +H1_Pyramid_Lagrange1_Gauss5_impl::calcGradFaceBubbleN( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& gradN)[numFaces][3] ) { GEOS_UNUSED_VAR( q, X, gradN ); GEOS_ERROR( "Unsupported bubble functions for pyramid elements" ); @@ -627,7 +629,7 @@ H1_Pyramid_Lagrange1_Gauss5::calcGradFaceBubbleN( localIndex const q, GEOS_HOST_DEVICE inline real64 -H1_Pyramid_Lagrange1_Gauss5:: +H1_Pyramid_Lagrange1_Gauss5_impl:: transformedQuadratureWeight( localIndex const q, real64 const (&X)[numNodes][3] ) { @@ -640,6 +642,47 @@ H1_Pyramid_Lagrange1_Gauss5:: /// @endcond +/// @copydoc H1_Pyramid_Lagrange1_Gauss5_impl +class H1_Pyramid_Lagrange1_Gauss5 final : public H1_Pyramid_Lagrange1_Gauss5_impl, + public FiniteElementBase +{ +public: + + /// The type of basis used for this element + using BASIS = LagrangeBasis1; + + /// The Implementation type + using ImplType = H1_Pyramid_Lagrange1_Gauss5_impl; + + + H1_Pyramid_Lagrange1_Gauss5(): + FiniteElementBase( numNodes, + maxSupportPoints, + numQuadraturePoints ) + {} + + virtual ~H1_Pyramid_Lagrange1_Gauss5() override final = default; + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Pyramid_Lagrange1_Gauss5_impl * getImpl() + { + return static_cast< H1_Pyramid_Lagrange1_Gauss5_impl * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Pyramid_Lagrange1_Gauss5_impl const * getImpl() const + { + return static_cast< H1_Pyramid_Lagrange1_Gauss5_impl const * >(this); + } + +}; + } } #endif //GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_H1PYRAMIDLAGRANGE1GAUSS5_HPP_ diff --git a/src/coreComponents/finiteElement/elementFormulations/H1_QuadrilateralFace_Lagrange1_GaussLegendre2.hpp b/src/coreComponents/finiteElement/elementFormulations/H1_QuadrilateralFace_Lagrange1_GaussLegendre2.hpp index 6aa3001b291..ac6926defe4 100644 --- a/src/coreComponents/finiteElement/elementFormulations/H1_QuadrilateralFace_Lagrange1_GaussLegendre2.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/H1_QuadrilateralFace_Lagrange1_GaussLegendre2.hpp @@ -47,27 +47,45 @@ namespace finiteElement * ===== === === * */ -class H1_QuadrilateralFace_Lagrange1_GaussLegendre2 final : public FiniteElementBase +class H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl : public FiniteElementBase_impl< 4, 4, 4 > { public: + /// Convenience type alias for the base class + using Base = FiniteElementBase_impl< 4, 4, 4 >; /// The type of basis used for this element using BASIS = LagrangeBasis1; - /// The number of nodes/support points per element. - constexpr static localIndex numNodes = 4; - /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = 4; + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; - GEOS_HOST_DEVICE - virtual ~H1_QuadrilateralFace_Lagrange1_GaussLegendre2() override - {} + /// Number of nodes in the element + using Base::numNodes; + + /// Number of quadrature points in the element + using Base::numQuadraturePoints; + + /// Maximum number of support points in the element + using Base::maxSupportPoints; + /// @cond DO_NOT_DOCUMENT + + H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl() = default; + ~H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl() = default; + H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl( H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl const & ) = default; + H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl & operator=( H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl const & ) = default; + H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl( H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl && ) = default; + H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl & operator=( H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl && ) = default; + + /// @endcond DO_NOT_DOCUMENT + + /// @copydoc FiniteElementBase_impl::getNumQuadraturePoints() GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override + static localIndex getNumQuadraturePoints() { return numQuadraturePoints; } @@ -84,14 +102,16 @@ class H1_QuadrilateralFace_Lagrange1_GaussLegendre2 final : public FiniteElement return numQuadraturePoints; } + /// @copydoc FiniteElementBase_impl::getNumSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const override + static localIndex getNumSupportPoints() { return numNodes; } + /// @copydoc FiniteElementBase_impl::getMaxSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const override + static localIndex getMaxSupportPoints() { return maxSupportPoints; } @@ -276,7 +296,7 @@ class H1_QuadrilateralFace_Lagrange1_GaussLegendre2 final : public FiniteElement template< localIndex NUMDOFSPERTRIALSUPPORTPOINT, bool UPPER > GEOS_HOST_DEVICE inline -void H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: +void H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl:: addGradGradStabilization( StackVariables const & stack, real64 ( & matrix ) [maxSupportPoints * NUMDOFSPERTRIALSUPPORTPOINT] @@ -291,7 +311,7 @@ void H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline void -H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: +H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl:: calcN( real64 const (&coords)[2], real64 (& N)[numNodes] ) { @@ -305,7 +325,7 @@ H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline void -H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: +H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl:: calcN( localIndex const q, real64 (& N)[numNodes] ) { @@ -319,7 +339,7 @@ H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline -void H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: +void H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl:: calcN( localIndex const q, StackVariables const & GEOS_UNUSED_PARAM( stack ), real64 ( & N )[numNodes] ) @@ -332,7 +352,7 @@ void H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: GEOS_HOST_DEVICE inline real64 -H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: +H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl:: transformedQuadratureWeight( localIndex const q, real64 const (&X)[numNodes][3] ) { @@ -375,6 +395,48 @@ H1_QuadrilateralFace_Lagrange1_GaussLegendre2:: /// @endcond + +/// @copydoc H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl +class H1_QuadrilateralFace_Lagrange1_GaussLegendre2 final : public H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl, + public FiniteElementBase +{ +public: + + /// The type of basis used for this element + using BASIS = LagrangeBasis1; + + /// The Implementation type + using ImplType = H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl; + + H1_QuadrilateralFace_Lagrange1_GaussLegendre2(): + FiniteElementBase( ImplType::numNodes, + ImplType::maxSupportPoints, + ImplType::numQuadraturePoints ) + {} + + virtual ~H1_QuadrilateralFace_Lagrange1_GaussLegendre2() override final = default; + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl * getImpl() + { + return static_cast< H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl const * getImpl() const + { + return static_cast< H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl const * >(this); + } + + +}; + } } #endif //GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_H1QUADRILATERALFACELAGRANGE1GAUSSLEGENDRE2_HPP_ diff --git a/src/coreComponents/finiteElement/elementFormulations/H1_Tetrahedron_Lagrange1_Gauss.hpp b/src/coreComponents/finiteElement/elementFormulations/H1_Tetrahedron_Lagrange1_Gauss.hpp index 2736955bff6..4da4aa68c69 100644 --- a/src/coreComponents/finiteElement/elementFormulations/H1_Tetrahedron_Lagrange1_Gauss.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/H1_Tetrahedron_Lagrange1_Gauss.hpp @@ -47,9 +47,39 @@ namespace finiteElement * */ template< typename NUM_Q_POINTS > -class H1_Tetrahedron_Lagrange1_Gauss final : public FiniteElementBase +class H1_Tetrahedron_Lagrange1_Gauss_impl : public FiniteElementBase_impl< 4, 4, NUM_Q_POINTS::value > { public: + /// Convenience type alias for the base class + using Base = FiniteElementBase_impl< 4, 4, NUM_Q_POINTS::value >; + + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; + + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; + + /// Number of nodes in the element + using Base::numNodes; + + /// Number of quadrature points in the element + using Base::numQuadraturePoints; + + /// Maximum number of support points in the element + using Base::maxSupportPoints; + + /// Number of support points in the element + constexpr static localIndex numSupportPoints = Base::numSupportPoints; + + /// Number of faces in the element + constexpr static localIndex numFaces = Base::numFaces; + + /// Number of sampling points per direction + constexpr static int numSamplingPointsPerDirection = 10; + + /// Total number of sampling points + constexpr static int numSamplingPoints = numSamplingPointsPerDirection * numSamplingPointsPerDirection * numSamplingPointsPerDirection; /// Check that the number of quadrature points is valid. static_assert( ( NUM_Q_POINTS::value == 1 || @@ -60,27 +90,18 @@ class H1_Tetrahedron_Lagrange1_Gauss final : public FiniteElementBase /// The type of basis used for this element using BASIS = LagrangeBasis1; - /// The number of nodes/support points per element. - constexpr static localIndex numNodes = 4; - - /// The number of faces/support points per element. - constexpr static localIndex numFaces = 4; - - /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; - - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = NUM_Q_POINTS::value; - - /// The number of sampling points per element. - constexpr static int numSamplingPoints = numSamplingPointsPerDirection * numSamplingPointsPerDirection * numSamplingPointsPerDirection; + /// @cond DO_NOT_DOCUMENT + H1_Tetrahedron_Lagrange1_Gauss_impl() = default; + ~H1_Tetrahedron_Lagrange1_Gauss_impl() = default; + H1_Tetrahedron_Lagrange1_Gauss_impl( H1_Tetrahedron_Lagrange1_Gauss_impl const & ) = default; + H1_Tetrahedron_Lagrange1_Gauss_impl & operator=( H1_Tetrahedron_Lagrange1_Gauss_impl const & ) = default; + H1_Tetrahedron_Lagrange1_Gauss_impl( H1_Tetrahedron_Lagrange1_Gauss_impl && ) = default; + H1_Tetrahedron_Lagrange1_Gauss_impl & operator=( H1_Tetrahedron_Lagrange1_Gauss_impl && ) = default; + /// @endcond DO_NOT_DOCUMENT + /// @copydoc FiniteElementBase_impl::getNumQuadraturePoints() GEOS_HOST_DEVICE - virtual ~H1_Tetrahedron_Lagrange1_Gauss() override - {} - - GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override + static localIndex getNumQuadraturePoints() { return numQuadraturePoints; } @@ -98,14 +119,16 @@ class H1_Tetrahedron_Lagrange1_Gauss final : public FiniteElementBase return numQuadraturePoints; } + /// @copydoc FiniteElementBase_impl::getNumSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const override + static localIndex getNumSupportPoints() { return numNodes; } + /// @copydoc FiniteElementBase_impl::getMaxSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const override + static localIndex getMaxSupportPoints() { return maxSupportPoints; } @@ -237,6 +260,36 @@ class H1_Tetrahedron_Lagrange1_Gauss final : public FiniteElementBase calcFaceBubbleN( pointCoord, N ); } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 ( &J )[3][3] ); + + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param stack Variables allocated on the stack as filled by @ref setupStack. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const &stack, + real64 ( &J )[3][3] ); + /** * @brief Calculate the shape functions derivatives wrt the physical * coordinates. @@ -516,7 +569,7 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline real64 -H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: determinantJacobianTransformation( real64 const (&X)[numNodes][3] ) { return ( X[1][0] - X[0][0] )*( ( X[2][1] - X[0][1] )*( X[3][2] - X[0][2] ) - ( X[3][1] - X[0][1] )*( X[2][2] - X[0][2] ) ) @@ -530,7 +583,7 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline void -H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcN( real64 const (&coords)[3], real64 (& N)[numNodes] ) { @@ -550,7 +603,7 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline void -H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcN( localIndex const q, real64 (& N)[numNodes] ) { @@ -564,7 +617,7 @@ calcN( localIndex const q, template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline -void H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >:: +void H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcN( localIndex const q, StackVariables const & GEOS_UNUSED_PARAM( stack ), real64 ( & N )[numNodes] ) @@ -573,12 +626,55 @@ calcN( localIndex const q, } //************************************************************************************************* +template< typename NUM_Q_POINTS > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& J)[3][3] ) +{ + for( int i = 0; i < 3; ++i ) + { + for( int j = 0; j < 3; ++j ) + { + J[i][j] = 0; + } + } + J[0][0] = X[1][0] - X[0][0]; + J[0][1] = X[2][0] - X[0][0]; + J[0][2] = X[3][0] - X[0][0]; + + J[1][0] = X[1][1] - X[0][1]; + J[1][1] = X[2][1] - X[0][1]; + J[1][2] = X[3][1] - X[0][1]; + + J[2][0] = X[1][2] - X[0][2]; + J[2][1] = X[2][2] - X[0][2]; + J[2][2] = X[3][2] - X[0][2]; + real64 const detJ = LvArray::tensorOps::determinant< 3 >( J ); + return detJ * quadratureWeight( q ); +} + +template< typename NUM_Q_POINTS > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & GEOS_UNUSED_PARAM( stack ), + real64 (& J)[3][3] ) +{ + return calcJacobian( q, X, J ); +} + + template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline real64 -H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcGradN( localIndex const q, real64 const (&X)[numNodes][3], real64 (& gradN)[numNodes][3] ) @@ -617,7 +713,7 @@ calcGradN( localIndex const q, template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline -real64 H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >:: +real64 H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcGradN( localIndex const q, real64 const (&X)[numNodes][3], StackVariables const & GEOS_UNUSED_PARAM( stack ), @@ -630,9 +726,9 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline real64 -H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >::calcGradFaceBubbleN( localIndex const q, - real64 const (&X)[numNodes][3], - real64 (& gradN)[numFaces][3] ) +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >::calcGradFaceBubbleN( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& gradN)[numFaces][3] ) { //real64 detJ = determinantJacobianTransformation( X ); @@ -691,7 +787,7 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline real64 -H1_Tetrahedron_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: transformedQuadratureWeight( localIndex const q, real64 const (&X)[numNodes][3] ) { @@ -703,13 +799,63 @@ transformedQuadratureWeight( localIndex const q, /// @endcond -/// @brief Instantiate the H1_Tetrahedron_Lagrange1_Gauss class for the 1-point Gaussian quadrature rule. + +/// @copydoc H1_Tetrahedron_Lagrange1_Gauss_impl +template< typename NUM_Q_POINTS > +class H1_Tetrahedron_Lagrange1_Gauss final : public H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >, + public FiniteElementBase +{ +public: + + /// The type of basis used for this element + using BASIS = LagrangeBasis1; + + /// The Implementation type. + using ImplType = H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS >; + + /// Constructor + H1_Tetrahedron_Lagrange1_Gauss(): + FiniteElementBase( ImplType::numNodes, + ImplType::maxSupportPoints, + ImplType::numQuadraturePoints ) + {} + + /// Destructor + virtual ~H1_Tetrahedron_Lagrange1_Gauss() override final = default; + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS > * getImpl() + { + return static_cast< H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS > * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS > const * getImpl() const + { + return static_cast< H1_Tetrahedron_Lagrange1_Gauss_impl< NUM_Q_POINTS > const * >(this); + } + +}; + +/// @brief Instantiate the H1_Tetrahedron_Lagrange1_Gauss_impl class for the 1-point Gaussian quadrature rule. using H1_Tetrahedron_Lagrange1_Gauss1 = H1_Tetrahedron_Lagrange1_Gauss< std::integral_constant< int, 1 > >; /// @brief Instantiate the H1_Tetrahedron_Lagrange1_Gauss class for the 5-point Gaussian quadrature rule. using H1_Tetrahedron_Lagrange1_Gauss5 = H1_Tetrahedron_Lagrange1_Gauss< std::integral_constant< int, 5 > >; /// @brief Instantiate the H1_Tetrahedron_Lagrange1_Gauss class for the 14-point Gaussian quadrature rule. using H1_Tetrahedron_Lagrange1_Gauss14 = H1_Tetrahedron_Lagrange1_Gauss< std::integral_constant< int, 14 > >; +/// @brief Instantiate the H1_Tetrahedron_Lagrange1_Gauss_impl class for the 1-point Gaussian quadrature rule. +using H1_Tetrahedron_Lagrange1_Gauss1_impl = H1_Tetrahedron_Lagrange1_Gauss_impl< std::integral_constant< int, 1 > >; +/// @brief Instantiate the H1_Tetrahedron_Lagrange1_Gauss class for the 5-point Gaussian quadrature rule. +using H1_Tetrahedron_Lagrange1_Gauss5_impl = H1_Tetrahedron_Lagrange1_Gauss_impl< std::integral_constant< int, 5 > >; +/// @brief Instantiate the H1_Tetrahedron_Lagrange1_Gauss class for the 14-point Gaussian quadrature rule. +using H1_Tetrahedron_Lagrange1_Gauss14_impl = H1_Tetrahedron_Lagrange1_Gauss_impl< std::integral_constant< int, 14 > >; } } diff --git a/src/coreComponents/finiteElement/elementFormulations/H1_TriangleFace_Lagrange1_Gauss.hpp b/src/coreComponents/finiteElement/elementFormulations/H1_TriangleFace_Lagrange1_Gauss.hpp index 61a3086598b..38a747b1974 100644 --- a/src/coreComponents/finiteElement/elementFormulations/H1_TriangleFace_Lagrange1_Gauss.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/H1_TriangleFace_Lagrange1_Gauss.hpp @@ -48,9 +48,27 @@ namespace finiteElement * */ template< typename NUM_Q_POINTS > -class H1_TriangleFace_Lagrange1_Gauss final : public FiniteElementBase +class H1_TriangleFace_Lagrange1_Gauss_impl : public FiniteElementBase_impl< 3, 3, NUM_Q_POINTS::value > { public: + /// Convenience type alias for the base class + using Base = FiniteElementBase_impl< 3, 3, NUM_Q_POINTS::value >; + + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; + + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; + + /// Number of nodes in the element + using Base::numNodes; + + /// Number of quadrature points in the element + using Base::numQuadraturePoints; + + /// Maximum number of support points in the element + using Base::maxSupportPoints; /// Check that the number of quadrature points is valid. static_assert( ( NUM_Q_POINTS::value == 1 || @@ -61,20 +79,18 @@ class H1_TriangleFace_Lagrange1_Gauss final : public FiniteElementBase /// The type of basis used for this element using BASIS = LagrangeBasis1; - /// The number of nodes/support points per element. - constexpr static localIndex numNodes = 3; - /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; - - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = NUM_Q_POINTS::value; - - GEOS_HOST_DEVICE - virtual ~H1_TriangleFace_Lagrange1_Gauss() override - {} + /// @cond DO_NOT_DOCUMENT + H1_TriangleFace_Lagrange1_Gauss_impl() = default; + ~H1_TriangleFace_Lagrange1_Gauss_impl() = default; + H1_TriangleFace_Lagrange1_Gauss_impl( H1_TriangleFace_Lagrange1_Gauss_impl const & ) = default; + H1_TriangleFace_Lagrange1_Gauss_impl & operator=( H1_TriangleFace_Lagrange1_Gauss_impl const & ) = default; + H1_TriangleFace_Lagrange1_Gauss_impl( H1_TriangleFace_Lagrange1_Gauss_impl && ) = default; + H1_TriangleFace_Lagrange1_Gauss_impl & operator=( H1_TriangleFace_Lagrange1_Gauss_impl && ) = default; + /// @endcond DO_NOT_DOCUMENT + /// @copydoc FiniteElementBase_impl::getNumQuadraturePoints() GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override + localIndex getNumQuadraturePoints() { return numQuadraturePoints; } @@ -91,8 +107,9 @@ class H1_TriangleFace_Lagrange1_Gauss final : public FiniteElementBase return numQuadraturePoints; } + /// @copydoc FiniteElementBase_impl::getNumSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const override + localIndex getNumSupportPoints() { return numNodes; } @@ -109,8 +126,9 @@ class H1_TriangleFace_Lagrange1_Gauss final : public FiniteElementBase return numNodes; } + /// @copydoc FiniteElementBase_impl::getMaxSupportPoints() GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const override + localIndex getMaxSupportPoints() { return maxSupportPoints; } @@ -356,7 +374,7 @@ template< typename NUM_Q_POINTS > template< localIndex NUMDOFSPERTRIALSUPPORTPOINT, bool UPPER > GEOS_HOST_DEVICE inline -void H1_TriangleFace_Lagrange1_Gauss< NUM_Q_POINTS >:: +void H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: addGradGradStabilization( StackVariables const & stack, real64 ( & matrix ) [maxSupportPoints * NUMDOFSPERTRIALSUPPORTPOINT] @@ -372,7 +390,7 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline void -H1_TriangleFace_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcN( real64 const (&coords)[2], real64 ( & N )[numNodes] ) { @@ -388,7 +406,7 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline void -H1_TriangleFace_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcN( localIndex const q, real64 (& N)[numNodes] ) { @@ -402,7 +420,7 @@ calcN( localIndex const q, template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline -void H1_TriangleFace_Lagrange1_Gauss< NUM_Q_POINTS >:: +void H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: calcN( localIndex const q, StackVariables const & GEOS_UNUSED_PARAM( stack ), real64 ( & N )[numNodes] ) @@ -416,7 +434,7 @@ template< typename NUM_Q_POINTS > GEOS_HOST_DEVICE inline real64 -H1_TriangleFace_Lagrange1_Gauss< NUM_Q_POINTS >:: +H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS >:: transformedQuadratureWeight( localIndex const q, real64 const (&X)[numNodes][3] ) { @@ -430,13 +448,63 @@ transformedQuadratureWeight( localIndex const q, /// @endcond -/// @brief Istanciation of the class with 1 quadrature points. + +/// @copydoc H1_TriangleFace_Lagrange1_Gauss_impl +template< typename NUM_Q_POINTS > +class H1_TriangleFace_Lagrange1_Gauss final : public H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS >, + public FiniteElementBase +{ +public: + + /// The type of basis used for this element + using BASIS = LagrangeBasis1; + + /// The Implementation type + using ImplType = H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS >; + + /// Constructor + H1_TriangleFace_Lagrange1_Gauss(): + FiniteElementBase( ImplType::numNodes, + ImplType::maxSupportPoints, + ImplType::numQuadraturePoints ) + {} + + /// Destructor + virtual ~H1_TriangleFace_Lagrange1_Gauss() override final = default; + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS > * getImpl() + { + return static_cast< H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS > * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + const H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS > * getImpl() const + { + return static_cast< H1_TriangleFace_Lagrange1_Gauss_impl< NUM_Q_POINTS > const * >(this); + } + +}; + +/// @brief Instantiation of the class with 1 quadrature points. using H1_TriangleFace_Lagrange1_Gauss1 = H1_TriangleFace_Lagrange1_Gauss< std::integral_constant< int, 1 > >; -/// @brief Istanciation of the class with 4 quadrature points. +/// @brief Instantiation of the class with 4 quadrature points. using H1_TriangleFace_Lagrange1_Gauss4 = H1_TriangleFace_Lagrange1_Gauss< std::integral_constant< int, 4 > >; -/// @brief Istanciation of the class with 6 quadrature points. +/// @brief Instantiation of the class with 6 quadrature points. using H1_TriangleFace_Lagrange1_Gauss6 = H1_TriangleFace_Lagrange1_Gauss< std::integral_constant< int, 6 > >; +/// @brief Instantiation of the class with 1 quadrature points. +using H1_TriangleFace_Lagrange1_Gauss1_impl = H1_TriangleFace_Lagrange1_Gauss_impl< std::integral_constant< int, 1 > >; +/// @brief Instantiation of the class with 4 quadrature points. +using H1_TriangleFace_Lagrange1_Gauss4_impl = H1_TriangleFace_Lagrange1_Gauss_impl< std::integral_constant< int, 4 > >; +/// @brief Instantiation of the class with 6 quadrature points. +using H1_TriangleFace_Lagrange1_Gauss6_impl = H1_TriangleFace_Lagrange1_Gauss_impl< std::integral_constant< int, 6 > >; } } diff --git a/src/coreComponents/finiteElement/elementFormulations/H1_Wedge_Lagrange1_Gauss6.hpp b/src/coreComponents/finiteElement/elementFormulations/H1_Wedge_Lagrange1_Gauss6.hpp index d901a13572b..9727671bbb1 100644 --- a/src/coreComponents/finiteElement/elementFormulations/H1_Wedge_Lagrange1_Gauss6.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/H1_Wedge_Lagrange1_Gauss6.hpp @@ -52,37 +52,31 @@ namespace finiteElement * 0 2 |/____ r * */ -class H1_Wedge_Lagrange1_Gauss6 final : public FiniteElementBase +class H1_Wedge_Lagrange1_Gauss6_impl : public FiniteElementBase_impl< 6, 5, 6 > { public: + /// The base class for this element + using Base = FiniteElementBase_impl< 6, 5, 6 >; + /// The type of basis used for this element using BASIS = LagrangeBasis1; - /// The number of nodes/support points per element. - constexpr static localIndex numNodes = 6; - - /// The number of faces/support points per element. - constexpr static localIndex numFaces = 5; - - /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = 6; + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; - /// The number of sampling points per element. - constexpr static int numSamplingPoints = numSamplingPointsPerDirection * numSamplingPointsPerDirection * numSamplingPointsPerDirection; - - GEOS_HOST_DEVICE - virtual ~H1_Wedge_Lagrange1_Gauss6() override - {} - - GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override - { - return numQuadraturePoints; - } + /// @cond DO_NOT_DOCUMENT + H1_Wedge_Lagrange1_Gauss6_impl() = default; + ~H1_Wedge_Lagrange1_Gauss6_impl() = default; + H1_Wedge_Lagrange1_Gauss6_impl( H1_Wedge_Lagrange1_Gauss6_impl const & ) = default; + H1_Wedge_Lagrange1_Gauss6_impl & operator=( H1_Wedge_Lagrange1_Gauss6_impl const & ) = default; + H1_Wedge_Lagrange1_Gauss6_impl( H1_Wedge_Lagrange1_Gauss6_impl && ) = default; + H1_Wedge_Lagrange1_Gauss6_impl & operator=( H1_Wedge_Lagrange1_Gauss6_impl && ) = default; + /// @endcond DO_NOT_DOCUMENT /** * @brief Get the number of quadrature points. @@ -96,18 +90,6 @@ class H1_Wedge_Lagrange1_Gauss6 final : public FiniteElementBase return numQuadraturePoints; } - GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const override - { - return numNodes; - } - - GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const override - { - return maxSupportPoints; - } - /** * @brief Get the number of support points. * @param stack Object that holds stack variables. @@ -236,6 +218,36 @@ class H1_Wedge_Lagrange1_Gauss6 final : public FiniteElementBase calcFaceBubbleN( pointCoord, N ); } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 ( &J )[3][3] ); + + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param stack Variables allocated on the stack as filled by @ref setupStack. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const &stack, + real64 ( &J )[3][3] ); + /** * @brief Calculate the shape functions derivatives wrt the physical * coordinates. @@ -466,7 +478,7 @@ class H1_Wedge_Lagrange1_Gauss6 final : public FiniteElementBase GEOS_HOST_DEVICE inline void -H1_Wedge_Lagrange1_Gauss6:: +H1_Wedge_Lagrange1_Gauss6_impl:: jacobianTransformation( int const q, real64 const (&X)[numNodes][3], real64 ( & J )[3][3] ) @@ -504,7 +516,7 @@ H1_Wedge_Lagrange1_Gauss6:: GEOS_HOST_DEVICE inline void -H1_Wedge_Lagrange1_Gauss6:: +H1_Wedge_Lagrange1_Gauss6_impl:: applyJacobianTransformationToShapeFunctionsDerivatives( int const q, real64 const ( &invJ )[3][3], real64 (& gradN)[numNodes][3] ) @@ -543,8 +555,8 @@ H1_Wedge_Lagrange1_Gauss6:: GEOS_HOST_DEVICE inline void -H1_Wedge_Lagrange1_Gauss6::calcN( real64 const (&coords)[3], - real64 (& N)[numNodes] ) +H1_Wedge_Lagrange1_Gauss6_impl::calcN( real64 const (&coords)[3], + real64 (& N)[numNodes] ) { real64 const r = coords[0]; real64 const s = coords[1]; @@ -563,7 +575,7 @@ H1_Wedge_Lagrange1_Gauss6::calcN( real64 const (&coords)[3], GEOS_HOST_DEVICE inline void -H1_Wedge_Lagrange1_Gauss6:: +H1_Wedge_Lagrange1_Gauss6_impl:: calcN( localIndex const q, real64 (& N)[numNodes] ) { @@ -576,7 +588,7 @@ H1_Wedge_Lagrange1_Gauss6:: GEOS_HOST_DEVICE inline -void H1_Wedge_Lagrange1_Gauss6:: +void H1_Wedge_Lagrange1_Gauss6_impl:: calcN( localIndex const q, StackVariables const & GEOS_UNUSED_PARAM( stack ), real64 ( & N )[numNodes] ) @@ -586,10 +598,40 @@ void H1_Wedge_Lagrange1_Gauss6:: //************************************************************************************************* +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Wedge_Lagrange1_Gauss6_impl::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& J)[3][3] ) +{ + for( int i = 0; i < 3; ++i ) + { + for( int j = 0; j < 3; ++j ) + { + J[i][j] = 0; + } + } + jacobianTransformation( q, X, J ); + real64 const detJ = LvArray::tensorOps::determinant< 3 >( J ); + return detJ * weight; +} + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +H1_Wedge_Lagrange1_Gauss6_impl::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & GEOS_UNUSED_PARAM( stack ), + real64 (& J)[3][3] ) +{ + return calcJacobian( q, X, J ); +} + GEOS_HOST_DEVICE inline real64 -H1_Wedge_Lagrange1_Gauss6:: +H1_Wedge_Lagrange1_Gauss6_impl:: calcGradN( localIndex const q, real64 const (&X)[numNodes][3], real64 (& gradN)[numNodes][3] ) @@ -607,7 +649,7 @@ H1_Wedge_Lagrange1_Gauss6:: GEOS_HOST_DEVICE inline -real64 H1_Wedge_Lagrange1_Gauss6:: +real64 H1_Wedge_Lagrange1_Gauss6_impl:: calcGradN( localIndex const q, real64 const (&X)[numNodes][3], StackVariables const & GEOS_UNUSED_PARAM( stack ), @@ -619,9 +661,9 @@ real64 H1_Wedge_Lagrange1_Gauss6:: GEOS_HOST_DEVICE inline real64 -H1_Wedge_Lagrange1_Gauss6::calcGradFaceBubbleN( localIndex const q, - real64 const (&X)[numNodes][3], - real64 (& gradN)[numFaces][3] ) +H1_Wedge_Lagrange1_Gauss6_impl::calcGradFaceBubbleN( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& gradN)[numFaces][3] ) { real64 J[3][3] = {{0}}; @@ -671,7 +713,7 @@ H1_Wedge_Lagrange1_Gauss6::calcGradFaceBubbleN( localIndex const q, GEOS_HOST_DEVICE inline real64 -H1_Wedge_Lagrange1_Gauss6:: +H1_Wedge_Lagrange1_Gauss6_impl:: transformedQuadratureWeight( localIndex const q, real64 const (&X)[numNodes][3] ) { @@ -682,7 +724,41 @@ H1_Wedge_Lagrange1_Gauss6:: return LvArray::tensorOps::determinant< 3 >( J ) * weight; } -/// @endcond +/// @endcond Doxygen_Suppress + +/// @copydoc H1_Wedge_Lagrange1_Gauss6_impl +class H1_Wedge_Lagrange1_Gauss6 final : public H1_Wedge_Lagrange1_Gauss6_impl, + public FiniteElementBase +{ + +public: + + /// Implementation type + using ImplType = H1_Wedge_Lagrange1_Gauss6_impl; + + H1_Wedge_Lagrange1_Gauss6(): + FiniteElementBase( numNodes, maxSupportPoints, numQuadraturePoints ) + {} + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Wedge_Lagrange1_Gauss6_impl * getImpl() + { + return static_cast< H1_Wedge_Lagrange1_Gauss6_impl * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + H1_Wedge_Lagrange1_Gauss6_impl const * getImpl() const + { + return static_cast< H1_Wedge_Lagrange1_Gauss6_impl const * >(this); + } + +}; } } diff --git a/src/coreComponents/finiteElement/elementFormulations/Pk_Pyramid_BCD.hpp b/src/coreComponents/finiteElement/elementFormulations/Pk_Pyramid_BCD.hpp index ec0b93f71a0..e1db00ac246 100644 --- a/src/coreComponents/finiteElement/elementFormulations/Pk_Pyramid_BCD.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/Pk_Pyramid_BCD.hpp @@ -31,6 +31,12 @@ namespace geos namespace finiteElement { +namespace +{ +template< int ORDER > +constexpr int Pk_Pyramid_BCD_NumNodes = ( ORDER + 1 ) * ( ORDER + 2 ) * ( 2 * ORDER + 3 ) / 6; +} + /** * This class is the basis class for the pyramid finite element cells with @@ -39,36 +45,41 @@ namespace finiteElement * For now only P1 is implemented, P2 and higher will be implemented later. */ template< int ORDER > -class Pk_Pyramid_BCD final : public FiniteElementBase +class Pk_Pyramid_BCD_impl : public FiniteElementBase_impl< Pk_Pyramid_BCD_NumNodes< ORDER >, + 5, + Pk_Pyramid_BCD_NumNodes< ORDER > > { public: + /// Convenience alias for the base class. + using Base = FiniteElementBase_impl< Pk_Pyramid_BCD_NumNodes< ORDER >, + 5, + Pk_Pyramid_BCD_NumNodes< ORDER > >; - /// The order of the finite element. - static constexpr int order = ORDER; + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; + + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; /// The number of shape functions per element. - constexpr static localIndex numNodes = ( ORDER + 1 ) * ( ORDER + 2 ) * ( 2 * ORDER + 3 ) / 6; + using Base::numNodes; - /// The number of faces points per element. - constexpr static localIndex numFaces = 5; + /// The number of quadrature points per element. + using Base::numQuadraturePoints; /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; + using Base::maxSupportPoints; - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = numNodes; + /// The order of the finite element. + static constexpr int order = ORDER; /// The number of modal points per element. constexpr static localIndex numModes = numNodes; - /** @cond Doxygen_Suppress */ - USING_FINITEELEMENTBASE - /** @endcond Doxygen_Suppress */ - - virtual ~Pk_Pyramid_BCD() = default; - + /// @copydoc FiniteElementBase_impl::getNumQuadraturePoints() GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override + static localIndex getNumQuadraturePoints() { return numQuadraturePoints; } @@ -86,16 +97,18 @@ class Pk_Pyramid_BCD final : public FiniteElementBase return numQuadraturePoints; } + /// @copydoc FiniteElementBase_impl::getNumSupportPoints() GEOS_HOST_DEVICE GEOS_FORCE_INLINE - virtual localIndex getNumSupportPoints() const override + static localIndex getNumSupportPoints() { return numNodes; } + /// @copydoc FiniteElementBase_impl::getMaxSupportPoints() GEOS_HOST_DEVICE GEOS_FORCE_INLINE - virtual localIndex getMaxSupportPoints() const override + static localIndex getMaxSupportPoints() { return maxSupportPoints; } @@ -199,9 +212,29 @@ class Pk_Pyramid_BCD final : public FiniteElementBase func( i, j, k ); } } - } + } + /** + * @brief Generate the indexes for the modal shape functions + * @param func The function to call with the generated indexes + */ + template< typename FUNC > + GEOS_FORCE_INLINE + static constexpr void generateIndexesHost( FUNC && func ) + { + + for( localIndex i = 0; i <= ORDER; ++i ) + { + for( localIndex j = 0; j <= ORDER; ++j ) + { + localIndex maxIj = LvArray::math::max( i, j ); + for( localIndex k = 0; k <= ORDER - maxIj; ++k ) + { + func( i, j, k ); + } + } + } } /** @@ -462,13 +495,12 @@ class Pk_Pyramid_BCD final : public FiniteElementBase for( int j = 0; j < numNodes; ++j ) { localIndex count = 0; - generateIndexes( [&]( localIndex const p, localIndex const r, localIndex const s ) + generateIndexesHost( [&]( localIndex const p, localIndex const r, localIndex const s ) { - PsiX[count]=calcModal( p, r, s, coords[j] ); + PsiX[count] = calcModal( p, r, s, coords[j] ); VDM[count][j] = PsiX[count]; ++count; } ); - // } } array2d< real64 > VDM_inv; VDM_inv.resize( numNodes, numNodes ); @@ -742,11 +774,66 @@ class Pk_Pyramid_BCD final : public FiniteElementBase }; -/** - * Pyramid element with BCD basis functions of order 1. - */ +/// @copydoc Pk_Pyramid_BCD_impl +template< int ORDER > +class Pk_Pyramid_BCD final : public Pk_Pyramid_BCD_impl< ORDER >, public FiniteElementBase +{ +public: + + /// The Implementation type + using ImplType = Pk_Pyramid_BCD_impl< ORDER >; + + /// The number of nodes per element. + using ImplType::numNodes; + + /// The max number of support points per element. + using ImplType::maxSupportPoints; + + /// The number of quadrature points per element. + using ImplType::numQuadraturePoints; + + Pk_Pyramid_BCD(): + FiniteElementBase( numNodes, + maxSupportPoints, + numQuadraturePoints ) + {} + +#ifdef __CUDACC__ + #pragma diag_push + #pragma nv_diag_suppress 20012 +#endif + GEOS_HOST_DEVICE + virtual ~Pk_Pyramid_BCD() override final = default; +#ifdef __CUDACC__ + #pragma diag_pop +#endif + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + ImplType * getImpl() + { + return static_cast< ImplType * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + ImplType const * getImpl() const + { + return static_cast< ImplType const * >(this); + } + +}; + +/// Pyramid element with BCD basis functions of order 1. using P1_Pyramid_BCD = Pk_Pyramid_BCD< 1 >; +/// Pyramid element with BCD basis functions of order 1. +using P1_Pyramid_BCD_impl = Pk_Pyramid_BCD_impl< 1 >; + } } diff --git a/src/coreComponents/finiteElement/elementFormulations/Qk_Hexahedron_Lagrange_GaussLobatto.hpp b/src/coreComponents/finiteElement/elementFormulations/Qk_Hexahedron_Lagrange_GaussLobatto.hpp index 25a3f6c7783..50d782b382c 100644 --- a/src/coreComponents/finiteElement/elementFormulations/Qk_Hexahedron_Lagrange_GaussLobatto.hpp +++ b/src/coreComponents/finiteElement/elementFormulations/Qk_Hexahedron_Lagrange_GaussLobatto.hpp @@ -41,9 +41,24 @@ namespace finiteElement * All the degree-specific versions (Q1, Q2, Q3, ...) are defined at the end of this file. */ template< typename GL_BASIS > -class Qk_Hexahedron_Lagrange_GaussLobatto final : public FiniteElementBase +class Qk_Hexahedron_Lagrange_GaussLobatto_impl : public FiniteElementBase_impl< GL_BASIS::TensorProduct3D::numSupportPoints, + 6, + GL_BASIS::TensorProduct3D::numSupportPoints > { public: + /// Convenience type alias for the base class + using Base = FiniteElementBase_impl< GL_BASIS::TensorProduct3D::numSupportPoints, + 6, + GL_BASIS::TensorProduct3D::numSupportPoints >; + + /// The number of shape functions per element. + using Base::numNodes; + + /// The number of quadrature points per element. + using Base::numQuadraturePoints; + + /// The maximum number of support points per element. + using Base::maxSupportPoints; /// The number of nodes/support points per element per dimension. constexpr static localIndex num1dNodes = GL_BASIS::numSupportPoints; @@ -51,17 +66,24 @@ class Qk_Hexahedron_Lagrange_GaussLobatto final : public FiniteElementBase /// Half the number of support points, rounded down. Precomputed for efficiency constexpr static localIndex halfNodes = ( GL_BASIS::numSupportPoints - 1 )/ 2; - /// The number of nodes/support points per element. - constexpr static localIndex numNodes = GL_BASIS::TensorProduct3D::numSupportPoints; - /// The number of nodes/support points per face constexpr static localIndex numNodesPerFace = GL_BASIS::TensorProduct2D::numSupportPoints; - /// The maximum number of support points per element. - constexpr static localIndex maxSupportPoints = numNodes; + /// Stack variables for the element. + using StackVariables = typename Base::StackVariables; - /// The number of quadrature points per element. - constexpr static localIndex numQuadraturePoints = numNodes; + /// Mesh data structure for the element. + template< typename SubregionType > + using MeshData = typename Base::template MeshData< SubregionType >; + + /// @cond DO_NOT_DOCUMENT + Qk_Hexahedron_Lagrange_GaussLobatto_impl() = default; + ~Qk_Hexahedron_Lagrange_GaussLobatto_impl() = default; + Qk_Hexahedron_Lagrange_GaussLobatto_impl( Qk_Hexahedron_Lagrange_GaussLobatto_impl const & ) = default; + Qk_Hexahedron_Lagrange_GaussLobatto_impl & operator=( Qk_Hexahedron_Lagrange_GaussLobatto_impl const & ) = default; + Qk_Hexahedron_Lagrange_GaussLobatto_impl( Qk_Hexahedron_Lagrange_GaussLobatto_impl && ) = default; + Qk_Hexahedron_Lagrange_GaussLobatto_impl & operator=( Qk_Hexahedron_Lagrange_GaussLobatto_impl && ) = default; + /// @endcond DO_NOT_DOCUMENT /** * @brief The linear index associated to the given one-dimensional indices in the three directions @@ -118,18 +140,6 @@ class Qk_Hexahedron_Lagrange_GaussLobatto final : public FiniteElementBase ( num1dNodes - 1 ) * ( k / 2 ) ); } - /** @cond Doxygen_Suppress */ - USING_FINITEELEMENTBASE - /** @endcond Doxygen_Suppress */ - - ~Qk_Hexahedron_Lagrange_GaussLobatto() = default; - - GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override - { - return numQuadraturePoints; - } - /** * @brief Get the number of quadrature points. * @param stack Stack variables as filled by @ref setupStack. @@ -143,20 +153,6 @@ class Qk_Hexahedron_Lagrange_GaussLobatto final : public FiniteElementBase return numQuadraturePoints; } - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual localIndex getNumSupportPoints() const override - { - return numNodes; - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual localIndex getMaxSupportPoints() const override - { - return maxSupportPoints; - } - /** * @brief Get the number of support points. * @param stack Object that holds stack variables. @@ -281,6 +277,35 @@ class Qk_Hexahedron_Lagrange_GaussLobatto final : public FiniteElementBase return calcN( q, N ); } + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 ( &J )[3][3] ); + + /** + * @brief Calculate the Jacobian matrix at a quadrature point. + * @param q Index of the quadrature point. + * @param X Array containing the coordinates of the support points. + * @param stack Variables allocated on the stack as filled by @ref setupStack. + * @param J Array to contain the Jacobian matrix at the quadrature point. + * @return The determinant of the Jacobian matrix multiplied by the quadrature weight. + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static + real64 calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const &stack, + real64 ( &J )[3][3] ); /** * @brief Calculate the shape functions derivatives wrt the physical @@ -864,9 +889,9 @@ template< typename FUNC, typename ... PARAMS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::supportLoop( real64 const (&coords)[3], - FUNC && func, - PARAMS &&... params ) +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::supportLoop( real64 const (&coords)[3], + FUNC && func, + PARAMS &&... params ) { for( int c=0; c GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::supportLoop( localIndex const q, - FUNC && func, - PARAMS &&... params ) +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::supportLoop( localIndex const q, + FUNC && func, + PARAMS &&... params ) { int qa, qb, qc; GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc ); @@ -927,9 +952,9 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradN( localIndex const q, - real64 const (&X)[numNodes][3], - real64 (& gradN)[numNodes][3] ) +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::calcGradN( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& gradN)[numNodes][3] ) { int qa, qb, qc; GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc ); @@ -950,16 +975,58 @@ Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradN( localIndex const q, applyTransformationToParentGradients( q, J, gradN ); - return detJ; + return detJ * GL_BASIS::weight( qa ) * GL_BASIS::weight( qb ) * GL_BASIS::weight( qc ); } //************************************************************************************************* template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradN( real64 const (&coords)[3], - real64 const (&X)[numNodes][3], - real64 (& gradN)[numNodes][3] ) +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + real64 (& J)[3][3] ) +{ + for( int i = 0; i < 3; ++i ) + { + for( int j = 0; j < 3; ++j ) + { + J[i][j] = 0; + } + } + int qa, qb, qc; + GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc ); + real64 Xmesh[8][3] = {{0}}; + for( int k = 0; k < 8; k++ ) + { + const localIndex nodeIndex = meshIndexToLinearIndex3D( k ); + for( int i = 0; i < 3; i++ ) + { + Xmesh[k][i] = X[nodeIndex][i]; + } + } + jacobianTransformation( qa, qb, qc, Xmesh, J ); + return LvArray::tensorOps::determinant< 3 >( J ); +} + +template< typename GL_BASIS > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::calcJacobian( localIndex const q, + real64 const (&X)[numNodes][3], + StackVariables const & GEOS_UNUSED_PARAM( stack ), + real64 (& J)[3][3] ) +{ + return calcJacobian( q, X, J ); +} + +template< typename GL_BASIS > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::calcGradN( real64 const (&coords)[3], + real64 const (&X)[numNodes][3], + real64 (& gradN)[numNodes][3] ) { real64 J[3][3] = {{0}}; @@ -974,7 +1041,7 @@ Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradN( real64 const (&coord template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE -real64 Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +real64 Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: calcGradN( localIndex const q, real64 const (&X)[numNodes][3], StackVariables const & GEOS_UNUSED_PARAM( stack ), @@ -987,9 +1054,9 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradNWithCorners( localIndex const q, - real64 const (&X)[8][3], - real64 (& gradN)[numNodes][3] ) +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::calcGradNWithCorners( localIndex const q, + real64 const (&X)[8][3], + real64 (& gradN)[numNodes][3] ) { int qa, qb, qc; GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc ); @@ -1002,16 +1069,16 @@ Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradNWithCorners( localInde applyTransformationToParentGradients( q, J, gradN ); - return detJ; + return detJ * GL_BASIS::weight( qa ) * GL_BASIS::weight( qb ) * GL_BASIS::weight( qc ); } //************************************************************************************************* template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradNWithCorners( real64 const (&coords)[3], - real64 const (&X)[8][3], - real64 (& gradN)[numNodes][3] ) +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::calcGradNWithCorners( real64 const (&coords)[3], + real64 const (&X)[8][3], + real64 (& gradN)[numNodes][3] ) { real64 J[3][3] = {{0}}; @@ -1026,7 +1093,7 @@ Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::calcGradNWithCorners( real64 co template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE -real64 Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +real64 Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: calcGradNWithCorners( localIndex const q, real64 const (&X)[8][3], StackVariables const & GEOS_UNUSED_PARAM( stack ), @@ -1044,7 +1111,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: jacobianTransformation( int const qa, int const qb, int const qc, @@ -1073,7 +1140,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: jacobianTransformation( real64 const (&coords)[3], real64 const (&X)[numNodes][3], real64 ( & J )[3][3] ) @@ -1098,7 +1165,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: jacobianTransformationWithCorners( real64 const (&coords)[3], real64 const (&X)[8][3], real64 ( & J )[3][3] ) @@ -1129,7 +1196,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: trilinearInterp( real64 const alpha, real64 const beta, real64 const gamma, @@ -1154,7 +1221,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeLocalCoords( real64 const (&Xmesh)[8][3], real64 const (&X)[numNodes][3] ) { @@ -1173,7 +1240,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: jacobianTransformation2d( int const qa, int const qb, real64 const (&X)[4][3], @@ -1199,7 +1266,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeMassTerm( localIndex const q, real64 const (&X)[8][3] ) { @@ -1215,7 +1282,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeDampingTerm( localIndex const q, real64 const (&X)[4][3] ) { @@ -1236,7 +1303,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeBMatrix( int const qa, int const qb, int const qc, @@ -1263,7 +1330,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeBzMatrix( int const qa, int const qb, int const qc, @@ -1290,7 +1357,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeBxyMatrix( int const qa, int const qb, int const qc, @@ -1318,7 +1385,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeGradPhiBGradPhi( int const qa, int const qb, int const qc, @@ -1368,7 +1435,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeStiffnessxyTerm( localIndex const q, real64 const (&X)[8][3], FUNC && func ) @@ -1386,7 +1453,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeStiffnesszTerm( localIndex const q, real64 const (&X)[8][3], FUNC && func ) @@ -1404,7 +1471,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeStiffnessTerm( localIndex const q, real64 const (&X)[8][3], FUNC && func ) @@ -1422,7 +1489,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeFirstOrderStiffnessTerm( localIndex const q, real64 const (&X)[8][3], FUNC && func ) @@ -1475,7 +1542,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeFirstOrderStiffnessTermX( localIndex const q, real64 const (&X)[8][3], FUNC && func ) @@ -1500,7 +1567,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeFirstOrderStiffnessTermY( localIndex const q, real64 const (&X)[8][3], FUNC && func ) @@ -1524,7 +1591,7 @@ template< typename FUNC > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: computeFirstOrderStiffnessTermZ( localIndex const q, real64 const (&X)[8][3], FUNC && func ) @@ -1548,7 +1615,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: applyTransformationToParentGradients( int const q, real64 const ( &invJ )[3][3], real64 (& gradN)[numNodes][3] ) @@ -1572,7 +1639,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE void -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: applyTransformationToParentGradients( real64 const (&coords)[3], real64 const ( &invJ )[3][3], real64 (& gradN)[numNodes][3] ) @@ -1592,7 +1659,7 @@ template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 -Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: transformedQuadratureWeight( localIndex const q, real64 const (&X)[numNodes][3] ) { @@ -1610,7 +1677,7 @@ transformedQuadratureWeight( localIndex const q, template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE -void Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +void Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: symmetricGradient( int const q, real64 const (&invJ)[3][3], real64 const (&var)[numNodes][3], @@ -1644,7 +1711,7 @@ symmetricGradient( int const q, template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE -void Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +void Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: plusGradNajAij( int const q, real64 const (&invJ)[3][3], real64 const (&var)[6], @@ -1678,7 +1745,7 @@ plusGradNajAij( int const q, template< typename GL_BASIS > GEOS_HOST_DEVICE GEOS_FORCE_INLINE -void Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >:: +void Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >:: gradient( int const q, real64 const (&invJ)[3][3], real64 const (&var)[numNodes][3], @@ -1704,6 +1771,46 @@ gradient( int const q, } }, invJ, var, grad ); } + + +template< typename GL_BASIS > +class Qk_Hexahedron_Lagrange_GaussLobatto final : public Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >, + public FiniteElementBase +{ +public: + + /// The type of basis used for this element + using BASIS = GL_BASIS; + + using ImplType = Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >; + + Qk_Hexahedron_Lagrange_GaussLobatto(): FiniteElementBase( ImplType::numNodes, + ImplType::maxSupportPoints, + ImplType::numQuadraturePoints ) + { } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > * getImpl() + { + return static_cast< Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > * >(this); + } + + /** + * @brief Get the device-compatible implementation type. + * @return A pointer to the device-compatible implementation type. + */ + const Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > * getImpl() const + { + return static_cast< const Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > * >(this); + } + + virtual ~Qk_Hexahedron_Lagrange_GaussLobatto() override final = default; +}; + + /** * This class contains the kernel accessible functions specific to the standard * Trilinear Hexahedron finite element with a Gaussian quadrature rule. It is @@ -1909,6 +2016,12 @@ using Q4_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< */ using Q5_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis5GL >; +using Q1_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis1 >; +using Q2_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis2 >; +using Q3_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis3GL >; +using Q4_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis4GL >; +using Q5_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis5GL >; + /// @endcond #if __GNUC__ diff --git a/src/coreComponents/finiteElement/elementFormulations/unitTests/testConformingVirtualElementOrder1.cpp b/src/coreComponents/finiteElement/elementFormulations/unitTests/testConformingVirtualElementOrder1.cpp index 266ce88d436..dea9c0437fc 100644 --- a/src/coreComponents/finiteElement/elementFormulations/unitTests/testConformingVirtualElementOrder1.cpp +++ b/src/coreComponents/finiteElement/elementFormulations/unitTests/testConformingVirtualElementOrder1.cpp @@ -35,8 +35,7 @@ constexpr real64 relTol = geos::testing::DEFAULT_REL_TOL*10; template< typename VEM > GEOS_HOST_DEVICE -static void checkIntegralMeanConsistency( FiniteElementBase const & feBase, - typename VEM::StackVariables const & stack, +static void checkIntegralMeanConsistency( typename VEM::StackVariables const & stack, real64 & sumBasisFunctions ) { static constexpr localIndex @@ -44,8 +43,7 @@ static void checkIntegralMeanConsistency( FiniteElementBase const & feBase, real64 basisFunctionsIntegralMean[maxSupportPoints]; VEM::calcN( 0, stack, basisFunctionsIntegralMean ); sumBasisFunctions = 0; - for( localIndex iBasisFun = 0; - iBasisFun < feBase.template numSupportPoints< VEM >( stack ); ++iBasisFun ) + for( localIndex iBasisFun = 0; iBasisFun < VEM::getNumSupportPoints( stack ); ++iBasisFun ) { sumBasisFunctions += basisFunctionsIntegralMean[iBasisFun]; } @@ -54,8 +52,7 @@ static void checkIntegralMeanConsistency( FiniteElementBase const & feBase, template< typename VEM > GEOS_HOST_DEVICE static void -checkIntegralMeanDerivativesConsistency( FiniteElementBase const & feBase, - typename VEM::StackVariables const & stack, +checkIntegralMeanDerivativesConsistency( typename VEM::StackVariables const & stack, real64 & sumXDerivatives, real64 & sumYDerivatives, real64 & sumZDerivatives ) @@ -63,15 +60,12 @@ checkIntegralMeanDerivativesConsistency( FiniteElementBase const & feBase, static constexpr localIndex maxSupportPoints = VEM::maxSupportPoints; real64 const dummy[VEM::numNodes][3] { { 0.0 } }; - localIndex const k = 0; for( localIndex q = 0; q < VEM::numQuadraturePoints; ++q ) { real64 basisDerivativesIntegralMean[maxSupportPoints][3]{}; - feBase.template getGradN< VEM >( k, q, dummy, stack, basisDerivativesIntegralMean ); + VEM::calcGradN( q, dummy, stack, basisDerivativesIntegralMean ); sumXDerivatives = 0; sumYDerivatives = 0; sumZDerivatives = 0; - for( localIndex iBasisFun = 0; - iBasisFun < feBase.template numSupportPoints< VEM >( stack ); - ++iBasisFun ) + for( localIndex iBasisFun = 0; iBasisFun < VEM::getNumSupportPoints( stack ); ++iBasisFun ) { sumXDerivatives += basisDerivativesIntegralMean[iBasisFun][0]; sumYDerivatives += basisDerivativesIntegralMean[iBasisFun][1]; @@ -88,7 +82,7 @@ checkStabilizationMatrixConsistency ( arrayView2d< real64 const, localIndex const & cellIndex, traits::ViewTypeConst< CellElementSubRegion::NodeMapType > const & cellToNodes, arrayView2d< real64 const > const & cellCenters, - FiniteElementBase const & feBase, + VEM const & feBase, typename VEM::StackVariables const & stack, arraySlice1d< real64 > & stabTimeMonomialDofsNorm ) { @@ -193,11 +187,11 @@ static void testCellsInMeshLevel( MeshLevel const & mesh ) arrayView1d< real64 const > cellVolumes = cellSubRegion.getElementVolume(); // Allocate and fill a VEM::MeshData struct. - using VEM = ConformingVirtualElementOrder1< MAXCELLNODES, MAXFACENODES >; + using VEM = ConformingVirtualElementOrder1_impl< MAXCELLNODES, MAXFACENODES >; typename VEM::template MeshData< CellElementSubRegion > meshData; - FiniteElementBase::initialize< VEM >( nodeManager, edgeManager, - faceManager, cellSubRegion, - meshData ); + VEM::template initialize< VEM >( nodeManager, edgeManager, + faceManager, cellSubRegion, + meshData ); // Arrays that store quantities to be tested. localIndex const numCells = cellSubRegion.getElementVolume().size(); @@ -221,9 +215,9 @@ static void testCellsInMeshLevel( MeshLevel const & mesh ) VEM virtualElement; virtualElement.template setup< VEM >( cellIndex, meshData, stack ); - checkIntegralMeanConsistency< VEM >( virtualElement, stack, + checkIntegralMeanConsistency< VEM >( stack, sumBasisFunctionsView( cellIndex ) ); - checkIntegralMeanDerivativesConsistency< VEM >( virtualElement, stack, + checkIntegralMeanDerivativesConsistency< VEM >( stack, sumXDerivativesView( cellIndex ), sumYDerivativesView( cellIndex ), sumZDerivativesView( cellIndex ) diff --git a/src/coreComponents/finiteElement/kernelInterface/ImplicitKernelBase.hpp b/src/coreComponents/finiteElement/kernelInterface/ImplicitKernelBase.hpp index 8e86d076e68..5d257e6df5d 100644 --- a/src/coreComponents/finiteElement/kernelInterface/ImplicitKernelBase.hpp +++ b/src/coreComponents/finiteElement/kernelInterface/ImplicitKernelBase.hpp @@ -104,11 +104,12 @@ class ImplicitKernelBase : public KernelBase< SUBREGION_TYPE, m_rhs( inputRhs ), m_dt( inputDt ) { - FiniteElementBase::initialize< FE_TYPE >( nodeManager, - edgeManager, - faceManager, - elementSubRegion, - m_meshData ); + + FE_TYPE::fillMeshData( nodeManager, + edgeManager, + faceManager, + elementSubRegion, + m_meshData ); GEOS_UNUSED_VAR( targetRegionIndex ); } @@ -184,7 +185,7 @@ class ImplicitKernelBase : public KernelBase< SUBREGION_TYPE, StackVariables & stack ) const { m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack ); - localIndex numTestSupportPoints = m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + localIndex numTestSupportPoints = FE_TYPE::getNumSupportPoints( stack.feStack ); localIndex numTrialSupportPoints = numTestSupportPoints; stack.numRows = numTestSupportPoints * numDofPerTestSupportPoint; stack.numCols = numTrialSupportPoints * numDofPerTrialSupportPoint; diff --git a/src/coreComponents/finiteElement/kernelInterface/KernelBase.hpp b/src/coreComponents/finiteElement/kernelInterface/KernelBase.hpp index 836a885512a..e924b2f3be9 100644 --- a/src/coreComponents/finiteElement/kernelInterface/KernelBase.hpp +++ b/src/coreComponents/finiteElement/kernelInterface/KernelBase.hpp @@ -545,7 +545,7 @@ real64 regionBasedKernelApplication( MeshLevel & mesh, SUBREGION_TYPE & castedSubRegion = dynamicCast< SUBREGION_TYPE & >( elementSubRegion ); CONSTITUTIVE_TYPE & castedConstitutiveRelation = dynamicCast< CONSTITUTIVE_TYPE & >( *constitutiveRelation ); - FE_TYPE & castedFiniteElement = dynamicCast< FE_TYPE & >( subRegionFE ); + typename FE_TYPE::ImplType & castedFiniteElement = *(dynamicCast< FE_TYPE & >( subRegionFE ).getImpl()); auto kernel = kernelFactory.createKernel( nodeManager, edgeManager, diff --git a/src/coreComponents/finiteElement/unitTests/testFiniteElementBase.cpp b/src/coreComponents/finiteElement/unitTests/testFiniteElementBase.cpp index b6e3c1f4610..682991e138f 100644 --- a/src/coreComponents/finiteElement/unitTests/testFiniteElementBase.cpp +++ b/src/coreComponents/finiteElement/unitTests/testFiniteElementBase.cpp @@ -15,6 +15,7 @@ #include "finiteElement/elementFormulations/FiniteElementBase.hpp" +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" #include "gtest/gtest.h" #include "testFiniteElementHelpers.hpp" #include "common/GEOS_RAJA_Interface.hpp" @@ -24,17 +25,16 @@ using namespace geos; using namespace finiteElement; - //***** TEST VIEW SETTERS/GETTERS ***************************************************************** -class TestFiniteElementBase final : public FiniteElementBase +class TestFiniteElementBase final : public FiniteElementBase, + public FiniteElementBase_impl< 8, 8, 8 > { - GEOS_HOST_DEVICE - virtual localIndex getNumQuadraturePoints() const override {return 8;}; - GEOS_HOST_DEVICE - virtual localIndex getNumSupportPoints() const override {return 8;}; - GEOS_HOST_DEVICE - virtual localIndex getMaxSupportPoints() const override {return 8;}; + TestFiniteElementBase(): + FiniteElementBase( 8, 8, 8 ), + FiniteElementBase_impl< 8, 8, 8 >() + {} + template< typename SUBREGION_TYPE > static void fillMeshData( NodeManager const & GEOS_UNUSED_PARAM( nodeManager ), EdgeManager const & GEOS_UNUSED_PARAM( edgeManager ), @@ -43,131 +43,16 @@ class TestFiniteElementBase final : public FiniteElementBase MeshData< SUBREGION_TYPE > & GEOS_UNUSED_PARAM( meshData ) ) {} + template< typename SUBREGION_TYPE > - GEOS_HOST_DEVICE + // GEOS_HOST_DEVICE static void setupStack( localIndex const & GEOS_UNUSED_PARAM( cellIndex ), MeshData< SUBREGION_TYPE > const & GEOS_UNUSED_PARAM( meshData ), StackVariables & GEOS_UNUSED_PARAM( stack ) ) {} }; -TEST( FiniteElementBase, test_setGradNView ) -{ - TestFiniteElementBase feBase; - { - array4d< real64 > gradN( 2, 8, 8, 3 ); - feBase.setGradNView( gradN.toViewConst() ); - - EXPECT_EQ( feBase.getGradNView().size( 0 ), gradN.size( 0 ) ); - EXPECT_EQ( feBase.getGradNView().size( 1 ), gradN.size( 1 ) ); - EXPECT_EQ( feBase.getGradNView().size( 2 ), gradN.size( 2 ) ); - EXPECT_EQ( feBase.getGradNView().size( 3 ), gradN.size( 3 ) ); - } - - { - array4d< real64 > gradN( 2, 7, 8, 3 ); - EXPECT_DEATH_IF_SUPPORTED( feBase.setGradNView( gradN.toViewConst() ), "" ); - } - - { - array4d< real64 > gradN( 2, 8, 7, 3 ); - EXPECT_DEATH_IF_SUPPORTED( feBase.setGradNView( gradN.toViewConst() ), "" ); - } - - { - array4d< real64 > gradN( 2, 8, 8, 2 ); - EXPECT_DEATH_IF_SUPPORTED( feBase.setGradNView( gradN.toViewConst() ), "" ); - } -} - -TEST( FiniteElementBase, test_setDetJView ) -{ - TestFiniteElementBase feBase; - { - array2d< real64 > detJ( 4, 8 ); - feBase.setDetJView( detJ.toViewConst() ); - EXPECT_EQ( feBase.getDetJView().size( 0 ), detJ.size( 0 ) ); - EXPECT_EQ( feBase.getDetJView().size( 1 ), detJ.size( 1 ) ); - } - - { - array2d< real64 > detJ( 4, 7 ); - EXPECT_DEATH_IF_SUPPORTED( feBase.setDetJView( detJ.toViewConst() ), "" ); - } -} - -//***** TEST getGradN ***************************************************************************** -TEST( FiniteElementBase, test_capture ) -{ - TestFiniteElementBase feBase; - array4d< real64 > gradN( 4, 8, 8, 3 ); - array2d< real64 > detJ( 4, 8 ); - feBase.setGradNView( gradN.toViewConst() ); - feBase.setDetJView( detJ.toViewConst() ); - - - array1d< localIndex > gradNDims( 4 ); - array1d< localIndex > detJDims( 2 ); - arrayView1d< localIndex > gradNDimsView = gradNDims.toView(); - arrayView1d< localIndex > detJDimsView = detJDims.toView(); -#if defined(CALC_FEM_SHAPE_IN_KERNEL) - - forAll< parallelDevicePolicy<> >( 1, [ feBase, gradNDimsView, detJDimsView ]( int const i ) - { - gradNDimsView[0] = feBase.getGradNView().size( 0 ); - gradNDimsView[1] = feBase.getGradNView().size( 1 ); - gradNDimsView[2] = feBase.getGradNView().size( 2 ); - gradNDimsView[3] = feBase.getGradNView().size( 3 ); - detJDimsView[0] = feBase.getDetJView().size( 0 ); - detJDimsView[1] = feBase.getDetJView().size( 1 ); - - printf( "gradNDimsView = { %ld, %ld, %ld, %ld }\n", - gradNDimsView[0], - gradNDimsView[1], - gradNDimsView[2], - gradNDimsView[3] ); - - printf( "detJDimsView = { %ld, %ld }\n", - detJDimsView[0], - detJDimsView[1] ); - } ); - - forAll< serialPolicy >( 1, [ feBase, gradNDimsView, detJDimsView ]( int const i ) - {} ); - - EXPECT_EQ( gradNDimsView[0], 0 ); - EXPECT_EQ( gradNDimsView[1], 0 ); - EXPECT_EQ( gradNDimsView[2], 0 ); - EXPECT_EQ( gradNDimsView[3], 0 ); - - EXPECT_EQ( detJDimsView[0], 0 ); - EXPECT_EQ( detJDimsView[1], 0 ); -#endif - - - forAll< serialPolicy >( 1, [ feBase, gradNDimsView, detJDimsView ]( int const ) - { - gradNDimsView[0] = feBase.getGradNView().size( 0 ); - gradNDimsView[1] = feBase.getGradNView().size( 1 ); - gradNDimsView[2] = feBase.getGradNView().size( 2 ); - gradNDimsView[3] = feBase.getGradNView().size( 3 ); - detJDimsView[0] = feBase.getDetJView().size( 0 ); - detJDimsView[1] = feBase.getDetJView().size( 1 ); - } ); - - - EXPECT_EQ( gradNDimsView[0], gradN.size( 0 ) ); - EXPECT_EQ( gradNDimsView[1], gradN.size( 1 ) ); - EXPECT_EQ( gradNDimsView[2], gradN.size( 2 ) ); - EXPECT_EQ( gradNDimsView[3], gradN.size( 3 ) ); - - EXPECT_EQ( detJDimsView[0], detJ.size( 0 ) ); - EXPECT_EQ( detJDimsView[1], detJ.size( 1 ) ); - - - -} //***** TEST value() ****************************************************************************** @@ -219,7 +104,7 @@ TEST( FiniteElementBase, test_value ) real64 referenceScalarValue = -1.0; real64 feBaseScalarValue = -1.0; value( N, scalar, referenceScalarValue ); - FiniteElementBase::value( N, scalar, feBaseScalarValue ); + finiteElement::feOps::value( N, scalar, feBaseScalarValue ); EXPECT_FLOAT_EQ( feBaseScalarValue, referenceScalarValue ); @@ -227,7 +112,7 @@ TEST( FiniteElementBase, test_value ) real64 referenceVectorValue[3] = {-1, -1, -1}; real64 feBaseVectorValue[3] = {-1, -1, -1}; value( N, vector, referenceVectorValue ); - FiniteElementBase::value( N, vector, feBaseVectorValue ); + finiteElement::feOps::value( N, vector, feBaseVectorValue ); EXPECT_FLOAT_EQ( feBaseVectorValue[0], referenceVectorValue[0] ); EXPECT_FLOAT_EQ( feBaseVectorValue[1], referenceVectorValue[1] ); @@ -274,7 +159,7 @@ TEST( FiniteElementBase, test_symmetricGradient ) real64 referenceVectorGradient[6] = {-1, -1, -1, -1, -1, -1}; real64 feBaseVectorGradient[6] = {-1, -1, -1, -1, -1, -1}; symmetricGradient( gradN, vector, referenceVectorGradient ); - FiniteElementBase::symmetricGradient( gradN, vector, feBaseVectorGradient ); + finiteElement::feOps::symmetricGradient( gradN, vector, feBaseVectorGradient ); for( int i=0; i<6; ++i ) { @@ -344,13 +229,13 @@ TEST( FiniteElementBase, test_gradient ) real64 referenceScalarGradient[3] = {-1, -1, -1}; real64 feBaseScalarGradient[3] = {-1, -1, -1}; gradient( gradN, scalar, referenceScalarGradient ); - FiniteElementBase::gradient( gradN, scalar, feBaseScalarGradient ); + finiteElement::feOps::gradient( gradN, scalar, feBaseScalarGradient ); real64 referenceVectorGradient[3][3] = {{-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}}; real64 feBaseVectorGradient[3][3] = {{-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}}; gradient( gradN, vector, referenceVectorGradient ); - FiniteElementBase::gradient( gradN, vector, feBaseVectorGradient ); + finiteElement::feOps::gradient( gradN, vector, feBaseVectorGradient ); for( int i=0; i<3; ++i ) { @@ -411,7 +296,7 @@ TEST( FiniteElementBase, test_valueAndGradient ) real64 referenceScalarGradient[3] = {-1, -1, -1}; real64 feBaseScalarGradient[3] = {-1, -1, -1}; valueAndGradient( N, gradN, scalar, referenceScalarValue, referenceScalarGradient ); - FiniteElementBase::valueAndGradient( N, gradN, scalar, feBaseScalarValue, feBaseScalarGradient ); + finiteElement::feOps::valueAndGradient( N, gradN, scalar, feBaseScalarValue, feBaseScalarGradient ); EXPECT_FLOAT_EQ( feBaseScalarValue, referenceScalarValue ); for( int i=0; i<3; ++i ) @@ -425,7 +310,7 @@ TEST( FiniteElementBase, test_valueAndGradient ) // real64 referenceVectorGradient[3][3] = {{-1,-1,-1},{-1,-1,-1},{-1,-1,-1}}; // real64 feBaseVectorGradient[3][3] = {{-1,-1,-1},{-1,-1,-1},{-1,-1,-1}}; // valueAndGradient( N, gradN, vector, referenceVectorValue, referenceVectorGradient ); -// FiniteElementBase::valueAndGradient( N, gradN, vector, feBaseVectorValue, feBaseVectorGradient ); +// finiteElement::feOps::valueAndGradient( N, gradN, vector, feBaseVectorValue, feBaseVectorGradient ); // // // for( int i=0; i<3; ++i ) @@ -458,7 +343,7 @@ static void plusGradNajAij( real64 const (&gradN)[NUM_SUPPORT_POINTS][3], template< int NUM_SUPPORT_POINTS > -GEOS_HOST_DEVICE +// GEOS_HOST_DEVICE GEOS_FORCE_INLINE void plusGradNajAij( real64 const (&gradN)[NUM_SUPPORT_POINTS][3], real64 const (&var_detJxW)[3][3], @@ -495,10 +380,10 @@ TEST( FiniteElementBase, test_plusGradNajAij ) randomVar( r2SymmTensor ); plusGradNajAij( gradN, r2Tensor, baselineResult ); - FiniteElementBase::plusGradNajAij( gradN, r2Tensor, feResult ); + finiteElement::feOps::plusGradNajAij( gradN, r2Tensor, feResult ); plusGradNajAij( gradN, r2SymmTensor, baselineResultSym ); - FiniteElementBase::plusGradNajAij( gradN, r2SymmTensor, feResultSym ); + finiteElement::feOps::plusGradNajAij( gradN, r2SymmTensor, feResultSym ); } for( int a=0; a +#include "../elementFormulations/H1_Pyramid_Lagrange1_Gauss5.hpp" #include "common/GEOS_RAJA_Interface.hpp" #include "gtest/gtest.h" @@ -62,7 +62,7 @@ void testKernelDriver() for( localIndex q=0; q VDM_inv; VDM_inv.resize( numNodes, numNodes ); - VDM_inv = Pk_Pyramid_BCD< 1 >::computeVanderMondeMatrixInverse( ); + VDM_inv = Pk_Pyramid_BCD_impl< 1 >::computeVanderMondeMatrixInverse( ); arrayView2d< real64 const > const & VDM_inv_view = VDM_inv; @@ -53,7 +53,7 @@ void testKernelDriver() for( localIndex q=0; q::calcN( q, VDM_inv_view, N ); + Pk_Pyramid_BCD_impl< 1 >::calcN( q, VDM_inv_view, N ); for( localIndex a=0; a MtestArray( numNodes, numNodes ); arrayView2d< real64 > const & Mtest = MtestArray; - Pk_Pyramid_BCD< 1 >::computeMassTerm( VDM_inv_view, [=] GEOS_HOST_DEVICE ( const localIndex i, const localIndex j, const real64 Mij ) + Pk_Pyramid_BCD_impl< 1 >::computeMassTerm( VDM_inv_view, [=] GEOS_HOST_DEVICE ( const localIndex i, const localIndex j, const real64 Mij ) { Mtest[i][j] = Mij; } ); @@ -172,7 +172,7 @@ void testKernelDriver() real64 gradNtest[numNodes][3]; for( localIndex i = 0; i < numNodes; ++i ) { - Pk_Pyramid_BCD< 1 >::calcGradN( coords[i], VDM_inv_view, gradNtest ); + Pk_Pyramid_BCD_impl< 1 >::calcGradN( coords[i], VDM_inv_view, gradNtest ); EXPECT_FLOAT_EQ( gradNtest[0][0], gradPhi1test[i][0] ); EXPECT_FLOAT_EQ( gradNtest[1][0], gradPhi2test[i][0] ); EXPECT_FLOAT_EQ( gradNtest[2][0], gradPhi3test[i][0] ); @@ -195,7 +195,7 @@ void testKernelDriver() //Test on stiffness matrix array2d< real64 > RtestArray( numNodes, numNodes ); arrayView2d< real64 > const & Rtest = RtestArray; - Pk_Pyramid_BCD< 1 >::computeStiffnessTerm( VDM_inv_view, [=] GEOS_HOST_DEVICE ( const localIndex i, const localIndex j, const real64 Rij ) + Pk_Pyramid_BCD_impl< 1 >::computeStiffnessTerm( VDM_inv_view, [=] GEOS_HOST_DEVICE ( const localIndex i, const localIndex j, const real64 Rij ) { Rtest[i][j] = Rij; // Initialize the mass term } ); diff --git a/src/coreComponents/finiteElement/unitTests/testQ3_Hexahedron_Lagrange_GaussLobatto.cpp b/src/coreComponents/finiteElement/unitTests/testQ3_Hexahedron_Lagrange_GaussLobatto.cpp index b204cc9baa9..a3e8f48cd9a 100644 --- a/src/coreComponents/finiteElement/unitTests/testQ3_Hexahedron_Lagrange_GaussLobatto.cpp +++ b/src/coreComponents/finiteElement/unitTests/testQ3_Hexahedron_Lagrange_GaussLobatto.cpp @@ -53,7 +53,7 @@ void testKernelDriver() for( localIndex q=0; q, localIndex > ProblemManager:: ElementRegionManager & elemManager = meshLevel.getElemManager(); FaceManager const & faceManager = meshLevel.getFaceManager(); EdgeManager const & edgeManager = meshLevel.getEdgeManager(); - arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X = nodeManager.referencePosition(); for( auto const & regionName : regionNames ) { @@ -986,18 +985,14 @@ map< std::tuple< string, string, string, string >, localIndex > ProblemManager:: using SUBREGION_TYPE = TYPEOFREF( subRegion ); typename FE_TYPE::template MeshData< SUBREGION_TYPE > meshData; - finiteElement::FiniteElementBase::initialize< FE_TYPE, SUBREGION_TYPE >( nodeManager, - edgeManager, - faceManager, - subRegion, - meshData ); + FE_TYPE::template initialize< FE_TYPE, SUBREGION_TYPE >( nodeManager, + edgeManager, + faceManager, + subRegion, + meshData ); localIndex const numQuadraturePoints = FE_TYPE::numQuadraturePoints; -//#if ! defined( CALC_FEM_SHAPE_IN_KERNEL ) - feDiscretization->calculateShapeFunctionGradients< SUBREGION_TYPE, FE_TYPE >( X, &subRegion, meshData, finiteElement ); -//#endif - localIndex & numQuadraturePointsInList = regionQuadrature[ std::make_tuple( meshBodyName, meshLevel.getName(), regionName, diff --git a/src/coreComponents/mesh/CellElementSubRegion.cpp b/src/coreComponents/mesh/CellElementSubRegion.cpp index 95b2ac8b269..380233345dd 100644 --- a/src/coreComponents/mesh/CellElementSubRegion.cpp +++ b/src/coreComponents/mesh/CellElementSubRegion.cpp @@ -31,10 +31,6 @@ CellElementSubRegion::CellElementSubRegion( string const & name, Group * const p registerWrapper( viewKeyStruct::edgeListString(), &m_toEdgesRelation ); registerWrapper( viewKeyStruct::faceListString(), &m_toFacesRelation ); - registerWrapper( viewKeyStruct::dNdXString(), &m_dNdX ).setSizedFromParent( 1 ).reference().resizeDimension< 3 >( 3 ); - - registerWrapper( viewKeyStruct::detJString(), &m_detJ ).setSizedFromParent( 1 ).reference(); - registerWrapper( viewKeyStruct::toEmbSurfString(), &m_toEmbeddedSurfaces ).setSizedFromParent( 1 ); registerWrapper( viewKeyStruct::fracturedCellsString(), &m_fracturedCells ).setSizedFromParent( 1 ); diff --git a/src/coreComponents/mesh/CellElementSubRegion.hpp b/src/coreComponents/mesh/CellElementSubRegion.hpp index 64a6931cfa2..06be9938fce 100644 --- a/src/coreComponents/mesh/CellElementSubRegion.hpp +++ b/src/coreComponents/mesh/CellElementSubRegion.hpp @@ -156,10 +156,7 @@ class CellElementSubRegion : public ElementSubRegionBase */ struct viewKeyStruct : public ElementSubRegionBase::viewKeyStruct { - /// @return String key for the derivatives of the shape functions with respect to the reference configuration - static constexpr char const * dNdXString() { return "dNdX"; } - /// @return String key for the derivative of the jacobian. - static constexpr char const * detJString() { return "detJ"; } /// @return String key to embSurfMap + /// @return String key to embSurfMap static constexpr char const * toEmbSurfString() { return "ToEmbeddedSurfaces"; } /// @return String key to fracturedCells static constexpr char const * fracturedCellsString() { return "fracturedCells"; } @@ -240,30 +237,6 @@ class CellElementSubRegion : public ElementSubRegionBase */ localIndex faceList( localIndex k, localIndex a ) const { return m_toFacesRelation( k, a ); } - /** - * @brief @return The array of shape function derivatives. - */ - array4d< real64 > & dNdX() - { return m_dNdX; } - - /** - * @brief @return The array of shape function derivatives. - */ - arrayView4d< real64 const > dNdX() const - { return m_dNdX; } - - /** - * @brief @return The array of jacobian determinantes. - */ - array2d< real64 > & detJ() - { return m_detJ; } - - /** - * @brief @return The array of jacobian determinantes. - */ - arrayView2d< real64 const > detJ() const - { return m_detJ; } - /** * @brief @return The sorted array of local fractured elements. */ @@ -349,12 +322,6 @@ class CellElementSubRegion : public ElementSubRegionBase void calculateElementCenterAndVolume( localIndex const k, arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X ) const; - /// The array of shape function derivaties. - array4d< real64 > m_dNdX; - - /// The array of jacobian determinantes. - array2d< real64 > m_detJ; - /// Map of unmapped global indices in the element-to-node map map< localIndex, array1d< globalIndex > > m_unmappedGlobalIndicesInNodelist; diff --git a/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp b/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp index 5beecb1842c..fbcd9258750 100644 --- a/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp +++ b/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp @@ -215,7 +215,7 @@ void SpatialPartition::setSizes( real64 const ( &min )[ 3 ], //check to make sure our dimensions agree { - string_view partitionsLogMessage = + GEOS_MAYBE_UNUSED string_view partitionsLogMessage = "The total number of processes = {} does not correspond to the total number of partitions = {}.\n" "The number of cells in an axis cannot be lower that the partition count of this axis\n"; diff --git a/src/coreComponents/mesh/utilities/AverageOverQuadraturePointsKernel.hpp b/src/coreComponents/mesh/utilities/AverageOverQuadraturePointsKernel.hpp index 254bc81fcce..867ab86bc3f 100644 --- a/src/coreComponents/mesh/utilities/AverageOverQuadraturePointsKernel.hpp +++ b/src/coreComponents/mesh/utilities/AverageOverQuadraturePointsKernel.hpp @@ -57,12 +57,12 @@ class AverageOverQuadraturePointsBase m_X( nodeManager.referencePosition() ), m_elementVolume( elementSubRegion.getElementVolume() ) { - finiteElement::FiniteElementBase:: - initialize< FE_TYPE >( nodeManager, - edgeManager, - faceManager, - elementSubRegion, - m_meshData ); + FE_TYPE:: template + initialize< FE_TYPE >( nodeManager, + edgeManager, + faceManager, + elementSubRegion, + m_meshData ); } //***************************************************************************** diff --git a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp index 359f428a3c3..75de5e22b49 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp @@ -144,7 +144,7 @@ struct DamageAndDamageGradientInterpolationKernel real64 qDamage = 0.0; real64 qDamageGrad[3] = {0, 0, 0}; - FE_TYPE::valueAndGradient( N, dNdX, nodalDamageLocal, qDamage, qDamageGrad ); + finiteElement::feOps::valueAndGradient( N, dNdX, nodalDamageLocal, qDamage, qDamageGrad ); damageFieldOnMaterial( k, q ) = qDamage; diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/MultiphasePoromechanics_impl.hpp b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/MultiphasePoromechanics_impl.hpp index 1cba31bbe0f..6a00810b11c 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/MultiphasePoromechanics_impl.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/MultiphasePoromechanics_impl.hpp @@ -23,6 +23,7 @@ #include "constitutive/fluid/multifluid/MultiFluidBase.hpp" #include "finiteElement/BilinearFormUtilities.hpp" #include "finiteElement/LinearFormUtilities.hpp" +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" #include "physicsSolvers/multiphysics/poromechanicsKernels/MultiphasePoromechanics.hpp" @@ -617,12 +618,12 @@ quadraturePointKernel( localIndex const k, real64 N[numNodesPerElem]{}; real64 dNdX[numNodesPerElem][3]{}; FE_TYPE::calcN( q, stack.feStack, N ); - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, - stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, + stack.feStack, dNdX ); // Step 2: compute strain increment LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 ); - FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); // Step 3: compute 1) the total stress, 2) the body force terms, and 3) the fluidMassIncrement // using quantities returned by the PorousSolid constitutive model. @@ -656,7 +657,7 @@ complete( localIndex const k, real64 maxForce = 0; localIndex const numSupportPoints = - m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + m_finiteElementSpace.getNumSupportPoints( stack.feStack ); integer numDisplacementDofs = numSupportPoints * numDofPerTestSupportPoint; constexpr integer maxNumDisplacementDofs = FE_TYPE::maxSupportPoints * numDofPerTestSupportPoint; diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsBase.hpp b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsBase.hpp index 2ddcd79ea32..29e23ced577 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsBase.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsBase.hpp @@ -150,13 +150,8 @@ class PoromechanicsBase : localPressureDofIndex{ 0 } {} -#if !defined(CALC_FEM_SHAPE_IN_KERNEL) - /// Dummy - int xLocal; -#else /// C-array stack storage for element local the nodal positions. real64 xLocal[numNodesPerElem][3]; -#endif // Storage for displacements @@ -227,7 +222,7 @@ class PoromechanicsBase : m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack ); localIndex const numSupportPoints = - m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + m_finiteElementSpace.getNumSupportPoints( stack.feStack ); for( localIndex a=0; a; \ -template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >::kernelLaunch< NAME##Policy, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > > \ +template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >; \ +template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >::kernelLaunch< NAME##Policy, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > > \ ( localIndex const, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > const & ); \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > const & ); \ namespace geos diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsEFEMKernels.cpp.template b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsEFEMKernels.cpp.template index dac09e6f19e..762ec297a74 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsEFEMKernels.cpp.template +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsEFEMKernels.cpp.template @@ -19,11 +19,11 @@ using SinglePhasePoromechanicsEFEMPolicy = @SinglePhasePoromechanicsEFEMPolicy@; #define INSTANTIATION( NAME )\ -template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >; \ -template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >::kernelLaunch< NAME##Policy, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > > \ +template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >; \ +template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >::kernelLaunch< NAME##Policy, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > > \ ( localIndex const, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > const & ); \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > const & ); \ namespace geos diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsKernels.cpp.template b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsKernels.cpp.template index acbc3d67733..f21f470601b 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsKernels.cpp.template +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/PoromechanicsKernels.cpp.template @@ -21,11 +21,11 @@ using SinglePhasePoromechanicsPolicy = @SinglePhasePoromechanicsPolicy@; using MultiphasePoromechanicsPolicy = @MultiphasePoromechanicsPolicy@; #define INSTANTIATION( NAME )\ -template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >; \ -template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >::kernelLaunch< NAME##Policy, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > > \ +template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >; \ +template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >::kernelLaunch< NAME##Policy, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > > \ ( localIndex const, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > const & ); \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > const & ); \ namespace geos diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsDamage_impl.hpp b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsDamage_impl.hpp index 67250f7b36d..b155566b2aa 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsDamage_impl.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsDamage_impl.hpp @@ -260,12 +260,12 @@ quadraturePointKernel( localIndex const k, real64 N[numNodesPerElem]{}; real64 dNdX[numNodesPerElem][3]{}; FE_TYPE::calcN( q, stack.feStack, N ); - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, - stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, + stack.feStack, dNdX ); // Step 2: compute strain increment LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 ); - FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); // Step 3: compute 1) the total stress, 2) the body force terms, and 3) the fluidMassIncrement // using quantities returned by the PorousSolid constitutive model. diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsEFEM_impl.hpp b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsEFEM_impl.hpp index 06887b4ce6d..9a2981a2636 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsEFEM_impl.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsEFEM_impl.hpp @@ -199,7 +199,7 @@ quadraturePointKernel( localIndex const k, // derivatives (dNdX), and (iii) determinant of the Jacobian transformation // matrix times the quadrature weight (detJxW) real64 dNdX[numNodesPerElem][3]; - real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, dNdX ); + real64 const detJ = FE_TYPE::calcGradN( q, stack.xLocal, dNdX ); // EFEM part starts here constexpr int nUdof = numNodesPerElem*3; diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanics_impl.hpp b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanics_impl.hpp index 6fbd016afe5..035e510aa3b 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanics_impl.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanics_impl.hpp @@ -22,6 +22,7 @@ #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" #include "finiteElement/BilinearFormUtilities.hpp" +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" #include "finiteElement/LinearFormUtilities.hpp" #include "physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanics.hpp" @@ -365,12 +366,12 @@ quadraturePointKernel( localIndex const k, real64 N[numNodesPerElem]{}; real64 dNdX[numNodesPerElem][3]{}; FE_TYPE::calcN( q, stack.feStack, N ); - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, - stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, + stack.feStack, dNdX ); // Step 2: compute strain increment LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 ); - FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); // Step 3: compute 1) the total stress, 2) the body force terms, and 3) the fluidMassIncrement // using quantities returned by the PorousSolid constitutive model. @@ -398,7 +399,7 @@ complete( localIndex const k, GEOS_UNUSED_VAR( k ); real64 maxForce = 0; localIndex const numSupportPoints = - m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + m_finiteElementSpace.getNumSupportPoints( stack.feStack ); integer numDisplacementDofs = numSupportPoints * numDofPerTestSupportPoint; for( int localNode = 0; localNode < numSupportPoints; ++localNode ) diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalMultiphasePoromechanics_impl.hpp b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalMultiphasePoromechanics_impl.hpp index c9b830ddb5a..26872bff2c8 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalMultiphasePoromechanics_impl.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalMultiphasePoromechanics_impl.hpp @@ -495,12 +495,12 @@ quadraturePointKernel( localIndex const k, real64 N[numNodesPerElem]{}; real64 dNdX[numNodesPerElem][3]{}; FE_TYPE::calcN( q, stack.feStack, N ); - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, - stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, + stack.feStack, dNdX ); // Step 2: compute strain increment LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 ); - FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); // Step 3: compute 1) the total stress, 2) the body force terms, and 3) the fluidMassIncrement // using quantities returned by the PorousSolid constitutive model. @@ -530,7 +530,7 @@ complete( localIndex const k, real64 const maxForce = Base::complete( k, stack ); localIndex const numSupportPoints = - m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + m_finiteElementSpace.getNumSupportPoints( stack.feStack ); integer numDisplacementDofs = numSupportPoints * numDofPerTestSupportPoint; if( m_useTotalMassEquation > 0 ) diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalSinglePhasePoromechanics_impl.hpp b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalSinglePhasePoromechanics_impl.hpp index c8ba6eb78a9..d4bd828fc12 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalSinglePhasePoromechanics_impl.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermalSinglePhasePoromechanics_impl.hpp @@ -364,12 +364,12 @@ quadraturePointKernel( localIndex const k, real64 N[numNodesPerElem]{}; real64 dNdX[numNodesPerElem][3]{}; FE_TYPE::calcN( q, stack.feStack, N ); - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, - stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, + stack.feStack, dNdX ); // Step 2: compute strain increment LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 ); - FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement ); // Step 3: compute 1) the total stress, 2) the body force terms, and 3) the fluidMassIncrement // using quantities returned by the PorousSolid constitutive model. @@ -397,7 +397,7 @@ complete( localIndex const k, real64 const maxForce = Base::complete( k, stack ); localIndex const numSupportPoints = - m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + m_finiteElementSpace.getNumSupportPoints( stack.feStack ); integer numDisplacementDofs = numSupportPoints * numDofPerTestSupportPoint; // Step 1: assemble the derivatives of linear momentum balance wrt temperature into the global matrix diff --git a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermoPoromechanicsKernels.cpp.template b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermoPoromechanicsKernels.cpp.template index cc9d40018d3..4a3c87b955c 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermoPoromechanicsKernels.cpp.template +++ b/src/coreComponents/physicsSolvers/multiphysics/poromechanicsKernels/ThermoPoromechanicsKernels.cpp.template @@ -25,11 +25,11 @@ using ThermalSinglePhasePoromechanicsPolicy = @ThermalSinglePhasePoromechanicsPo using ThermalSinglePhasePoromechanicsEFEMPolicy = @ThermalSinglePhasePoromechanicsEFEMPolicy@; #define INSTANTIATION( NAME )\ -template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >; \ -template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >::kernelLaunch< NAME##Policy, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > > \ +template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >; \ +template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >::kernelLaunch< NAME##Policy, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > > \ ( localIndex const, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > const & ); \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > const & ); \ namespace geos { diff --git a/src/coreComponents/physicsSolvers/simplePDE/LaplaceFEMKernels.hpp b/src/coreComponents/physicsSolvers/simplePDE/LaplaceFEMKernels.hpp index 6d992ba0134..3f8db629455 100644 --- a/src/coreComponents/physicsSolvers/simplePDE/LaplaceFEMKernels.hpp +++ b/src/coreComponents/physicsSolvers/simplePDE/LaplaceFEMKernels.hpp @@ -138,13 +138,8 @@ class LaplaceFEMKernel : primaryField_local{ 0.0 } {} -#if !defined(CALC_FEM_SHAPE_IN_KERNEL) - /// Dummy - int xLocal; -#else /// C-array stack storage for element local the nodal positions. real64 xLocal[ maxNumTestSupportPointsPerElem ][ 3 ]; -#endif /// C-array storage for the element local primary field variable. real64 primaryField_local[ maxNumTestSupportPointsPerElem ]; @@ -165,18 +160,16 @@ class LaplaceFEMKernel : StackVariables & stack ) const { m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack ); - stack.numRows = m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + stack.numRows = m_finiteElementSpace.getNumSupportPoints( stack.feStack ); stack.numCols = stack.numRows; for( localIndex a = 0; a < stack.numRows; ++a ) { localIndex const localNodeIndex = m_elemsToNodes( k, a ); -#if defined(CALC_FEM_SHAPE_IN_KERNEL) for( int i=0; i<3; ++i ) { stack.xLocal[ a ][ i ] = m_X[ localNodeIndex ][ i ]; } -#endif stack.primaryField_local[ a ] = m_primaryField[ localNodeIndex ]; stack.localRowDofIndex[a] = m_dofNumber[localNodeIndex]; @@ -196,9 +189,9 @@ class LaplaceFEMKernel : localIndex const q, StackVariables & stack ) const { + GEOS_UNUSED_VAR( k ); real64 dNdX[ maxNumTestSupportPointsPerElem ][ 3 ]; - real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, - stack.feStack, dNdX ); + real64 const detJ = FE_TYPE::calcGradN( q, stack.xLocal, stack.feStack, dNdX ); for( localIndex a = 0; a < stack.numRows; ++a ) { for( localIndex b = 0; b < stack.numCols; ++b ) diff --git a/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldDamageFEMKernels.hpp b/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldDamageFEMKernels.hpp index 32768c1074d..8bca1266398 100644 --- a/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldDamageFEMKernels.hpp +++ b/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldDamageFEMKernels.hpp @@ -21,6 +21,7 @@ #define GEOS_PHYSICSSOLVERS_SIMPLEPDE_PHASEFIELDDAMAGEKERNELS_HPP_ #include "finiteElement/kernelInterface/ImplicitKernelBase.hpp" +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" namespace geos { @@ -152,13 +153,8 @@ class PhaseFieldDamageKernel : nodalDamageLocal{ 0.0 } {} -#if !defined(CALC_FEM_SHAPE_IN_KERNEL) - /// Dummy - int xLocal; -#else /// C-array stack storage for element local the nodal positions. real64 xLocal[ numNodesPerElem ][ 3 ]; -#endif /// C-array storage for the element local primary field variable. real64 nodalDamageLocal[numNodesPerElem]; @@ -182,9 +178,7 @@ class PhaseFieldDamageKernel : { localIndex const localNodeIndex = m_elemsToNodes( k, a ); -#if defined(CALC_FEM_SHAPE_IN_KERNEL) LvArray::tensorOps::copy< 3 >( stack.xLocal[ a ], m_X[ localNodeIndex ] ); -#endif stack.nodalDamageLocal[ a ] = m_nodalDamage[ localNodeIndex ]; stack.localRowDofIndex[a] = m_dofNumber[localNodeIndex]; @@ -210,12 +204,12 @@ class PhaseFieldDamageKernel : //Interpolate d and grad_d real64 N[ numNodesPerElem ]; real64 dNdX[ numNodesPerElem ][ 3 ]; - real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, dNdX ); + real64 const detJ = FE_TYPE::calcGradN( q, stack.xLocal, dNdX ); FE_TYPE::calcN( q, N ); real64 qp_damage = 0.0; real64 qp_grad_damage[3] = {0, 0, 0}; - FE_TYPE::valueAndGradient( N, dNdX, stack.nodalDamageLocal, qp_damage, qp_grad_damage ); + finiteElement::feOps::valueAndGradient( N, dNdX, stack.nodalDamageLocal, qp_damage, qp_grad_damage ); real64 D = 0; //max between threshold and // Elastic energy diff --git a/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldPressurizedDamageFEMKernels.hpp b/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldPressurizedDamageFEMKernels.hpp index 44747dd0546..0623667d56c 100644 --- a/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldPressurizedDamageFEMKernels.hpp +++ b/src/coreComponents/physicsSolvers/simplePDE/PhaseFieldPressurizedDamageFEMKernels.hpp @@ -172,14 +172,14 @@ class PhaseFieldPressurizedDamageKernel : //Interpolate d and grad_d real64 N[ numNodesPerElem ]; real64 dNdX[ numNodesPerElem ][ 3 ]; - real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, dNdX ); + real64 const detJ = FE_TYPE::calcGradN( q, stack.xLocal, dNdX ); FE_TYPE::calcN( q, N ); real64 qp_damage = 0.0; - FE_TYPE::value( N, stack.nodalDamageLocal, qp_damage ); + finiteElement::feOps::value( N, stack.nodalDamageLocal, qp_damage ); real64 qp_disp[3] = {0, 0, 0}; - FE_TYPE::value( N, stack.u_local, qp_disp ); + finiteElement::feOps::value( N, stack.u_local, qp_disp ); real64 elemPresGradient[3] = {0, 0, 0}; for( integer i=0; i<3; ++i ) diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp index 18e7714e97d..2f3726d7e4f 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp @@ -300,6 +300,64 @@ real64 SolidMechanicsLagrangianFEM::explicitKernelDispatch( MeshLevel & mesh, return rval; } +void SolidMechanicsLagrangianFEM::initializeMass( MeshLevel & mesh, CellElementSubRegion & subRegion ) +{ + NodeManager & nodes = mesh.getNodeManager(); + arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X = nodes.referencePosition(); + + arrayView1d< real64 > & mass = nodes.getField< solidMechanics::mass >(); + + SolidBase & solid = getConstitutiveModel< SolidBase >( subRegion ); + arrayView2d< real64 const > const rho = solid.getDensity(); + arrayView2d< localIndex const, cells::NODE_MAP_USD > const & elemsToNodes = subRegion.nodeList(); + + finiteElement::FiniteElementBase const & + fe = subRegion.getReference< finiteElement::FiniteElementBase >( getDiscretizationName() ); + finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( fe, [&] ( auto const element ) + { + using FE_TYPE = TYPEOFREF( element ); + + typename FE_TYPE::template MeshData< CellElementSubRegion > meshData; + FE_TYPE::template fillMeshData< CellElementSubRegion >( nodes, + mesh.getEdgeManager(), + mesh.getFaceManager(), + subRegion, + meshData ); + constexpr localIndex maxSupportPoints = FE_TYPE::maxSupportPoints; + constexpr localIndex numQuadraturePointsPerElem = FE_TYPE::numQuadraturePoints; + constexpr localIndex numNodesPerElem = FE_TYPE::numNodes; + + forAll< serialPolicy >( subRegion.size(), [&] ( localIndex const ei ) + { + real64 N[ maxSupportPoints ]; + real64 xLocal[ numNodesPerElem ][3]; + real64 J[3][3]; + real64 detJxW = 0.0; + typename FE_TYPE::StackVariables feStack; + element.template setup< FE_TYPE >( ei, meshData, feStack ); + localIndex const numSupportPoints = element.getNumSupportPoints( feStack ); + + for( localIndex a = 0; a < numSupportPoints; ++a ) + { + localIndex const nodeIndex = elemsToNodes[ ei ][ a ]; + for( int i = 0; i < 3; ++i ) + { + xLocal[ a ][ i ] = X[ nodeIndex ][ i ]; + } + } + + for( localIndex q = 0; q < numQuadraturePointsPerElem; ++q ) + { + FE_TYPE::calcN( q, feStack, N ); + detJxW = FE_TYPE::calcJacobian( q, xLocal, feStack, J ); + for( localIndex a = 0; a < numSupportPoints; ++a ) + { + mass[ elemsToNodes[ ei ][ a ] ] += rho[ ei ][ q ] * detJxW * N[ a ]; + } + } + } ); + } ); +} void SolidMechanicsLagrangianFEM::initializePostInitialConditionsPreSubGroups() { @@ -339,8 +397,9 @@ void SolidMechanicsLagrangianFEM::initializePostInitialConditionsPreSubGroups() { elemRegion.forElementSubRegionsIndex< CellElementSubRegion >( [&]( localIndex const esr, CellElementSubRegion & elementSubRegion ) { - SolidBase & solid = getConstitutiveModel< SolidBase >( elementSubRegion ); - arrayView2d< real64 const > const rho = solid.getDensity(); + initializeMass( mesh, elementSubRegion ); + + arrayView2d< localIndex const, cells::NODE_MAP_USD > const & elemsToNodes = elementSubRegion.nodeList(); SortedArray< localIndex > & elemsAttachedToSendOrReceiveNodes = getElemsAttachedToSendOrReceiveNodes( elementSubRegion ); SortedArray< localIndex > & elemsNotAttachedToSendOrReceiveNodes = getElemsNotAttachedToSendOrReceiveNodes( elementSubRegion ); @@ -356,49 +415,30 @@ void SolidMechanicsLagrangianFEM::initializePostInitialConditionsPreSubGroups() "SolidMechanicsLagrangianFEM::m_elemsNotAttachedToSendOrReceiveNodes[" + std::to_string( er ) + "][" + std::to_string( esr ) + "]" ); - arrayView2d< real64 const > const & detJ = elementSubRegion.detJ(); - arrayView2d< localIndex const, cells::NODE_MAP_USD > const & elemsToNodes = elementSubRegion.nodeList(); finiteElement::FiniteElementBase const & fe = elementSubRegion.getReference< finiteElement::FiniteElementBase >( getDiscretizationName() ); - finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( fe, - [&] ( auto const finiteElement ) + finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( fe, [&] ( auto const element ) { - using FE_TYPE = TYPEOFREF( finiteElement ); + using FE_TYPE = TYPEOFREF( element ); using SUBREGION_TYPE = TYPEOFREF( elementSubRegion ); typename FE_TYPE::template MeshData< SUBREGION_TYPE > meshData; - finiteElement::FiniteElementBase::initialize< FE_TYPE, SUBREGION_TYPE >( nodes, - edgeManager, - faceManager, - elementSubRegion, - meshData ); + FE_TYPE::template initialize< FE_TYPE, SUBREGION_TYPE >( nodes, + edgeManager, + faceManager, + elementSubRegion, + meshData ); + constexpr localIndex numNodesPerElem = FE_TYPE::numNodes; - constexpr localIndex maxSupportPoints = FE_TYPE::maxSupportPoints; - constexpr localIndex numQuadraturePointsPerElem = FE_TYPE::numQuadraturePoints; - - real64 N[maxSupportPoints]; for( localIndex k=0; k < elemsToNodes.size( 0 ); ++k ) { - typename FE_TYPE::StackVariables feStack; - finiteElement.template setup< FE_TYPE >( k, meshData, feStack ); - localIndex const numSupportPoints = - finiteElement.template numSupportPoints< FE_TYPE >( feStack ); - -//#if ! defined( CALC_FEM_SHAPE_IN_KERNEL ) // we don't calculate detJ in this case - for( localIndex q=0; q( k, meshData, feStack ); bool isAttachedToGhostNode = false; - for( localIndex a=0; a= -1 ) { @@ -410,7 +450,6 @@ void SolidMechanicsLagrangianFEM::initializePostInitialConditionsPreSubGroups() tmpNonSendOrReceiveNodes.insert( elemsToNodes[k][a] ); } } - if( isAttachedToGhostNode ) { tmpElemsAttachedToSendOrReceiveNodes.insert( k ); @@ -433,11 +472,8 @@ void SolidMechanicsLagrangianFEM::initializePostInitialConditionsPreSubGroups() m_targetNodes = m_sendOrReceiveNodes; m_targetNodes.insert( m_nonSendOrReceiveNodes.begin(), m_nonSendOrReceiveNodes.end() ); - - } ); } ); - } ); } diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp index 8681e826d44..b3ec0b40083 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp @@ -289,6 +289,8 @@ class SolidMechanicsLagrangianFEM : public PhysicsSolverBase protected: virtual void postInputInitialization() override; + void initializeMass( MeshLevel & mesh, CellElementSubRegion & subRegion ); + virtual void initializePostInitialConditionsPreSubGroups() override; virtual void setConstitutiveNamesCallSuper( ElementSubRegionBase & subRegion ) const override; diff --git a/src/coreComponents/physicsSolvers/solidMechanics/contact/kernels/SolidMechanicsEFEMKernelsBase.hpp b/src/coreComponents/physicsSolvers/solidMechanics/contact/kernels/SolidMechanicsEFEMKernelsBase.hpp index eef5c878ab1..f05817185e7 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/contact/kernels/SolidMechanicsEFEMKernelsBase.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/contact/kernels/SolidMechanicsEFEMKernelsBase.hpp @@ -247,7 +247,7 @@ class EFEMKernelsBase : localIndex const embSurfIndex = m_cellsToEmbeddedSurfaces[k][0]; real64 dNdX[ numNodesPerElem ][ 3 ]; - real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.X, dNdX ); + real64 const detJ = FE_TYPE::calcGradN( q, stack.X, dNdX ); constexpr int nUdof = numNodesPerElem*3; diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitFiniteStrain_impl.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitFiniteStrain_impl.hpp index 8454837b438..eee43c6a04a 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitFiniteStrain_impl.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitFiniteStrain_impl.hpp @@ -67,9 +67,7 @@ void ExplicitFiniteStrain< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >::setup( localIndex const nodeIndex = m_elemsToNodes( k, a ); for( int i=0; i::quadrat StackVariables & stack ) const { real64 dNdX[ numNodesPerElem ][ 3 ]; - real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, dNdX ); + real64 const detJ = FE_TYPE::calcGradN( q, stack.xLocal, dNdX ); real64 dUhatdX[3][3] = { {0} }; real64 dUdX[3][3] = { {0} }; @@ -94,8 +92,8 @@ void ExplicitFiniteStrain< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >::quadrat real64 Ldt[3][3] = { {0} }; real64 fInv[3][3] = { {0} }; - FE_TYPE::gradient( dNdX, stack.varLocal, dUhatdX ); - FE_TYPE::gradient( dNdX, stack.uLocal, dUdX ); + finiteElement::feOps::gradient( dNdX, stack.varLocal, dUhatdX ); + finiteElement::feOps::gradient( dNdX, stack.uLocal, dUdX ); LvArray::tensorOps::scale< 3, 3 >( dUhatdX, m_dt ); @@ -127,7 +125,7 @@ void ExplicitFiniteStrain< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >::quadrat LvArray::tensorOps::Rij_eq_symAikBjk< 3 >( P, stress, fInv ); LvArray::tensorOps::scale< 3, 3 >( P, -detJ * detF ); - FE_TYPE::plusGradNajAij( dNdX, P, stack.fLocal ); + finiteElement::feOps::plusGradNajAij( dNdX, P, stack.fLocal ); } diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain.hpp index b4518ca4cbd..aa590299f28 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain.hpp @@ -131,13 +131,8 @@ class ExplicitSmallStrain : public finiteElement::KernelBase< SUBREGION_TYPE, /// C-array stack storage for element local primary variable values. real64 varLocal[ numNodesPerElem ][ numDofPerTestSupportPoint ]; -#if !defined(CALC_FEM_SHAPE_IN_KERNEL) - /// Dummy - int xLocal; -#else /// C-array stack storage for element local the nodal positions. real64 xLocal[ numNodesPerElem ][ 3 ]; -#endif }; //*************************************************************************** diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain_impl.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain_impl.hpp index 30910aac4b0..de1de659b3b 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain_impl.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitSmallStrain_impl.hpp @@ -23,6 +23,7 @@ //#include "ExplicitFiniteStrain.hpp" #include "ExplicitSmallStrain.hpp" +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" namespace geos { @@ -73,10 +74,7 @@ void ExplicitSmallStrain< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >::setup( l localIndex const nodeIndex = m_elemsToNodes( k, a ); for( int i=0; i::quadratu //#define USE_JACOBIAN #if !defined( USE_JACOBIAN ) real64 dNdX[ numNodesPerElem ][ 3 ]; - real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, dNdX ); + real64 const detJ = FE_TYPE::calcGradN( q, stack.xLocal, dNdX ); /// Macro to substitute in the shape function derivatives. real64 strain[6] = {0}; //real64 timeIncrement = 0.0; - FE_TYPE::symmetricGradient( dNdX, stack.varLocal, strain ); + finiteElement::feOps::symmetricGradient( dNdX, stack.varLocal, strain ); real64 stressLocal[ 6 ] = {0}; #if UPDATE_STRESS == 2 @@ -124,14 +122,14 @@ void ExplicitSmallStrain< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >::quadratu #endif } - FE_TYPE::plusGradNajAij( dNdX, stressLocal, stack.fLocal ); + finiteElement::feOps::plusGradNajAij( dNdX, stressLocal, stack.fLocal ); #else real64 invJ[3][3]; real64 const detJ = FE_TYPE::inverseJacobianTransformation( q, stack.xLocal, invJ ); real64 strain[6] = {0}; - FE_TYPE::symmetricGradient( q, invJ, stack.varLocal, strain ); + finiteElement::feOps::symmetricGradient( q, invJ, stack.varLocal, strain ); real64 stressLocal[ 6 ] = {0}; #if UPDATE_STRESS == 2 @@ -153,7 +151,7 @@ void ExplicitSmallStrain< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >::quadratu #endif } - FE_TYPE::plusGradNajAij( q, invJ, stressLocal, stack.fLocal ); + finiteElement::feOps::plusGradNajAij( q, invJ, stressLocal, stack.fLocal ); #endif } diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics.hpp index 4b67faf912a..a2a751c7ae2 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics.hpp @@ -117,13 +117,8 @@ class FixedStressThermoPoromechanics : constitutiveStiffness() {} -#if !defined(CALC_FEM_SHAPE_IN_KERNEL) - /// Dummy - int xLocal; -#else /// C-array stack storage for element local the nodal positions. real64 xLocal[ numNodesPerElem ][ 3 ]; -#endif /// Stack storage for the element local nodal displacement real64 u_local[numNodesPerElem][numDofPerTrialSupportPoint]; diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics_impl.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics_impl.hpp index 8d4983a6dfb..9adb8ead2c4 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics_impl.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/FixedStressThermoPoromechanics_impl.hpp @@ -21,6 +21,7 @@ #define GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_FIXEDSTRESSTHERMOPOROMECHANICS_IMPL_HPP_ #include "FixedStressThermoPoromechanics.hpp" +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" #include "physicsSolvers/multiphysics/PoromechanicsFields.hpp" #include "physicsSolvers/solidMechanics/SolidMechanicsFields.hpp" @@ -84,7 +85,7 @@ setup( localIndex const k, { m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack ); localIndex const numSupportPoints = - m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + m_finiteElementSpace.getNumSupportPoints( stack.feStack ); stack.numRows = 3 * numSupportPoints; stack.numCols = stack.numRows; @@ -94,9 +95,7 @@ setup( localIndex const k, for( int i = 0; i < 3; ++i ) { -#if defined(CALC_FEM_SHAPE_IN_KERNEL) stack.xLocal[ a ][ i ] = m_X[ localNodeIndex ][ i ]; -#endif stack.u_local[ a ][i] = m_disp[ localNodeIndex ][i]; stack.uhat_local[ a ][i] = m_uhat[ localNodeIndex ][i]; stack.localRowDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i; @@ -124,15 +123,15 @@ quadraturePointKernel( localIndex const k, StackVariables & stack ) const { real64 dNdX[ numNodesPerElem ][ 3 ]; - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, - stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, + stack.feStack, dNdX ); real64 strainInc[6] = {0}; real64 totalStress[6] = {0}; typename CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness; - FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, strainInc ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, strainInc ); // Evaluate total stress and its derivatives // TODO: allow for a customization of the kernel to pass the average pressure to the small strain update (to account for cap pressure @@ -161,11 +160,11 @@ quadraturePointKernel( localIndex const k, real64 N[numNodesPerElem]; FE_TYPE::calcN( q, stack.feStack, N ); - FE_TYPE::plusGradNajAijPlusNaFi( dNdX, - totalStress, - N, - gravityForce, - reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual) ); + finiteElement::feOps::plusGradNajAijPlusNaFi( dNdX, + totalStress, + N, + gravityForce, + reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual) ); real64 const stabilizationScaling = computeStabilizationScaling( k ); m_finiteElementSpace.template addEvaluatedGradGradStabilizationVector< FE_TYPE, @@ -191,7 +190,7 @@ complete( localIndex const k, // TODO: Does this work if BTDB is non-symmetric? CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps::template fillLowerBTDB< numNodesPerElem >( stack.localJacobian ); localIndex const numSupportPoints = - m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + m_finiteElementSpace.getNumSupportPoints( stack.feStack ); for( int localNode = 0; localNode < numSupportPoints; ++localNode ) { for( int dim = 0; dim < numDofPerTestSupportPoint; ++dim ) diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic.hpp index 0e9bcf87b18..b5f1d5a05d6 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic.hpp @@ -128,13 +128,8 @@ class ImplicitSmallStrainQuasiStatic : constitutiveStiffness() {} -#if !defined(CALC_FEM_SHAPE_IN_KERNEL) - /// Dummy - int xLocal; -#else /// C-array stack storage for element local the nodal positions. real64 xLocal[ numNodesPerElem ][ 3 ]; -#endif /// Stack storage for the element local nodal displacement real64 u_local[numNodesPerElem][numDofPerTrialSupportPoint]; diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic_impl.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic_impl.hpp index 12753ab393f..1acbcf75f78 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic_impl.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ImplicitSmallStrainQuasiStatic_impl.hpp @@ -77,7 +77,7 @@ setup( localIndex const k, { m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack ); - localIndex const numSupportPoints = m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + localIndex const numSupportPoints = m_finiteElementSpace.getNumSupportPoints( stack.feStack ); stack.numRows = 3 * numSupportPoints; stack.numCols = stack.numRows; @@ -90,9 +90,7 @@ setup( localIndex const k, // #pragma unroll for( int i = 0; i < numDofPerTestSupportPoint; ++i ) { -#if defined(CALC_FEM_SHAPE_IN_KERNEL) stack.xLocal[ a ][ i ] = m_X[ localNodeIndex ][ i ]; -#endif stack.u_local[ a ][i] = m_disp[ localNodeIndex ][i]; stack.uhat_local[ a ][i] = m_uhat[ localNodeIndex ][i]; stack.localRowDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i; @@ -120,14 +118,14 @@ void ImplicitSmallStrainQuasiStatic< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE STRESS_MODIFIER && stressModifier ) const { real64 dNdX[ numNodesPerElem ][ 3 ]; - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, stack.feStack, dNdX ); real64 strainInc[6] = {0}; real64 stress[6] = {0}; typename CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness; - FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, strainInc ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, strainInc ); m_constitutiveUpdate.smallStrainUpdate( k, q, m_dt, strainInc, stress, stiffness ); @@ -144,11 +142,11 @@ void ImplicitSmallStrainQuasiStatic< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE real64 N[numNodesPerElem]; FE_TYPE::calcN( q, stack.feStack, N ); - FE_TYPE::plusGradNajAijPlusNaFi( dNdX, - stress, - N, - gravityForce, - reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual) ); + finiteElement::feOps::plusGradNajAijPlusNaFi( dNdX, + stress, + N, + gravityForce, + reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual) ); real64 const stabilizationScaling = computeStabilizationScaling( k ); m_finiteElementSpace.template addEvaluatedGradGradStabilizationVector< FE_TYPE, numDofPerTrialSupportPoint >( stack.feStack, stack.uhat_local, @@ -177,7 +175,7 @@ real64 ImplicitSmallStrainQuasiStatic< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYP // TODO: Does this work if BTDB is non-symmetric? CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps::template fillLowerBTDB< numNodesPerElem >( stack.localJacobian ); #endif - localIndex const numSupportPoints = m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + localIndex const numSupportPoints = m_finiteElementSpace.getNumSupportPoints( stack.feStack ); // #pragma unroll for( int localNode = 0; localNode < numSupportPoints; ++localNode ) diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsFixedStressThermoPoromechanicsKernels.cpp.template b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsFixedStressThermoPoromechanicsKernels.cpp.template index 7219cabb372..ca0d672c006 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsFixedStressThermoPoromechanicsKernels.cpp.template +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsFixedStressThermoPoromechanicsKernels.cpp.template @@ -18,11 +18,11 @@ using FixedStressThermoPoromechanicsPolicy = @FixedStressThermoPoromechanicsPolicy@; #define INSTANTIATION( NAME )\ -template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >; \ -template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >::kernelLaunch< NAME##Policy, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > > \ +template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >; \ +template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >::kernelLaunch< NAME##Policy, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > > \ ( localIndex const, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > const & ); \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > const & ); \ namespace geos diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsKernels.cpp.template b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsKernels.cpp.template index 17f65b6db6a..37de9d379a6 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsKernels.cpp.template +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsKernels.cpp.template @@ -24,11 +24,11 @@ using ImplicitSmallStrainNewmarkPolicy = @ImplicitSmallStrainNewmarkPolicy@; using ImplicitSmallStrainQuasiStaticPolicy = @ImplicitSmallStrainQuasiStaticPolicy@; #define INSTANTIATION( NAME )\ -template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >; \ -template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >::kernelLaunch< NAME##Policy, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > > \ +template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >; \ +template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl >::kernelLaunch< NAME##Policy, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > > \ ( localIndex const, \ - NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > const & ); \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@_impl > const & ); \ namespace geos diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsLagrangianFEMKernels.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsLagrangianFEMKernels.hpp index 2ccdfd7a87d..3074123d427 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsLagrangianFEMKernels.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsLagrangianFEMKernels.hpp @@ -77,46 +77,6 @@ inline void displacementUpdate( arrayView2d< real64 const, nodes::VELOCITY_USD > } ); } - -/** - * @struct Structure to wrap templated function that implements the explicit time integration kernel. - */ -struct ExplicitKernel -{ - - static inline real64 - calculateSingleNodalForce( localIndex const k, - localIndex const targetNode, - localIndex const numQuadraturePoints, - arrayView4d< real64 const > const & dNdX, - arrayView2d< real64 const > const & detJ, - arrayView3d< real64 const, solid::STRESS_USD > const & stress, - real64 ( & force )[ 3 ] ) - { - GEOS_MARK_FUNCTION; - localIndex const & a = targetNode; - - //Compute Quadrature - for( localIndex q = 0; q < numQuadraturePoints; ++q ) - { - force[ 0 ] -= ( stress( k, q, 0 ) * dNdX( k, q, a, 0 ) + - stress( k, q, 5 ) * dNdX( k, q, a, 1 ) + - stress( k, q, 4 ) * dNdX( k, q, a, 2 ) ) * detJ( k, q ); - force[ 1 ] -= ( stress( k, q, 5 ) * dNdX( k, q, a, 0 ) + - stress( k, q, 1 ) * dNdX( k, q, a, 1 ) + - stress( k, q, 3 ) * dNdX( k, q, a, 2 ) ) * detJ( k, q ); - force[ 2 ] -= ( stress( k, q, 4 ) * dNdX( k, q, a, 0 ) + - stress( k, q, 3 ) * dNdX( k, q, a, 1 ) + - stress( k, q, 2 ) * dNdX( k, q, a, 2 ) ) * detJ( k, q ); - - }//quadrature loop - - return 0; - } - -}; - - } // namespace solidMechanicsLagrangianFEMKernels } // namespace geos diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/StressStrainAverageKernels.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/StressStrainAverageKernels.hpp index 1381b6627f0..9765e7a262d 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/StressStrainAverageKernels.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/StressStrainAverageKernels.hpp @@ -23,6 +23,7 @@ #include "common/DataTypes.hpp" #include "common/GEOS_RAJA_Interface.hpp" #include "finiteElement/FiniteElementDispatch.hpp" +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" #include "constitutive/ConstitutivePassThru.hpp" #include "mesh/CellElementSubRegion.hpp" #include "mesh/utilities/AverageOverQuadraturePointsKernel.hpp" @@ -141,11 +142,11 @@ class AverageStressStrainOverQuadraturePoints : //real64 const weight = FE_TYPE::transformedQuadratureWeight( q, stack.xLocal, stack.feStack ) / m_elementVolume[k]; real64 dNdX[ FE_TYPE::maxSupportPoints ][3]; - real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, stack.feStack, dNdX ); + real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal, stack.feStack, dNdX ); real64 strain[6] = {0.0}; real64 strainInc[6] = {0.0}; - FE_TYPE::symmetricGradient( dNdX, stack.uLocal, strain ); - FE_TYPE::symmetricGradient( dNdX, stack.uHatLocal, strainInc ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uLocal, strain ); + finiteElement::feOps::symmetricGradient( dNdX, stack.uHatLocal, strainInc ); real64 elasticStrainInc[6] = {0.0}; m_solidUpdate.getElasticStrainInc( k, q, elasticStrainInc ); diff --git a/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp b/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp index 76a9fd032c4..1c9d19daec7 100644 --- a/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp +++ b/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp @@ -3919,12 +3919,6 @@ int SurfaceGenerator::calculateElementForcesOnEdge( DomainPartition const & doma arrayView3d< real64 const, geos::solid::STRESS_USD > >( fields::solid::stress::key(), constitutiveManager ); - ElementRegionManager::ElementViewAccessor< arrayView4d< real64 const > > const - dNdX = elementManager.constructViewAccessor< array4d< real64 >, arrayView4d< real64 const > >( keys::dNdX ); - - ElementRegionManager::ElementViewAccessor< arrayView2d< real64 const > > const - detJ = elementManager.constructViewAccessor< array2d< real64 >, arrayView2d< real64 const > >( keys::detJ ); - ElementRegionManager::ElementViewAccessor< arrayView2d< real64 const > > const elemCenter = elementManager.constructViewAccessor< array2d< real64 >, arrayView2d< real64 const > >( ElementSubRegionBase::viewKeyStruct::elementCenterString() ); @@ -3942,11 +3936,6 @@ int SurfaceGenerator::calculateElementForcesOnEdge( DomainPartition const & doma for( localIndex i=0; i < nodeIndices.size(); ++i ) { localIndex nodeID = nodeIndices( i ); -// localIndex_array temp11; -// for (int ii = 0; ii < nodeToElementMap.sizeOfArray(nodeID); ii++) -// { -// temp11.emplace_back(nodeToElementMap[nodeID][ii]); -// } for( localIndex k=0; k( x0_xEle, X[edgeToNodeMap[edgeID][1]] ); real64 const udist = LvArray::tensorOps::AiBi< 3 >( x0_x1, x0_xEle ); - localIndex const numQuadraturePoints = detJ[er][esr].size( 1 ); - if(( udist <= edgeLength && udist > 0.0 ) || threeNodesPinched ) { real64 const K = bulkModulus[er][esr][m_solidMaterialFullIndex[er]][ei]; @@ -3980,20 +3967,55 @@ int SurfaceGenerator::calculateElementForcesOnEdge( DomainPartition const & doma { if( elementsToNodes( ei, n ) == nodeID ) { - real64 temp[3]{}; + real64 temp[3] {0}; LvArray::tensorOps::copy< 3 >( xEle, elemCenter[er][esr][ei] ); //For C3D6 element type, elementsToNodes map may include // repeated indices and the following may run multiple // times for the same element. - //wu40: the nodal force need to be weighted by Young's modulus and possion's ratio. - solidMechanicsLagrangianFEMKernels::ExplicitKernel:: - calculateSingleNodalForce( ei, - n, - numQuadraturePoints, - dNdX[er][esr], - detJ[er][esr], - stress[er][esr][m_solidMaterialFullIndex[er]], - temp ); + // wu40: the nodal force need to be weighted by Young's modulus and possion's ratio. + + arrayView3d< real64 const, geos::solid::STRESS_USD > const & subregionStress = stress[er][esr][m_solidMaterialFullIndex[er]]; + + // ASSUMPTION(?): subregions only have one registered element type + finiteElement::FiniteElementBase const * finiteElement = nullptr; + elementSubRegion.forWrappers< finiteElement::FiniteElementBase >( [&]( auto const & fe ) + { + finiteElement = &fe.reference(); + } ); + + finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( *finiteElement, [ & ]( auto const & fe ) + { + + using FE_TYPE = TYPEOFREF( fe ); + typename FE_TYPE::StackVariables feStack; + constexpr localIndex numQuadraturePoints = FE_TYPE::numQuadraturePoints; + constexpr localIndex numNodesPerElement = FE_TYPE::numNodes; + real64 xLocal[numNodesPerElement][3] = {{0}}; + localIndex const numSupportPoints = finiteElement->getNumSupportPoints(); + for( localIndex a = 0; a < numSupportPoints; ++a ) + { + LvArray::tensorOps::copy< 3 >( xLocal[a], X[elementsToNodes( ei, a )] ); + } + + for( localIndex q = 0; q < numQuadraturePoints; ++q ) + { + real64 dNdX[numNodesPerElement][3] = {{0}}; + real64 J[3][3] = {{0}}; + + real64 const detJxW = FE_TYPE::calcJacobian( q, xLocal, feStack, J ); + FE_TYPE::calcGradN( q, xLocal, feStack, dNdX ); + + temp[0] -= (subregionStress( ei, q, 0 ) * dNdX[n][0] + + subregionStress( ei, q, 5 ) * dNdX[n][1] + + subregionStress( ei, q, 4 ) * dNdX[n][2]) * detJxW; + temp[1] -= (subregionStress( ei, q, 5 ) * dNdX[n][0] + + subregionStress( ei, q, 1 ) * dNdX[n][1] + + subregionStress( ei, q, 3 ) * dNdX[n][2]) * detJxW; + temp[2] -= (subregionStress( ei, q, 4 ) * dNdX[n][0] + + subregionStress( ei, q, 3 ) * dNdX[n][1] + + subregionStress( ei, q, 2 ) * dNdX[n][2]) * detJxW; + } + } ); LvArray::tensorOps::scale< 3 >( temp, YoungModulus ); LvArray::tensorOps::scale< 3 >( temp, 1.0 / (1 - poissonRatio * poissonRatio) ); diff --git a/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernels.hpp b/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernels.hpp index f4ef1f6545b..144f95a2f26 100644 --- a/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernels.hpp +++ b/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernels.hpp @@ -41,8 +41,7 @@ class NodalForceKernel NodalForceKernel( ElementRegionManager const & elemManager, constitutive::ConstitutiveManager const & constitutiveManager, string const solidMaterialKey ): - m_dNdX( elemManager.constructViewAccessor< array4d< real64 >, arrayView4d< real64 const > >( dataRepository::keys::dNdX ) ), - m_detJ( elemManager.constructViewAccessor< array2d< real64 >, arrayView2d< real64 const > >( dataRepository::keys::detJ ) ), + m_elementRegionManager( elemManager ), m_bulkModulus( elemManager.constructFullMaterialViewAccessor< array1d< real64 >, arrayView1d< real64 const > >( "bulkModulus", constitutiveManager ) ), m_shearModulus( elemManager.constructFullMaterialViewAccessor< array1d< real64 >, arrayView1d< real64 const > >( "shearModulus", constitutiveManager ) ), m_stress( elemManager.constructFullMaterialViewAccessor< array3d< real64, geos::solid::STRESS_PERMUTATION >, @@ -68,15 +67,44 @@ class NodalForceKernel { GEOS_MARK_FUNCTION; - localIndex const numQuadraturePoints = m_detJ[er][esr].size( 1 ); + NodeManager const & nodeManager = m_elementRegionManager.getParent().template getGroup< NodeManager >( MeshLevel::groupStructKeys::nodeManagerString() ); + arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X = nodeManager.referencePosition(); - // Loop over quadrature points - for( localIndex q = 0; q < numQuadraturePoints; ++q ) + CellElementRegion const & region = m_elementRegionManager.getRegion< CellElementRegion >( er ); + CellElementSubRegion const & subRegion = region.getSubRegion< CellElementSubRegion >( esr ); + CellElementSubRegion::NodeMapType const & toNodesRelation = subRegion.nodeList(); + + // ASSUMPTION(?): subregions only have one registered element type + finiteElement::FiniteElementBase const * finiteElement = nullptr; + subRegion.forWrappers< finiteElement::FiniteElementBase >( [&]( auto const & fe ) { - real64 const quadratureStress[6] = LVARRAY_TENSOROPS_INIT_LOCAL_6 ( m_stress[er][esr][m_solidMaterialFullIndex[er]][ei][q] ); - real64 const dNdX[3] = LVARRAY_TENSOROPS_INIT_LOCAL_3 ( m_dNdX[er][esr][ei][q][targetNode] ); - surfaceGenerationKernelsHelpers::computeNodalForce( quadratureStress, dNdX, m_detJ[er][esr][ei][q], force ); - } + finiteElement = &fe.reference(); + } ); + + finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( *finiteElement, [ & ]( auto const & fe ) + { + using FE_TYPE = TYPEOFREF( fe ); + typename FE_TYPE::StackVariables feStack; + constexpr localIndex numQuadraturePoints = FE_TYPE::numQuadraturePoints; + constexpr localIndex numNodesPerElement = FE_TYPE::numNodes; + real64 xLocal[numNodesPerElement][3] = { { 0 } }; + + localIndex const numSupportPoints = finiteElement->getNumSupportPoints( ); + for( localIndex a = 0; a < numSupportPoints; ++a ) + { + LvArray::tensorOps::copy< 3 >( xLocal[a], X[toNodesRelation( ei, a )] ); + } + + for( localIndex q = 0; q < numQuadraturePoints; ++q ) + { + real64 const quadratureStress[6] = LVARRAY_TENSOROPS_INIT_LOCAL_6 ( m_stress[er][esr][m_solidMaterialFullIndex[er]][ei][q] ); + real64 dNdX[numNodesPerElement][3] = {{0}}; + real64 J[3][3] = {{0}}; + real64 const detJxW = FE_TYPE::calcJacobian( q, xLocal, feStack, J ); + FE_TYPE::calcGradN( q, xLocal, feStack, dNdX ); + surfaceGenerationKernelsHelpers::computeNodalForce( quadratureStress, dNdX[targetNode], detJxW, force ); + } + } ); //wu40: the nodal force need to be weighted by Young's modulus and possion's ratio. surfaceGenerationKernelsHelpers::scaleNodalForce( m_bulkModulus[er][esr][m_solidMaterialFullIndex[er]][ei], m_shearModulus[er][esr][m_solidMaterialFullIndex[er]][ei], force ); @@ -84,9 +112,7 @@ class NodalForceKernel protected: - ElementRegionManager::ElementViewAccessor< arrayView4d< real64 const > > const m_dNdX; - - ElementRegionManager::ElementViewAccessor< arrayView2d< real64 const > > const m_detJ; + ElementRegionManager const & m_elementRegionManager; ElementRegionManager::MaterialViewAccessor< arrayView1d< real64 const > > const m_bulkModulus; @@ -131,18 +157,47 @@ class PoroElasticNodalForceKernel : public NodalForceKernel { GEOS_MARK_FUNCTION; - localIndex const numQuadraturePoints = m_detJ[er][esr].size( 1 ); + NodeManager const & nodeManager = m_elementRegionManager.getParent().template getGroup< NodeManager >( MeshLevel::groupStructKeys::nodeManagerString() ); + arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X = nodeManager.referencePosition(); + + CellElementRegion const & region = m_elementRegionManager.getRegion< CellElementRegion >( er ); + CellElementSubRegion const & subRegion = region.getSubRegion< CellElementSubRegion >( esr ); + CellElementSubRegion::NodeMapType const & toNodesRelation = subRegion.nodeList(); - // Loop over quadrature points - for( localIndex q = 0; q < numQuadraturePoints; ++q ) + // ASSUMPTION(?): subregions only have one registered element type + finiteElement::FiniteElementBase const * finiteElement = nullptr; + subRegion.forWrappers< finiteElement::FiniteElementBase >( [&]( auto const & fe ) { - real64 totalStress[6] = LVARRAY_TENSOROPS_INIT_LOCAL_6 ( m_stress[er][esr][m_solidMaterialFullIndex[er]][ei][q] ); - real64 const dNdX[3] = LVARRAY_TENSOROPS_INIT_LOCAL_3 ( m_dNdX[er][esr][ei][q][targetNode] ); - /// TODO: make it work for the thermal case as well - LvArray::tensorOps::symAddIdentity< 3 >( totalStress, -m_biotCoefficient[er][esr][m_porosityMaterialFullIndex[er]][ei] * m_pressure[er][esr][ei] ); + finiteElement = &fe.reference(); + } ); - surfaceGenerationKernelsHelpers::computeNodalForce( totalStress, dNdX, m_detJ[er][esr][ei][q], force ); - } + finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( *finiteElement, [ & ]( auto const & fe ) + { + using FE_TYPE = TYPEOFREF( fe ); + typename FE_TYPE::StackVariables feStack; + constexpr localIndex numQuadraturePoints = FE_TYPE::numQuadraturePoints; + constexpr localIndex numNodesPerElement = FE_TYPE::numNodes; + real64 xLocal[numNodesPerElement][3] = {{0}}; + + localIndex const numSupportPoints = finiteElement->getNumSupportPoints( ); + for( localIndex a = 0; a < numSupportPoints; ++a ) + { + LvArray::tensorOps::copy< 3 >( xLocal[a], X[toNodesRelation( ei, a )] ); + } + + for( localIndex q = 0; q < numQuadraturePoints; ++q ) + { + real64 totalStress[6] = LVARRAY_TENSOROPS_INIT_LOCAL_6 ( m_stress[er][esr][m_solidMaterialFullIndex[er]][ei][q] ); + /// TODO: make it work for the thermal case as well + LvArray::tensorOps::symAddIdentity< 3 >( totalStress, -m_biotCoefficient[er][esr][m_porosityMaterialFullIndex[er]][ei] * m_pressure[er][esr][ei] ); + + real64 dNdX[numNodesPerElement][3] = {{0}}; + real64 J[3][3] = {{0}}; + real64 const detJxW = FE_TYPE::calcJacobian( q, xLocal, feStack, J ); + FE_TYPE::calcGradN( q, xLocal, feStack, dNdX ); + surfaceGenerationKernelsHelpers::computeNodalForce( totalStress, dNdX[targetNode], detJxW, force ); + } + } ); //wu40: the nodal force need to be weighted by Young's modulus and possion's ratio. surfaceGenerationKernelsHelpers::scaleNodalForce( m_bulkModulus[er][esr][m_solidMaterialFullIndex[er]][ei], m_shearModulus[er][esr][m_solidMaterialFullIndex[er]][ei], force ); diff --git a/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernelsHelpers.hpp b/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernelsHelpers.hpp index 1e1a596bb68..5e89358ff76 100644 --- a/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernelsHelpers.hpp +++ b/src/coreComponents/physicsSolvers/surfaceGeneration/kernels/surfaceGenerationKernelsHelpers.hpp @@ -30,19 +30,19 @@ namespace surfaceGenerationKernelsHelpers GEOS_HOST_DEVICE inline void computeNodalForce( real64 const ( &stress) [ 6 ], real64 const ( &dNdX) [ 3 ], - real64 const detJ, + real64 const detJxW, real64 ( & force ) [ 3 ] ) { force[ 0 ] -= ( stress[ 0 ] * dNdX[ 0 ] + stress[ 5 ] * dNdX[ 1 ] + - stress[ 4 ] * dNdX[ 2 ] ) * detJ; + stress[ 4 ] * dNdX[ 2 ] ) * detJxW; force[ 1 ] -= ( stress[ 5 ] * dNdX[ 0 ] + stress[ 1 ] * dNdX[ 1 ] + - stress[ 3 ] * dNdX[ 2 ] ) * detJ; + stress[ 3 ] * dNdX[ 2 ] ) * detJxW; force[ 2 ] -= ( stress[ 4 ] * dNdX[ 0 ] + stress[ 3 ] * dNdX[ 1 ] + - stress[ 2 ] * dNdX[ 2 ] ) * detJ; + stress[ 2 ] * dNdX[ 2 ] ) * detJxW; } GEOS_HOST_DEVICE diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticPMLSEMKernel.hpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticPMLSEMKernel.hpp index 8f1b96077ba..322046c293c 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticPMLSEMKernel.hpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticPMLSEMKernel.hpp @@ -20,6 +20,8 @@ #ifndef GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_ACOUSTICPMLSEMKERNEL_HPP_ #define GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_ACOUSTICPMLSEMKERNEL_HPP_ +#include "finiteElement/elementFormulations/FiniteElementOperators.hpp" + namespace geos { @@ -190,15 +192,15 @@ struct AcousticPMLSEM { /// compute the shape functions gradients - real32 const detJ = m_finiteElement.template getGradN< FE_TYPE >( k, i, xLocal, gradN ); + real32 const detJ = FE_TYPE::calcGradN( i, xLocal, gradN ); GEOS_UNUSED_VAR ( detJ ); /// compute the gradient of the pressure and the PML auxiliary variables at the node - m_finiteElement.template gradient< numNodesPerElem, GRADIENT_TYPE >( gradN, pressure, pressureGrad ); - m_finiteElement.template gradient< numNodesPerElem, GRADIENT_TYPE >( gradN, auxU, auxUGrad ); + finiteElement::feOps::gradient< numNodesPerElem, GRADIENT_TYPE >( gradN, pressure, pressureGrad ); + finiteElement::feOps::gradient< numNodesPerElem, GRADIENT_TYPE >( gradN, auxU, auxUGrad ); for( int j=0; j<3; ++j ) { - m_finiteElement.template gradient< numNodesPerElem, GRADIENT_TYPE >( gradN, auxV[j], auxVGrad[j] ); + finiteElement::feOps::gradient< numNodesPerElem, GRADIENT_TYPE >( gradN, auxV[j], auxVGrad[j] ); } /// compute the PML damping profile diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp index 6190586dded..241339c735c 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp @@ -37,9 +37,48 @@ #include "physicsSolvers/wavePropagation/shared/PrecomputeSourcesAndReceiversKernel.hpp" #include "physicsSolvers/wavePropagation/LogLevelsInfo.hpp" +#include "common/MpiWrapper.hpp" + +#include + namespace geos { +namespace +{ + +struct ApplyFreeSurfaceBCKernel +{ + template< typename POLICY > + static void launch( SortedArrayView< localIndex const > const & targetSet, + ArrayOfArraysView< localIndex const > const & faceToNodeMap, + arrayView1d< localIndex > const & freeSurfaceFaceIndicator, + arrayView1d< localIndex > const & freeSurfaceNodeIndicator, + arrayView1d< real32 > const & p_np1, + arrayView1d< real32 > const & p_n, + arrayView1d< real32 > const & p_nm1, + real32 const & value ) + { + forAll< POLICY >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const i ) + { + localIndex const kf = targetSet[i]; + freeSurfaceFaceIndicator[kf] = 1; + localIndex const numNodes = faceToNodeMap.sizeOfArray( kf ); + for( localIndex a = 0; a < numNodes; ++a ) + { + localIndex const dof = faceToNodeMap( kf, a ); + freeSurfaceNodeIndicator[dof] = 1; + p_np1[dof] = value; + p_n[dof] = value; + p_nm1[dof] = value; + } + } ); + } +}; + + +} + using namespace dataRepository; using namespace fields; @@ -341,11 +380,11 @@ void AcousticWaveEquationSEM::initializePostInitialConditionsPreSubGroups() ArrayOfArraysView< localIndex const > const facesToNodes = faceManager.nodeList().toViewConst(); // mass matrix to be computed in this function - arrayView1d< real32 > const mass = nodeManager.getField< acousticfields::AcousticMassVector >(); + auto & mass = nodeManager.getField< acousticfields::AcousticMassVector >(); mass.zero(); /// damping matrix to be computed for each dof in the boundary of the mesh - arrayView1d< real32 > const damping = nodeManager.getField< acousticfields::DampingVector >(); + auto & damping = nodeManager.getField< acousticfields::DampingVector >(); damping.zero(); /// get array of indicators: 1 if face is on the free surface; 0 otherwise @@ -396,6 +435,7 @@ void AcousticWaveEquationSEM::initializePostInitialConditionsPreSubGroups() damping ); } ); } ); + // Here we compute the timeStep only one time (beginning of the simulation). if( m_timestepStabilityLimit==1 ) { @@ -606,24 +646,15 @@ void AcousticWaveEquationSEM::applyFreeSurfaceBC( real64 time, DomainPartition & if( functionName.empty() || functionManager.getGroup< FunctionBase >( functionName ).isFunctionOfTime() == 2 ) { - real64 const value = bc.getScale(); - - for( localIndex i = 0; i < targetSet.size(); ++i ) - { - localIndex const kf = targetSet[ i ]; - freeSurfaceFaceIndicator[kf] = 1; - - localIndex const numNodes = faceToNodeMap.sizeOfArray( kf ); - for( localIndex a=0; a < numNodes; ++a ) - { - localIndex const dof = faceToNodeMap( kf, a ); - freeSurfaceNodeIndicator[dof] = 1; - - p_np1[dof] = value; - p_n[dof] = value; - p_nm1[dof] = value; - } - } + real32 const value = static_cast< real32 >( bc.getScale() ); + ApplyFreeSurfaceBCKernel::launch< EXEC_POLICY >( targetSet, + faceToNodeMap, + freeSurfaceFaceIndicator, + freeSurfaceNodeIndicator, + p_np1, + p_n, + p_nm1, + value ); } else { @@ -1223,18 +1254,18 @@ void AcousticWaveEquationSEM::computeUnknowns( real64 const & time_n, { NodeManager & nodeManager = mesh.getNodeManager(); - arrayView1d< real32 const > const mass = nodeManager.getField< acousticfields::AcousticMassVector >(); - arrayView1d< real32 const > const damping = nodeManager.getField< acousticfields::DampingVector >(); + auto & mass = nodeManager.getField< acousticfields::AcousticMassVector >(); + auto & damping = nodeManager.getField< acousticfields::DampingVector >(); - arrayView1d< real32 > const p_nm1 = nodeManager.getField< acousticfields::Pressure_nm1 >(); - arrayView1d< real32 > const p_n = nodeManager.getField< acousticfields::Pressure_n >(); - arrayView1d< real32 > const p_np1 = nodeManager.getField< acousticfields::Pressure_np1 >(); + auto & p_nm1 = nodeManager.getField< acousticfields::Pressure_nm1 >(); + auto & p_n = nodeManager.getField< acousticfields::Pressure_n >(); + auto & p_np1 = nodeManager.getField< acousticfields::Pressure_np1 >(); arrayView1d< real32 > const taperCoeff = nodeManager.getField< fields::taperCoeff >(); arrayView1d< localIndex const > const freeSurfaceNodeIndicator = nodeManager.getField< acousticfields::AcousticFreeSurfaceNodeIndicator >(); - arrayView1d< real32 > const stiffnessVector = nodeManager.getField< acousticfields::StiffnessVector >(); - arrayView1d< real32 > const rhs = nodeManager.getField< acousticfields::ForcingRHS >(); + auto & stiffnessVector = nodeManager.getField< acousticfields::StiffnessVector >(); + auto & rhs = nodeManager.getField< acousticfields::ForcingRHS >(); auto kernelFactory = acousticWaveEquationSEMKernels::ExplicitAcousticSEMFactory( dt ); @@ -1374,8 +1405,8 @@ void AcousticWaveEquationSEM::synchronizeUnknowns( real64 const & time_n, { NodeManager & nodeManager = mesh.getNodeManager(); - arrayView1d< real32 > const p_n = nodeManager.getField< acousticfields::Pressure_n >(); - arrayView1d< real32 > const p_np1 = nodeManager.getField< acousticfields::Pressure_np1 >(); + auto & p_n = nodeManager.getField< acousticfields::Pressure_n >(); + auto & p_np1 = nodeManager.getField< acousticfields::Pressure_np1 >(); arrayView1d< real32 > const stiffnessVector = nodeManager.getField< acousticfields::StiffnessVector >(); arrayView1d< real32 > const rhs = nodeManager.getField< acousticfields::ForcingRHS >(); @@ -1402,10 +1433,12 @@ void AcousticWaveEquationSEM::synchronizeUnknowns( real64 const & time_n, mesh, domain.getNeighbors(), true ); - /// compute the seismic traces since last step. + + // compute the seismic traces since last step. arrayView2d< real32 > const pReceivers = m_pressureNp1AtReceivers.toView(); computeAllSeismoTraces( time_n, dt, p_np1, p_n, pReceivers ); + incrementIndexSeismoTrace( time_n ); if( m_usePML ) diff --git a/src/docs/doxygen/Doxyfile.in b/src/docs/doxygen/Doxyfile.in index 491e9d0b754..cc9821e305c 100644 --- a/src/docs/doxygen/Doxyfile.in +++ b/src/docs/doxygen/Doxyfile.in @@ -2035,7 +2035,6 @@ EXPAND_AS_DEFINED = LVARRAY_HOST_DEVICE \ DISABLE_HD_WARNING \ DECLARE_FIELD \ GEOS_FORCE_INLINE \ - USING_FINITEELEMENTBASE \ MAKE_PRINT_MATVIEW # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will