10 template<
typename PhysicsT>
18#ifdef SUBCELL_FV_BLENDING
25 operator_cache.bc_descriptors = bc_descriptors;
26 operator_cache.bc_scalar_data = bc_scalar_data;
27 operator_cache.bc_vector_data = bc_vector_data;
30#ifdef SUBCELL_FV_BLENDING
31 MFEM_VERIFY(indicator,
"SUBCELL_FV_BLENDING enabled but indicator is null.");
38 template<
typename PhysicsT>
40 mfem::Vector &uInt, mfem::Vector &uBnd)
const
43 const int psize = operator_cache.restr_v->Height();
44 if(uVol.Size() != psize){
48 operator_cache.restr_v->Mult(pu, uVol);
49 const int int_restr_size = operator_cache.restr_f->Height();
50 if(uInt.Size() != int_restr_size){
51 uInt.SetSize(int_restr_size);
54 operator_cache.restr_f->Mult(pu, uInt);
55 const int bnd_restr_size = operator_cache.restr_b->Height();
56 if(uBnd.Size() != bnd_restr_size){
57 uBnd.SetSize(bnd_restr_size);
60 operator_cache.restr_b->Mult(pu, uBnd);
61 operator_cache.u_vol_restr_ready =
true;
62 operator_cache.u_bnd_restr_ready =
true;
63 operator_cache.u_int_restr_ready =
true;
66#ifdef SUBCELL_FV_BLENDING
67 template<
typename PhysicsT>
73 const int nval_restr = operator_cache.restr_v->Height();
75 auto dc = device_cache;
78 const int dim = dc.dim;
79 const int ne = dc.num_elements;
80 const int ndof = dc.ndof_scalar_el;
81 const int neq = dc.num_equations;
82 const int Np_x = dc.Np_x;
83 const int Np_y = dc.Np_y;
84 const int Np_z = dc.Np_z;
86 MFEM_ASSERT(nval_restr == ne*ndof*neq,
"Unexpected size for volume restriction in indicator calc.");
87 const int nval_ind = nval_restr / neq;
89 if(operator_cache.uVol.Size() != nval_restr){
90 operator_cache.uVol.SetSize(nval_restr);
91 operator_cache.uVol.UseDevice();
93 mfem::Vector &Ue(operator_cache.uVol);
94 if(!operator_cache.u_vol_restr_ready){
95 operator_cache.restr_v->Mult(pu, Ue);
96 operator_cache.u_vol_restr_ready =
true;
98 const mfem::real_t *Ue_d = Ue.Read();
100 mfem::Vector &indicator_field(operator_cache.indicatorField);
101 if(indicator_field.Size() != nval_ind){
102 indicator_field.SetSize(nval_ind);
103 indicator_field.UseDevice();
105 mfem::real_t *ifield_d = indicator_field.Write();
107 const int estride = ndof*neq;
110 mfem::forall(nval_ind, [=] MFEM_HOST_DEVICE (
int vind)
112 const int e = vind / ndof;
113 const int evind = vind - e * ndof;
114 const mfem::real_t *u_el = Ue_d + e * estride;
118 ifield_d[vind] = dc.gas.pressure(S) * dc.gas.density(S);
123 template<
typename PhysicsT>
124 void RHSOperator<PhysicsT>::ComputeBlendingCoefficient()
const
126 ScopedTimer timer(
"ComputeBlendingCoeff");
127 const mfem::real_t *eta_d = operator_cache.eta.Read();
128 mfem::real_t *alpha_d = operator_cache.alpha->Write();
130 int ne = operator_cache.num_elements;
131 mfem::real_t mthresh = modalThreshold;
132 mfem::real_t sharp_fac = sharpness_fac;
133 mfem::real_t alpmin = alpha_min;
134 mfem::real_t alpmax = alpha_max;
135 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
137 mfem::real_t alpha_dof = \
138 1.0 / (1.0 + std::exp(-sharp_fac * (eta_d[e] - mthresh) / mthresh));
139 if (alpha_dof < alpmin)
143 else if (alpha_dof > (1.0 - alpmin))
147 alpha_d[e] = std::min(alpha_dof, alpmax);
151 template<
typename PhysicsT>
152 void RHSOperator<PhysicsT>::CheckIndicatorSmoothness()
const
156 const int ne = operator_cache.num_elements;
157 const int ndofs = operator_cache.ndof_scalar_el;
159 const mfem::real_t *indicator_d = operator_cache.indicatorField.Read();
160 const mfem::real_t *modal_d = operator_cache.modal.Read();
161 const mfem::real_t *keep_M1_d = operator_cache.keep_M1.Read();
162 const mfem::real_t *keep_M2_d = operator_cache.keep_M2.Read();
163 mfem::real_t *eta_d = operator_cache.eta.ReadWrite();
165 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
167 const mfem::real_t *u = indicator_d + e * ndofs;
169 mfem::real_t mm = 0.0;
170 mfem::real_t m1m1 = 0.0;
171 mfem::real_t m2m2 = 0.0;
173 for (
int m = 0; m < ndofs; ++m)
175 mfem::real_t mode = 0.0;
177 for (
int q = 0; q < ndofs; ++q)
179 mode += modal_d[m * ndofs + q] * u[q];
182 const mfem::real_t m1 = keep_M1_d[m] * mode;
183 const mfem::real_t m2 = keep_M2_d[m] * mode;
190 const mfem::real_t eps = 1.0e-30;
191 mfem::real_t val = 0.0;
194 val = 1.0 - m1m1 / mm;
207 template<
typename PhysicsT>
213 const int nval_restr = operator_cache.restr_v->Height();
216 auto dc = device_cache;
219 const int ne = dc.num_elements;
220 const int ndof = dc.ndof_scalar_el;
221 const int neq = dc.num_equations;
222 const mfem::real_t *qWts_d = dc.elQWgts_d;
223 const mfem::real_t *radius_d = dc.elRadius_d;
226 if(operator_cache.uVol.Size() != nval_restr){
227 operator_cache.uVol.SetSize(nval_restr);
228 operator_cache.uVol.UseDevice();
230 mfem::Vector &Ue(operator_cache.uVol);
231 if(!operator_cache.u_vol_restr_ready){
232 operator_cache.restr_v->Mult(u, Ue);
233 operator_cache.u_vol_restr_ready =
true;
236 const mfem::real_t *Ue_d = Ue.Read();
237 const int estride = ndof*neq;
239 mfem::Vector elMass_integral(ne);
240 mfem::Vector elKE_integral(ne);
241 mfem::Vector elEnergy_integral(ne);
242 mfem::Vector elMaxPressure(ne);
243 mfem::Vector elMaxTemperature(ne);
244 mfem::Vector elMaxDensity(ne);
245 mfem::Vector elMinPressure(ne);
246 mfem::Vector elMinTemperature(ne);
247 mfem::Vector elMinDensity(ne);
249 elMass_integral.UseDevice();
250 elKE_integral.UseDevice();
251 elEnergy_integral.UseDevice();
252 elMaxPressure.UseDevice();
253 elMaxTemperature.UseDevice();
254 elMaxDensity.UseDevice();
255 elMinPressure.UseDevice();
256 elMinTemperature.UseDevice();
257 elMinDensity.UseDevice();
259 mfem::real_t *elMass_int_d = elMass_integral.Write();
260 mfem::real_t *elKE_int_d = elKE_integral.Write();
261 mfem::real_t *elEnergy_int_d = elEnergy_integral.Write();
263 mfem::real_t *elPress_max_d = elMaxPressure.Write();
264 mfem::real_t *elTemp_max_d = elMaxTemperature.Write();
265 mfem::real_t *elDens_max_d = elMaxDensity.Write();
266 mfem::real_t *elPress_min_d = elMinPressure.Write();
267 mfem::real_t *elTemp_min_d = elMinTemperature.Write();
268 mfem::real_t *elDens_min_d = elMinDensity.Write();
271 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
273 const mfem::real_t *u_el = Ue_d + e * estride;
274 const mfem::real_t *qWgt = qWts_d + e * ndof;
275 const mfem::real_t *radius = dc.axisymmetric ?
276 radius_d + e * ndof :
nullptr;
278 mfem::real_t mass_int = 0.0;
279 mfem::real_t ke_int = 0.0;
280 mfem::real_t en_int = 0.0;
281 mfem::real_t min_dens = 1e32;
282 mfem::real_t max_dens = 0.0;
283 mfem::real_t min_temp = 1e32;
284 mfem::real_t max_temp = 0.0;
285 mfem::real_t min_press = 1e32;
286 mfem::real_t max_press = 0.0;
288 for(
int ep = 0;ep < ndof;ep++){
293 mfem::real_t rho = gas.density(S);
294 mfem::real_t ke = gas.kinetic_energy_density(S);
295 mfem::real_t rhoE = gas.
energy(S);
296 mfem::real_t press = gas.pressure(S);
297 mfem::real_t temper = gas.temperature(S);
299 const mfem::real_t measure = qWgt[ep] *
301 dc.axisymmetric, dc.axisymmetric ? radius[ep] : 0.0);
302 mass_int += rho * measure;
303 ke_int += ke * measure;
304 en_int += rhoE * measure;
314 elMass_int_d[e] = mass_int;
315 elKE_int_d[e] = ke_int;
316 elEnergy_int_d[e] = en_int;
317 elPress_max_d[e] = max_press;
318 elPress_min_d[e] = min_press;
319 elDens_max_d[e] = max_dens;
320 elDens_min_d[e] = min_dens;
321 elTemp_min_d[e] = min_temp;
322 elTemp_max_d[e] = max_temp;
339 const mfem::real_t *mass_h = elMass_integral.HostRead();
340 const mfem::real_t *ke_h = elKE_integral.HostRead();
341 const mfem::real_t *en_h = elEnergy_integral.HostRead();
342 const mfem::real_t *minpress_h = elMinPressure.HostRead();
343 const mfem::real_t *maxpress_h = elMaxPressure.HostRead();
344 const mfem::real_t *mindens_h = elMinDensity.HostRead();
345 const mfem::real_t *maxdens_h = elMaxDensity.HostRead();
346 const mfem::real_t *mintemp_h = elMinTemperature.HostRead();
347 const mfem::real_t *maxtemp_h = elMaxTemperature.HostRead();
349 for (
int e = 0; e < ne; ++e) {
350 diag.
mass += mass_h[e];
361 mfem::real_t sendbuf[3] = {diag.
mass, diag.
ke, diag.
en};
362 mfem::real_t recvbuf[3] = {0.0, 0.0, 0.0};
364 MPI_Allreduce(sendbuf, recvbuf, 3, mfem::MPITypeMap<mfem::real_t>::mpi_type, MPI_SUM, pmesh->GetComm());
366 diag.
mass = recvbuf[0];
367 diag.
ke = recvbuf[1];
368 diag.
en = recvbuf[2];
374 MPI_Allreduce(sendbuf, recvbuf, 3, mfem::MPITypeMap<mfem::real_t>::mpi_type, MPI_MIN, pmesh->GetComm());
384 MPI_Allreduce(sendbuf, recvbuf, 3, mfem::MPITypeMap<mfem::real_t>::mpi_type, MPI_MAX, pmesh->GetComm());
390 if(diag0.mass == 0.0){
396 template<
typename PhysicsT>
400 operator_cache.u_vol_restr_ready =
false;
401 operator_cache.u_bnd_restr_ready =
false;
402 operator_cache.u_int_restr_ready =
false;
405 const mfem::Vector &pu = this->Prolongate(u);
406 FetchRestrictions(pu, operator_cache.uVol, operator_cache.uInt, operator_cache.uBnd);
409 operator_cache.pdudt.SetSize(this->P->Height());
412 mfem::Vector &pdudt = this->P ? operator_cache.pdudt : dudt;
415 int nval_restr = operator_cache.restr_v->Height();
416 if(operator_cache.uVol.Size() != nval_restr){
417 operator_cache.uVol.SetSize(nval_restr);
418 operator_cache.uVol.UseDevice();
420 mfem::Vector &Ue(operator_cache.uVol);
421 if(operator_cache.rhsVol.Size() != nval_restr){
422 operator_cache.rhsVol.SetSize(nval_restr);
423 operator_cache.rhsVol.UseDevice();
425 mfem::Vector &dUe(operator_cache.rhsVol);
427#ifdef SUBCELL_FV_BLENDING
430 const mfem::Vector &pu = this->Prolongate(u);
431 ComputeIndicatorField(pu);
432 CheckIndicatorSmoothness();
433 ComputeBlendingCoefficient();
438 int psize = pdudt.Size();
439 mfem::real_t *pdudt_d = pdudt.Write();
442 mfem::forall(psize, [=] MFEM_HOST_DEVICE (
int i) { pdudt_d[i] = 0.0; });
449 max_char_speed = FlowMult(u, pdudt);
454 if(this->cP) this->cP->MultTranspose(pdudt, dudt);
458 if(this->P) this->P->MultTranspose(pdudt, dudt);
461 const int N = this->ess_tdof_list.Size();
462 const auto idx = this->ess_tdof_list.Read();
463 auto DU_RW = dudt.ReadWrite();
464 mfem::forall(N, [=] MFEM_HOST_DEVICE (
int i) { DU_RW[idx[i]] = 0.0; });
467 operator_cache.u_vol_restr_ready =
false;
468 operator_cache.u_bnd_restr_ready =
false;
469 operator_cache.u_int_restr_ready =
false;
virtual void Finalize(mfem::real_t time=0)
Definition RHSOperator.hpp:84
Definition RHSOperator.hpp:121
void Mult(const mfem::Vector &u, mfem::Vector &dudt) const override
Definition RHSOperator_impl.hpp:397
void FetchRestrictions(const mfem::Vector &pu, mfem::Vector &uVol, mfem::Vector &uInt, mfem::Vector &uBnd) const
Definition RHSOperator_impl.hpp:39
void Finalize(mfem::real_t time=0) override
Definition RHSOperator_impl.hpp:11
void ComputeIntegralMeasures(const mfem::Vector &u, Theseus::IntegralMeasures &diag) const override
Definition RHSOperator_impl.hpp:208
MFEM_HOST_DEVICE mfem::real_t rmin(mfem::real_t a, mfem::real_t b)
Definition theseus_kernels.hpp:18
MFEM_HOST_DEVICE void el_gather_state(const mfem::real_t *u, const int dof, const int num_eq, const int id, mfem::real_t *dst)
Definition theseus_kernels.hpp:135
MFEM_HOST_DEVICE mfem::real_t rmax(mfem::real_t a, mfem::real_t b)
Definition theseus_kernels.hpp:17
Definition AxisymmetricGeometry.hpp:15
void GetDeviceCache(CacheT &cache, DeviceCacheT &device_cache)
Definition dgsem_cache_utilities.hpp:844
void BuildPerssonDeviceCache(CacheT &c, Prandtl::ModalBasis &modalBasis)
Definition dgsem_cache_utilities.hpp:950
void AssembleBoundaryFaceGeometryTerms(mfem::FiniteElementSpace *fes, const std::vector< mfem::Array< int > > &bdr_marker_vector, CacheT *cache)
Definition dgsem_cache_utilities.hpp:337
constexpr const int MAXEQ
Definition theseus_kernels.hpp:13
void GetOperatorCache(mfem::FiniteElementSpace *fes, CacheT *cache)
Definition dgsem_cache_utilities.hpp:18
void ValidateAxisBoundaryGeometry(const CacheT &cache)
Definition dgsem_cache_utilities.hpp:943
void ComputeSubcellMetrics(mfem::FiniteElementSpace *fes, CacheT *cache)
Definition dgsem_cache_utilities.hpp:627
static MFEM_HOST_DEVICE mfem::real_t MeasureMultiplier(bool axisymmetric, mfem::real_t radius)
Definition AxisymmetricGeometry.hpp:37
Definition dgsem_cache.hpp:16
mfem::real_t max_temp
Definition dgsem_cache.hpp:22
mfem::real_t min_dens
Definition dgsem_cache.hpp:25
mfem::real_t en
Definition dgsem_cache.hpp:19
mfem::real_t mass
Definition dgsem_cache.hpp:17
mfem::real_t ke
Definition dgsem_cache.hpp:18
mfem::real_t max_press
Definition dgsem_cache.hpp:20
mfem::real_t max_dens
Definition dgsem_cache.hpp:24
mfem::real_t min_press
Definition dgsem_cache.hpp:21
mfem::real_t min_temp
Definition dgsem_cache.hpp:23
Definition GasState.hpp:127
MFEM_HOST_DEVICE mfem::real_t energy(const StateLayout &L) const
Definition GasState.hpp:190