Walker test code coverage report
Current view: top level - DiffEq - DiffEqStack.cpp (source / functions) Hit Total Coverage
Commit: test_coverage.info Lines: 95 101 94.1 %
Date: 2022-09-21 13:52:12 Functions: 4 4 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 133 240 55.4 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/DiffEq/DiffEqStack.cpp
       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     Stack of differential equations
       9                 :            :   \details   This file defines class DiffEqStack, which implements various
      10                 :            :     functionality related to registering and instantiating differential equation
      11                 :            :     types. Registration and instantiation use a differential equation factory,
      12                 :            :     which is a std::map (an associative container), associating unique
      13                 :            :     differential equation keys to their constructor calls. For more details, see
      14                 :            :     the in-code documentation of the constructor.
      15                 :            : */
      16                 :            : // *****************************************************************************
      17                 :            : 
      18                 :            : #include "DiffEqStack.hpp"
      19                 :            : #include "Tags.hpp"
      20                 :            : 
      21                 :            : #include "ConfigureDirichlet.hpp"
      22                 :            : #include "ConfigureMixDirichlet.hpp"
      23                 :            : #include "ConfigureGeneralizedDirichlet.hpp"
      24                 :            : #include "ConfigureWrightFisher.hpp"
      25                 :            : #include "ConfigureOrnsteinUhlenbeck.hpp"
      26                 :            : #include "ConfigureDiagOrnsteinUhlenbeck.hpp"
      27                 :            : #include "ConfigureBeta.hpp"
      28                 :            : #include "ConfigureNumberFractionBeta.hpp"
      29                 :            : #include "ConfigureMassFractionBeta.hpp"
      30                 :            : #include "ConfigureMixNumberFractionBeta.hpp"
      31                 :            : #include "ConfigureMixMassFractionBeta.hpp"
      32                 :            : #include "ConfigureGamma.hpp"
      33                 :            : #include "ConfigureSkewNormal.hpp"
      34                 :            : #include "ConfigureVelocity.hpp"
      35                 :            : #include "ConfigurePosition.hpp"
      36                 :            : #include "ConfigureDissipation.hpp"
      37                 :            : 
      38                 :            : using walker::DiffEqStack;
      39                 :            : 
      40         [ +  - ]:        374 : DiffEqStack::DiffEqStack() : m_factory(), m_eqTypes()
      41                 :            : // *****************************************************************************
      42                 :            : //  Constructor: register all differential equations into factory
      43                 :            : //! \details This constructor consists of several blocks, each registering a
      44                 :            : //!   potentially large number of entries in the differential equation factory,
      45                 :            : //!   m_factory, which is of type walker::DiffEqFactory, a std::map. At this
      46                 :            : //!   time, each type of differential equation can be configured to use a unique
      47                 :            : //!   _initialization policy_ and a unique _coefficients policy_. (More types
      48                 :            : //!   of policies will most likely come in the future.) The policy classes are
      49                 :            : //!   template arguments to the differential equation classes and influence
      50                 :            : //!   their behavior in a different way, abstracting away certain functions,
      51                 :            : //!   e.g., how to set initial conditions and how to update their coefficients
      52                 :            : //!   during time integration. For more information on policy-based design, see
      53                 :            : //!   http://en.wikipedia.org/wiki/Policy-based_design. This abstraction allows
      54                 :            : //!   [separation of concerns]
      55                 :            : //!   (http://en.wikipedia.org/wiki/Separation_of_concerns).
      56                 :            : //!
      57                 :            : //!   Since the functionality of the policies are orthogonal to each other,
      58                 :            : //!   i.e., they do not depend on each other or their host (the differential
      59                 :            : //!   equation class), a Cartesian product of combinations are possible,
      60                 :            : //!   depending on which policies are selected. _This constructor registers all
      61                 :            : //!   possible combinations of policies for all available differential
      62                 :            : //!   equations._ By _register_, we mean, an entry is recorded in an associative
      63                 :            : //!   container, a std::map, that associates a lightweight key of type
      64                 :            : //!   walker::ctr::DiffEqKey, consisting of only an enum for each policy type,
      65                 :            : //!   to an std::function object that holds the constructor bound to its
      66                 :            : //!   arguments corresponding to a particular differential equation + policies
      67                 :            : //!   combination. Note that registering these entries in the map does not
      68                 :            : //!   invoke the constructors. The mapped value simply stores how the
      69                 :            : //!   constructors should be invoked at a later time. At some point later,
      70                 :            : //!   based on user input, we then instantiate only the differential equations
      71                 :            : //!   (and only those configurations) that are requested by the user.
      72                 :            : //!
      73                 :            : //!   Since all differential equation types (registered in the factory)
      74                 :            : //!   "inherit" from a common "base", client-code is unform and generic, and
      75                 :            : //!   thus immune to changes in the inner workings of the particular
      76                 :            : //!   differential equations as long as they fullfill certain concepts, i.e.,
      77                 :            : //!   implement certain member functinos, enforced by the _common base_, DiffEq.
      78                 :            : //!   The words "inherit and "base" are quoted here, because the common base
      79                 :            : //!   does not use inheritance in the normal OOP sense and does not use
      80                 :            : //!   reference semantics, i.e., pointers, visible to client-code either. The
      81                 :            : //!   relationship is more of a _models a_-type, which simplifies client-code
      82                 :            : //!   and allows for the benfits of runtime inheritance with value-semantics
      83                 :            : //!   which is less error prone and easier to read. See more about the
      84                 :            : //!   _models-a_ relationship and its implementation in DiffEq/DiffEq.h.
      85                 :            : //!
      86                 :            : //!   The design discussed above allows the registration, instantiation, and
      87                 :            : //!   use of the differential equations to be generic, which eliminates a lot of
      88                 :            : //!   boiler-plate code and makes client-code uniform.
      89                 :            : //!
      90                 :            : //!   _Details of registration using brigand::for_each and
      91                 :            : //!   tk::cartesian_product:_
      92                 :            : //!
      93                 :            : //!   The template argument to brigand::for_each, as used below, requires a
      94                 :            : //!   list of list of types. We use brigand::list of brigand::list of types,
      95                 :            : //!   listing all possible policies, where the inner list must have exactly two
      96                 :            : //!   types, as the list of lists is constructed from two lists using the
      97                 :            : //!   cartesian product, and the length of the outer list (the list of lists) is
      98                 :            : //!   arbitrary. The constructor argument to brigand::for_each is a functor that
      99                 :            : //!   is to be applied to all members of the outer list. tk::cartesian_product
     100                 :            : //!   will create all possible combinations of these types and call the functor
     101                 :            : //!   with each type of the created sequence as a template parameter. The
     102                 :            : //!   functor here inherits from registerDiffEq, which, i.e., its constructor
     103                 :            : //!   call, needs a single template argument, a class templated on policy
     104                 :            : //!   classes. This is the differential equation class to be configured by
     105                 :            : //!   selecting policies and to be registered. The arguments to
     106                 :            : //!   registerDiffEq's constructor are the factory, the enum denoting the
     107                 :            : //!   differential equation type, and a reference to a variable of type
     108                 :            : //!   std::set< ctr::DiffEqType >, which is only used internally to DiffEqStack
     109                 :            : //!   for counting up the number of unique differential equation types
     110                 :            : //!   registered, used for diagnostics purposes.
     111                 :            : // *****************************************************************************
     112                 :            : {
     113         [ +  - ]:        374 :   registerDirichlet( m_factory, m_eqTypes );
     114         [ +  - ]:        374 :   registerMixDirichlet( m_factory, m_eqTypes );
     115         [ +  - ]:        374 :   registerGenDir( m_factory, m_eqTypes );
     116         [ +  - ]:        374 :   registerWrightFisher( m_factory, m_eqTypes );
     117         [ +  - ]:        374 :   registerOrnsteinUhlenbeck( m_factory, m_eqTypes );
     118         [ +  - ]:        374 :   registerDiagOrnsteinUhlenbeck( m_factory, m_eqTypes );
     119         [ +  - ]:        374 :   registerBeta( m_factory, m_eqTypes );
     120         [ +  - ]:        374 :   registerNumberFractionBeta( m_factory, m_eqTypes );
     121         [ +  - ]:        374 :   registerMassFractionBeta( m_factory, m_eqTypes );
     122         [ +  - ]:        374 :   registerMixNumberFractionBeta( m_factory, m_eqTypes );
     123         [ +  - ]:        374 :   registerMixMassFractionBeta( m_factory, m_eqTypes );
     124         [ +  - ]:        374 :   registerGamma( m_factory, m_eqTypes );
     125         [ +  - ]:        374 :   registerSkewNormal( m_factory, m_eqTypes );
     126         [ +  - ]:        374 :   registerVelocity( m_factory, m_eqTypes );
     127         [ +  - ]:        374 :   registerPosition( m_factory, m_eqTypes );
     128         [ +  - ]:        374 :   registerDissipation( m_factory, m_eqTypes );
     129                 :        374 : }
     130                 :            : 
     131                 :            : std::vector< walker::DiffEq >
     132                 :        281 : DiffEqStack::selected() const
     133                 :            : // *****************************************************************************
     134                 :            : //  Instantiate all selected differential equations
     135                 :            : //! \return std::vector of instantiated differential equation objects
     136                 :            : // *****************************************************************************
     137                 :            : {
     138                 :            :   std::map< ctr::DiffEqType, ncomp_t > cnt; // count DiffEqs per type
     139                 :            :   std::vector< DiffEq > diffeqs;            // will store instantiated DiffEqs
     140                 :            : 
     141         [ +  + ]:        598 :   for (const auto& d : g_inputdeck.get< tag::selected, tag::diffeq >()) {
     142         [ +  + ]:        317 :     if (d == ctr::DiffEqType::DIRICHLET)
     143         [ +  - ]:         66 :       diffeqs.push_back( createDiffEq< tag::dirichlet >( d, cnt ) );
     144         [ +  + ]:        284 :     else if (d == ctr::DiffEqType::MIXDIRICHLET)
     145         [ +  - ]:         64 :       diffeqs.push_back( createDiffEq< tag::mixdirichlet >( d, cnt ) );
     146         [ +  + ]:        252 :     else if (d == ctr::DiffEqType::GENDIR)
     147         [ +  - ]:         22 :       diffeqs.push_back( createDiffEq< tag::gendir >( d, cnt ) );
     148         [ -  + ]:        241 :     else if (d == ctr::DiffEqType::WRIGHTFISHER)
     149         [ -  - ]:          0 :       diffeqs.push_back( createDiffEq< tag::wrightfisher >( d, cnt ) );
     150         [ +  + ]:        241 :     else if (d == ctr::DiffEqType::OU)
     151         [ +  - ]:         68 :       diffeqs.push_back( createDiffEq< tag::ou >( d, cnt ) );
     152         [ +  + ]:        207 :     else if (d == ctr::DiffEqType::DIAG_OU)
     153         [ +  - ]:         90 :       diffeqs.push_back( createDiffEq< tag::diagou >( d, cnt ) );
     154         [ +  + ]:        162 :     else if (d == ctr::DiffEqType::BETA)
     155         [ +  - ]:         22 :       diffeqs.push_back( createDiffEq< tag::beta >( d, cnt ) );
     156         [ +  + ]:        151 :     else if (d == ctr::DiffEqType::NUMFRACBETA)
     157         [ +  - ]:         22 :       diffeqs.push_back( createDiffEq< tag::numfracbeta >( d, cnt ) );
     158         [ +  + ]:        140 :     else if (d == ctr::DiffEqType::MASSFRACBETA)
     159         [ +  - ]:         22 :       diffeqs.push_back( createDiffEq< tag::massfracbeta >( d, cnt ) );
     160         [ -  + ]:        129 :     else if (d == ctr::DiffEqType::MIXNUMFRACBETA)
     161         [ -  - ]:          0 :       diffeqs.push_back( createDiffEq< tag::mixnumfracbeta >( d, cnt ) );
     162         [ +  + ]:        129 :     else if (d == ctr::DiffEqType::MIXMASSFRACBETA)
     163         [ +  - ]:         30 :       diffeqs.push_back( createDiffEq< tag::mixmassfracbeta >( d, cnt ) );
     164         [ +  + ]:        114 :     else if (d == ctr::DiffEqType::SKEWNORMAL)
     165         [ +  - ]:         90 :       diffeqs.push_back( createDiffEq< tag::skewnormal >( d, cnt ) );
     166         [ +  + ]:         69 :     else if (d == ctr::DiffEqType::GAMMA)
     167         [ +  - ]:         22 :       diffeqs.push_back( createDiffEq< tag::gamma >( d, cnt ) );
     168         [ +  + ]:         58 :     else if (d == ctr::DiffEqType::VELOCITY)
     169         [ +  - ]:         44 :       diffeqs.push_back( createDiffEq< tag::velocity >( d, cnt ) );
     170         [ +  + ]:         36 :     else if (d == ctr::DiffEqType::POSITION)
     171         [ +  - ]:         36 :       diffeqs.push_back( createDiffEq< tag::position >( d, cnt ) );
     172         [ +  - ]:         18 :     else if (d == ctr::DiffEqType::DISSIPATION)
     173         [ +  - ]:         36 :       diffeqs.push_back( createDiffEq< tag::dissipation >( d, cnt ) );
     174 [ -  - ][ -  - ]:          0 :     else Throw( "Can't find selected DiffEq" );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     175                 :            :   }
     176                 :            : 
     177                 :        281 :   return diffeqs;
     178                 :            : }
     179                 :            : 
     180                 :            : std::pair< std::vector< std::string >, std::vector< tk::Table<1> > >
     181                 :         93 : DiffEqStack::tables() const
     182                 :            : // *****************************************************************************
     183                 :            : //  Instantiate tables from which extra statistics data to be output sampled for
     184                 :            : //  all selected differential equations
     185                 :            : //! \return Vector of names and tables to sample from during time stepping
     186                 :            : // *****************************************************************************
     187                 :            : {
     188                 :            :   std::map< ctr::DiffEqType, ncomp_t > cnt;     // count DiffEqs per type
     189                 :         93 :   std::vector< std::string > nam;               // names of instantiated tables
     190                 :         93 :   std::vector< tk::Table<1> > tab;              // instantiated tables
     191                 :            : 
     192         [ +  + ]:        198 :   for (const auto& d : g_inputdeck.get< tag::selected, tag::diffeq >()) {
     193                 :            :     std::pair< std::vector< std::string >, std::vector< tk::Table<1> > > t;
     194                 :            : 
     195         [ +  + ]:        105 :     if (d == ctr::DiffEqType::MIXMASSFRACBETA)
     196         [ +  - ]:         10 :       t = createTables< tag::mixmassfracbeta >( d, cnt );
     197         [ +  + ]:        100 :     else if (d == ctr::DiffEqType::VELOCITY)
     198         [ +  - ]:         14 :       t = createTables< tag::velocity >( d, cnt );
     199                 :            : 
     200 [ +  - ][ +  - ]:        105 :     nam.insert( end(nam), begin(t.first), end(t.first) );
     201         [ +  - ]:        105 :     tab.insert( end(tab), begin(t.second), end(t.second) );
     202                 :            :   }
     203                 :            : 
     204         [ +  - ]:        186 :   return { nam, tab };
     205                 :            : }
     206                 :            : 
     207                 :            : std::vector< std::vector< std::pair< std::string, std::string > > >
     208                 :         93 : DiffEqStack::info() const
     209                 :            : // *****************************************************************************
     210                 :            : //  Return information on all selected differential equations
     211                 :            : //! \return A vector of vector of pair of strings, containing the configuration
     212                 :            : //!   for each selected differential equation
     213                 :            : // *****************************************************************************
     214                 :            : {
     215                 :            :   std::map< ctr::DiffEqType, ncomp_t > cnt; // count DiffEqs per type
     216                 :            :   // will store info on all differential equations selected
     217                 :            :   std::vector< std::vector< std::pair< std::string, std::string > > > nfo;
     218                 :            : 
     219         [ +  + ]:        198 :   for (const auto& d : g_inputdeck.get< tag::selected, tag::diffeq >()) {
     220         [ +  + ]:        105 :     if (d == ctr::DiffEqType::DIRICHLET)
     221 [ +  - ][ +  - ]:         12 :       nfo.emplace_back( infoDirichlet( cnt ) );
     222         [ +  + ]:         93 :     else if (d == ctr::DiffEqType::MIXDIRICHLET)
     223 [ +  - ][ +  - ]:          8 :       nfo.emplace_back( infoMixDirichlet( cnt ) );
     224         [ +  + ]:         85 :     else if (d == ctr::DiffEqType::GENDIR)
     225 [ +  - ][ +  - ]:          4 :       nfo.emplace_back( infoGenDir( cnt ) );
     226         [ -  + ]:         81 :     else if (d == ctr::DiffEqType::WRIGHTFISHER)
     227 [ -  - ][ -  - ]:          0 :       nfo.emplace_back( infoWrightFisher( cnt ) );
     228         [ +  + ]:         81 :     else if (d == ctr::DiffEqType::OU)
     229 [ +  - ][ +  - ]:         11 :       nfo.emplace_back( infoOrnsteinUhlenbeck( cnt ) );
     230         [ +  + ]:         70 :     else if (d == ctr::DiffEqType::DIAG_OU)
     231 [ +  - ][ +  - ]:         15 :       nfo.emplace_back( infoDiagOrnsteinUhlenbeck( cnt ) );
     232         [ +  + ]:         55 :     else if (d == ctr::DiffEqType::BETA)
     233 [ +  - ][ +  - ]:          4 :       nfo.emplace_back( infoBeta( cnt ) );
     234         [ +  + ]:         51 :     else if (d == ctr::DiffEqType::NUMFRACBETA)
     235 [ +  - ][ +  - ]:          4 :       nfo.emplace_back( infoNumberFractionBeta( cnt ) );
     236         [ +  + ]:         47 :     else if (d == ctr::DiffEqType::MASSFRACBETA)
     237 [ +  - ][ +  - ]:          4 :       nfo.emplace_back( infoMassFractionBeta( cnt ) );
     238         [ -  + ]:         43 :     else if (d == ctr::DiffEqType::MIXNUMFRACBETA)
     239 [ -  - ][ -  - ]:          0 :       nfo.emplace_back( infoMixNumberFractionBeta( cnt ) );
     240         [ +  + ]:         43 :     else if (d == ctr::DiffEqType::MIXMASSFRACBETA)
     241 [ +  - ][ +  - ]:          5 :       nfo.emplace_back( infoMixMassFractionBeta( cnt ) );
     242         [ +  + ]:         38 :     else if (d == ctr::DiffEqType::SKEWNORMAL)
     243 [ +  - ][ +  - ]:         15 :       nfo.emplace_back( infoSkewNormal( cnt ) );
     244         [ +  + ]:         23 :     else if (d == ctr::DiffEqType::GAMMA)
     245 [ +  - ][ +  - ]:          4 :       nfo.emplace_back( infoGamma( cnt ) );
     246         [ +  + ]:         19 :     else if (d == ctr::DiffEqType::VELOCITY)
     247 [ +  - ][ +  - ]:          7 :       nfo.emplace_back( infoVelocity( cnt ) );
     248         [ +  + ]:         12 :     else if (d == ctr::DiffEqType::POSITION)
     249 [ +  - ][ +  - ]:          6 :       nfo.emplace_back( infoPosition( cnt ) );
     250         [ +  - ]:          6 :     else if (d == ctr::DiffEqType::DISSIPATION)
     251 [ +  - ][ +  - ]:          6 :       nfo.emplace_back( infoDissipation( cnt ) );
     252 [ -  - ][ -  - ]:          0 :     else Throw( "Can't find selected DiffEq" );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     253                 :            :   }
     254                 :            : 
     255                 :         93 :   return nfo;
     256                 :            : }

Generated by: LCOV version 1.14