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;
103#ifdef POINT_PARALLEL_VOLUME
104 const int npoints = ne * ndof;
105 mfem::forall(npoints, [=] MFEM_HOST_DEVICE (
int p)
107 const int e = p / ndof;
108 const int point = p % ndof;
109 const int attr = elem_attr_d[e];
110 if (attr_marker_d[attr-1] == 0) {
114 const int element_offset = e * estride;
115 DGSEMIntegrator::AssembleVolumePointKernel(
116 dc, Ue_d + element_offset, elJac_d + e*jac_stride,
117 elMetric_d + e*metric_stride, point, dUe_d + element_offset);
120 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
122 const int attr = elem_attr_d[e];
123 if (attr_marker_d[attr-1] == 0) {
127 const int element_offset = e * estride;
128 const mfem::real_t *u_el = Ue_d + element_offset;
129 mfem::real_t *du_el = dUe_d + element_offset;
130 const mfem::real_t *jac_el = elJac_d + e*jac_stride;
131 const mfem::real_t *metric_el = elMetric_d + e*metric_stride;
132 const mfem::real_t *radius_el =
133 dc.axisymmetric ? elRadius_d + e*jac_stride :
nullptr;
134#ifdef SUBCELL_FV_BLENDING
135 const mfem::real_t alpha_fv = alpha_d[e];
136 if (alpha_fv > 1e-16) {
137 const mfem::real_t alpha_dg = 1.0 - alpha_fv;
138 mfem::real_t *du_fv = dUfv_d + element_offset;
139 const mfem::real_t *el_metric_xi =
140 metric_xi_d + e*npe_metric_xi*dim;
141 const mfem::real_t *el_metric_eta = dim > 1 ?
142 metric_eta_d + e*npe_metric_eta*dim :
nullptr;
143 const mfem::real_t *el_metric_zeta = dim > 2 ?
144 metric_zeta_d + e*npe_metric_zeta*dim :
nullptr;
145 DGSEMIntegrator::ComputeFVFluxesKernel(
146 dc, u_el, jac_el, el_metric_xi, el_metric_eta,
147 el_metric_zeta, du_fv);
148 for (
int value = 0; value < estride; ++value) {
150 alpha_dg*du_el[value] + alpha_fv*du_fv[value];
156 dc, u_el, radius_el, jac_el, metric_el, du_el);
159 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
162 const mfem::real_t *jac_el = elJac_d + e * jac_stride;
163 const mfem::real_t *metric_el = elMetric_d + e * metric_stride;
164 const mfem::real_t *radius_el = dc.axisymmetric ?
165 elRadius_d + e * jac_stride :
nullptr;
167 const int attr = elem_attr_d[e];
168 if (attr_marker_d[attr-1] == 0) {
172 const int eoff = e * estride;
173 const mfem::real_t *u_el = Ue_d + eoff;
174 mfem::real_t *du_el = dUe_d + eoff;
177 DGSEMIntegrator::AssembleElementVolumeKernel(dc, u_el,
178 jac_el, metric_el, du_el);
179#ifdef SUBCELL_FV_BLENDING
180 mfem::real_t alpha_fv = alpha_d[e];
181 if(alpha_fv > 1e-16){
182 mfem::real_t alpha_inv = (1.0 - alpha_fv);
183 mfem::real_t *du_fv = dUfv_d + eoff;
184 const mfem::real_t *el_metric_xi = metric_xi_d + e * npe_metric_xi * dim;
185 const mfem::real_t *el_metric_eta = (dim > 1 ? metric_eta_d + e * npe_metric_eta * dim :
187 const mfem::real_t *el_metric_zeta = (dim > 2 ? metric_zeta_d + e * npe_metric_zeta * dim :
189 DGSEMIntegrator::ComputeFVFluxesKernel(
190 dc, u_el, jac_el, el_metric_xi, el_metric_eta,
191 el_metric_zeta, du_fv);
193 for(
int ipt = 0;ipt < estride;ipt++){
194 du_el[ipt] = alpha_inv * du_el[ipt] + alpha_fv * du_fv[ipt];
201 dc, u_el, radius_el, jac_el, metric_el, du_el);
207 operator_cache.restr_v->AddMultTranspose(dUe, pdudt);
215 auto dc = device_cache;
216 const int dim = dc.dim;
217 const int neq = dc.num_equations;
218 const int nfp = dc.num_face_points;
219 const int nval_restr = operator_cache.restr_f->Height();
220 const int nfaces = nval_restr / (nfp * neq * 2);
221 const int npoints = nfaces * nfp;
222 const int face_size = 2*nfp*neq;
224 if(operator_cache.uInt.Size() != nval_restr){
225 operator_cache.uInt.SetSize(nval_restr);
226 operator_cache.uInt.UseDevice(
true);
228 mfem::Vector &u_faces(operator_cache.uInt);
229 if(!operator_cache.u_int_restr_ready){
230 operator_cache.restr_f->Mult(pu, u_faces);
231 operator_cache.u_int_restr_ready =
true;
234 if(operator_cache.rhsInt.Size() != nval_restr){
235 operator_cache.rhsInt.SetSize(nval_restr);
236 operator_cache.rhsInt.UseDevice(
true);
238 mfem::Vector &rhs_faces(operator_cache.rhsInt);
241 mfem::Vector faces_dudt(pdudt);
243 faces_dudt.UseDevice(
true);
245 const mfem::real_t *u_d = u_faces.Read();
246 mfem::real_t *rhs_d = rhs_faces.Write();
248 const mfem::real_t *nor_d = dc.nor_d;
249 const mfem::real_t *inv1_d = dc.fw_minus_d;
250 const mfem::real_t *inv2_d = dc.fw_plus_d;
252#ifdef POINT_PARALLEL_INTERIOR_FACES
253 mfem::forall(npoints, [=] MFEM_HOST_DEVICE (
int p)
255 const int f = p / nfp;
256 const int fp = p % nfp;
257 const int face_offset = f*face_size;
258 const int point_offset = f*nfp + fp;
260 const mfem::real_t *u_face_d = u_d + face_offset;
261 mfem::real_t *rhs_face_d = rhs_d + face_offset;
263 DGSEMIntegrator::AssembleFacePointKernel(
264 dc, u_face_d, nor_d + point_offset*dim,
265 inv1_d[point_offset], inv2_d[point_offset], fp, rhs_face_d);
268 const int norm_size = nfp*dim;
269 mfem::forall(nfaces, [=] MFEM_HOST_DEVICE (
int f)
271 const int face_offset = f*face_size;
272 const int n_offset = f*norm_size;
273 const int w_offset = f*nfp;
275 const mfem::real_t *u_face_d = u_d + face_offset;
276 mfem::real_t *rhs_face_d = rhs_d + face_offset;
277 const mfem::real_t *nor_face_d = nor_d + n_offset;
278 const mfem::real_t *w_minus_d = inv1_d + w_offset;
279 const mfem::real_t *w_plus_d = inv2_d + w_offset;
281 DGSEMIntegrator::AssembleElementFaceKernel(
282 dc, u_face_d, nor_face_d, w_minus_d, w_plus_d, rhs_face_d);
287 operator_cache.restr_f->MultTranspose(rhs_faces, faces_dudt);
297 auto dc = device_cache;
298 const int dim = dc.dim;
299 const int neq = dc.num_equations;
300 const int nfp = dc.num_face_points;
301 const int face_size = nfp * neq;
302 const int restr_size = operator_cache.restr_b->Height();
303 const int nfaces_restr = restr_size / face_size;
304 const int norm_size = nfp * dc.dim;
305 const int npoints_bnd = nfaces_restr * nfp;
311 if(operator_cache.uBnd.Size() != restr_size)
313 operator_cache.uBnd.SetSize(restr_size);
314 operator_cache.uBnd.UseDevice();
316 mfem::Vector &u_faces(operator_cache.uBnd);
317 if(!operator_cache.u_bnd_restr_ready){
318 operator_cache.restr_b->Mult(pu, u_faces);
319 operator_cache.u_bnd_restr_ready =
true;
321 if(operator_cache.rhsBnd.Size() != restr_size){
322 operator_cache.rhsBnd.SetSize(restr_size);
323 operator_cache.rhsBnd.UseDevice(
true);
325 if(operator_cache.dudtBnd.Size() != restr_size){
326 operator_cache.dudtBnd.SetSize(pdudt.Size());
327 operator_cache.dudtBnd.UseDevice(
true);
330 mfem::Vector &rhs_faces(operator_cache.rhsBnd);
331 mfem::Vector faces_dudt(pdudt);
332 faces_dudt.UseDevice(
true);
336 mfem::real_t *rd = rhs_faces.Write();
337 mfem::forall(rhs_faces.Size(), [=] MFEM_HOST_DEVICE (
int i)
338 { rd[i] = mfem::real_t(0);});
342 const mfem::real_t *u_d = u_faces.Read();
343 mfem::real_t *rhs_d = rhs_faces.Write();
345 const mfem::real_t *nor_d = dc.bnd_nor_d;
346 const mfem::real_t *inv1_d = dc.bnd_wt_d;
347 const int *bnd_marker_index_d = dc.bnd_marker_index_d;
348 mfem::forall(npoints_bnd, [=] MFEM_HOST_DEVICE (
int p)
350 const int f = p / nfp;
351 const int fp = p % nfp;
353 int bnd_face_marker_index = bnd_marker_index_d[f];
354 if(bnd_face_marker_index < 0){
358 int bc_index = bnd_face_marker_index;
368 const int face_offset = f * face_size;
369 const int n_offset = f * norm_size;
370 const int w_offset = f * nfp;
372 const mfem::real_t *u_face_d = u_d + face_offset;
373 mfem::real_t *rhs_face_d = rhs_d + face_offset;
374 const mfem::real_t *nor_face_d = nor_d + n_offset;
375 const mfem::real_t *w_minus_d = inv1_d + w_offset;
376 const mfem::real_t *nor_point = nor_face_d + fp*dim;
377 mfem::real_t scale = -w_minus_d[fp];
388 operator_cache.restr_b->MultTranspose(rhs_faces, faces_dudt);