17 const int nval_restr = operator_cache.restr_v->Height();
20 auto dc = device_cache;
23 const int ne = dc.num_elements;
24 const int ndof = dc.ndof_scalar_el;
25 const int neq = dc.num_equations;
26 const int npts = ndof * ne;
28 MFEM_ASSERT(nval_restr == npts*neq,
"Unexpected size in ComputeEntropyState");
32 if (operator_cache.uVol.Size() != nval_restr){
33 operator_cache.uVol.SetSize(nval_restr);
34 operator_cache.uVol.UseDevice();
36 mfem::Vector &restrU(operator_cache.uVol);
37 if (operator_cache.uVol.Size() != nval_restr){
38 operator_cache.uVol.SetSize(nval_restr);
39 operator_cache.uVol.UseDevice();
41 mfem::Vector &restrE(operator_cache.sVol);
42 if(restrE.Size() != nval_restr){
43 restrE.SetSize(nval_restr);
46 mfem::real_t *eState_d = restrE.Write();
47 operator_cache.restr_v->Mult(u, restrU);
49 if(e.Size() != u.Size()){
54 const mfem::real_t *restrU_d = restrU.Read();
55 const int estride = ndof*neq;
58 mfem::forall(npts, [=] MFEM_HOST_DEVICE (
int pt)
60 const int elno = pt / ndof;
61 const int ept = pt % ndof;
62 const int eoff = elno * estride;
63 const mfem::real_t *u_el = restrU_d + eoff;
71 gas.entropy_state(S, E);
72 mfem::real_t *e_el = eState_d + eoff;
76 operator_cache.restr_v->MultTranspose(restrE, e);
87 const int nval_restr = operator_cache.restr_v->Height();
90 auto dc = device_cache;
93 const int ne = dc.num_elements;
94 const int ndof = dc.ndof_scalar_el;
95 const int neq = dc.num_equations;
96 const int npts = ndof * ne;
97 const int dim = dc.dim;
99 MFEM_ASSERT(nval_restr == npts*neq,
"Unexpected size in ComputeEntropyState");
103 if (operator_cache.uVol.Size() != nval_restr){
104 operator_cache.uVol.SetSize(nval_restr);
105 operator_cache.uVol.UseDevice();
107 mfem::Vector &restr_state(operator_cache.uVol);
108 if(!operator_cache.u_vol_restr_ready){
109 operator_cache.restr_v->Mult(u, restr_state);
110 operator_cache.u_vol_restr_ready =
true;
112 const mfem::real_t *restr_state_d = restr_state.Read();
113 const int estride = ndof*neq;
116 if(operator_cache.volAux.Size() != nval_restr){
117 operator_cache.volAux.SetSize(nval_restr);
118 operator_cache.volAux.UseDevice();
120 mfem::Vector &restr_grad_prim_dir(operator_cache.volAux);
122 for(
int idim = 0;idim < dim;idim++){
124 mfem::Vector &grad_state_dir(*gradEntropy[idim]);
125 operator_cache.restr_v->Mult(grad_state_dir, restr_grad_prim_dir);
126 mfem::real_t *grad_prim_dir_d = restr_grad_prim_dir.Write();
129 mfem::forall(npts, [=] MFEM_HOST_DEVICE (
int pt)
131 const int e = pt / ndof;
132 const int ept = pt % ndof;
133 const int eoff = e * estride;
134 const mfem::real_t *u_el = restr_state_d + eoff;
135 mfem::real_t *grad_prim_el = grad_prim_dir_d + eoff;
147 gas.grad_entropy_to_grad_prim(CV, dS, dP);
156 operator_cache.restr_v->MultTranspose(restr_grad_prim_dir, grad_state_dir);
197 std::vector<mfem::Vector *> &p_grad_u)
const
201 const int dim = operator_cache.dim;
202 const int restr_size = operator_cache.restr_v->Height();
204 if(operator_cache.sVol.Size() != restr_size){
205 operator_cache.sVol.SetSize(restr_size);
206 operator_cache.sVol.UseDevice();
208 mfem::Vector &Ue(operator_cache.sVol);
211 if (operator_cache.gradVol.size() != dim){
212 operator_cache.gradVol.resize(dim);
213 for(
int idim = 0;idim < dim;idim++){
214 operator_cache.gradVol[idim].SetSize(restr_size);
215 operator_cache.gradVol[idim].UseDevice();
218 std::vector<mfem::Vector> &dUe(operator_cache.gradVol);
219 for(
int idim = 0;idim < dim;idim++){
220 dU_d[idim] = dUe[idim].Write();
221 pgrad_d[idim] = p_grad_u[idim]->Write();
224 mfem::forall(restr_size, [=] MFEM_HOST_DEVICE (
int i)
226 for(
int idim = 0;idim < dim;idim++){
227 dU_d[idim][i] = mfem::real_t(0);
228 pgrad_d[idim][i] = mfem::real_t(0);
232 operator_cache.restr_v->Mult(pu, Ue);
233 const mfem::real_t *Ue_d = Ue.Read();
235 auto dc = device_cache;
237 const int ne = dc.num_elements;
238 const int ndof = dc.ndof_scalar_el;
239 const int neq = dc.num_equations;
240 const int estride = ndof * neq;
241 const int jac_stride = ndof;
242 const int metric_stride = ndof * dc.dim * dc.dim;
244 const mfem::real_t *elJac_d = dc.elJac_d;
245 const mfem::real_t *elMetric_d = dc.elMetric_d;
247 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
249 const mfem::real_t *u_el = Ue_d + e * estride;
251 for(
int idim = 0;idim < dim;idim++){
252 du_el_d[idim] = dU_d[idim] + e*estride;
255 const mfem::real_t *jac_el = elJac_d + e * jac_stride;
256 const mfem::real_t *metric_el = elMetric_d + e * metric_stride;
258 Theseus::DGSEMIntegrator::AssembleGradElementVolumeKernel(dc, u_el, jac_el, metric_el,
262 for(
int idim = 0;idim < dim;idim++){
263 operator_cache.restr_v->AddMultTranspose(dUe[idim], *p_grad_u[idim]);
270 std::vector<mfem::Vector *> &p_grad_u)
const
274 auto dc = device_cache;
275 const int dim = dc.dim;
276 const int neq = dc.num_equations;
277 const int nfp = dc.num_face_points;
278 const int face_size = nfp * neq;
279 const int restr_size = operator_cache.restr_b->Height();
280 const int nfaces_restr = restr_size / face_size;
281 const int norm_size = nfp * dim;
282 const int npoints_bnd = nfaces_restr * nfp;
283 const int psize = pu.Size();
289 mfem::Vector &u_faces(operator_cache.sBnd);
290 if(u_faces.Size() != restr_size){
291 u_faces.SetSize(restr_size);
295 std::vector<mfem::Vector> &rhs_faces(operator_cache.gradBnd);
296 if(rhs_faces.size() != dim){
297 rhs_faces.resize(dim);
298 for(
int idim = 0;idim < dim;idim++){
299 rhs_faces[idim].SetSize(restr_size);
300 rhs_faces[idim].UseDevice();
304 mfem::Vector &duBnd(operator_cache.duBnd);
305 if(duBnd.Size() != psize){
306 duBnd.SetSize(psize);
310 operator_cache.restr_b->Mult(pu, u_faces);
312 const mfem::real_t *u_d = u_faces.Read();
313 const mfem::real_t *nor_d = dc.bnd_nor_d;
314 const mfem::real_t *wt_d = dc.bnd_wt_d;
315 const int *bnd_marker_index_d = dc.bnd_marker_index_d;
319 for(
int idim = 0;idim < dim;idim++){
320 rhs_d[idim] = rhs_faces[idim].Write();
321 du_d[idim] = duBnd.Write();
324 for (
int idim = 0; idim < dim; ++idim) {
325 mfem::real_t *rd = rhs_d[idim];
326 mfem::forall(restr_size, [=] MFEM_HOST_DEVICE (
int i) { rd[i] = mfem::real_t(0); });
328 for (
int idim = 0; idim < 1; ++idim) {
329 mfem::real_t *dud = du_d[idim];
330 mfem::forall(psize, [=] MFEM_HOST_DEVICE (
int i) { dud[i] = mfem::real_t(0); });
333 mfem::forall(npoints_bnd, [=] MFEM_HOST_DEVICE (
int p)
335 const int f = p / nfp;
336 const int fp = p % nfp;
338 const int bnd_face_marker_index = bnd_marker_index_d[f];
339 if (bnd_face_marker_index < 0)
344 const int bc_index = bnd_face_marker_index;
356 const int face_offset = f * face_size;
357 const int norm_offset = f * norm_size;
358 const int w_offset = f * nfp;
360 const mfem::real_t *u_face_d = u_d + face_offset;
362 const mfem::real_t *nor_face_d = nor_d + norm_offset;
363 const mfem::real_t *nor_point = nor_face_d + fp * dim;
366 const mfem::real_t scale = wt_d[w_offset + fp];
369 for(
int idim = 0;idim < dim;idim++){
370 rhs_face[idim] = rhs_d[idim] + face_offset;
373 Theseus::DGSEMIntegrator::AssembleGradBoundaryPointKernel(dc, bc,
381 for(
int idim = 0;idim < dim;idim++){
382 operator_cache.restr_b->MultTranspose(rhs_faces[idim], duBnd);
383 *p_grad_u[idim] += duBnd;
390 std::vector<mfem::Vector *> &p_grad_u)
const
394 auto dc = device_cache;
395 const int dim = dc.dim;
396 const int psize = pu.Size();
397 const int restr_size = operator_cache.restr_f->Height();
398 const int neq = dc.num_equations;
399 const int nfp = dc.num_face_points;
400 const int nfaces = restr_size / (2 * nfp * neq);
401 const int face_size = 2 * nfp * neq;
402 const int norm_size = nfp * dim;
404 mfem::Vector &u_faces(operator_cache.sInt);
405 if(u_faces.Size() != restr_size){
406 u_faces.SetSize(restr_size);
410 std::vector<mfem::Vector> &rhs_faces(operator_cache.gradInt);
411 if(rhs_faces.size() != dim){
412 rhs_faces.resize(dim);
413 for(
int idim = 0;idim < dim;idim++){
414 rhs_faces[idim].SetSize(restr_size);
415 rhs_faces[idim].UseDevice();
419 mfem::Vector &duInt(operator_cache.duInt);
420 if(duInt.Size() != psize){
421 duInt.SetSize(psize);
425 operator_cache.restr_f->Mult(pu, u_faces);
426 const mfem::real_t *u_d = u_faces.Read();
430 for(
int idim = 0;idim < dim;idim++){
431 rhs_d[idim] = rhs_faces[idim].Write();
433 du_d[idim] = duInt.Write();
436 for (
int idim = 0; idim < dim; ++idim) {
437 mfem::real_t *rd = rhs_d[idim];
438 mfem::forall(restr_size, [=] MFEM_HOST_DEVICE (
int i) { rd[i] = mfem::real_t(0); });
441 for (
int idim = 0; idim < 1; ++idim) {
442 mfem::real_t *dud = du_d[idim];
443 mfem::forall(psize, [=] MFEM_HOST_DEVICE (
int i) { dud[i] = mfem::real_t(0); });
446 const mfem::real_t *nor_d = dc.nor_d;
447 const mfem::real_t *wm_d = dc.fw_minus_d;
448 const mfem::real_t *wp_d = dc.fw_plus_d;
450 mfem::forall(nfaces, [=] MFEM_HOST_DEVICE (
int f)
452 const int face_offset = f * face_size;
453 const int norm_offset = f * norm_size;
454 const int w_offset = f * nfp;
456 const mfem::real_t *u_face_d = u_d + face_offset;
457 const mfem::real_t *nor_face_d = nor_d + norm_offset;
458 const mfem::real_t *w_minus_d = wm_d + w_offset;
459 const mfem::real_t *w_plus_d = wp_d + w_offset;
462 for(
int idim = 0;idim < dim;idim++){
463 rhs_face[idim] = rhs_d[idim] + face_offset;
466 Theseus::DGSEMIntegrator::AssembleGradInteriorFaceKernel(dc,
474 for(
int idim = 0;idim < dim;idim++){
475 operator_cache.restr_f->MultTranspose(rhs_faces[idim], duInt);
476 *p_grad_u[idim] += duInt;
483 std::vector<mfem::Vector *> &grad_u)
const
486 const int dim = operator_cache.dim;
487 const mfem::Vector &pu = this->Prolongate(u);
488 std::vector<mfem::Vector *> p_grad_(dim);
491 const int psize = this->P->Height();
492 if(operator_cache.pGrad.size() != dim){
493 operator_cache.pGrad.resize(dim);
494 for(
int idim = 0;idim < dim;idim++){
495 operator_cache.pGrad[idim].SetSize(psize);
496 operator_cache.pGrad[idim].UseDevice();
499 for(
int idim = 0;idim < dim;idim++){
500 p_grad_[idim] = &(operator_cache.pGrad[idim]);
503 std::vector<mfem::Vector *> &p_grad_u = this->P ? p_grad_ : grad_u;
505 MFEM_ASSERT(p_grad_u.size() == dim,
"Size mismatch for gradient storage");
506 MFEM_ASSERT(grad_u.size() == dim,
"Size mismatch for gradient storage");
508 GradOperator_Volume(pu, p_grad_u);
510 GradOperator_InteriorFaces(pu, p_grad_u);
512 GradOperator_BoundaryFaces(pu, p_grad_u);
518 for(
int idim = 0;idim < dim;idim++){
519 this->cP->MultTranspose(*p_grad_u[idim], *grad_u[idim]);
526 for(
int idim = 0;idim < dim;idim++){
527 this->P->MultTranspose(*p_grad_u[idim], *grad_u[idim]);
532 const int N = this->ess_tdof_list.Size();
533 const auto idx = this->ess_tdof_list.Read();
535 for(
int idim = 0;idim < dim;idim++){
536 auto gradu_dim_d = grad_u[idim]->ReadWrite();
537 mfem::forall(N, [=] MFEM_HOST_DEVICE (
int i) { gradu_dim_d[idx[i]] = 0.0; });
543 const std::vector<mfem::Vector *> &p_grad_prim,
544 mfem::Vector &pdudt)
const
548 auto dc = device_cache;
549 const int dim = dc.dim;
550 const int neq = dc.num_equations;
551 const int nfp = dc.num_face_points;
552 const int nfaces = operator_cache.restr_f->Height() / (nfp * neq * 2);
553 const int face_size = 2*nfp*neq;
554 const int norm_size = nfp*dim;
556 const int restr_size = operator_cache.restr_f->Height();
557 mfem::Vector &int_u(operator_cache.uInt);
558 if(int_u.Size() != restr_size){
559 int_u.SetSize(restr_size);
563 mfem::Vector &rhs_faces(operator_cache.rhsInt);
564 if(rhs_faces.Size() != restr_size){
565 rhs_faces.SetSize(restr_size);
566 rhs_faces.UseDevice();
569 mfem::Vector &faces_dudt(operator_cache.dudtInt);
570 if(faces_dudt.Size() != pdudt.Size()){
571 faces_dudt.SetSize(pdudt.Size());
572 faces_dudt.UseDevice();
576 const mfem::real_t *grad_prim_d[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
577 std::vector<mfem::Vector> &int_grad_prim(operator_cache.gradInt);
579 if(int_grad_prim.size() != dim){
580 int_grad_prim.resize(dim);
581 for(
int idim = 0;idim < dim;idim++){
582 int_grad_prim[idim].SetSize(restr_size);
583 int_grad_prim[idim].UseDevice();
587 for(
int idim = 0;idim < dim;idim++){
588 operator_cache.restr_f->Mult(*p_grad_prim[idim], int_grad_prim[idim]);
589 grad_prim_d[idim] = int_grad_prim[idim].Read();
595 mfem::real_t *d = rhs_faces.Write();
596 mfem::forall(rhs_faces.Size(), [=] MFEM_HOST_DEVICE (
int i) { d[i] = mfem::real_t(0); });
599 if(!operator_cache.u_int_restr_ready){
600 operator_cache.restr_f->Mult(pu, int_u);
601 operator_cache.u_int_restr_ready =
true;
604 const mfem::real_t *u_d = int_u.Read();
605 mfem::real_t *rhs_d = rhs_faces.Write();
606 const mfem::real_t *nor_d = dc.nor_d;
607 const mfem::real_t *inv1_d = dc.fw_minus_d;
608 const mfem::real_t *inv2_d = dc.fw_plus_d;
609 const mfem::real_t *face_radius_d = dc.face_radius_d;
611 mfem::real_t *ws_d = dc.ifWaveSpeed_d;
613 mfem::forall(nfaces, [=] MFEM_HOST_DEVICE (
int i)
615 const int face_offset = i*face_size;
616 const int n_offset = i*norm_size;
617 const int w_offset = i*nfp;
619 const mfem::real_t *u_face_d = u_d + face_offset;
620 mfem::real_t *rhs_face_d = rhs_d + face_offset;
621 const mfem::real_t *nor_face_d = nor_d + n_offset;
622 const mfem::real_t *w_minus_d = inv1_d + w_offset;
623 const mfem::real_t *w_plus_d = inv2_d + w_offset;
624 const mfem::real_t *radius_face_d = dc.axisymmetric ?
625 face_radius_d + w_offset :
nullptr;
626 const mfem::real_t *dprim_face_x = (dim > 0) ? grad_prim_d[0] + face_offset :
nullptr;
627 const mfem::real_t *dprim_face_y = (dim > 1) ? grad_prim_d[1] + face_offset :
nullptr;
628 const mfem::real_t *dprim_face_z = (dim > 2) ? grad_prim_d[2] + face_offset :
nullptr;
631 mfem::real_t ws = Theseus::DGSEMIntegrator::AssembleViscousElementFaceKernel(dc, u_face_d, nor_face_d,
641 operator_cache.restr_f->MultTranspose(rhs_faces, faces_dudt);
646 const mfem::real_t *ws = operator_cache.ifWaveSpeed.HostRead();
647 mfem::real_t max_char_speed_facial = 0.0;
648 for(
int f = 0;f < operator_cache.num_interior_faces;f++)
650 max_char_speed_facial = std::max(max_char_speed_facial, ws[f]);
653 return max_char_speed_facial;
659 const std::vector<mfem::Vector *> &p_grad_prim,
660 mfem::Vector &pdudt)
const
664 auto dc = device_cache;
665 const int dim = dc.dim;
666 const int neq = dc.num_equations;
667 const int nfp = dc.num_face_points;
668 const int face_size = nfp * neq;
669 const int restr_size = operator_cache.restr_b->Height();
670 const int nfaces_restr = restr_size / face_size;
671 const int norm_size = nfp * dc.dim;
672 const int npoints_bnd = nfaces_restr * nfp;
673 const int psize = pdudt.Size();
679 mfem::Vector &rhs_faces(operator_cache.rhsBnd);
680 mfem::Vector &faces_dudt(operator_cache.dudtBnd);
681 if(rhs_faces.Size() != restr_size){
682 rhs_faces.SetSize(restr_size);
683 rhs_faces.UseDevice();
685 if(faces_dudt.Size() != psize){
686 faces_dudt.SetSize(psize);
687 faces_dudt.UseDevice();
689 mfem::Vector &bnd_u(operator_cache.uBnd);
690 if(bnd_u.Size() != restr_size){
691 bnd_u.SetSize(restr_size);
694 const mfem::real_t *grad_prim_d[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
695 std::vector<mfem::Vector> &bnd_grad_prim(operator_cache.gradBnd);
696 if(bnd_grad_prim.size() != dim){
697 bnd_grad_prim.resize(dim);
698 for(
int idim = 0;idim < dim;idim++){
699 bnd_grad_prim[idim].SetSize(restr_size);
700 bnd_grad_prim[idim].UseDevice();
703 for(
int idim = 0;idim < dim;idim++){
704 operator_cache.restr_b->Mult(*p_grad_prim[idim], bnd_grad_prim[idim]);
705 grad_prim_d[idim] = bnd_grad_prim[idim].Read();
711 mfem::real_t *rd = rhs_faces.Write();
712 mfem::forall(rhs_faces.Size(), [=] MFEM_HOST_DEVICE (
int i)
713 { rd[i] = mfem::real_t(0);});
714 mfem::real_t *fd = faces_dudt.Write();
715 mfem::forall(faces_dudt.Size(), [=] MFEM_HOST_DEVICE (
int i)
716 { fd[i] = mfem::real_t(0);});
719 if(!operator_cache.u_bnd_restr_ready){
720 operator_cache.restr_b->Mult(pu, bnd_u);
721 operator_cache.u_bnd_restr_ready =
true;
724 const mfem::real_t *u_d = bnd_u.Read();
725 mfem::real_t *rhs_d = rhs_faces.Write();
727 const mfem::real_t *nor_d = dc.bnd_nor_d;
728 const mfem::real_t *radius_d = dc.bnd_radius_d;
729 const mfem::real_t *inv1_d = dc.bnd_wt_d;
730 const int *bnd_marker_index_d = dc.bnd_marker_index_d;
731 mfem::real_t *ws_d = dc.bndWaveSpeed_d;
733 mfem::forall(npoints_bnd, [=] MFEM_HOST_DEVICE (
int p)
735 const int f = p / nfp;
736 const int fp = p % nfp;
738 int bnd_face_marker_index = bnd_marker_index_d[f];
739 if(bnd_face_marker_index < 0){
743 int bc_index = bnd_face_marker_index;
755 const int face_offset = f * face_size;
756 const int n_offset = f * norm_size;
757 const int w_offset = f * nfp;
759 const mfem::real_t *u_face_d = u_d + face_offset;
760 mfem::real_t *rhs_face_d = rhs_d + face_offset;
761 const mfem::real_t *nor_face_d = nor_d + n_offset;
762 const mfem::real_t *w_minus_d = inv1_d + w_offset;
763 const mfem::real_t *nor_point = nor_face_d + fp*dim;
764 const mfem::real_t radius = dc.axisymmetric ? radius_d[w_offset + fp] : 0.0;
765 mfem::real_t scale = -w_minus_d[fp];
771 const mfem::real_t *dprim_face_x = (dim > 0) ? grad_prim_d[0] + face_offset :
nullptr;
772 const mfem::real_t *dprim_face_y = (dim > 1) ? grad_prim_d[1] + face_offset :
nullptr;
773 const mfem::real_t *dprim_face_z = (dim > 2) ? grad_prim_d[2] + face_offset :
nullptr;
775 dim, nfp, neq, fp, gradPrim_x, gradPrim_y,
779 const mfem::real_t ws = \
780 Theseus::BC::ApplyViscousBoundaryCondition(dc, bc, state1, gradPrim_x, gradPrim_y,
781 gradPrim_z, nor_point, radius, fluxN);
786 operator_cache.restr_b->MultTranspose(rhs_faces, faces_dudt);
791 const mfem::real_t *ws = operator_cache.bndWaveSpeed.HostRead();
792 mfem::real_t max_char_speed_facial = 0.0;
793 for(
int p = 0;p < npoints_bnd;p++)
795 max_char_speed_facial = std::max(max_char_speed_facial, ws[p]);
798 return max_char_speed_facial;
803 mfem::Vector &pdudt)
const
807 auto dc = device_cache;
808 const int dim = dc.dim;
809 const int restr_size = operator_cache.restr_v->Height();
811 mfem::Vector &vol_u(operator_cache.uVol);
812 if(vol_u.Size() != restr_size){
813 vol_u.SetSize(restr_size);
817 mfem::Vector &dUe(operator_cache.rhsVol);
818 if(dUe.Size() != restr_size){
819 dUe.SetSize(restr_size);
823 std::vector<mfem::Vector> &vol_grad_prim(operator_cache.gradVol);
824 if(vol_grad_prim.size() != dim){
825 vol_grad_prim.resize(dim);
826 for(
int idim = 0;idim < dim;idim++){
827 vol_grad_prim[idim].SetSize(restr_size);
828 vol_grad_prim[idim].UseDevice();
832 if(!operator_cache.u_vol_restr_ready){
833 operator_cache.restr_v->Mult(pu, vol_u);
834 operator_cache.u_vol_restr_ready =
true;
836 for(
int idim = 0;idim < dim;idim++){
837 operator_cache.restr_v->Mult(*p_grad_prim[idim], vol_grad_prim[idim]);
842 mfem::real_t *d = dUe.Write();
843 mfem::forall(dUe.Size(), [=] MFEM_HOST_DEVICE (
int i) { d[i] = mfem::real_t(0); });
847 const mfem::real_t *Ue_d = vol_u.Read();
848 const mfem::real_t *gradPrim_d[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
849 for(
int idim = 0;idim < dim;idim++){
850 gradPrim_d[idim] = vol_grad_prim[idim].Read();
854 mfem::real_t *dUe_d = dUe.Write();
857 const int ne = dc.num_elements;
858 const int ndof = dc.ndof_scalar_el;
859 const int neq = dc.num_equations;
861#ifdef SUBCELL_FV_BLENDING
862 const int Np_x = dc.Np_x;
863 const int Np_y = dc.Np_y;
864 const int Np_z = dc.Np_z;
865 const int npe_metric_xi = (Np_x + 1)*Np_y*Np_z;
866 const int npe_metric_eta = Np_x*(Np_y + 1)*Np_z;
867 const int npe_metric_zeta = Np_x * Np_y * (Np_z + 1);
868 const mfem::real_t *metric_xi_d = dc.subcell_metric_xi_d;
869 const mfem::real_t *metric_eta_d = (dim > 1 ? dc.subcell_metric_eta_d :
nullptr);
870 const mfem::real_t *metric_zeta_d = (dim > 2 ? dc.subcell_metric_zeta_d :
nullptr);
872 mfem::Vector dUfv(operator_cache.restr_v->Height());
874 mfem::real_t *dUfv_d = dUfv.Write();
877 mfem::real_t *d = dUfv_d;
878 mfem::forall(dUfv.Size(), [=] MFEM_HOST_DEVICE (
int i) { d[i] = mfem::real_t(0); });
881 const mfem::real_t *alpha_d = operator_cache.alpha->Read();
885 const int metric_stride = ndof * dim * dim;
886 const int jac_stride = ndof;
887 const int estride = ndof*neq;
890 const int *elem_attr_d = dc.elem_attr_d;
891 const int *attr_marker_d = dc.attr_marker_d;
892 const mfem::real_t *elJac_d = dc.elJac_d;
893 const mfem::real_t *elMetric_d = dc.elMetric_d;
894 const mfem::real_t *elRadius_d = dc.elRadius_d;
896 mfem::real_t *ws_d = dc.elWaveSpeed_d;
899 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
902 const mfem::real_t *jac_el = elJac_d + e * jac_stride;
903 const mfem::real_t *metric_el = elMetric_d + e * metric_stride;
904 const mfem::real_t *radius_el = dc.axisymmetric ?
905 elRadius_d + e * jac_stride :
nullptr;
907 const int attr = elem_attr_d[e];
908 if (attr_marker_d[attr-1] == 0) {
914 const int eoff = e * estride;
915 const mfem::real_t *u_el = Ue_d + eoff;
916 mfem::real_t *du_el = dUe_d + eoff;
918 mfem::real_t cs_el = \
919 Theseus::DGSEMIntegrator::AssembleElementVolumeKernel(dc, u_el,
920 jac_el, metric_el, du_el);
921#ifdef SUBCELL_FV_BLENDING
922 mfem::real_t alpha_fv = alpha_d[e];
923 if(alpha_fv > 1e-16){
924 mfem::real_t alpha_dg = (1.0 - alpha_fv);
925 mfem::real_t *du_fv = dUfv_d + eoff;
926 const mfem::real_t *el_metric_xi = metric_xi_d + e * npe_metric_xi * dim;
927 const mfem::real_t *el_metric_eta = (dim > 1 ? metric_eta_d + e * npe_metric_eta * dim :
929 const mfem::real_t *el_metric_zeta = (dim > 2 ? metric_zeta_d + e * npe_metric_zeta * dim :
931 const mfem::real_t cs_fv = \
932 Theseus::DGSEMIntegrator::ComputeFVFluxesKernel(dc, u_el, jac_el, el_metric_xi, el_metric_eta, el_metric_zeta, du_fv);
934 for(
int ipt = 0;ipt < estride;ipt++){
935 du_el[ipt] = alpha_dg * du_el[ipt] + alpha_fv * du_fv[ipt];
942 dc, u_el, radius_el, jac_el, metric_el, du_el);
948 const mfem::real_t *grad_prim_el[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
949 for(
int idim = 0;idim < dim;idim++){
950 grad_prim_el[idim] = gradPrim_d[idim] + eoff;
953 Theseus::DGSEMIntegrator::AssembleViscousElementVolumeKernel(dc, u_el, jac_el, metric_el,
955 grad_prim_el[0], grad_prim_el[1],
956 grad_prim_el[2], du_el);
962 operator_cache.restr_v->AddMultTranspose(dUe, pdudt);
966 const mfem::real_t *ws = operator_cache.elWaveSpeed.HostRead();
967 mfem::real_t max_char_speed = 0.0;
968 for(
int e = 0;e < operator_cache.num_elements;e++)
970 max_char_speed = std::max(max_char_speed, ws[e]);
973 return max_char_speed;
978 mfem::Vector &pdudt)
const
980 const int dim = operator_cache.dim;
981 std::vector<mfem::Vector *> p_grad_(dim);
984 const int psize = this->P->Height();
985 if(operator_cache.pGrad.size() != dim){
986 operator_cache.pGrad.resize(dim);
987 for(
int idim = 0;idim < dim;idim++){
988 operator_cache.pGrad[idim].SetSize(psize);
989 operator_cache.pGrad[idim].UseDevice();
992 for(
int idim = 0;idim < dim;idim++){
993 p_grad_[idim] = &(operator_cache.pGrad[idim]);
994 this->P->Mult(*grad_prim[idim], *p_grad_[idim]);
996 if(operator_cache.pdudt.Size() != psize){
997 operator_cache.pdudt.SetSize(psize);
998 operator_cache.pdudt.UseDevice();
1001 const std::vector<mfem::Vector *> &pGradPrim = this->P ? p_grad_ : grad_prim;
1003 mfem::real_t max_char_speed = MultCNS_Volume(u, pGradPrim, pdudt);
1005 mfem::real_t max_char_speed_faces = MultCNS_InteriorFaces(u, pGradPrim, pdudt);
1006 max_char_speed = std::max(max_char_speed, max_char_speed_faces);
1008 mfem::real_t max_char_speed_bnd = MultCNS_BoundaryFaces(u, pGradPrim, pdudt);
1009 max_char_speed = std::max(max_char_speed, max_char_speed_bnd);
1011 return max_char_speed;