Quinoa all test code coverage report
Current view: top level - DiffEq/Velocity - Velocity.hpp (source / functions) Hit Total Coverage
Commit: Quinoa_v0.3-957-gb4f0efae0 Lines: 77 107 72.0 %
Date: 2021-11-11 18:25:50 Functions: 8 96 8.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 35 116 30.2 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/DiffEq/Velocity/Velocity.hpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.
       7                 :            :              All rights reserved. See the LICENSE file for details.
       8                 :            :   \brief     A model for velocity in variable-density turbulence
       9                 :            :   \details   This file implements the time integration of a system of stochastic
      10                 :            :     differential equations (SDEs) to model the fluctuating velocity components
      11                 :            :     in homogeneous variable-density turbulence. This model is an extension of
      12                 :            :     the generalized Langevin (GLM) model for constant-density flows by Haworth &
      13                 :            :     Pope (https://doi.org/10.1063/1.865723). The extension is roughly along the
      14                 :            :     lines of https://doi.org/10.1080/14685248.2011.554419.
      15                 :            : */
      16                 :            : // *****************************************************************************
      17                 :            : #ifndef Velocity_h
      18                 :            : #define Velocity_h
      19                 :            : 
      20                 :            : #include <array>
      21                 :            : #include <vector>
      22                 :            : #include <cmath>
      23                 :            : 
      24                 :            : #include "InitPolicy.hpp"
      25                 :            : #include "VelocityCoeffPolicy.hpp"
      26                 :            : #include "RNG.hpp"
      27                 :            : #include "Particles.hpp"
      28                 :            : #include "CoupledEq.hpp"
      29                 :            : 
      30                 :            : namespace walker {
      31                 :            : 
      32                 :            : extern ctr::InputDeck g_inputdeck;
      33                 :            : extern std::map< tk::ctr::RawRNGType, tk::RNG > g_rng;
      34                 :            : 
      35                 :            : //! \brief Velocity SDE used polymorphically with DiffEq
      36                 :            : //! \details The template arguments specify policies and are used to configure
      37                 :            : //!   the behavior of the class. The policies are:
      38                 :            : //!   - Init - initialization policy, see DiffEq/InitPolicy.h
      39                 :            : //!   - Coefficients - coefficients policy, see DiffEq/VelocityCoeffPolicy.h
      40                 :            : template< class Init, class Coefficients >
      41                 :            : class Velocity {
      42                 :            : 
      43                 :            :   private:
      44                 :            :     using ncomp_t = tk::ctr::ncomp_t;
      45                 :            :     using eq = tag::velocity;
      46                 :            : 
      47                 :            :   public:
      48                 :            :     //! \brief Constructor
      49                 :            :     //! \param[in] c Index specifying which system of velocity SDEs to construct
      50                 :            :     //!   There can be multiple velocity ... end blocks in a control file. This
      51                 :            :     //!   index specifies which velocity SDE system to instantiate. The index
      52                 :            :     //!   corresponds to the order in which the velocity ... end blocks are
      53                 :            :     //!   given the control file.
      54                 :         22 :     explicit Velocity( ncomp_t c ) :
      55                 :            :       m_c( c ),
      56                 :         22 :       m_depvar( g_inputdeck.get< tag::param, eq, tag::depvar >().at(c) ),
      57                 :         22 :       m_solve( g_inputdeck.get< tag::param, eq, tag::solve >().at(c) ),
      58                 :         22 :       m_mixmassfracbeta_coupled( coupled< eq, tag::mixmassfracbeta >( c ) ),
      59                 :         22 :       m_mixmassfracbeta_depvar( depvar< eq, tag::mixmassfracbeta >( c ) ),
      60                 :            :       m_mixmassfracbeta_offset(
      61                 :         44 :         offset< eq, tag::mixmassfracbeta, tag::mixmassfracbeta_id >( c ) ),
      62                 :            :       m_mixmassfracbeta_ncomp(
      63                 :            :         // The magic number, 4, below is MixMassFractionBeta::NUMDERIVED + 1,
      64                 :            :         // but cannot be given as such, because that would lead to circular
      65                 :            :         // dependencies of Velocity depending on MixMassfractionBeta, and vice
      66                 :            :         // versa.
      67                 :         22 :         m_mixmassfracbeta_coupled ?
      68                 :          0 :         ncomp< eq, tag::mixmassfracbeta, tag::mixmassfracbeta_id >( c ) / 4 :
      69                 :            :         0 ),
      70                 :            :       m_numderived( numderived() ),
      71                 :         22 :       m_ncomp( g_inputdeck.get< tag::component, eq >().at(c) - m_numderived ),
      72                 :            :       m_offset(
      73                 :         22 :         g_inputdeck.get< tag::component >().offset< eq >(c) ),
      74         [ +  - ]:         22 :       m_rng( g_rng.at( tk::ctr::raw(
      75                 :         22 :         g_inputdeck.get< tag::param, eq, tag::rng >().at(c) ) ) ),
      76                 :         22 :       m_position_coupled( coupled< eq, tag::position >( c ) ),
      77                 :         22 :       m_position_depvar( depvar< eq, tag::position >( c ) ),
      78                 :         44 :       m_position_offset( offset< eq, tag::position, tag::position_id >( c ) ),
      79                 :         22 :       m_dissipation_coupled( coupled< eq, tag::dissipation >( c ) ),
      80                 :         22 :       m_dissipation_depvar( depvar< eq, tag::dissipation >( c ) ),
      81                 :            :       m_dissipation_offset(
      82                 :         44 :         offset< eq, tag::dissipation, tag::dissipation_id >( c ) ),
      83                 :         22 :       m_U( {{ tk::ctr::mean( m_depvar, 0 ),
      84                 :         22 :               tk::ctr::mean( m_depvar, 1 ),
      85                 :         22 :               tk::ctr::mean( m_depvar, 2 ) }} ),
      86         [ +  - ]:         22 :       m_variant( g_inputdeck.get< tag::param, eq, tag::variant >().at(c) ),
      87                 :            :       m_c0(),
      88                 :            :       m_G(),
      89         [ +  - ]:         22 :       m_coeff( g_inputdeck.get< tag::param, eq, tag::c0 >().at(c), m_c0, m_dU ),
      90 [ -  + ][ +  - ]:        176 :       m_gravity( { 0.0, 0.0, 0.0 } )
      91                 :            :     {
      92 [ -  + ][ -  - ]:         22 :       Assert( m_ncomp == 3, "Velocity eq number of components must be 3" );
         [ -  - ][ -  - ]
      93                 :            :       // Zero prescribed mean velocity gradient if full variable is solved for
      94 [ +  + ][ +  - ]:         22 :       if (m_solve == ctr::DepvarType::FULLVAR) m_dU.fill( 0.0 );
      95                 :            :       // Populate inverse hydrodynamics time scales extracted from DNS
      96         [ -  + ]:         22 :       if ( Coefficients::type() == ctr::CoeffPolicyType::HYDROTIMESCALE ) {
      97                 :            :         // Configure inverse hydrodyanmics time scale from DNS
      98                 :            :         const auto& hts =
      99         [ -  - ]:          0 :           g_inputdeck.get< tag::param, eq, tag::hydrotimescales >().at(c);
     100 [ -  - ][ -  - ]:          0 :         Assert( hts.size() == 1,
         [ -  - ][ -  - ]
     101                 :            :                 "Velocity eq Hydrotimescales vector size must be 1" );
     102 [ -  - ][ -  - ]:          0 :         m_hts = ctr::HydroTimeScales().table( hts[0] );
     103                 :            :       }
     104                 :            :       // Initialize gravity body force if configured
     105                 :            :       const auto& gravity =
     106         [ +  - ]:         22 :         g_inputdeck.get< tag::param, eq, tag::gravity >().at(c);
     107         [ +  - ]:         22 :       if (!gravity.empty()) {
     108                 :         22 :         m_gravity[0] = gravity[0];
     109                 :         22 :         m_gravity[1] = gravity[1];
     110                 :         22 :         m_gravity[2] = gravity[2];
     111                 :            :       }
     112                 :         22 :     }
     113                 :            : 
     114                 :            :     //! Compute number of derived variables
     115                 :            :     //! \return Number of derived variables computed
     116                 :         22 :     std::size_t numderived() const {
     117         [ +  - ]:         22 :       if (m_solve == ctr::DepvarType::PRODUCT ||
     118         [ -  + ]:         22 :           m_solve == ctr::DepvarType::FLUCTUATING_MOMENTUM)
     119                 :            :       { // derived: 3 velocity components for each coupled mass fraction
     120                 :          0 :         return m_mixmassfracbeta_ncomp * 3;
     121                 :            :       } else {
     122                 :         22 :         return 0;
     123                 :            :       }
     124                 :            :     }
     125                 :            : 
     126                 :            :     //! Initalize SDE, prepare for time integration
     127                 :            :     //! \param[in] stream Thread (or more precisely stream) ID
     128                 :            :     //! \param[in,out] particles Array of particle properties
     129                 :         94 :     void initialize( int stream, tk::Particles& particles ) {
     130                 :            :       // Set initial conditions using initialization policy
     131                 :            :       Init::template init< eq >
     132                 :         94 :         ( g_inputdeck, m_rng, stream, particles, m_c, m_ncomp, m_offset );
     133                 :         94 :     }
     134                 :            : 
     135                 :            :     //! \brief Advance particles according to the system of velocity SDEs
     136                 :            :     //! \param[in,out] particles Array of particle properties
     137                 :            :     //! \param[in] stream Thread (or more precisely stream) ID
     138                 :            :     //! \param[in] dt Time step size
     139                 :            :     //! \param[in] t Physical time of the simulation
     140                 :            :     //! \param[in] moments Map of statistical moments
     141                 :       7146 :     void advance( tk::Particles& particles,
     142                 :            :                   int stream,
     143                 :            :                   tk::real dt,
     144                 :            :                   tk::real t,
     145                 :            :                   const std::map< tk::ctr::Product, tk::real >& moments )
     146                 :            :     {
     147                 :            :       using ctr::DepvarType;
     148                 :       7146 :       const auto epsilon = std::numeric_limits< tk::real >::epsilon();
     149                 :            : 
     150                 :            :       // Update coefficients
     151                 :       7146 :       tk::real eps = 0.0;
     152                 :       7146 :       m_coeff.update( m_depvar, m_dissipation_depvar, moments, m_hts, m_solve,
     153         [ +  - ]:       7146 :                       m_variant, m_c0, t, eps, m_G );
     154                 :            : 
     155                 :            :       // Access mean velocity (if needed)
     156                 :       7146 :       std::array< tk::real, 3 > U{{ 0.0, 0.0, 0.0 }};
     157 [ +  + ][ -  + ]:       7146 :       if (m_solve == DepvarType::FULLVAR || m_solve == DepvarType::PRODUCT) {
     158                 :            :         using tk::ctr::lookup;
     159         [ +  - ]:        396 :         U[0] = lookup( m_U[0], moments );
     160         [ +  - ]:        396 :         U[1] = lookup( m_U[1], moments );
     161         [ +  - ]:        396 :         U[2] = lookup( m_U[2], moments );
     162                 :            :       }
     163                 :            : 
     164                 :            :       // Modify G with the mean velocity gradient
     165         [ +  + ]:      71460 :       for (std::size_t i=0; i<9; ++i) m_G[i] -= m_dU[i];
     166                 :            : 
     167                 :            :       // Access mean specific volume (if needed)
     168                 :            :       using tk::ctr::mean;
     169                 :            :       using tk::ctr::Term;
     170                 :            :       using tk::ctr::Product;
     171                 :       7146 :       auto mixncomp = m_mixmassfracbeta_ncomp;
     172                 :      14292 :       std::vector< tk::real > R;
     173                 :      14292 :       std::vector< tk::real > RU;
     174                 :       7146 :       auto Uc = static_cast< char >( std::toupper(m_depvar) );
     175         [ +  - ]:       7146 :       if (m_solve == ctr::DepvarType::PRODUCT ||
     176         [ -  + ]:       7146 :           m_solve == DepvarType::FLUCTUATING_MOMENTUM)
     177                 :            :       {
     178         [ -  - ]:          0 :         R.resize( mixncomp, 0.0 );
     179         [ -  - ]:          0 :         RU.resize( mixncomp*3, 0.0 );
     180         [ -  - ]:          0 :         for (std::size_t c=0; c<mixncomp; ++c) {
     181 [ -  - ][ -  - ]:          0 :           R[c] = lookup(mean(m_mixmassfracbeta_depvar, c+mixncomp), moments);
     182                 :          0 :           Term Rs( static_cast<char>(std::toupper(m_mixmassfracbeta_depvar)),
     183                 :            :                    mixncomp + c,
     184                 :            :                    tk::ctr::Moment::ORDINARY );
     185                 :          0 :           std::array< Term, 3 > Us{
     186                 :          0 :             Term( Uc, m_ncomp+(c*3)+0, tk::ctr::Moment::ORDINARY ),
     187                 :          0 :             Term( Uc, m_ncomp+(c*3)+1, tk::ctr::Moment::ORDINARY ),
     188                 :          0 :             Term( Uc, m_ncomp+(c*3)+2, tk::ctr::Moment::ORDINARY ) };
     189 [ -  - ][ -  - ]:          0 :           std::array< Product, 3 > RsUs{ Product( { Us[0], Rs } ),
                 [ -  - ]
     190                 :          0 :                                          Product( { Us[1], Rs } ),
     191                 :          0 :                                          Product( { Us[2], Rs } ) };
     192         [ -  - ]:          0 :           RU[ c*3+0 ] = lookup( RsUs[0], moments );
     193         [ -  - ]:          0 :           RU[ c*3+1 ] = lookup( RsUs[1], moments );
     194         [ -  - ]:          0 :           RU[ c*3+2 ] = lookup( RsUs[2], moments );
     195                 :            :         }
     196                 :            :       }
     197                 :            : 
     198                 :       7146 :       const auto npar = particles.nunk();
     199         [ +  + ]:   36457146 :       for (auto p=decltype(npar){0}; p<npar; ++p) {
     200                 :            :         // Generate Gaussian random numbers with zero mean and unit variance
     201         [ +  - ]:   72900000 :         std::vector< tk::real > dW( m_ncomp );
     202         [ +  - ]:   36450000 :         m_rng.gaussian( stream, m_ncomp, dW.data() );
     203                 :            :         // Access particle velocity
     204         [ +  - ]:   36450000 :         tk::real& Up = particles( p, 0, m_offset );
     205         [ +  - ]:   36450000 :         tk::real& Vp = particles( p, 1, m_offset );
     206         [ +  - ]:   36450000 :         tk::real& Wp = particles( p, 2, m_offset );
     207                 :            :         // Compute diffusion
     208                 :   36450000 :         tk::real d = m_c0 * eps * dt;
     209         [ +  - ]:   36450000 :         d = (d > 0.0 ? std::sqrt(d) : 0.0);
     210                 :            :         // Compute velocity fluctuation
     211                 :   36450000 :         tk::real u = Up - U[0];
     212                 :   36450000 :         tk::real v = Vp - U[1];
     213                 :   36450000 :         tk::real w = Wp - U[2];
     214                 :            :         // Update particle velocity based on Langevin model
     215                 :   36450000 :         Up += (m_G[0]*u + m_G[1]*v + m_G[2]*w)*dt + d*dW[0];
     216                 :   36450000 :         Vp += (m_G[3]*u + m_G[4]*v + m_G[5]*w)*dt + d*dW[1];
     217                 :   36450000 :         Wp += (m_G[6]*u + m_G[7]*v + m_G[8]*w)*dt + d*dW[2];
     218                 :            :         // Add gravity
     219         [ +  - ]:   36450000 :         if (m_solve == ctr::DepvarType::PRODUCT ||
     220         [ -  + ]:   36450000 :             m_solve == ctr::DepvarType::FLUCTUATING_MOMENTUM)
     221                 :            :         {
     222         [ -  - ]:          0 :           for (ncomp_t c=0; c<mixncomp; ++c) {
     223         [ -  - ]:          0 :             auto rhoi = particles( p, mixncomp + c, m_mixmassfracbeta_offset );
     224         [ -  - ]:          0 :             if (std::abs(rhoi) > epsilon) {
     225                 :            :               // add gravity force to particle momentum
     226                 :          0 :               Up += (rhoi - R[c]) * m_gravity[0] * dt;
     227                 :          0 :               Vp += (rhoi - R[c]) * m_gravity[1] * dt;
     228                 :          0 :               Wp += (rhoi - R[c]) * m_gravity[2] * dt;
     229                 :            :               // compute derived particle velocity
     230         [ -  - ]:          0 :               particles( p, m_ncomp+(c*3)+0, m_offset ) = (Up + RU[c*3+0])/rhoi;
     231         [ -  - ]:          0 :               particles( p, m_ncomp+(c*3)+1, m_offset ) = (Vp + RU[c*3+1])/rhoi;
     232         [ -  - ]:          0 :               particles( p, m_ncomp+(c*3)+2, m_offset ) = (Wp + RU[c*3+2])/rhoi;
     233                 :            :             }
     234                 :          0 :           }
     235                 :            :         } else {
     236                 :   36450000 :           Up += m_gravity[0] * dt;
     237                 :   36450000 :           Vp += m_gravity[1] * dt;
     238                 :   36450000 :           Wp += m_gravity[2] * dt;
     239                 :            :         }
     240                 :            :       }
     241                 :       7146 :     }
     242                 :            : 
     243                 :            :   private:
     244                 :            :     const ncomp_t m_c;                  //!< Equation system index
     245                 :            :     const char m_depvar;                //!< Dependent variable
     246                 :            :     const ctr::DepvarType m_solve;      //!< Dependent variable to solve for
     247                 :            : 
     248                 :            :     //! True if coupled to mixmassfracbeta
     249                 :            :     const bool m_mixmassfracbeta_coupled;
     250                 :            :     //! Depvar of coupled mixmassfracbeta eq
     251                 :            :     const char m_mixmassfracbeta_depvar;
     252                 :            :     //! Offset of coupled mixmassfracbeta eq
     253                 :            :     const ncomp_t m_mixmassfracbeta_offset;
     254                 :            :     //! Number of scalar components in coupled mixmassfracbeta eq
     255                 :            :     const ncomp_t m_mixmassfracbeta_ncomp;
     256                 :            : 
     257                 :            :     const ncomp_t m_numderived;         //!< Number of derived variables
     258                 :            :     const ncomp_t m_ncomp;              //!< Number of components
     259                 :            :     const ncomp_t m_offset;             //!< Offset SDE operates from
     260                 :            :     const tk::RNG& m_rng;               //!< Random number generator
     261                 :            : 
     262                 :            :     const bool m_position_coupled;      //!< True if coupled to position
     263                 :            :     const char m_position_depvar;       //!< Coupled position dependent variable
     264                 :            :     const ncomp_t m_position_offset;    //!< Offset of coupled position eq
     265                 :            : 
     266                 :            :     const bool m_dissipation_coupled;   //!< True if coupled to dissipation
     267                 :            :     const char m_dissipation_depvar;    //!< Coupled dissipation dependent var
     268                 :            :     const ncomp_t m_dissipation_offset; //!< Offset of coupled dissipation eq
     269                 :            : 
     270                 :            :     //! Array of tk::ctr::Product used to access the mean velocity
     271                 :            :     const std::array< tk::ctr::Product, 3 > m_U;
     272                 :            :     //! Velocity model variant
     273                 :            :     const ctr::VelocityVariantType m_variant;
     274                 :            : 
     275                 :            :     //! Selected inverse hydrodynamics time scale (if used)
     276                 :            :     //! \details This is only used if the coefficients policy is
     277                 :            :     //!   VelocityCoeffHydroTimeScale. See constructor.
     278                 :            :     tk::Table<1> m_hts;
     279                 :            : 
     280                 :            :     //! Coefficients
     281                 :            :     kw::sde_c0::info::expect::type m_c0;
     282                 :            :     std::array< tk::real, 9 > m_G;
     283                 :            : 
     284                 :            :     //! Coefficients policy
     285                 :            :     Coefficients m_coeff;
     286                 :            : 
     287                 :            :     //! (Optionally) prescribed mean velocity gradient
     288                 :            :     std::array< tk::real, 9 > m_dU;
     289                 :            : 
     290                 :            :     //! Optional gravity body force
     291                 :            :     std::array< tk::real, 3 > m_gravity;
     292                 :            : };
     293                 :            : 
     294                 :            : } // walker::
     295                 :            : 
     296                 :            : #endif // Velocity_h

Generated by: LCOV version 1.14