Quinoa all test code coverage report
Current view: top level - PDE/MultiMat - MiscMultiMatFns.cpp (source / functions) Hit Total Coverage
Commit: -128-NOTFOUND Lines: 242 258 93.8 %
Date: 2024-04-22 13:39:53 Functions: 9 10 90.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 189 294 64.3 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/PDE/MultiMat/MiscMultiMatFns.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     Misc multi-material system functions
       9                 :            :   \details   This file defines functions that required for multi-material
      10                 :            :     compressible hydrodynamics.
      11                 :            : */
      12                 :            : // *****************************************************************************
      13                 :            : 
      14                 :            : #include <iostream>
      15                 :            : 
      16                 :            : #include "MiscMultiMatFns.hpp"
      17                 :            : #include "Inciter/InputDeck/InputDeck.hpp"
      18                 :            : #include "Integrate/Basis.hpp"
      19                 :            : #include "MultiMat/MultiMatIndexing.hpp"
      20                 :            : 
      21                 :            : namespace inciter {
      22                 :            : 
      23                 :            : extern ctr::InputDeck g_inputdeck;
      24                 :            : 
      25                 :        209 : void initializeMaterialEoS( std::vector< EOS >& mat_blk )
      26                 :            : // *****************************************************************************
      27                 :            : //  Initialize the material block with configured EOS
      28                 :            : //! \param[in,out] mat_blk Material block that gets initialized
      29                 :            : // *****************************************************************************
      30                 :            : {
      31                 :            :   // EoS initialization
      32                 :        209 :   auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
      33                 :        209 :   const auto& matprop = g_inputdeck.get< tag::material >();
      34                 :        209 :   const auto& matidxmap = g_inputdeck.get< tag::matidxmap >();
      35         [ +  + ]:        778 :   for (std::size_t k=0; k<nmat; ++k) {
      36                 :        569 :     auto mateos = matprop[matidxmap.get< tag::eosidx >()[k]].get<tag::eos>();
      37         [ +  - ]:        569 :     mat_blk.emplace_back(mateos, EqType::multimat, k);
      38                 :            :   }
      39                 :        209 : }
      40                 :            : 
      41                 :            : bool
      42                 :       7048 : cleanTraceMultiMat(
      43                 :            :   tk::real t,
      44                 :            :   std::size_t nelem,
      45                 :            :   const std::vector< EOS >& mat_blk,
      46                 :            :   const tk::Fields& geoElem,
      47                 :            :   std::size_t nmat,
      48                 :            :   tk::Fields& U,
      49                 :            :   tk::Fields& P )
      50                 :            : // *****************************************************************************
      51                 :            : //  Clean up the state of trace materials for multi-material PDE system
      52                 :            : //! \param[in] t Physical time
      53                 :            : //! \param[in] nelem Number of elements
      54                 :            : //! \param[in] mat_blk EOS material block
      55                 :            : //! \param[in] geoElem Element geometry array
      56                 :            : //! \param[in] nmat Number of materials in this PDE system
      57                 :            : //! \param[in/out] U High-order solution vector which gets modified
      58                 :            : //! \param[in/out] P High-order vector of primitives which gets modified
      59                 :            : //! \return Boolean indicating if an unphysical material state was found
      60                 :            : // *****************************************************************************
      61                 :            : {
      62                 :       7048 :   const auto ndof = g_inputdeck.get< tag::ndof >();
      63                 :       7048 :   const auto rdof = g_inputdeck.get< tag::rdof >();
      64                 :       7048 :   std::size_t ncomp = U.nprop()/rdof;
      65                 :       7048 :   auto al_eps = 1.0e-02;
      66                 :       7048 :   auto neg_density = false;
      67                 :            : 
      68         [ +  - ]:       7048 :   std::vector< tk::real > ugp(ncomp, 0.0);
      69                 :            : 
      70         [ +  + ]:    2575548 :   for (std::size_t e=0; e<nelem; ++e)
      71                 :            :   {
      72                 :            :     // find material in largest quantity, and determine if pressure
      73                 :            :     // relaxation is needed. If it is, determine materials that need
      74                 :            :     // relaxation, and the total volume of these materials.
      75         [ +  - ]:    5137000 :     std::vector< int > relaxInd(nmat, 0);
      76                 :    2568500 :     auto almax(0.0), relaxVol(0.0);
      77                 :    2568500 :     std::size_t kmax = 0;
      78         [ +  + ]:    8850960 :     for (std::size_t k=0; k<nmat; ++k)
      79                 :            :     {
      80         [ +  - ]:    6282460 :       auto al = U(e, volfracDofIdx(nmat, k, rdof, 0));
      81         [ +  + ]:    6282460 :       if (al > almax)
      82                 :            :       {
      83                 :    3937154 :         almax = al;
      84                 :    3937154 :         kmax = k;
      85                 :            :       }
      86         [ +  + ]:    2345306 :       else if (al < al_eps)
      87                 :            :       {
      88                 :    2316852 :         relaxInd[k] = 1;
      89                 :    2316852 :         relaxVol += al;
      90                 :            :       }
      91                 :            :     }
      92                 :    2568500 :     relaxInd[kmax] = 1;
      93                 :    2568500 :     relaxVol += almax;
      94                 :            : 
      95                 :            :     // get conserved quantities
      96         [ +  - ]:    5137000 :     std::vector< tk::real > B(rdof, 0.0);
      97                 :    2568500 :     B[0] = 1.0;
      98         [ +  - ]:    2568500 :     ugp = eval_state(ncomp, rdof, ndof, e, U, B);
      99                 :            : 
     100         [ +  - ]:    2568500 :     auto u = P(e, velocityDofIdx(nmat, 0, rdof, 0));
     101         [ +  - ]:    2568500 :     auto v = P(e, velocityDofIdx(nmat, 1, rdof, 0));
     102         [ +  - ]:    2568500 :     auto w = P(e, velocityDofIdx(nmat, 2, rdof, 0));
     103         [ +  - ]:    2568500 :     auto pmax = P(e, pressureDofIdx(nmat, kmax, rdof, 0))/almax;
     104         [ +  - ]:    2568500 :     auto gmax = getDeformGrad(nmat, kmax, ugp);
     105                 :    2568500 :     auto tmax = mat_blk[kmax].compute< EOS::temperature >(
     106 [ +  - ][ +  - ]:    2568500 :       U(e, densityDofIdx(nmat, kmax, rdof, 0)), u, v, w,
     107         [ +  - ]:    2568500 :       U(e, energyDofIdx(nmat, kmax, rdof, 0)), almax, gmax );
     108                 :            : 
     109                 :    2568500 :     tk::real p_target(0.0), d_al(0.0), d_arE(0.0);
     110                 :            :     //// get equilibrium pressure
     111                 :            :     //std::vector< tk::real > kmat(nmat, 0.0);
     112                 :            :     //tk::real ratio(0.0);
     113                 :            :     //for (std::size_t k=0; k<nmat; ++k)
     114                 :            :     //{
     115                 :            :     //  auto arhok = U(e, densityDofIdx(nmat,k,rdof,0));
     116                 :            :     //  auto alk = U(e, volfracDofIdx(nmat,k,rdof,0));
     117                 :            :     //  auto apk = P(e, pressureDofIdx(nmat,k,rdof,0)3);
     118                 :            :     //  auto ak = mat_blk[k].compute< EOS::soundspeed >(arhok, apk, alk, k);
     119                 :            :     //  kmat[k] = arhok * ak * ak;
     120                 :            : 
     121                 :            :     //  p_target += alk * apk / kmat[k];
     122                 :            :     //  ratio += alk * alk / kmat[k];
     123                 :            :     //}
     124                 :            :     //p_target /= ratio;
     125                 :            :     //p_target = std::max(p_target, 1e-14);
     126                 :    2568500 :     p_target = std::max(pmax, 1e-14);
     127                 :            : 
     128                 :            :     // 1. Correct minority materials and store volume/energy changes
     129         [ +  + ]:    8850960 :     for (std::size_t k=0; k<nmat; ++k)
     130                 :            :     {
     131         [ +  - ]:    6282460 :       auto alk = U(e, volfracDofIdx(nmat, k, rdof, 0));
     132         [ +  - ]:    6282460 :       auto pk = P(e, pressureDofIdx(nmat, k, rdof, 0)) / alk;
     133                 :            :       // for positive volume fractions
     134         [ +  + ]:    6282460 :       if (matExists(alk))
     135                 :            :       {
     136                 :            :         // check if volume fraction is lesser than threshold (al_eps) and
     137                 :            :         // if the material (effective) pressure is negative. If either of
     138                 :            :         // these conditions is true, perform pressure relaxation.
     139         [ +  + ]:    5459093 :         if ((alk < al_eps) ||
     140 [ +  + ][ +  + ]:    8081857 :           (pk < mat_blk[k].compute< EOS::min_eff_pressure >(1e-12,
     141 [ +  - ][ +  - ]:    2622764 :           U(e, densityDofIdx(nmat, k, rdof, 0)), alk))
     142                 :            :           /*&& (std::fabs((pk-pmax)/pmax) > 1e-08)*/)
     143                 :            :         {
     144                 :            :           //auto gk = gamma< tag::multimat >(0, k);
     145                 :            : 
     146                 :     213567 :           tk::real alk_new(0.0);
     147                 :            :           //// volume change based on polytropic expansion/isentropic compression
     148                 :            :           //if (pk > p_target)
     149                 :            :           //{
     150                 :            :           //  alk_new = std::pow((pk/p_target), (1.0/gk)) * alk;
     151                 :            :           //}
     152                 :            :           //else
     153                 :            :           //{
     154                 :            :           //  auto arhok = U(e, densityDofIdx(nmat, k, rdof, 0));
     155                 :            :           //  auto ck = eos_soundspeed< tag::multimat >(0, arhok, alk*pk,
     156                 :            :           //    alk, k);
     157                 :            :           //  auto kk = arhok * ck * ck;
     158                 :            :           //  alk_new = alk - (alk*alk/kk) * (p_target-pk);
     159                 :            :           //}
     160                 :     213567 :           alk_new = alk;
     161                 :            : 
     162                 :            :           // determine target relaxation pressure
     163                 :     213567 :           auto prelax = mat_blk[k].compute< EOS::min_eff_pressure >(1e-10,
     164 [ +  - ][ +  - ]:     213567 :             U(e, densityDofIdx(nmat, k, rdof, 0)), alk_new);
     165                 :     213567 :           prelax = std::max(prelax, p_target);
     166                 :            : 
     167                 :            :           // energy change
     168         [ +  - ]:     213567 :           auto rhomat = U(e, densityDofIdx(nmat, k, rdof, 0))
     169                 :     213567 :             / alk_new;
     170                 :     213567 :           std::array< std::array< tk::real, 3 >, 3 > gmat {{
     171                 :            :             {{1, 0, 0}},
     172                 :            :             {{0, 1, 0}},
     173                 :            :             {{0, 0, 1}} }};
     174         [ +  - ]:     213567 :           auto rhoEmat = mat_blk[k].compute< EOS::totalenergy >(rhomat, u, v, w,
     175                 :            :             prelax, gmat);
     176                 :            : 
     177                 :            :           // volume-fraction and total energy flux into majority material
     178                 :     213567 :           d_al += (alk - alk_new);
     179         [ +  - ]:     213567 :           d_arE += (U(e, energyDofIdx(nmat, k, rdof, 0))
     180                 :     213567 :             - alk_new * rhoEmat);
     181                 :            : 
     182                 :            :           // update state of trace material
     183         [ +  - ]:     213567 :           U(e, volfracDofIdx(nmat, k, rdof, 0)) = alk_new;
     184         [ +  - ]:     213567 :           U(e, energyDofIdx(nmat, k, rdof, 0)) = alk_new*rhoEmat;
     185         [ +  - ]:     213567 :           P(e, pressureDofIdx(nmat, k, rdof, 0)) = alk_new*prelax;
     186         [ +  - ]:     213567 :           resetSolidTensors(nmat, k, e, alk_new*prelax, U, P);
     187                 :            :         }
     188                 :            :       }
     189                 :            :       // check for unbounded volume fractions
     190 [ +  + ][ -  + ]:    3446131 :       else if (alk < 0.0 || !std::isfinite(alk))
                 [ +  + ]
     191                 :            :       {
     192         [ +  - ]:         20 :         auto rhok = mat_blk[k].compute< EOS::density >(p_target,
     193                 :         10 :           std::max(1e-8,tmax));
     194         [ +  - ]:         10 :         if (std::isfinite(alk)) d_al += (alk - 1e-14);
     195                 :            :         // update state of trace material
     196         [ +  - ]:         10 :         U(e, volfracDofIdx(nmat, k, rdof, 0)) = 1e-14;
     197         [ +  - ]:         10 :         U(e, densityDofIdx(nmat, k, rdof, 0)) = 1e-14 * rhok;
     198         [ +  - ]:         10 :         U(e, energyDofIdx(nmat, k, rdof, 0)) = 1e-14
     199         [ +  - ]:         10 :           * mat_blk[k].compute< EOS::totalenergy >(rhok, u, v, w, p_target,
     200                 :            :           gmax);
     201         [ +  - ]:         10 :         P(e, pressureDofIdx(nmat, k, rdof, 0)) = 1e-14 *
     202                 :            :           p_target;
     203         [ +  - ]:         10 :         resetSolidTensors(nmat, k, e, 1e-14*p_target, U, P);
     204         [ +  + ]:         40 :         for (std::size_t i=1; i<rdof; ++i) {
     205         [ +  - ]:         30 :           U(e, volfracDofIdx(nmat, k, rdof, i)) = 0.0;
     206         [ +  - ]:         30 :           U(e, densityDofIdx(nmat, k, rdof, i)) = 0.0;
     207         [ +  - ]:         30 :           U(e, energyDofIdx(nmat, k, rdof, i)) = 0.0;
     208         [ +  - ]:         30 :           P(e, pressureDofIdx(nmat, k, rdof, i)) = 0.0;
     209                 :            :         }
     210                 :            :       }
     211                 :            :       else {
     212                 :            :         // determine target relaxation pressure
     213                 :    3446121 :         auto prelax = mat_blk[k].compute< EOS::min_eff_pressure >(1e-10,
     214 [ +  - ][ +  - ]:    3446121 :           U(e, densityDofIdx(nmat, k, rdof, 0)), alk);
     215                 :    3446121 :         prelax = std::max(prelax, p_target);
     216         [ +  - ]:    3446121 :         auto rhok = U(e, densityDofIdx(nmat, k, rdof, 0)) / alk;
     217         [ +  - ]:    3446121 :         auto gk = getDeformGrad(nmat, k, ugp);
     218                 :            :         // update state of trace material
     219         [ +  - ]:    3446121 :         U(e, energyDofIdx(nmat, k, rdof, 0)) = alk
     220         [ +  - ]:    3446121 :           * mat_blk[k].compute< EOS::totalenergy >( rhok, u, v, w, prelax, gk );
     221         [ +  - ]:    3446121 :         P(e, pressureDofIdx(nmat, k, rdof, 0)) = alk *
     222                 :            :           prelax;
     223         [ +  - ]:    3446121 :         resetSolidTensors(nmat, k, e, alk*prelax, U, P);
     224         [ +  + ]:    6963918 :         for (std::size_t i=1; i<rdof; ++i) {
     225         [ +  - ]:    3517797 :           U(e, energyDofIdx(nmat, k, rdof, i)) = 0.0;
     226         [ +  - ]:    3517797 :           P(e, pressureDofIdx(nmat, k, rdof, i)) = 0.0;
     227                 :            :         }
     228                 :            :       }
     229                 :            :     }
     230                 :            : 
     231                 :            :     // 2. Based on volume change in majority material, compute energy change
     232                 :            :     //auto gmax = gamma< tag::multimat >(0, kmax);
     233                 :            :     //auto pmax_new = pmax * std::pow(almax/(almax+d_al), gmax);
     234                 :            :     //auto rhomax_new = U(e, densityDofIdx(nmat, kmax, rdof, 0))
     235                 :            :     //  / (almax+d_al);
     236                 :            :     //auto rhoEmax_new = eos_totalenergy< tag::multimat >(0, rhomax_new, u,
     237                 :            :     //  v, w, pmax_new, kmax);
     238                 :            :     //auto d_arEmax_new = (almax+d_al) * rhoEmax_new
     239                 :            :     //  - U(e, energyDofIdx(nmat, kmax, rdof, 0));
     240                 :            : 
     241         [ +  - ]:    2568500 :     U(e, volfracDofIdx(nmat, kmax, rdof, 0)) += d_al;
     242                 :            :     //U(e, energyDofIdx(nmat, kmax, rdof, 0)) += d_arEmax_new;
     243                 :            : 
     244                 :            :     // 2. Flux energy change into majority material
     245         [ +  - ]:    2568500 :     U(e, energyDofIdx(nmat, kmax, rdof, 0)) += d_arE;
     246         [ +  - ]:    2568500 :     P(e, pressureDofIdx(nmat, kmax, rdof, 0)) =
     247                 :    5137000 :       mat_blk[kmax].compute< EOS::pressure >(
     248 [ +  - ][ +  - ]:    2568500 :       U(e, densityDofIdx(nmat, kmax, rdof, 0)), u, v, w,
     249         [ +  - ]:    2568500 :       U(e, energyDofIdx(nmat, kmax, rdof, 0)),
     250         [ +  - ]:    2568500 :       U(e, volfracDofIdx(nmat, kmax, rdof, 0)), kmax, gmax );
     251                 :            : 
     252                 :            :     // enforce unit sum of volume fractions
     253                 :    2568500 :     auto alsum = 0.0;
     254         [ +  + ]:    8850960 :     for (std::size_t k=0; k<nmat; ++k)
     255         [ +  - ]:    6282460 :       alsum += U(e, volfracDofIdx(nmat, k, rdof, 0));
     256                 :            : 
     257         [ +  + ]:    8850960 :     for (std::size_t k=0; k<nmat; ++k) {
     258         [ +  - ]:    6282460 :       U(e, volfracDofIdx(nmat, k, rdof, 0)) /= alsum;
     259         [ +  - ]:    6282460 :       U(e, densityDofIdx(nmat, k, rdof, 0)) /= alsum;
     260         [ +  - ]:    6282460 :       U(e, energyDofIdx(nmat, k, rdof, 0)) /= alsum;
     261         [ +  - ]:    6282460 :       P(e, pressureDofIdx(nmat, k, rdof, 0)) /= alsum;
     262                 :            :     }
     263                 :            : 
     264                 :            :     //// bulk quantities
     265                 :            :     //auto rhoEb(0.0), rhob(0.0), volb(0.0);
     266                 :            :     //for (std::size_t k=0; k<nmat; ++k)
     267                 :            :     //{
     268                 :            :     //  if (relaxInd[k] > 0.0)
     269                 :            :     //  {
     270                 :            :     //    rhoEb += U(e, energyDofIdx(nmat,k,rdof,0));
     271                 :            :     //    volb += U(e, volfracDofIdx(nmat,k,rdof,0));
     272                 :            :     //    rhob += U(e, densityDofIdx(nmat,k,rdof,0));
     273                 :            :     //  }
     274                 :            :     //}
     275                 :            : 
     276                 :            :     //// 2. find mixture-pressure
     277                 :            :     //tk::real pmix(0.0), den(0.0);
     278                 :            :     //pmix = rhoEb - 0.5*rhob*(u*u+v*v+w*w);
     279                 :            :     //for (std::size_t k=0; k<nmat; ++k)
     280                 :            :     //{
     281                 :            :     //  auto gk = gamma< tag::multimat >(0, k);
     282                 :            :     //  auto Pck = pstiff< tag::multimat >(0, k);
     283                 :            : 
     284                 :            :     //  pmix -= U(e, volfracDofIdx(nmat,k,rdof,0)) * gk * Pck *
     285                 :            :     //    relaxInd[k] / (gk-1.0);
     286                 :            :     //  den += U(e, volfracDofIdx(nmat,k,rdof,0)) * relaxInd[k]
     287                 :            :     //    / (gk-1.0);
     288                 :            :     //}
     289                 :            :     //pmix /= den;
     290                 :            : 
     291                 :            :     //// 3. correct energies
     292                 :            :     //for (std::size_t k=0; k<nmat; ++k)
     293                 :            :     //{
     294                 :            :     //  if (relaxInd[k] > 0.0)
     295                 :            :     //  {
     296                 :            :     //    auto alk_new = U(e, volfracDofIdx(nmat,k,rdof,0));
     297                 :            :     //    U(e, energyDofIdx(nmat,k,rdof,0)) = alk_new *
     298                 :            :     //      eos_totalenergy< tag::multimat >(0, rhomat[k], u, v, w, pmix,
     299                 :            :     //      k);
     300                 :            :     //    P(e, pressureDofIdx(nmat, k, rdof, 0)) = alk_new * pmix;
     301                 :            :     //  }
     302                 :            :     //}
     303                 :            : 
     304         [ +  - ]:    2568500 :     pmax = P(e, pressureDofIdx(nmat, kmax, rdof, 0)) /
     305         [ +  - ]:    2568500 :       U(e, volfracDofIdx(nmat, kmax, rdof, 0));
     306                 :            : 
     307                 :            :     // check for unphysical state
     308         [ +  + ]:    8850960 :     for (std::size_t k=0; k<nmat; ++k)
     309                 :            :     {
     310         [ +  - ]:    6282460 :       auto alpha = U(e, volfracDofIdx(nmat, k, rdof, 0));
     311         [ +  - ]:    6282460 :       auto arho = U(e, densityDofIdx(nmat, k, rdof, 0));
     312         [ +  - ]:    6282460 :       auto apr = P(e, pressureDofIdx(nmat, k, rdof, 0));
     313                 :            : 
     314                 :            :       // lambda for screen outputs
     315                 :          0 :       auto screenout = [&]()
     316                 :            :       {
     317                 :          0 :         std::cout << "Physical time:     " << t << std::endl;
     318                 :          0 :         std::cout << "Element centroid:  " << geoElem(e,1) << ", "
     319                 :          0 :           << geoElem(e,2) << ", " << geoElem(e,3) << std::endl;
     320                 :          0 :         std::cout << "Material-id:       " << k << std::endl;
     321                 :          0 :         std::cout << "Volume-fraction:   " << alpha << std::endl;
     322                 :          0 :         std::cout << "Partial density:   " << arho << std::endl;
     323                 :          0 :         std::cout << "Partial pressure:  " << apr << std::endl;
     324                 :          0 :         std::cout << "Major pressure:    " << pmax << " (mat " << kmax << ")"
     325                 :          0 :           << std::endl;
     326                 :          0 :         std::cout << "Major temperature: " << tmax << " (mat " << kmax << ")"
     327                 :          0 :           << std::endl;
     328                 :          0 :         std::cout << "Velocity:          " << u << ", " << v << ", " << w
     329                 :          0 :           << std::endl;
     330                 :    6282460 :       };
     331                 :            : 
     332         [ -  + ]:    6282460 :       if (arho < 0.0)
     333                 :            :       {
     334                 :          0 :         neg_density = true;
     335         [ -  - ]:          0 :         screenout();
     336                 :            :       }
     337                 :            :     }
     338                 :            :   }
     339                 :      14096 :   return neg_density;
     340                 :            : }
     341                 :            : 
     342                 :            : tk::real
     343                 :        335 : timeStepSizeMultiMat(
     344                 :            :   const std::vector< EOS >& mat_blk,
     345                 :            :   const std::vector< int >& esuf,
     346                 :            :   const tk::Fields& geoFace,
     347                 :            :   const tk::Fields& geoElem,
     348                 :            :   const std::size_t nelem,
     349                 :            :   std::size_t nmat,
     350                 :            :   const tk::Fields& U,
     351                 :            :   const tk::Fields& P )
     352                 :            : // *****************************************************************************
     353                 :            : //  Time step restriction for multi material cell-centered schemes
     354                 :            : //! \param[in] mat_blk EOS material block
     355                 :            : //! \param[in] esuf Elements surrounding elements array
     356                 :            : //! \param[in] geoFace Face geometry array
     357                 :            : //! \param[in] geoElem Element geometry array
     358                 :            : //! \param[in] nelem Number of elements
     359                 :            : //! \param[in] nmat Number of materials in this PDE system
     360                 :            : //! \param[in] U High-order solution vector
     361                 :            : //! \param[in] P High-order vector of primitives
     362                 :            : //! \return Maximum allowable time step based on cfl criterion
     363                 :            : // *****************************************************************************
     364                 :            : {
     365                 :        335 :   const auto ndof = g_inputdeck.get< tag::ndof >();
     366                 :        335 :   const auto rdof = g_inputdeck.get< tag::rdof >();
     367                 :        335 :   std::size_t ncomp = U.nprop()/rdof;
     368                 :        335 :   std::size_t nprim = P.nprop()/rdof;
     369                 :            : 
     370                 :            :   tk::real u, v, w, a, vn, dSV_l, dSV_r;
     371         [ +  - ]:        670 :   std::vector< tk::real > delt(U.nunk(), 0.0);
     372 [ +  - ][ +  - ]:        670 :   std::vector< tk::real > ugp(ncomp, 0.0), pgp(nprim, 0.0);
     373                 :            : 
     374                 :            :   // compute maximum characteristic speed at all internal element faces
     375         [ +  + ]:     526965 :   for (std::size_t f=0; f<esuf.size()/2; ++f)
     376                 :            :   {
     377                 :     526630 :     std::size_t el = static_cast< std::size_t >(esuf[2*f]);
     378                 :     526630 :     auto er = esuf[2*f+1];
     379                 :            : 
     380                 :            :     std::array< tk::real, 3 > fn;
     381         [ +  - ]:     526630 :     fn[0] = geoFace(f,1);
     382         [ +  - ]:     526630 :     fn[1] = geoFace(f,2);
     383         [ +  - ]:     526630 :     fn[2] = geoFace(f,3);
     384                 :            : 
     385                 :            :     // left element
     386                 :            : 
     387                 :            :     // Compute the basis function for the left element
     388         [ +  - ]:     526630 :     std::vector< tk::real > B_l(rdof, 0.0);
     389                 :     526630 :     B_l[0] = 1.0;
     390                 :            : 
     391                 :            :     // get conserved quantities
     392         [ +  - ]:     526630 :     ugp = eval_state(ncomp, rdof, ndof, el, U, B_l);
     393                 :            :     // get primitive quantities
     394         [ +  - ]:     526630 :     pgp = eval_state(nprim, rdof, ndof, el, P, B_l);
     395                 :            : 
     396                 :            :     // advection velocity
     397                 :     526630 :     u = pgp[velocityIdx(nmat, 0)];
     398                 :     526630 :     v = pgp[velocityIdx(nmat, 1)];
     399                 :     526630 :     w = pgp[velocityIdx(nmat, 2)];
     400                 :            : 
     401 [ +  - ][ +  - ]:     526630 :     vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
                 [ +  - ]
     402                 :            : 
     403                 :            :     // acoustic speed
     404                 :     526630 :     a = 0.0;
     405         [ +  + ]:    1579890 :     for (std::size_t k=0; k<nmat; ++k)
     406                 :            :     {
     407         [ +  + ]:    1053260 :       if (ugp[volfracIdx(nmat, k)] > 1.0e-04) {
     408         [ +  - ]:     546463 :         auto gk = getDeformGrad(nmat, k, ugp);
     409         [ +  - ]:     546463 :         gk = tk::rotateTensor(gk, fn);
     410         [ +  - ]:    1639389 :         a = std::max( a, mat_blk[k].compute< EOS::soundspeed >(
     411                 :     546463 :           ugp[densityIdx(nmat, k)],
     412                 :    1092926 :           pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) );
     413                 :            :       }
     414                 :            :     }
     415                 :            : 
     416         [ +  - ]:     526630 :     dSV_l = geoFace(f,0) * (std::fabs(vn) + a);
     417                 :            : 
     418                 :            :     // right element
     419         [ +  + ]:     526630 :     if (er > -1) {
     420                 :     406010 :       std::size_t eR = static_cast< std::size_t >( er );
     421                 :            : 
     422                 :            :       // Compute the basis function for the right element
     423         [ +  - ]:     406010 :       std::vector< tk::real > B_r(rdof, 0.0);
     424                 :     406010 :       B_r[0] = 1.0;
     425                 :            : 
     426                 :            :       // get conserved quantities
     427         [ +  - ]:     406010 :       ugp = eval_state( ncomp, rdof, ndof, eR, U, B_r);
     428                 :            :       // get primitive quantities
     429         [ +  - ]:     406010 :       pgp = eval_state( nprim, rdof, ndof, eR, P, B_r);
     430                 :            : 
     431                 :            :       // advection velocity
     432                 :     406010 :       u = pgp[velocityIdx(nmat, 0)];
     433                 :     406010 :       v = pgp[velocityIdx(nmat, 1)];
     434                 :     406010 :       w = pgp[velocityIdx(nmat, 2)];
     435                 :            : 
     436 [ +  - ][ +  - ]:     406010 :       vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
                 [ +  - ]
     437                 :            : 
     438                 :            :       // acoustic speed
     439                 :     406010 :       a = 0.0;
     440         [ +  + ]:    1218030 :       for (std::size_t k=0; k<nmat; ++k)
     441                 :            :       {
     442         [ +  + ]:     812020 :         if (ugp[volfracIdx(nmat, k)] > 1.0e-04) {
     443         [ +  - ]:     421988 :           auto gk = getDeformGrad(nmat, k, ugp);
     444         [ +  - ]:     421988 :           gk = tk::rotateTensor(gk, fn);
     445         [ +  - ]:    1265964 :           a = std::max( a, mat_blk[k].compute< EOS::soundspeed >(
     446                 :     421988 :             ugp[densityIdx(nmat, k)],
     447                 :     843976 :             pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) );
     448                 :            :         }
     449                 :            :       }
     450                 :            : 
     451         [ +  - ]:     406010 :       dSV_r = geoFace(f,0) * (std::fabs(vn) + a);
     452                 :            : 
     453                 :     406010 :       delt[eR] += std::max( dSV_l, dSV_r );
     454                 :            :     } else {
     455                 :     120620 :       dSV_r = dSV_l;
     456                 :            :     }
     457                 :            : 
     458                 :     526630 :     delt[el] += std::max( dSV_l, dSV_r );
     459                 :            :   }
     460                 :            : 
     461                 :        335 :   tk::real mindt = std::numeric_limits< tk::real >::max();
     462                 :            : 
     463                 :            :   // compute allowable dt
     464         [ +  + ]:     229115 :   for (std::size_t e=0; e<nelem; ++e)
     465                 :            :   {
     466         [ +  - ]:     228780 :     mindt = std::min( mindt, geoElem(e,0)/delt[e] );
     467                 :            :   }
     468                 :            : 
     469                 :        670 :   return mindt;
     470                 :            : }
     471                 :            : 
     472                 :            : tk::real
     473                 :        225 : timeStepSizeMultiMatFV(
     474                 :            :   const std::vector< EOS >& mat_blk,
     475                 :            :   const tk::Fields& geoElem,
     476                 :            :   std::size_t nelem,
     477                 :            :   std::size_t nmat,
     478                 :            :   const tk::Fields& U,
     479                 :            :   const tk::Fields& P,
     480                 :            :   std::vector< tk::real >& local_dte )
     481                 :            : // *****************************************************************************
     482                 :            : //  Time step restriction for multi material cell-centered FV scheme
     483                 :            : //! \param[in] mat_blk Material EOS block
     484                 :            : //! \param[in] geoElem Element geometry array
     485                 :            : //! \param[in] nelem Number of elements
     486                 :            : //! \param[in] nmat Number of materials in this PDE system
     487                 :            : //! \param[in] U High-order solution vector
     488                 :            : //! \param[in] P High-order vector of primitives
     489                 :            : //! \param[in,out] local_dte Time step size for each element (for local
     490                 :            : //!   time stepping)
     491                 :            : //! \return Maximum allowable time step based on cfl criterion
     492                 :            : // *****************************************************************************
     493                 :            : {
     494                 :        225 :   const auto ndof = g_inputdeck.get< tag::ndof >();
     495                 :        225 :   const auto rdof = g_inputdeck.get< tag::rdof >();
     496                 :        225 :   std::size_t ncomp = U.nprop()/rdof;
     497                 :        225 :   std::size_t nprim = P.nprop()/rdof;
     498                 :            : 
     499 [ +  - ][ +  - ]:        450 :   std::vector< tk::real > ugp(ncomp, 0.0), pgp(nprim, 0.0);
     500                 :        225 :   tk::real mindt = std::numeric_limits< tk::real >::max();
     501                 :            : 
     502                 :            :   // loop over all elements
     503         [ +  + ]:      84325 :   for (std::size_t e=0; e<nelem; ++e)
     504                 :            :   {
     505                 :            :     // basis function at centroid
     506         [ +  - ]:      84100 :     std::vector< tk::real > B(rdof, 0.0);
     507                 :      84100 :     B[0] = 1.0;
     508                 :            : 
     509                 :            :     // get conserved quantities
     510         [ +  - ]:      84100 :     ugp = eval_state(ncomp, rdof, ndof, e, U, B);
     511                 :            :     // get primitive quantities
     512         [ +  - ]:      84100 :     pgp = eval_state(nprim, rdof, ndof, e, P, B);
     513                 :            : 
     514                 :            :     // magnitude of advection velocity
     515                 :      84100 :     auto u = pgp[velocityIdx(nmat, 0)];
     516                 :      84100 :     auto v = pgp[velocityIdx(nmat, 1)];
     517                 :      84100 :     auto w = pgp[velocityIdx(nmat, 2)];
     518                 :      84100 :     auto vmag = std::sqrt(tk::dot({u, v, w}, {u, v, w}));
     519                 :            : 
     520                 :            :     // acoustic speed
     521                 :      84100 :     tk::real a = 0.0;
     522         [ +  + ]:     252300 :     for (std::size_t k=0; k<nmat; ++k)
     523                 :            :     {
     524         [ +  + ]:     168200 :       if (ugp[volfracIdx(nmat, k)] > 1.0e-04) {
     525         [ +  - ]:     308808 :         a = std::max( a, mat_blk[k].compute< EOS::soundspeed >(
     526                 :     102936 :           ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
     527                 :     205872 :           ugp[volfracIdx(nmat, k)], k ) );
     528                 :            :       }
     529                 :            :     }
     530                 :            : 
     531                 :            :     // characteristic wave speed
     532                 :      84100 :     auto v_char = vmag + a;
     533                 :            : 
     534                 :            :     // characteristic length (radius of insphere)
     535 [ +  - ][ +  - ]:      84100 :     auto dx = std::min(std::cbrt(geoElem(e,0)), geoElem(e,4))
     536                 :      84100 :       /std::sqrt(24.0);
     537                 :            : 
     538                 :            :     // element dt
     539                 :      84100 :     local_dte[e] = dx/v_char;
     540                 :      84100 :     mindt = std::min(mindt, local_dte[e]);
     541                 :            :   }
     542                 :            : 
     543                 :        450 :   return mindt;
     544                 :            : }
     545                 :            : 
     546                 :            : void
     547                 :    3659698 : resetSolidTensors(
     548                 :            :   std::size_t nmat,
     549                 :            :   std::size_t k,
     550                 :            :   std::size_t e,
     551                 :            :   tk::real apr_target,
     552                 :            :   tk::Fields& U,
     553                 :            :   tk::Fields& P )
     554                 :            : // *****************************************************************************
     555                 :            : //  Reset the solid tensors
     556                 :            : //! \param[in] nmat Number of materials in this PDE system
     557                 :            : //! \param[in] k Material id whose deformation gradient is required
     558                 :            : //! \param[in] e Id of element whose solution is to be limited
     559                 :            : //! \param[in] apr_target Target partial pressure (alpha_k * p_k)
     560                 :            : //! \param[in/out] U High-order solution vector which gets modified
     561                 :            : //! \param[in/out] P High-order vector of primitives which gets modified
     562                 :            : // *****************************************************************************
     563                 :            : {
     564                 :    3659698 :   const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
     565                 :    3659698 :   const auto rdof = g_inputdeck.get< tag::rdof >();
     566                 :            : 
     567         [ +  + ]:    3659698 :   if (solidx[k] > 0) {
     568         [ +  + ]:     212256 :     for (std::size_t i=0; i<3; ++i) {
     569         [ +  + ]:     636768 :       for (std::size_t j=0; j<3; ++j) {
     570                 :            :         // deformation gradient reset
     571         [ +  + ]:     477576 :         if (i==j) U(e, deformDofIdx(nmat, solidx[k], i, j, rdof, 0)) = 1.0;
     572                 :     318384 :         else U(e, deformDofIdx(nmat, solidx[k], i, j, rdof, 0)) = 0.0;
     573                 :            : 
     574                 :            :         // Cauchy-stress reset
     575         [ +  + ]:     636768 :         if (i==j) P(e, stressDofIdx(nmat, solidx[k], stressCmp[i][j], rdof, 0))
     576                 :     318384 :           = -apr_target;
     577                 :     318384 :         else P(e, stressDofIdx(nmat, solidx[k], stressCmp[i][j], rdof, 0)) = 0.0;
     578                 :            : 
     579                 :            :         // high-order reset
     580         [ +  + ]:    1910304 :         for (std::size_t l=1; l<rdof; ++l) {
     581                 :    1432728 :           U(e, deformDofIdx(nmat, solidx[k], i, j, rdof, l)) = 0.0;
     582                 :    1432728 :           P(e, stressDofIdx(nmat, solidx[k], stressCmp[i][j], rdof, l)) = 0.0;
     583                 :            :         }
     584                 :            :       }
     585                 :            :     }
     586                 :            :   }
     587                 :    3659698 : }
     588                 :            : 
     589                 :            : std::array< std::array< tk::real, 3 >, 3 >
     590                 :   19430506 : getDeformGrad(
     591                 :            :   std::size_t nmat,
     592                 :            :   std::size_t k,
     593                 :            :   const std::vector< tk::real >& state )
     594                 :            : // *****************************************************************************
     595                 :            : //  Get the inverse deformation gradient tensor for a material at given location
     596                 :            : //! \param[in] nmat Number of materials in this PDE system
     597                 :            : //! \param[in] k Material id whose deformation gradient is required
     598                 :            : //! \param[in] state State vector at location
     599                 :            : //! \return Inverse deformation gradient tensor (g_k) of material k
     600                 :            : // *****************************************************************************
     601                 :            : {
     602                 :   19430506 :   const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
     603                 :            :   std::array< std::array< tk::real, 3 >, 3 > gk;
     604                 :            : 
     605         [ +  + ]:   19430506 :   if (solidx[k] > 0) {
     606                 :            :     // deformation gradient for solids
     607         [ +  + ]:    4872120 :     for (std::size_t i=0; i<3; ++i) {
     608         [ +  + ]:   14616360 :       for (std::size_t j=0; j<3; ++j)
     609                 :   10962270 :         gk[i][j] = state[deformIdx(nmat,solidx[k],i,j)];
     610                 :            :     }
     611                 :            :   }
     612                 :            :   else {
     613                 :            :     // empty vector for fluids
     614                 :   18212476 :     gk = {{}};
     615                 :            :   }
     616                 :            : 
     617                 :   19430506 :   return gk;
     618                 :            : }
     619                 :            : 
     620                 :            : std::array< std::array< tk::real, 3 >, 3 >
     621                 :     675360 : getCauchyStress(
     622                 :            :   std::size_t nmat,
     623                 :            :   std::size_t k,
     624                 :            :   std::size_t ncomp,
     625                 :            :   const std::vector< tk::real >& state )
     626                 :            : // *****************************************************************************
     627                 :            : //  Get the elastic Cauchy stress tensor for a material at given location
     628                 :            : //! \param[in] nmat Number of materials in this PDE system
     629                 :            : //! \param[in] k Material id whose deformation gradient is required
     630                 :            : //! \param[in] ncomp Number of components in the PDE system
     631                 :            : //! \param[in] state State vector at location
     632                 :            : //! \return Elastic Cauchy stress tensor (alpha * \sigma_ij) of material k
     633                 :            : // *****************************************************************************
     634                 :            : {
     635                 :     675360 :   const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
     636                 :            :   std::array< std::array< tk::real, 3 >, 3 >
     637                 :     675360 :     asigk{{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }};
     638                 :            : 
     639                 :            :   // elastic Cauchy stress for solids
     640         [ +  + ]:     675360 :   if (solidx[k] > 0) {
     641         [ +  + ]:    1843200 :     for (std::size_t i=0; i<3; ++i) {
     642         [ +  + ]:    5529600 :       for (std::size_t j=0; j<3; ++j)
     643                 :    4147200 :         asigk[i][j] = state[ncomp +
     644                 :    4147200 :           stressIdx(nmat, solidx[k], stressCmp[i][j])];
     645                 :            :     }
     646                 :            :   }
     647                 :            : 
     648                 :     675360 :   return asigk;
     649                 :            : }
     650                 :            : 
     651                 :            : bool
     652                 :    7374171 : haveSolid(
     653                 :            :   std::size_t nmat,
     654                 :            :   const std::vector< std::size_t >& solidx )
     655                 :            : // *****************************************************************************
     656                 :            : //  Check whether we have solid materials in our problem
     657                 :            : //! \param[in] nmat Number of materials in this PDE system
     658                 :            : //! \param[in] solidx Material index indicator
     659                 :            : //! \return true if we have at least one solid, false otherwise.
     660                 :            : // *****************************************************************************
     661                 :            : {
     662                 :    7374171 :   bool haveSolid = false;
     663         [ +  + ]:   22122528 :   for (std::size_t k=0; k<nmat; ++k)
     664         [ +  + ]:   14748357 :     if (solidx[k] > 0) haveSolid = true;
     665                 :            : 
     666                 :    7374171 :   return haveSolid;
     667                 :            : }
     668                 :            : 
     669                 :    2098350 : std::size_t numSolids(
     670                 :            :   std::size_t nmat,
     671                 :            :   const std::vector< std::size_t >& solidx )
     672                 :            : // *****************************************************************************
     673                 :            : //  Count total number of solid materials in the problem
     674                 :            : //! \param[in] nmat Number of materials in this PDE system
     675                 :            : //! \param[in] solidx Material index indicator
     676                 :            : //! \return Total number of solid materials in the problem
     677                 :            : // *****************************************************************************
     678                 :            : {
     679                 :            :   // count number of solid materials
     680                 :    2098350 :   std::size_t nsld(0);
     681         [ +  + ]:    6967200 :   for (std::size_t k=0; k<nmat; ++k)
     682         [ +  + ]:    4868850 :     if (solidx[k] > 0) ++nsld;
     683                 :            : 
     684                 :    2098350 :   return nsld;
     685                 :            : }
     686                 :            : 
     687                 :            : } //inciter::

Generated by: LCOV version 1.14