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);
196 std::vector<mfem::Vector *> &p_grad_u)
const
200 const int dim = operator_cache.dim;
201 const int restr_size = operator_cache.restr_v->Height();
203 if(operator_cache.sVol.Size() != restr_size){
204 operator_cache.sVol.SetSize(restr_size);
205 operator_cache.sVol.UseDevice();
207 mfem::Vector &Ue(operator_cache.sVol);
210 if (operator_cache.gradVol.size() != dim){
211 operator_cache.gradVol.resize(dim);
212 for(
int idim = 0;idim < dim;idim++){
213 operator_cache.gradVol[idim].SetSize(restr_size);
214 operator_cache.gradVol[idim].UseDevice();
217 std::vector<mfem::Vector> &dUe(operator_cache.gradVol);
218 for(
int idim = 0;idim < dim;idim++){
219 dU_d[idim] = dUe[idim].Write();
220 pgrad_d[idim] = p_grad_u[idim]->Write();
223 mfem::forall(restr_size, [=] MFEM_HOST_DEVICE (
int i)
225 for(
int idim = 0;idim < dim;idim++){
226 dU_d[idim][i] = mfem::real_t(0);
227 pgrad_d[idim][i] = mfem::real_t(0);
231 operator_cache.restr_v->Mult(pu, Ue);
232 const mfem::real_t *Ue_d = Ue.Read();
234 auto dc = device_cache;
236 const int ne = dc.num_elements;
237 const int ndof = dc.ndof_scalar_el;
238 const int neq = dc.num_equations;
239 const int npoints = ne * ndof;
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#ifdef POINT_PARALLEL_VOLUME
248 mfem::forall(npoints, [=] MFEM_HOST_DEVICE (
int p)
250 const int e = p / ndof;
251 const int point = p % ndof;
252 const int element_offset = e * estride;
254 for(
int idim = 0; idim < dim; ++idim){
255 du_el_d[idim] = dU_d[idim] + element_offset;
258 Theseus::DGSEMIntegrator::AssembleGradVolumePointKernel(
259 dc, Ue_d + element_offset, elJac_d + e*jac_stride,
260 elMetric_d + e*metric_stride, point, du_el_d);
263 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
265 const mfem::real_t *u_el = Ue_d + e * estride;
267 for(
int idim = 0;idim < dim;idim++){
268 du_el_d[idim] = dU_d[idim] + e*estride;
271 const mfem::real_t *jac_el = elJac_d + e * jac_stride;
272 const mfem::real_t *metric_el = elMetric_d + e * metric_stride;
274 Theseus::DGSEMIntegrator::AssembleGradElementVolumeKernel(dc, u_el, jac_el, metric_el,
279 for(
int idim = 0;idim < dim;idim++){
280 operator_cache.restr_v->AddMultTranspose(dUe[idim], *p_grad_u[idim]);
287 std::vector<mfem::Vector *> &p_grad_u)
const
291 auto dc = device_cache;
292 const int dim = dc.dim;
293 const int neq = dc.num_equations;
294 const int nfp = dc.num_face_points;
295 const int face_size = nfp * neq;
296 const int restr_size = operator_cache.restr_b->Height();
297 const int nfaces_restr = restr_size / face_size;
298 const int norm_size = nfp * dim;
299 const int npoints_bnd = nfaces_restr * nfp;
300 const int psize = pu.Size();
306 mfem::Vector &u_faces(operator_cache.sBnd);
307 if(u_faces.Size() != restr_size){
308 u_faces.SetSize(restr_size);
312 std::vector<mfem::Vector> &rhs_faces(operator_cache.gradBnd);
313 if(rhs_faces.size() != dim){
314 rhs_faces.resize(dim);
315 for(
int idim = 0;idim < dim;idim++){
316 rhs_faces[idim].SetSize(restr_size);
317 rhs_faces[idim].UseDevice();
321 mfem::Vector &duBnd(operator_cache.duBnd);
322 if(duBnd.Size() != psize){
323 duBnd.SetSize(psize);
327 operator_cache.restr_b->Mult(pu, u_faces);
329 const mfem::real_t *u_d = u_faces.Read();
330 const mfem::real_t *nor_d = dc.bnd_nor_d;
331 const mfem::real_t *wt_d = dc.bnd_wt_d;
332 const int *bnd_marker_index_d = dc.bnd_marker_index_d;
336 for(
int idim = 0;idim < dim;idim++){
337 rhs_d[idim] = rhs_faces[idim].Write();
338 du_d[idim] = duBnd.Write();
341 for (
int idim = 0; idim < dim; ++idim) {
342 mfem::real_t *rd = rhs_d[idim];
343 mfem::forall(restr_size, [=] MFEM_HOST_DEVICE (
int i) { rd[i] = mfem::real_t(0); });
345 for (
int idim = 0; idim < 1; ++idim) {
346 mfem::real_t *dud = du_d[idim];
347 mfem::forall(psize, [=] MFEM_HOST_DEVICE (
int i) { dud[i] = mfem::real_t(0); });
350 mfem::forall(npoints_bnd, [=] MFEM_HOST_DEVICE (
int p)
352 const int f = p / nfp;
353 const int fp = p % nfp;
355 const int bnd_face_marker_index = bnd_marker_index_d[f];
356 if (bnd_face_marker_index < 0)
361 const int bc_index = bnd_face_marker_index;
373 const int face_offset = f * face_size;
374 const int norm_offset = f * norm_size;
375 const int w_offset = f * nfp;
377 const mfem::real_t *u_face_d = u_d + face_offset;
379 const mfem::real_t *nor_face_d = nor_d + norm_offset;
380 const mfem::real_t *nor_point = nor_face_d + fp * dim;
383 const mfem::real_t scale = wt_d[w_offset + fp];
386 for(
int idim = 0;idim < dim;idim++){
387 rhs_face[idim] = rhs_d[idim] + face_offset;
390 Theseus::DGSEMIntegrator::AssembleGradBoundaryPointKernel(dc, bc,
398 for(
int idim = 0;idim < dim;idim++){
399 operator_cache.restr_b->MultTranspose(rhs_faces[idim], duBnd);
400 *p_grad_u[idim] += duBnd;
407 std::vector<mfem::Vector *> &p_grad_u)
const
411 auto dc = device_cache;
412 const int dim = dc.dim;
413 const int psize = pu.Size();
414 const int restr_size = operator_cache.restr_f->Height();
415 const int neq = dc.num_equations;
416 const int nfp = dc.num_face_points;
417 const int nfaces = restr_size / (2 * nfp * neq);
418 const int npoints = nfaces * nfp;
419 const int face_size = 2 * nfp * neq;
421 mfem::Vector &u_faces(operator_cache.sInt);
422 if(u_faces.Size() != restr_size){
423 u_faces.SetSize(restr_size);
427 std::vector<mfem::Vector> &rhs_faces(operator_cache.gradInt);
428 if(rhs_faces.size() != dim){
429 rhs_faces.resize(dim);
430 for(
int idim = 0;idim < dim;idim++){
431 rhs_faces[idim].SetSize(restr_size);
432 rhs_faces[idim].UseDevice();
436 mfem::Vector &duInt(operator_cache.duInt);
437 if(duInt.Size() != psize){
438 duInt.SetSize(psize);
442 operator_cache.restr_f->Mult(pu, u_faces);
443 const mfem::real_t *u_d = u_faces.Read();
447 for(
int idim = 0;idim < dim;idim++){
448 rhs_d[idim] = rhs_faces[idim].Write();
450 du_d[idim] = duInt.Write();
453 for (
int idim = 0; idim < dim; ++idim) {
454 mfem::real_t *rd = rhs_d[idim];
455 mfem::forall(restr_size, [=] MFEM_HOST_DEVICE (
int i) { rd[i] = mfem::real_t(0); });
458 for (
int idim = 0; idim < 1; ++idim) {
459 mfem::real_t *dud = du_d[idim];
460 mfem::forall(psize, [=] MFEM_HOST_DEVICE (
int i) { dud[i] = mfem::real_t(0); });
463 const mfem::real_t *nor_d = dc.nor_d;
464 const mfem::real_t *wm_d = dc.fw_minus_d;
465 const mfem::real_t *wp_d = dc.fw_plus_d;
467#ifdef POINT_PARALLEL_INTERIOR_FACES
468 mfem::forall(npoints, [=] MFEM_HOST_DEVICE (
int p)
470 const int f = p / nfp;
471 const int fp = p % nfp;
472 const int face_offset = f * face_size;
473 const int point_offset = f * nfp + fp;
476 for(
int idim = 0; idim < dim; ++idim){
477 rhs_face[idim] = rhs_d[idim] + face_offset;
480 Theseus::DGSEMIntegrator::AssembleGradInteriorFacePointKernel(
481 dc, u_d + face_offset, nor_d + point_offset*dim,
482 wm_d[point_offset], wp_d[point_offset], fp, rhs_face);
485 const int norm_size = nfp * dim;
486 mfem::forall(nfaces, [=] MFEM_HOST_DEVICE (
int f)
488 const int face_offset = f * face_size;
489 const int norm_offset = f * norm_size;
490 const int w_offset = f * nfp;
492 const mfem::real_t *u_face_d = u_d + face_offset;
493 const mfem::real_t *nor_face_d = nor_d + norm_offset;
494 const mfem::real_t *w_minus_d = wm_d + w_offset;
495 const mfem::real_t *w_plus_d = wp_d + w_offset;
498 for(
int idim = 0;idim < dim;idim++){
499 rhs_face[idim] = rhs_d[idim] + face_offset;
502 Theseus::DGSEMIntegrator::AssembleGradInteriorFaceKernel(dc,
511 for(
int idim = 0;idim < dim;idim++){
512 operator_cache.restr_f->MultTranspose(rhs_faces[idim], duInt);
513 *p_grad_u[idim] += duInt;
520 std::vector<mfem::Vector *> &grad_u)
const
523 const int dim = operator_cache.dim;
524 const mfem::Vector &pu = this->Prolongate(u);
525 std::vector<mfem::Vector *> p_grad_(dim);
528 const int psize = this->P->Height();
529 if(operator_cache.pGrad.size() != dim){
530 operator_cache.pGrad.resize(dim);
531 for(
int idim = 0;idim < dim;idim++){
532 operator_cache.pGrad[idim].SetSize(psize);
533 operator_cache.pGrad[idim].UseDevice();
536 for(
int idim = 0;idim < dim;idim++){
537 p_grad_[idim] = &(operator_cache.pGrad[idim]);
540 std::vector<mfem::Vector *> &p_grad_u = this->P ? p_grad_ : grad_u;
542 MFEM_ASSERT(p_grad_u.size() == dim,
"Size mismatch for gradient storage");
543 MFEM_ASSERT(grad_u.size() == dim,
"Size mismatch for gradient storage");
545 GradOperator_Volume(pu, p_grad_u);
547 GradOperator_InteriorFaces(pu, p_grad_u);
549 GradOperator_BoundaryFaces(pu, p_grad_u);
555 for(
int idim = 0;idim < dim;idim++){
556 this->cP->MultTranspose(*p_grad_u[idim], *grad_u[idim]);
563 for(
int idim = 0;idim < dim;idim++){
564 this->P->MultTranspose(*p_grad_u[idim], *grad_u[idim]);
569 const int N = this->ess_tdof_list.Size();
570 const auto idx = this->ess_tdof_list.Read();
572 for(
int idim = 0;idim < dim;idim++){
573 auto gradu_dim_d = grad_u[idim]->ReadWrite();
574 mfem::forall(N, [=] MFEM_HOST_DEVICE (
int i) { gradu_dim_d[idx[i]] = 0.0; });
580 const std::vector<mfem::Vector *> &p_grad_prim,
581 mfem::Vector &pdudt)
const
585 auto dc = device_cache;
586 const int dim = dc.dim;
587 const int neq = dc.num_equations;
588 const int nfp = dc.num_face_points;
589 const int nfaces = operator_cache.restr_f->Height() / (nfp * neq * 2);
590 const int npoints = nfaces * nfp;
591 const int face_size = 2*nfp*neq;
593 const int restr_size = operator_cache.restr_f->Height();
594 mfem::Vector &int_u(operator_cache.uInt);
595 if(int_u.Size() != restr_size){
596 int_u.SetSize(restr_size);
600 mfem::Vector &rhs_faces(operator_cache.rhsInt);
601 if(rhs_faces.Size() != restr_size){
602 rhs_faces.SetSize(restr_size);
603 rhs_faces.UseDevice();
606 mfem::Vector &faces_dudt(operator_cache.dudtInt);
607 if(faces_dudt.Size() != pdudt.Size()){
608 faces_dudt.SetSize(pdudt.Size());
609 faces_dudt.UseDevice();
613 const mfem::real_t *grad_prim_d[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
614 std::vector<mfem::Vector> &int_grad_prim(operator_cache.gradInt);
616 if(int_grad_prim.size() != dim){
617 int_grad_prim.resize(dim);
618 for(
int idim = 0;idim < dim;idim++){
619 int_grad_prim[idim].SetSize(restr_size);
620 int_grad_prim[idim].UseDevice();
626 for(
int idim = 0;idim < dim;idim++){
627 operator_cache.restr_f->Mult(*p_grad_prim[idim], int_grad_prim[idim]);
628 grad_prim_d[idim] = int_grad_prim[idim].Read();
636 mfem::real_t *d = rhs_faces.Write();
637 mfem::forall(rhs_faces.Size(), [=] MFEM_HOST_DEVICE (
int i) { d[i] = mfem::real_t(0); });
640 if(!operator_cache.u_int_restr_ready){
641 operator_cache.restr_f->Mult(pu, int_u);
642 operator_cache.u_int_restr_ready =
true;
645 const mfem::real_t *u_d = int_u.Read();
646 mfem::real_t *rhs_d = rhs_faces.Write();
647 const mfem::real_t *nor_d = dc.nor_d;
648 const mfem::real_t *inv1_d = dc.fw_minus_d;
649 const mfem::real_t *inv2_d = dc.fw_plus_d;
650 const mfem::real_t *face_radius_d = dc.face_radius_d;
654#ifdef POINT_PARALLEL_INTERIOR_FACES
655 mfem::forall(npoints, [=] MFEM_HOST_DEVICE (
int p)
657 const int f = p / nfp;
658 const int fp = p % nfp;
659 const int face_offset = f*face_size;
660 const int point_offset = f*nfp + fp;
662 const mfem::real_t *u_face_d = u_d + face_offset;
663 mfem::real_t *rhs_face_d = rhs_d + face_offset;
664 const mfem::real_t *dprim_face_x =
665 (dim > 0) ? grad_prim_d[0] + face_offset :
nullptr;
666 const mfem::real_t *dprim_face_y =
667 (dim > 1) ? grad_prim_d[1] + face_offset :
nullptr;
668 const mfem::real_t *dprim_face_z =
669 (dim > 2) ? grad_prim_d[2] + face_offset :
nullptr;
670 const mfem::real_t radius =
671 dc.axisymmetric ? face_radius_d[point_offset] : 0.0;
673 Theseus::DGSEMIntegrator::AssembleViscousFacePointKernel(
674 dc, u_face_d, nor_d + point_offset*dim,
675 inv1_d[point_offset], inv2_d[point_offset],
676 dprim_face_x, dprim_face_y, dprim_face_z, radius, fp, rhs_face_d);
679 const int norm_size = nfp*dim;
680 mfem::forall(nfaces, [=] MFEM_HOST_DEVICE (
int f)
682 const int face_offset = f*face_size;
683 const int n_offset = f*norm_size;
684 const int w_offset = f*nfp;
686 const mfem::real_t *u_face_d = u_d + face_offset;
687 mfem::real_t *rhs_face_d = rhs_d + face_offset;
688 const mfem::real_t *nor_face_d = nor_d + n_offset;
689 const mfem::real_t *w_minus_d = inv1_d + w_offset;
690 const mfem::real_t *w_plus_d = inv2_d + w_offset;
691 const mfem::real_t *radius_face_d = dc.axisymmetric ?
692 face_radius_d + w_offset :
nullptr;
693 const mfem::real_t *dprim_face_x = (dim > 0) ? grad_prim_d[0] + face_offset :
nullptr;
694 const mfem::real_t *dprim_face_y = (dim > 1) ? grad_prim_d[1] + face_offset :
nullptr;
695 const mfem::real_t *dprim_face_z = (dim > 2) ? grad_prim_d[2] + face_offset :
nullptr;
698 Theseus::DGSEMIntegrator::AssembleViscousElementFaceKernel(
699 dc, u_face_d, nor_face_d, w_minus_d, w_plus_d,
700 dprim_face_x, dprim_face_y, dprim_face_z, radius_face_d,
708 operator_cache.restr_f->MultTranspose(rhs_faces, faces_dudt);
717 const std::vector<mfem::Vector *> &p_grad_prim,
718 mfem::Vector &pdudt)
const
722 auto dc = device_cache;
723 const int dim = dc.dim;
724 const int neq = dc.num_equations;
725 const int nfp = dc.num_face_points;
726 const int face_size = nfp * neq;
727 const int restr_size = operator_cache.restr_b->Height();
728 const int nfaces_restr = restr_size / face_size;
729 const int norm_size = nfp * dc.dim;
730 const int npoints_bnd = nfaces_restr * nfp;
731 const int psize = pdudt.Size();
737 mfem::Vector &rhs_faces(operator_cache.rhsBnd);
738 mfem::Vector &faces_dudt(operator_cache.dudtBnd);
739 if(rhs_faces.Size() != restr_size){
740 rhs_faces.SetSize(restr_size);
741 rhs_faces.UseDevice();
743 if(faces_dudt.Size() != psize){
744 faces_dudt.SetSize(psize);
745 faces_dudt.UseDevice();
747 mfem::Vector &bnd_u(operator_cache.uBnd);
748 if(bnd_u.Size() != restr_size){
749 bnd_u.SetSize(restr_size);
752 const mfem::real_t *grad_prim_d[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
753 std::vector<mfem::Vector> &bnd_grad_prim(operator_cache.gradBnd);
754 if(bnd_grad_prim.size() != dim){
755 bnd_grad_prim.resize(dim);
756 for(
int idim = 0;idim < dim;idim++){
757 bnd_grad_prim[idim].SetSize(restr_size);
758 bnd_grad_prim[idim].UseDevice();
761 for(
int idim = 0;idim < dim;idim++){
762 operator_cache.restr_b->Mult(*p_grad_prim[idim], bnd_grad_prim[idim]);
763 grad_prim_d[idim] = bnd_grad_prim[idim].Read();
769 mfem::real_t *rd = rhs_faces.Write();
770 mfem::forall(rhs_faces.Size(), [=] MFEM_HOST_DEVICE (
int i)
771 { rd[i] = mfem::real_t(0);});
772 mfem::real_t *fd = faces_dudt.Write();
773 mfem::forall(faces_dudt.Size(), [=] MFEM_HOST_DEVICE (
int i)
774 { fd[i] = mfem::real_t(0);});
777 if(!operator_cache.u_bnd_restr_ready){
778 operator_cache.restr_b->Mult(pu, bnd_u);
779 operator_cache.u_bnd_restr_ready =
true;
782 const mfem::real_t *u_d = bnd_u.Read();
783 mfem::real_t *rhs_d = rhs_faces.Write();
785 const mfem::real_t *nor_d = dc.bnd_nor_d;
786 const mfem::real_t *radius_d = dc.bnd_radius_d;
787 const mfem::real_t *inv1_d = dc.bnd_wt_d;
788 const int *bnd_marker_index_d = dc.bnd_marker_index_d;
789 mfem::forall(npoints_bnd, [=] MFEM_HOST_DEVICE (
int p)
791 const int f = p / nfp;
792 const int fp = p % nfp;
794 int bnd_face_marker_index = bnd_marker_index_d[f];
795 if(bnd_face_marker_index < 0){
798 int bc_index = bnd_face_marker_index;
808 const int face_offset = f * face_size;
809 const int n_offset = f * norm_size;
810 const int w_offset = f * nfp;
812 const mfem::real_t *u_face_d = u_d + face_offset;
813 mfem::real_t *rhs_face_d = rhs_d + face_offset;
814 const mfem::real_t *nor_face_d = nor_d + n_offset;
815 const mfem::real_t *w_minus_d = inv1_d + w_offset;
816 const mfem::real_t *nor_point = nor_face_d + fp*dim;
817 const mfem::real_t radius = dc.axisymmetric ? radius_d[w_offset + fp] : 0.0;
818 mfem::real_t scale = -w_minus_d[fp];
824 const mfem::real_t *dprim_face_x = (dim > 0) ? grad_prim_d[0] + face_offset :
nullptr;
825 const mfem::real_t *dprim_face_y = (dim > 1) ? grad_prim_d[1] + face_offset :
nullptr;
826 const mfem::real_t *dprim_face_z = (dim > 2) ? grad_prim_d[2] + face_offset :
nullptr;
828 dim, nfp, neq, fp, gradPrim_x, gradPrim_y,
833 dc, bc, state1, gradPrim_x, gradPrim_y,
834 gradPrim_z, nor_point, radius, fluxN);
838 operator_cache.restr_b->MultTranspose(rhs_faces, faces_dudt);
845 mfem::Vector &pdudt)
const
849 auto dc = device_cache;
850 const int dim = dc.dim;
851 const int restr_size = operator_cache.restr_v->Height();
853 mfem::Vector &vol_u(operator_cache.uVol);
854 if(vol_u.Size() != restr_size){
855 vol_u.SetSize(restr_size);
859 mfem::Vector &dUe(operator_cache.rhsVol);
860 if(dUe.Size() != restr_size){
861 dUe.SetSize(restr_size);
865 std::vector<mfem::Vector> &vol_grad_prim(operator_cache.gradVol);
866 if(vol_grad_prim.size() != dim){
867 vol_grad_prim.resize(dim);
868 for(
int idim = 0;idim < dim;idim++){
869 vol_grad_prim[idim].SetSize(restr_size);
870 vol_grad_prim[idim].UseDevice();
874 if(!operator_cache.u_vol_restr_ready){
875 operator_cache.restr_v->Mult(pu, vol_u);
876 operator_cache.u_vol_restr_ready =
true;
878 for(
int idim = 0;idim < dim;idim++){
879 operator_cache.restr_v->Mult(*p_grad_prim[idim], vol_grad_prim[idim]);
884 mfem::real_t *d = dUe.Write();
885 mfem::forall(dUe.Size(), [=] MFEM_HOST_DEVICE (
int i) { d[i] = mfem::real_t(0); });
889 const mfem::real_t *Ue_d = vol_u.Read();
890 const mfem::real_t *gradPrim_d[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
891 for(
int idim = 0;idim < dim;idim++){
892 gradPrim_d[idim] = vol_grad_prim[idim].Read();
896 mfem::real_t *dUe_d = dUe.Write();
899 const int ne = dc.num_elements;
900 const int ndof = dc.ndof_scalar_el;
901 const int neq = dc.num_equations;
903#ifdef SUBCELL_FV_BLENDING
904 const int Np_x = dc.Np_x;
905 const int Np_y = dc.Np_y;
906 const int Np_z = dc.Np_z;
907 const int npe_metric_xi = (Np_x + 1)*Np_y*Np_z;
908 const int npe_metric_eta = Np_x*(Np_y + 1)*Np_z;
909 const int npe_metric_zeta = Np_x * Np_y * (Np_z + 1);
910 const mfem::real_t *metric_xi_d = dc.subcell_metric_xi_d;
911 const mfem::real_t *metric_eta_d = (dim > 1 ? dc.subcell_metric_eta_d :
nullptr);
912 const mfem::real_t *metric_zeta_d = (dim > 2 ? dc.subcell_metric_zeta_d :
nullptr);
914 mfem::Vector dUfv(operator_cache.restr_v->Height());
916 mfem::real_t *dUfv_d = dUfv.Write();
919 mfem::real_t *d = dUfv_d;
920 mfem::forall(dUfv.Size(), [=] MFEM_HOST_DEVICE (
int i) { d[i] = mfem::real_t(0); });
923 const mfem::real_t *alpha_d = operator_cache.alpha->Read();
927 const int metric_stride = ndof * dim * dim;
928 const int jac_stride = ndof;
929 const int estride = ndof*neq;
932 const int *elem_attr_d = dc.elem_attr_d;
933 const int *attr_marker_d = dc.attr_marker_d;
934 const mfem::real_t *elJac_d = dc.elJac_d;
935 const mfem::real_t *elMetric_d = dc.elMetric_d;
936 const mfem::real_t *elRadius_d = dc.elRadius_d;
938#ifdef POINT_PARALLEL_VOLUME
939 const int npoints = ne * ndof;
940 mfem::forall(npoints, [=] MFEM_HOST_DEVICE (
int p)
942 const int e = p / ndof;
943 const int point = p % ndof;
944 const int attr = elem_attr_d[e];
945 if (attr_marker_d[attr-1] == 0) {
949 const int element_offset = e * estride;
950 DGSEMIntegrator::AssembleVolumePointKernel(
951 dc, Ue_d + element_offset, elJac_d + e*jac_stride,
952 elMetric_d + e*metric_stride, point, dUe_d + element_offset);
957 mfem::forall(ne, [=] MFEM_HOST_DEVICE (
int e)
960 const mfem::real_t *jac_el = elJac_d + e * jac_stride;
961 const mfem::real_t *metric_el = elMetric_d + e * metric_stride;
962 const mfem::real_t *radius_el = dc.axisymmetric ?
963 elRadius_d + e * jac_stride :
nullptr;
965 const int attr = elem_attr_d[e];
966 if (attr_marker_d[attr-1] == 0) {
971 const int eoff = e * estride;
972 const mfem::real_t *u_el = Ue_d + eoff;
973 mfem::real_t *du_el = dUe_d + eoff;
975#ifndef POINT_PARALLEL_VOLUME
976 Theseus::DGSEMIntegrator::AssembleElementVolumeKernel(
977 dc, u_el, jac_el, metric_el, du_el);
979#ifdef SUBCELL_FV_BLENDING
980 mfem::real_t alpha_fv = alpha_d[e];
981 if(alpha_fv > 1e-16){
982 mfem::real_t alpha_dg = (1.0 - alpha_fv);
983 mfem::real_t *du_fv = dUfv_d + eoff;
984 const mfem::real_t *el_metric_xi = metric_xi_d + e * npe_metric_xi * dim;
985 const mfem::real_t *el_metric_eta = (dim > 1 ? metric_eta_d + e * npe_metric_eta * dim :
987 const mfem::real_t *el_metric_zeta = (dim > 2 ? metric_zeta_d + e * npe_metric_zeta * dim :
989 Theseus::DGSEMIntegrator::ComputeFVFluxesKernel(
990 dc, u_el, jac_el, el_metric_xi, el_metric_eta,
991 el_metric_zeta, du_fv);
993 for(
int ipt = 0;ipt < estride;ipt++){
994 du_el[ipt] = alpha_dg * du_el[ipt] + alpha_fv * du_fv[ipt];
1000 dc, u_el, radius_el, jac_el, metric_el, du_el);
1001#ifndef POINT_PARALLEL_VOLUME
1002 const mfem::real_t *grad_prim_el[
Theseus::MAXDIM] = {
nullptr,
nullptr,
nullptr};
1003 for(
int idim = 0;idim < dim;idim++){
1004 grad_prim_el[idim] = gradPrim_d[idim] + eoff;
1007 Theseus::DGSEMIntegrator::AssembleViscousElementVolumeKernel(dc, u_el, jac_el, metric_el,
1009 grad_prim_el[0], grad_prim_el[1],
1010 grad_prim_el[2], du_el);
1015#ifdef POINT_PARALLEL_VOLUME
1016 mfem::forall(npoints, [=] MFEM_HOST_DEVICE (
int p)
1018 const int e = p / ndof;
1019 const int point = p % ndof;
1020 const int attr = elem_attr_d[e];
1021 if (attr_marker_d[attr-1] == 0) {
1025 const int element_offset = e * estride;
1027 nullptr,
nullptr,
nullptr};
1028 for(
int idim = 0; idim < dim; ++idim){
1029 grad_prim_el[idim] = gradPrim_d[idim] + element_offset;
1032 Theseus::DGSEMIntegrator::AssembleViscousVolumePointKernel(
1033 dc, Ue_d + element_offset, elJac_d + e*jac_stride,
1034 elMetric_d + e*metric_stride,
1035 dc.axisymmetric ? elRadius_d + e*jac_stride :
nullptr,
1036 grad_prim_el[0], grad_prim_el[1], grad_prim_el[2], point,
1037 dUe_d + element_offset);
1043 operator_cache.restr_v->AddMultTranspose(dUe, pdudt);
1049 mfem::Vector &pdudt)
const
1051 const int dim = operator_cache.dim;
1052 std::vector<mfem::Vector *> p_grad_(dim);
1055 const int psize = this->P->Height();
1056 if(operator_cache.pGrad.size() != dim){
1057 operator_cache.pGrad.resize(dim);
1058 for(
int idim = 0;idim < dim;idim++){
1059 operator_cache.pGrad[idim].SetSize(psize);
1060 operator_cache.pGrad[idim].UseDevice();
1063 for(
int idim = 0;idim < dim;idim++){
1064 p_grad_[idim] = &(operator_cache.pGrad[idim]);
1065 this->P->Mult(*grad_prim[idim], *p_grad_[idim]);
1067 if(operator_cache.pdudt.Size() != psize){
1068 operator_cache.pdudt.SetSize(psize);
1069 operator_cache.pdudt.UseDevice();
1072 const std::vector<mfem::Vector *> &pGradPrim = this->P ? p_grad_ : grad_prim;
1074 MultCNS_Volume(u, pGradPrim, pdudt);
1075 MultCNS_InteriorFaces(u, pGradPrim, pdudt);
1076 MultCNS_BoundaryFaces(u, pGradPrim, pdudt);