34 int nval_restr = operator_cache.restr_v->Height();
35 if(operator_cache.uVol.Size() != nval_restr){
36 operator_cache.uVol.SetSize(nval_restr);
37 operator_cache.uVol.UseDevice();
39 mfem::Vector &Ue(operator_cache.uVol);
40 if(!operator_cache.u_vol_restr_ready){
42 operator_cache.restr_v->Mult(pu, Ue);
43 operator_cache.u_vol_restr_ready =
true;
45 if(operator_cache.rhsVol.Size() != nval_restr){
46 operator_cache.rhsVol.SetSize(nval_restr);
47 operator_cache.rhsVol.UseDevice();
49 mfem::Vector &dUe(operator_cache.rhsVol);
53 mfem::real_t *d = dUe.Write();
54 mfem::forall(dUe.Size(), [=] MFEM_HOST_DEVICE (
int i) { d[i] = mfem::real_t(0); });
57 const mfem::real_t *Ue_d = Ue.Read();
58 mfem::real_t *dUe_d = dUe.Write();
61 auto dc = device_cache;
64 const int dim = dc.dim;
65 const int ne = dc.num_elements;
66 const int ndof = dc.ndof_scalar_el;
67 const int neq = dc.num_equations;
68#ifdef SUBCELL_FV_BLENDING
69 const int Np_x = dc.Np_x;
70 const int Np_y = dc.Np_y;
71 const int Np_z = dc.Np_z;
72 const int npe_metric_xi = (Np_x + 1)*Np_y*Np_z;
73 const int npe_metric_eta = Np_x*(Np_y + 1)*Np_z;
74 const int npe_metric_zeta = Np_x * Np_y * (Np_z + 1);
75 const mfem::real_t *metric_xi_d = dc.subcell_metric_xi_d;
76 const mfem::real_t *metric_eta_d = (dim > 1 ? dc.subcell_metric_eta_d :
nullptr);
77 const mfem::real_t *metric_zeta_d = (dim > 2 ? dc.subcell_metric_zeta_d :
nullptr);
79 mfem::Vector &dUfv(operator_cache.dUfv);
81 dUfv.SetSize(nval_restr);
83 operator_cache.dUfv_d = dUfv.Write();
85 mfem::real_t *dUfv_d = operator_cache.dUfv_d;
87 const mfem::real_t *alpha_d = operator_cache.alpha->Read();
91 const int metric_stride = ndof * dim * dim;
92 const int jac_stride = ndof;
93 const int estride = ndof*neq;
96 const int *elem_attr_d = dc.elem_attr_d;
97 const int *attr_marker_d = dc.attr_marker_d;
98 const mfem::real_t *elJac_d = dc.elJac_d;
99 const mfem::real_t *elMetric_d = dc.elMetric_d;
100 const mfem::real_t *elRadius_d = dc.elRadius_d;
102 mfem::real_t *ws_d = dc.elWaveSpeed_d;
105 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
108 const mfem::real_t *jac_el = elJac_d + e * jac_stride;
109 const mfem::real_t *metric_el = elMetric_d + e * metric_stride;
110 const mfem::real_t *radius_el = dc.axisymmetric ?
111 elRadius_d + e * jac_stride :
nullptr;
113 const int attr = elem_attr_d[e];
114 if (attr_marker_d[attr-1] == 0) {
119 const int eoff = e * estride;
120 const mfem::real_t *u_el = Ue_d + eoff;
121 mfem::real_t *du_el = dUe_d + eoff;
124 mfem::real_t cs_el = \
125 DGSEMIntegrator::AssembleElementVolumeKernel(dc, u_el,
126 jac_el, metric_el, du_el);
127#ifdef SUBCELL_FV_BLENDING
128 mfem::real_t alpha_fv = alpha_d[e];
129 if(alpha_fv > 1e-16){
130 mfem::real_t alpha_inv = (1.0 - alpha_fv);
131 mfem::real_t *du_fv = dUfv_d + eoff;
132 const mfem::real_t *el_metric_xi = metric_xi_d + e * npe_metric_xi * dim;
133 const mfem::real_t *el_metric_eta = (dim > 1 ? metric_eta_d + e * npe_metric_eta * dim :
135 const mfem::real_t *el_metric_zeta = (dim > 2 ? metric_zeta_d + e * npe_metric_zeta * dim :
137 const mfem::real_t cs_fv = \
138 DGSEMIntegrator::ComputeFVFluxesKernel(dc, u_el, jac_el, el_metric_xi, el_metric_eta,
139 el_metric_zeta, du_fv);
141 for(
int ipt = 0;ipt < estride;ipt++){
142 du_el[ipt] = alpha_inv * du_el[ipt] + alpha_fv * du_fv[ipt];
150 dc, u_el, radius_el, jac_el, metric_el, du_el);
157 operator_cache.restr_v->AddMultTranspose(dUe, pdudt);
161 const mfem::real_t *ws = operator_cache.elWaveSpeed.HostRead();
162 mfem::real_t max_char_speed = 0.0;
163 for(
int e = 0;e < operator_cache.num_elements;e++)
165 max_char_speed = std::max(max_char_speed, ws[e]);
168 return max_char_speed;
175 auto dc = device_cache;
176 const int dim = dc.dim;
177 const int neq = dc.num_equations;
178 const int nfp = dc.num_face_points;
179 const int nval_restr = operator_cache.restr_f->Height();
180 const int nfaces = nval_restr / (nfp * neq * 2);
181 const int face_size = 2*nfp*neq;
182 const int norm_size = nfp*dim;
184 if(operator_cache.uInt.Size() != nval_restr){
185 operator_cache.uInt.SetSize(nval_restr);
186 operator_cache.uInt.UseDevice(
true);
188 mfem::Vector &u_faces(operator_cache.uInt);
189 if(!operator_cache.u_int_restr_ready){
190 operator_cache.restr_f->Mult(pu, u_faces);
191 operator_cache.u_int_restr_ready =
true;
194 if(operator_cache.rhsInt.Size() != nval_restr){
195 operator_cache.rhsInt.SetSize(nval_restr);
196 operator_cache.rhsInt.UseDevice(
true);
198 mfem::Vector &rhs_faces(operator_cache.rhsInt);
201 mfem::Vector faces_dudt(pdudt);
203 faces_dudt.UseDevice(
true);
205 const mfem::real_t *u_d = u_faces.Read();
206 mfem::real_t *rhs_d = rhs_faces.Write();
208 const mfem::real_t *nor_d = dc.nor_d;
209 const mfem::real_t *inv1_d = dc.fw_minus_d;
210 const mfem::real_t *inv2_d = dc.fw_plus_d;
212 mfem::real_t *ws_d = dc.ifWaveSpeed_d;
214 mfem::forall(nfaces, [=] MFEM_HOST_DEVICE (
int i)
216 const int face_offset = i*face_size;
217 const int n_offset = i*norm_size;
218 const int w_offset = i*nfp;
220 const mfem::real_t *u_face_d = u_d + face_offset;
221 mfem::real_t *rhs_face_d = rhs_d + face_offset;
222 const mfem::real_t *nor_face_d = nor_d + n_offset;
223 const mfem::real_t *w_minus_d = inv1_d + w_offset;
224 const mfem::real_t *w_plus_d = inv2_d + w_offset;
226 mfem::real_t ws = DGSEMIntegrator::AssembleElementFaceKernel(dc, u_face_d, nor_face_d,
227 w_minus_d, w_plus_d, rhs_face_d);
232 operator_cache.restr_f->MultTranspose(rhs_faces, faces_dudt);
237 const mfem::real_t *ws = operator_cache.ifWaveSpeed.HostRead();
238 mfem::real_t max_char_speed_facial = 0.0;
239 for(
int f = 0;f < operator_cache.num_interior_faces;f++)
241 max_char_speed_facial = std::max(max_char_speed_facial, ws[f]);
244 return max_char_speed_facial;
252 auto dc = device_cache;
253 const int dim = dc.dim;
254 const int neq = dc.num_equations;
255 const int nfp = dc.num_face_points;
256 const int face_size = nfp * neq;
257 const int restr_size = operator_cache.restr_b->Height();
258 const int nfaces_restr = restr_size / face_size;
259 const int norm_size = nfp * dc.dim;
260 const int npoints_bnd = nfaces_restr * nfp;
266 if(operator_cache.uBnd.Size() != restr_size)
268 operator_cache.uBnd.SetSize(restr_size);
269 operator_cache.uBnd.UseDevice();
271 mfem::Vector &u_faces(operator_cache.uBnd);
272 if(!operator_cache.u_bnd_restr_ready){
273 operator_cache.restr_b->Mult(pu, u_faces);
274 operator_cache.u_bnd_restr_ready =
true;
276 if(operator_cache.rhsBnd.Size() != restr_size){
277 operator_cache.rhsBnd.SetSize(restr_size);
278 operator_cache.rhsBnd.UseDevice(
true);
280 if(operator_cache.dudtBnd.Size() != restr_size){
281 operator_cache.dudtBnd.SetSize(pdudt.Size());
282 operator_cache.dudtBnd.UseDevice(
true);
285 mfem::Vector &rhs_faces(operator_cache.rhsBnd);
286 mfem::Vector faces_dudt(pdudt);
287 faces_dudt.UseDevice(
true);
291 mfem::real_t *rd = rhs_faces.Write();
292 mfem::forall(rhs_faces.Size(), [=] MFEM_HOST_DEVICE (
int i)
293 { rd[i] = mfem::real_t(0);});
297 const mfem::real_t *u_d = u_faces.Read();
298 mfem::real_t *rhs_d = rhs_faces.Write();
300 const mfem::real_t *nor_d = dc.bnd_nor_d;
301 const mfem::real_t *inv1_d = dc.bnd_wt_d;
302 const int *bnd_marker_index_d = dc.bnd_marker_index_d;
303 mfem::real_t *ws_d = dc.bndWaveSpeed_d;
305 mfem::forall(npoints_bnd, [=] MFEM_HOST_DEVICE (
int p)
307 const int f = p / nfp;
308 const int fp = p % nfp;
310 int bnd_face_marker_index = bnd_marker_index_d[f];
311 if(bnd_face_marker_index < 0){
316 int bc_index = bnd_face_marker_index;
328 const int face_offset = f * face_size;
329 const int n_offset = f * norm_size;
330 const int w_offset = f * nfp;
332 const mfem::real_t *u_face_d = u_d + face_offset;
333 mfem::real_t *rhs_face_d = rhs_d + face_offset;
334 const mfem::real_t *nor_face_d = nor_d + n_offset;
335 const mfem::real_t *w_minus_d = inv1_d + w_offset;
336 const mfem::real_t *nor_point = nor_face_d + fp*dim;
337 mfem::real_t scale = -w_minus_d[fp];
342 const mfem::real_t ws = \
343 Theseus::BC::ApplyBoundaryConditionInviscid(dc, bc, state1,
350 operator_cache.restr_b->MultTranspose(rhs_faces, faces_dudt);
356 const mfem::real_t *ws = operator_cache.bndWaveSpeed.HostRead();
357 mfem::real_t max_char_speed_facial = 0.0;
358 for(
int p = 0;p < npoints_bnd;p++)
360 max_char_speed_facial = std::max(max_char_speed_facial, ws[p]);
363 return max_char_speed_facial;
373 auto report_bad = [&](
const char *name,
const mfem::Vector &v)
378 mfem::out <<
"BAD VALUES IN: (" << name <<
"), count=" << nbad << std::endl;
382 mfem::real_t max_char_speed = 0.0;
384 const mfem::Vector &pu(this->Prolongate(u));
387 max_char_speed = MultEuler_Volume(pu, pdudt);
389 mfem::real_t max_char_speed_facial = 0.0;
390 max_char_speed_facial = MultEuler_InteriorFaces(pu, pdudt);
393 max_char_speed = std::max(max_char_speed, max_char_speed_facial);
394 mfem::real_t max_char_speed_bnd = 0.0;
395 max_char_speed_bnd = MultEuler_BoundaryFaces(pu, pdudt);
398 return std::max(max_char_speed, max_char_speed_bnd);