Quinoa all test code coverage report
Current view: top level - Inciter - NodeBC.cpp (source / functions) Hit Total Coverage
Commit: -128-NOTFOUND Lines: 17 17 100.0 %
Date: 2024-11-08 10:37:44 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 15 22 68.2 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Inciter/NodeBC.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     Boundary conditions for nodal discretizations
       9                 :            :   \details   Boundary conditions for nodal discretizations, such as continuous
      10                 :            :     Galerkin finite elements.
      11                 :            : */
      12                 :            : // *****************************************************************************
      13                 :            : 
      14                 :            : #include <vector>
      15                 :            : #include <map>
      16                 :            : #include <unordered_map>
      17                 :            : #include <algorithm>
      18                 :            : 
      19                 :            : #include "NodeBC.hpp"
      20                 :            : #include "CGPDE.hpp"
      21                 :            : #include "Fields.hpp"
      22                 :            : #include "Vector.hpp"
      23                 :            : 
      24                 :            : namespace inciter {
      25                 :            : 
      26                 :            : extern std::vector< CGPDE > g_cgpde;
      27                 :            : 
      28                 :            : std::unordered_map< std::size_t, std::vector< std::pair< bool, tk::real > > >
      29                 :      45114 : match( std::size_t meshid,
      30                 :            :        [[maybe_unused]] tk::ncomp_t ncomp,
      31                 :            :        tk::real t,
      32                 :            :        tk::real dt,
      33                 :            :        const std::vector< tk::real >& tp,
      34                 :            :        const std::vector< tk::real >& dtp,
      35                 :            :        const tk::UnsMesh::Coords& coord,
      36                 :            :        const std::unordered_map< std::size_t, std::size_t >& lid,
      37                 :            :        const std::map< int, std::vector< std::size_t > >& bnode,
      38                 :            :        bool increment )
      39                 :            : // *****************************************************************************
      40                 :            : //  Match user-specified boundary conditions at nodes for side sets
      41                 :            : //! \param[in] ncomp Number of scalar components in PDE system
      42                 :            : //! \param[in] t Physical time at which to query boundary conditions
      43                 :            : //! \param[in] dt Time step size (for querying BC increments in time)
      44                 :            : //! \param[in] tp Physical time for each mesh node
      45                 :            : //! \param[in] dtp Time step size for each mesh node
      46                 :            : //! \param[in] coord Mesh node coordinates
      47                 :            : //! \param[in] lid Local node IDs associated to local node IDs
      48                 :            : //! \param[in] bnode Map storing global mesh node IDs mapped to side set ids
      49                 :            : //! \param[in] increment If true, evaluate the solution increment between
      50                 :            : //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
      51                 :            : //! \return Vector of pairs of bool and boundary condition value associated to
      52                 :            : //!   local mesh node IDs at which the user has set Dirichlet boundary
      53                 :            : //!   conditions for all systems of PDEs integrated. The bool indicates whether
      54                 :            : //!   the BC is set at the node for that component: if true, the real value is
      55                 :            : //!   the increment (from t to dt) in (or the value of) the BC specified for a
      56                 :            : //!   component.
      57                 :            : //! \details Boundary conditions (BC), mathematically speaking, are applied on
      58                 :            : //!   finite surfaces. These finite surfaces are given by element sets (i.e., a
      59                 :            : //!   list of elements). This function queries Dirichlet boundary condition
      60                 :            : //!   values from all PDEs in the multiple systems of PDEs integrated at the
      61                 :            : //!   node lists associated to side set IDs, given by bnode. Each
      62                 :            : //!   PDE system returns a BC data structure. Note that the BC mesh nodes that
      63                 :            : //!   this function results in (stored in dirbc) only contains those nodes that
      64                 :            : //!   are supplied via bnode. i.e., in parallel only a part of the mesh is
      65                 :            : //!   worked on.
      66                 :            : // *****************************************************************************
      67                 :            : {
      68                 :            :   using inciter::g_cgpde;
      69                 :            : 
      70                 :            :   // Vector of pairs of bool and boundary condition value associated to mesh
      71                 :            :   // node IDs at which the user has set Dirichlet BCs for all PDEs integrated.
      72                 :            :   std::unordered_map< std::size_t,
      73                 :            :     std::vector< std::pair< bool, tk::real > > > dirbc;
      74                 :            : 
      75                 :            :   // Details for the algorithm below: PDE::dirbc() returns a new map that
      76                 :            :   // associates a vector of pairs associated to local node IDs. (The pair is a
      77                 :            :   // pair of bool and real value, the former is the fact that the BC is to be
      78                 :            :   // set while the latter is the value if it is to be set). The length of this
      79                 :            :   // NodeBC vector, returning from each system of PDEs equals to the number of
      80                 :            :   // scalar components the given PDE integrates. Here we contatenate this map
      81                 :            :   // for all PDEs being integrated. If there are multiple BCs set at a mesh node
      82                 :            :   // (dirbc::key), either because (1) in the same PDE system the user prescribed
      83                 :            :   // BCs on side sets that share nodes or (2) because more than a single PDE
      84                 :            :   // system assigns BCs to a given node (on different variables), the NodeBC
      85                 :            :   // vector must be correctly stored. "Correctly" here means that the size of
      86                 :            :   // the NodeBC vectors must all be the same and equal to the sum of all scalar
      87                 :            :   // components integrated by all PDE systems integrated. Example: single-phase
      88                 :            :   // compressible flow (density, momentum, energy = 5) + transported scalars of
      89                 :            :   // 10 variables -> NodeBC vector length = 15. Note that in case (1) above a
      90                 :            :   // new node encountered must "overwrite" the already existing space for the
      91                 :            :   // NodeBC vector. "Overwrite" here means that it should keep the existing BCs
      92                 :            :   // and add the new ones yielding the union the two prescription for BCs but in
      93                 :            :   // the same space that already exist in the NodeBC vector. In case (2),
      94                 :            :   // however, the NodeBC pairs must go to the location in the vector assigned to
      95                 :            :   // the given PDE system, i.e., using the above example BCs for the 10 (or
      96                 :            :   // less) scalars should go in the positions starting at 5, leaving the first 5
      97                 :            :   // false, indicating no BCs for the flow variables.
      98                 :            :   //
      99                 :            :   // Note that the logic described above is only partially implemented at this
     100                 :            :   // point. What works is the correct insertion of multiple BCs for nodes shared
     101                 :            :   // among multiple side sets, e.g., corners, originating from the same PDE
     102                 :            :   // system. What is not yet implemented is the case when there are no BCs set
     103                 :            :   // for flow variables but there are BCs for transport, the else branch below
     104                 :            :   // will incorrectly NOT skip the space for the flow variables. In other words,
     105                 :            :   // this only works for a single PDE system and a sytem of systems. This
     106                 :            :   // machinery is only tested with a single system of PDEs at this point.
     107                 :            :   //
     108                 :            :   // When a particular node belongs to two or more side sets with different BCs,
     109                 :            :   // there is an ambiguity as to which of the multiple BCs should be applied to
     110                 :            :   // the node. This issue is described in case (1) above. In the current
     111                 :            :   // implementation, every side set applies the BC to the common node in
     112                 :            :   // question, successively overwriting the BC applied by the previous side set.
     113                 :            :   // Effectively, the BC corresponding to the last side set ID is applied to the
     114                 :            :   // common node. Since bnode is an ordered map, the side set with a larger
     115                 :            :   // id wins if a node belongs to multiple side sets.
     116                 :            : 
     117                 :            :   // Lambda to convert global to local node ids of a list of nodes
     118                 :    8981959 :   auto local = [ &lid ]( const std::vector< std::size_t >& gnodes ){
     119                 :      73684 :     std::vector< std::size_t > lnodes( gnodes.size() );
     120         [ +  + ]:    9055643 :     for (std::size_t i=0; i<gnodes.size(); ++i)
     121                 :    8981959 :       lnodes[i] = tk::cref_find( lid, gnodes[i] );
     122                 :      73684 :     return lnodes;
     123                 :      45114 :   };
     124                 :            : 
     125                 :            :   // Query Dirichlet BCs for all PDEs integrated and assign to nodes
     126         [ +  + ]:     118798 :   for (const auto& s : bnode) {     // for all side sets passed in
     127                 :            :     std::size_t c = 0;
     128         [ +  - ]:      73684 :     auto l = local(s.second);   // generate local node ids on side set
     129                 :            :     // query Dirichlet BCs at nodes of this side set
     130                 :            :     auto eqbc =
     131 [ +  - ][ -  - ]:     147368 :       g_cgpde[meshid].dirbc( t, dt, tp, dtp, {s.first,l}, coord, increment );
     132         [ +  + ]:     856881 :     for (const auto& n : eqbc) {
     133         [ +  - ]:     783197 :       auto id = n.first;                      // BC node ID
     134                 :            :       const auto& bcs = n.second;             // BCs
     135                 :            :       auto& nodebc = dirbc[ id ];     // BCs to be set for node
     136         [ +  + ]:     783197 :       if (nodebc.size() > c) {        // node already has BCs from this PDE
     137                 :            :         Assert( nodebc.size() == c+bcs.size(), "Size mismatch" );
     138         [ +  + ]:     923016 :         for (std::size_t i=0; i<bcs.size(); i++) {
     139         [ +  - ]:     769180 :           if (bcs[i].first) nodebc[c+i] = bcs[i];
     140                 :            :         }
     141                 :            :       } else {        // node does not yet have BCs from this PDE
     142                 :            :         // This branch needs to be completed for system of systems of PDEs.
     143                 :            :         // See note above.
     144         [ +  - ]:     629361 :         nodebc.insert( end(nodebc), begin(bcs), end(bcs) );
     145                 :            :       }
     146                 :            :     }
     147                 :            :     if (!eqbc.empty()) c += eqbc.cbegin()->second.size();
     148                 :            :   }
     149                 :            : 
     150                 :            :   // Verify the size of each NodeBC vectors. They must have the same lengths and
     151                 :            :   // equal to the total number of scalar components for all systems of PDEs
     152                 :            :   // integrated.
     153                 :            :   Assert( std::all_of( begin(dirbc), end(dirbc),
     154                 :            :             [ ncomp ]( const auto& n ){ return n.second.size() == ncomp; } ),
     155                 :            :           "Size of NodeBC vector incorrect" );
     156                 :            :  
     157                 :      45114 :   return dirbc;
     158                 :            : }
     159                 :            : 
     160                 :            : } // inciter::

Generated by: LCOV version 1.14