Xyst test code coverage report
Current view: top level - Physics - BC.cpp (source / functions) Hit Total Coverage
Commit: 5689ba12dc66a776d3d75f1ee48cc7d78eaa18dc Lines: 95 101 94.1 %
Date: 2024-11-22 19:17:03 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 59 138 42.8 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Physics/BC.cpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.,
       7                 :            :              2022-2024 J. Bakosi
       8                 :            :              All rights reserved. See the LICENSE file for details.
       9                 :            :   \brief     Boundary conditions
      10                 :            : */
      11                 :            : // *****************************************************************************
      12                 :            : 
      13                 :            : #include "BC.hpp"
      14                 :            : #include "EOS.hpp"
      15                 :            : #include "Box.hpp"
      16                 :            : #include "Problems.hpp"
      17                 :            : #include "InciterConfig.hpp"
      18                 :            : 
      19                 :            : namespace inciter {
      20                 :            : 
      21                 :            : extern ctr::Config g_cfg;
      22                 :            : 
      23                 :            : } // ::inciter
      24                 :            : 
      25                 :            : namespace physics {
      26                 :            : 
      27                 :            : using inciter::g_cfg;
      28                 :            : 
      29                 :            : void
      30                 :      77800 : dirbc( tk::Fields& U,
      31                 :            :        tk::real t,
      32                 :            :        const std::array< std::vector< tk::real >, 3 >& coord,
      33                 :            :        const std::vector< std::unordered_set< std::size_t > >& boxnodes,
      34                 :            :        const std::vector< std::size_t >& dirbcmask,
      35                 :            :        const std::vector< double >& dirbcval )
      36                 :            : // *****************************************************************************
      37                 :            : //  Set Dirichlet boundary conditions at nodes
      38                 :            : //! \param[in] t Physical time at which to evaluate BCs
      39                 :            : //! \param[in] U Solution vector at recent time step
      40                 :            : //! \param[in] coord Mesh node coordinates
      41                 :            : //! \param[in] boxnodes List of nodes at which box user ICs are set
      42                 :            : //! \param[in] dirbcmask Nodes and component masks for Dirichlet BCs
      43                 :            : //! \param[in] dirbcval Nodes and component values for Dirichlet BCs
      44                 :            : // *****************************************************************************
      45                 :            : {
      46         [ +  + ]:      77800 :   if (g_cfg.get< tag::bc_dir >().empty()) return;
      47                 :            : 
      48                 :      34650 :   auto ncomp = U.nprop();
      49                 :      34650 :   auto nmask = ncomp + 1;
      50                 :            : 
      51 [ -  + ][ -  - ]:      34650 :   Assert( dirbcmask.size() % nmask == 0, "Size mismatch" );
         [ -  - ][ -  - ]
      52 [ -  + ][ -  - ]:      34650 :   Assert( dirbcval.size() % nmask == 0, "Size mismatch" );
         [ -  - ][ -  - ]
      53                 :            : 
      54                 :      34650 :   const auto& x = coord[0];
      55                 :      34650 :   const auto& y = coord[1];
      56                 :      34650 :   const auto& z = coord[2];
      57         [ +  - ]:      34650 :   auto ic = problems::IC();
      58                 :            : 
      59         [ +  + ]:    2897896 :   for (std::size_t i=0; i<dirbcmask.size()/nmask; ++i) {
      60                 :    2863246 :     auto p = dirbcmask[i*nmask+0];      // local node id
      61         [ +  - ]:    2863246 :     auto u = ic( x[p], y[p], z[p], t ); // evaluate solution/ic
      62         [ +  - ]:    2863246 :     problems::box( p, u, boxnodes );    // overwrite with box value
      63         [ +  + ]:   16095294 :     for (std::size_t c=0; c<ncomp; ++c) {
      64                 :   13232048 :       auto mask = dirbcmask[i*nmask+1+c];
      65         [ +  + ]:   13232048 :       if (mask == 1) {                              // mask == 1: IC+box value
      66         [ +  - ]:   10970411 :         U(p,c) = u[c];
      67 [ +  + ][ +  - ]:    2261637 :       } else if (mask == 2 && !dirbcval.empty()) {  // mask == 2: BC value
                 [ +  + ]
      68         [ +  - ]:      27114 :         U(p,c) = dirbcval[i*nmask+1+c];
      69                 :            :       }
      70                 :            :     }
      71                 :    2863246 :   }
      72                 :      34650 : }
      73                 :            : 
      74                 :            : void
      75                 :       4660 : dirbcp( tk::Fields& U,
      76                 :            :         const std::array< std::vector< tk::real >, 3 >& coord,
      77                 :            :         const std::vector< std::size_t >& dirbcmaskp,
      78                 :            :         const std::vector< double >& dirbcvalp )
      79                 :            : // *****************************************************************************
      80                 :            : //  Set pressure Dirichlet boundary conditions at nodes
      81                 :            : //! \param[in] U Solution vector at recent time step
      82                 :            : //! \param[in] coord Mesh node coordinates
      83                 :            : //! \param[in] dirbcmaskp Nodes and component masks for Dirichlet BCs
      84                 :            : //! \param[in] dirbcvalp Nodes and component values for Dirichlet BCs
      85                 :            : // *****************************************************************************
      86                 :            : {
      87         [ +  + ]:       4660 :   if (g_cfg.get< tag::pre_bc_dir >().empty()) return;
      88                 :            : 
      89                 :       1520 :   std::size_t nmask = 1 + 1;
      90                 :            : 
      91 [ -  + ][ -  - ]:       1520 :   Assert( dirbcmaskp.size() % nmask == 0, "Size mismatch" );
         [ -  - ][ -  - ]
      92 [ -  + ][ -  - ]:       1520 :   Assert( dirbcvalp.size() % nmask == 0, "Size mismatch" );
         [ -  - ][ -  - ]
      93                 :            : 
      94                 :       1520 :   const auto& x = coord[0];
      95                 :       1520 :   const auto& y = coord[1];
      96                 :       1520 :   const auto& z = coord[2];
      97         [ +  - ]:       1520 :   auto ic = problems::PRESSURE_IC();
      98                 :            : 
      99         [ +  + ]:      10640 :   for (std::size_t i=0; i<dirbcmaskp.size()/nmask; ++i) {
     100                 :       9120 :     auto p = dirbcmaskp[i*nmask+0];      // local node id
     101                 :       9120 :     auto mask = dirbcmaskp[i*nmask+1];
     102         [ -  + ]:       9120 :     if (mask == 1) {                               // mask == 1: IC value
     103 [ -  - ][ -  - ]:          0 :       U(p,0) = ic( x[p], y[p], z[p] );
     104 [ +  - ][ +  - ]:       9120 :     } else if (mask == 2 && !dirbcvalp.empty()) {  // mask == 2: BC value
                 [ +  - ]
     105         [ +  - ]:       9120 :       U(p,0) = dirbcvalp[i*nmask+1];
     106                 :            :     }
     107                 :            :   }
     108                 :       1520 : }
     109                 :            : 
     110                 :            : void
     111                 :      78458 : symbc( tk::Fields& U,
     112                 :            :        const std::vector< std::size_t >& symbcnodes,
     113                 :            :        const std::vector< tk::real >& symbcnorms,
     114                 :            :        std::size_t pos )
     115                 :            : // *****************************************************************************
     116                 :            : //  Set symmetry boundary conditions at nodes
     117                 :            : //! \param[in] U Solution vector at recent time step
     118                 :            : //! \param[in] symbcnodes Node ids at which to set symmetry BCs
     119                 :            : //! \param[in] symbcnorms Normals at nodes at which to set symmetry BCs
     120                 :            : //! \param[in] pos Position at which the three velocity components are in U
     121                 :            : // *****************************************************************************
     122                 :            : {
     123         [ +  + ]:      78458 :   if (g_cfg.get< tag::bc_sym >().empty()) return;
     124                 :            : 
     125 [ -  + ][ -  - ]:      44357 :   Assert( symbcnodes.size()*3 == symbcnorms.size(), "Size mismatch" );
         [ -  - ][ -  - ]
     126                 :            : 
     127         [ +  + ]:    2383980 :   for (std::size_t i=0; i<symbcnodes.size(); ++i) {
     128                 :    2339623 :     auto p = symbcnodes[i];
     129                 :    2339623 :     auto n = symbcnorms.data() + i*3;
     130                 :    2339623 :     auto& u = U(p,pos+0);
     131                 :    2339623 :     auto& v = U(p,pos+1);
     132                 :    2339623 :     auto& w = U(p,pos+2);
     133                 :    2339623 :     auto vn = u*n[0] + v*n[1] + w*n[2];
     134                 :    2339623 :     u -= vn * n[0];
     135                 :    2339623 :     v -= vn * n[1];
     136                 :    2339623 :     w -= vn * n[2];
     137                 :            :   }
     138                 :            : }
     139                 :            : 
     140                 :            : void
     141                 :      13420 : noslipbc( tk::Fields& U,
     142                 :            :           const std::vector< std::size_t >& noslipbcnodes,
     143                 :            :           std::size_t pos )
     144                 :            : // *****************************************************************************
     145                 :            : //  Set noslip boundary conditions at nodes
     146                 :            : //! \param[in] U Solution vector at recent time step
     147                 :            : //! \param[in] noslipbcnodes Node ids at which to set noslip BCs
     148                 :            : //! \param[in] pos Position at which the three velocity components are in U
     149                 :            : // *****************************************************************************
     150                 :            : {
     151         [ +  + ]:      13420 :   if (g_cfg.get< tag::bc_noslip >().empty()) return;
     152                 :            : 
     153 [ +  - ][ +  - ]:     426322 :   for (auto p : noslipbcnodes) U(p,pos+0) = U(p,pos+1) = U(p,pos+2) = 0.0;
         [ +  - ][ +  + ]
     154                 :            : }
     155                 :            : 
     156                 :            : void
     157                 :      64380 : farbc( tk::Fields& U,
     158                 :            :        const std::vector< std::size_t >& farbcnodes,
     159                 :            :        const std::vector< tk::real >& farbcnorms )
     160                 :            : // *****************************************************************************
     161                 :            : //  Set farfield boundary conditions at nodes
     162                 :            : //! \param[in] U Solution vector at recent time step
     163                 :            : //! \param[in] farbcnodes Nodes ids at which to set farfield BCs
     164                 :            : //! \param[in] farbcnorms Normals at nodes at which to set farfield BCs
     165                 :            : // *****************************************************************************
     166                 :            : {
     167         [ +  + ]:      64380 :   if (g_cfg.get< tag::bc_far >().empty()) return;
     168                 :            : 
     169 [ -  + ][ -  - ]:       2270 :   Assert( farbcnodes.size()*3 == farbcnorms.size(), "Size mismatch" );
         [ -  - ][ -  - ]
     170                 :            : 
     171                 :            :   // cppcheck-suppress unreadVariable
     172                 :       2270 :   tk::real fr = g_cfg.get< tag::bc_far_density >();
     173                 :            : 
     174                 :       2270 :   const auto& fue = g_cfg.get< tag::bc_far_velocity >();
     175 [ -  + ][ -  - ]:       2270 :   ErrChk( !fue.empty(), "No farfield velocity specified" );
         [ -  - ][ -  - ]
     176                 :            :   // cppcheck-suppress unreadVariable
     177                 :       2270 :   tk::real fu = fue[0];
     178                 :            :   // cppcheck-suppress unreadVariable
     179                 :       2270 :   tk::real fv = fue[1];
     180                 :            :   // cppcheck-suppress unreadVariable
     181                 :       2270 :   tk::real fw = fue[2];
     182                 :            : 
     183                 :       2270 :   tk::real fp = g_cfg.get< tag::bc_far_pressure >();
     184                 :            : 
     185         [ +  + ]:      45889 :   for (std::size_t i=0; i<farbcnodes.size(); ++i) {
     186                 :      43619 :     auto p  = farbcnodes[i];
     187                 :      43619 :     auto nx = farbcnorms[i*3+0];
     188                 :      43619 :     auto ny = farbcnorms[i*3+1];
     189                 :      43619 :     auto nz = farbcnorms[i*3+2];
     190                 :      43619 :     auto& r  = U(p,0);
     191                 :      43619 :     auto& ru = U(p,1);
     192                 :      43619 :     auto& rv = U(p,2);
     193                 :      43619 :     auto& rw = U(p,3);
     194                 :      43619 :     auto& re = U(p,4);
     195                 :            :     //auto vn = (ru*nx + rv*ny + rw*nz)/r;
     196                 :      43619 :     auto vn = fu*nx + fv*ny + fw*nz;
     197                 :            :     //auto a = eos::soundspeed( r,
     198                 :            :     //           eos::pressure( re - 0.5*(ru*ru + rv*rv + rw*rw)/r ) );
     199                 :      43619 :     auto a = eos::soundspeed( fr, fp );
     200                 :      43619 :     auto M = vn / a;
     201         [ -  + ]:      43619 :     if (M <= -1.0) {
     202                 :            :       // supersonic inflow, all characteristics from outside
     203                 :          0 :       r  = fr;
     204                 :          0 :       ru = fr * fu;
     205                 :          0 :       rv = fr * fv;
     206                 :          0 :       rw = fr * fw;
     207                 :          0 :       re = eos::totalenergy( fr, fu, fv, fw, fp );
     208 [ +  - ][ +  + ]:      43619 :     } else if (M > -1.0 && M < 0.0) {
     209                 :            :       // subsonic inflow: 1 outgoing and 4 incoming characteristics,
     210                 :            :       // pressure from inside, rest from outside
     211                 :      21799 :       auto pr = eos::pressure( re - 0.5*(ru*ru + rv*rv + rw*rw)/r );
     212                 :      21799 :       r  = fr;
     213                 :      21799 :       ru = fr * fu;
     214                 :      21799 :       rv = fr * fv;
     215                 :      21799 :       rw = fr * fw;
     216                 :      21799 :       re = eos::totalenergy( fr, fu, fv, fw, pr );
     217 [ +  - ][ +  - ]:      43619 :     } else if (M >= 0.0 && M < 1.0) {
     218                 :            :       // subsonic outflow: 1 incoming and 4 outgoing characteristics,
     219                 :            :       // pressure from outside, rest from inside
     220                 :      21820 :       re = eos::totalenergy( r, ru/r, rv/r, rw/r, fp );
     221                 :            :     }
     222                 :            :   }
     223                 :            : }
     224                 :            : 
     225                 :            : void
     226                 :      64380 : prebc( tk::Fields& U,
     227                 :            :        const std::vector< std::size_t >& prebcnodes,
     228                 :            :        const std::vector< tk::real >& prebcvals )
     229                 :            : // *****************************************************************************
     230                 :            : //  Set pressure boundary conditions at nodes
     231                 :            : //! \param[in] U Solution vector at recent time step
     232                 :            : //! \param[in] prebcnodes Node ids at which to set pressure BCs
     233                 :            : //! \param[in] prebcvals Density and pressure values at pressure BC nodes
     234                 :            : // *****************************************************************************
     235                 :            : {
     236 [ -  + ][ -  - ]:      64380 :   Assert( prebcnodes.size()*2 == prebcvals.size(), "Size mismatch" );
         [ -  - ][ -  - ]
     237                 :            : 
     238         [ +  + ]:      74714 :   for (std::size_t i=0; i<prebcnodes.size(); ++i) {
     239                 :      10334 :     auto p = prebcnodes[i];
     240                 :      10334 :     U(p,0) = prebcvals[i*2+0];
     241                 :      10334 :     U(p,4) = eos::totalenergy( U(p,0), U(p,1)/U(p,0), U(p,2)/U(p,0),
     242                 :      10334 :                                U(p,3)/U(p,0), prebcvals[i*2+1] );
     243                 :            :   }
     244                 :      64380 : }
     245                 :            : 
     246                 :            : } // physics::

Generated by: LCOV version 1.16