Branch data Line data Source code
1 : : // ***************************************************************************** 2 : : /*! 3 : : \file src/Physics/Box.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 Initial conditions box related functionality 10 : : */ 11 : : // ***************************************************************************** 12 : : 13 : : #include "Box.hpp" 14 : : #include "EOS.hpp" 15 : : #include "InciterConfig.hpp" 16 : : 17 : : namespace inciter { 18 : : 19 : : extern ctr::Config g_cfg; 20 : : 21 : : } // ::inciter 22 : : 23 : : namespace problems { 24 : : 25 : : using inciter::g_cfg; 26 : : 27 : : std::vector< std::unordered_set< std::size_t > > 28 [ + + ]: 2459 : boxnodes( const std::array< std::vector< tk::real >, 3 >& coord ) 29 : : // ***************************************************************************** 30 : : // Determine nodes that lie inside user-defined IC box(es) 31 : : //! \param[in] coord Mesh node coordinates 32 : : //! \return inbox List of nodes at which box user ICs are set for each IC box 33 : : // ***************************************************************************** 34 : : { 35 : : const auto& icbox = g_cfg.get< tag::ic >(); 36 : : 37 [ + + ]: 2459 : if (icbox.empty()) return {}; 38 : : 39 : : std::vector< std::unordered_set< std::size_t > > inbox; 40 : : 41 : : const auto& x = coord[0]; 42 : : const auto& y = coord[1]; 43 : : const auto& z = coord[2]; 44 : : 45 : : std::size_t bcnt = 0; 46 [ + + ]: 9 : for (const auto& b : icbox) { 47 [ + - ]: 6 : inbox.emplace_back(); 48 : : const auto& bx = b.get< tag::x >(); 49 : : const auto& by = b.get< tag::y >(); 50 : : const auto& bz = b.get< tag::z >(); 51 [ + - ][ + - ]: 6 : std::vector< tk::real > box{ bx[0], bx[1], by[0], by[1], bz[0], bz[1] }; 52 : : 53 : : const auto eps = std::numeric_limits< tk::real >::epsilon(); 54 : : // Determine which nodes lie in the IC box 55 [ + - ]: 6 : if ( std::any_of( begin(box), end(box), [=](auto p) 56 : : { return abs(p) > eps; } ) ) 57 : : { 58 : 6 : std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}}; 59 : 6 : std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}}; 60 [ + + ]: 2952 : for (std::size_t i=0; i<x.size(); ++i) { 61 : 2946 : std::array< tk::real, 3 > node{{ x[i], y[i], z[i] }}; 62 [ + + ][ + - ]: 2199 : if ( node[0]>b_min[0] && node[0]<b_max[0] && 63 [ + - ][ + - ]: 1473 : node[1]>b_min[1] && node[1]<b_max[1] && 64 [ + + ][ + - ]: 4419 : node[2]>b_min[2] && node[2]<b_max[2] ) 65 : : { 66 : : inbox[bcnt].insert( i ); 67 : : } 68 : : } 69 : : } 70 [ + - ]: 6 : ++bcnt; 71 : : } 72 : : 73 : : return inbox; 74 : 3 : } 75 : : 76 : : void 77 [ + + ]: 3208319 : box( std::size_t p, 78 : : std::vector< tk::real >& u, 79 : : const std::vector< std::unordered_set< std::size_t > >& boxnodes ) 80 : : // ***************************************************************************** 81 : : // Evaluate solution in user-defined IC box 82 : : //! \param[in] p Local mesh node id at which to evaluate 83 : : //! \param[in,out] u Solution to overwrite with box value 84 : : //! \param[in] boxnodes Nodes at which box user ICs are set (for each box IC) 85 : : // ***************************************************************************** 86 : : { 87 : : const auto& icbox = g_cfg.get< tag::ic >(); 88 [ + + ]: 3208319 : if (icbox.empty()) return; 89 : : 90 : : auto large = std::numeric_limits< double >::max(); 91 : : 92 [ + + ]: 5871 : for (std::size_t j=0; j<icbox.size(); ++j) { 93 : : const auto& b = icbox[j]; 94 [ + - ][ + + ]: 3914 : if (boxnodes.size() > j && boxnodes[j].find(p) != boxnodes[j].end()) { 95 : 1957 : auto boxr = b.get< tag::ic_density >(); 96 : : const auto& boxv = b.get< tag::ic_velocity >(); 97 : 1957 : auto boxp = b.get< tag::ic_pressure >(); 98 : 1957 : auto boxe = b.get< tag::ic_energy >(); 99 : 1957 : auto boxt = b.get< tag::ic_temperature >(); 100 : : 101 : : tk::real r = 0.0, ru = 0.0, rv = 0.0, rw = 0.0, re = 0.0; 102 [ - + ][ - + ]: 1957 : if (std::abs(boxr - large) > 1.0e-12 && boxr > 0.0) { 103 : : r = boxr; 104 : : } 105 [ + - ][ + - ]: 1957 : if (std::abs(boxv[0] - large) > 1.0e-12 && 106 [ + - ][ + - ]: 1957 : std::abs(boxv[1] - large) > 1.0e-12 && [ + - ] 107 [ + - ]: 1957 : std::abs(boxv[2] - large) > 1.0e-12) 108 : : { 109 : 1957 : ru = r * boxv[0]; 110 : 1957 : rv = r * boxv[1]; 111 : 1957 : rw = r * boxv[2]; 112 : : } 113 [ + - ][ + - ]: 1957 : if (std::abs(boxp - large) > 1.0e-12 && boxp> 0.0) { 114 : 1957 : re = eos::totalenergy( r, ru/r, rv/r, rw/r, boxp); 115 : : } 116 [ - + ][ - - ]: 1957 : if (std::abs(boxe - large) > 1.0e-12 && boxe > 0.0) { 117 : 0 : auto ux = ru/r, uy = rv/r, uz = rw/r; 118 : 0 : auto ke = 0.5*(ux*ux + uy*uy + uz*uz); 119 : 0 : re = r * (boxe + ke); 120 : : } 121 [ - + ][ - - ]: 1957 : if (std::abs(boxt - large) > 1.0e-12 && boxt > 0.0) { 122 : 0 : auto cv = g_cfg.get< tag::mat_spec_heat_const_vol >(); 123 [ - - ][ - - ]: 0 : if (std::abs(cv - large) > 1.0e-12 && cv > 0.0) { 124 : 0 : re = r * boxt * cv; 125 : : } 126 : : } 127 : 1957 : u[0] = r; 128 : 1957 : u[1] = ru; 129 : 1957 : u[2] = rv; 130 : 1957 : u[3] = rw; 131 : 1957 : u[4] = re; 132 : : } 133 : : } 134 : : } 135 : : 136 : : } // problems::