8 #include "xtensor-python/pyarray.hpp"
10 namespace py = pybind11;
22 template<
class CompKernelType,
24 int nQuadraturePoints_element,
25 int nDOF_mesh_trial_element,
26 int nDOF_trial_element,
27 int nDOF_test_element,
28 int nQuadraturePoints_elementBoundary>
40 const double vf[nSpace],
41 const double vs[nSpace],
43 const double& rhos_min,
44 const double& rhof_min,
48 for (
int I=0;I<nSpace;I++)
49 f[I] = (1.0-vos)*vf[I] + vos*vs[I];
51 a = 1.0/( vos*rhos_min*alphaBDF + (1.0-vos)*rhof_min*alphaBDF );
59 const double& bc_flux,
60 const double n[nSpace],
61 const double f[nSpace],
64 if (isFluxBoundary == 1)
69 for (
int I=0; I < nSpace; I++)
76 const int& isFluxBoundary,
77 const double n[nSpace],
79 const double grad_potential[nSpace],
82 const double& bc_flux,
83 const double& penalty,
86 if(isFluxBoundary == 1)
90 else if(isDOFBoundary == 1)
93 for(
int I=0;I<nSpace;I++)
94 flux-= a*grad_potential[I]*
n[I];
95 flux += a*penalty*(
u-bc_u);
99 std::cerr<<
"PresInc.h: warning, diffusion term with no boundary condition set, setting diffusive flux to 0.0"<<std::endl;
106 const int& isFluxBoundary,
107 const double n[nSpace],
110 const double grad_v[nSpace],
111 const double& penalty)
114 if(isFluxBoundary==0 && isDOFBoundary==1)
116 for(
int I=0;I<nSpace;I++)
117 tmp -= a*grad_v[I]*
n[I];
124 double* mesh_trial_ref,
125 double* mesh_grad_trial_ref,
130 double* u_grad_trial_ref,
132 double* u_grad_test_ref,
134 double* mesh_trial_trace_ref,
135 double* mesh_grad_trial_trace_ref,
137 double* u_trial_trace_ref,
138 double* u_grad_trial_trace_ref,
139 double* u_test_trace_ref,
140 double* u_grad_test_trace_ref,
142 double* boundaryJac_ref,
144 int nElements_global,
166 double* elementResidual_u,
167 int nExteriorElementBoundaries_global,
168 int* exteriorElementBoundariesArray,
169 int* elementBoundaryElementsArray,
170 int* elementBoundaryLocalElementBoundariesArray,
173 double compatibility_condition,
174 int INTEGRATE_BY_PARTS_DIV_U,
177 for (
int i=0;i<nDOF_test_element;i++)
179 elementResidual_u[i]=0.0;
182 for (
int k=0;k<nQuadraturePoints_element;k++)
185 register int eN_k = eN*nQuadraturePoints_element+k,
186 eN_k_nSpace = eN_k*nSpace;
188 register double u=0.0,grad_u[nSpace],
193 jacInv[nSpace*nSpace],
194 u_grad_trial[nDOF_trial_element*nSpace],
195 u_test_dV[nDOF_trial_element],
196 u_grad_test_dV[nDOF_test_element*nSpace],
198 G[nSpace*nSpace],G_dd_G,tr_G;
202 ck.calculateMapping_element(eN,
213 dV = fabs(jacDet)*dV_ref[k];
214 ck.calculateG(jacInv,G,G_dd_G,tr_G);
216 ck.gradTrialFromRef(&u_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
218 ck.valFromElementDOF(element_u,&u_trial_ref[k*nDOF_trial_element],
u);
220 ck.gradFromElementDOF(element_u,u_grad_trial,grad_u);
222 for (
int j=0;j<nDOF_trial_element;j++)
224 u_test_dV[j] = u_test_ref[k*nDOF_trial_element+j]*dV;
225 for (
int I=0;I<nSpace;I++)
227 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
244 for(
int i=0;i<nDOF_test_element;i++)
248 register int i_nSpace=i*nSpace;
249 elementResidual_u[i] +=
250 (INTEGRATE_BY_PARTS_DIV_U == 1 ?
ck.Advection_weak(
f,&u_grad_test_dV[i_nSpace]) : q_divU[eN_k]*u_test_dV[i])
252 +
ck.NumericalDiffusion(a,grad_u,&u_grad_test_dV[i_nSpace]);
261 for (
int I=0;I<nSpace;I++)
262 q_grad_u[eN_k_nSpace+I] = grad_u[I];
268 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
269 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
270 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
271 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
272 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
273 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
274 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
275 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
276 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
277 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
278 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
279 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
280 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
281 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
282 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
283 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
284 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
285 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
286 int nElements_global = args.
scalar<
int>(
"nElements_global");
287 xt::pyarray<int>& isDOFBoundary = args.
array<
int>(
"isDOFBoundary");
288 xt::pyarray<int>& isFluxBoundary = args.
array<
int>(
"isFluxBoundary");
289 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
290 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
291 double alphaBDF = args.
scalar<
double>(
"alphaBDF");
292 xt::pyarray<double>& q_vf = args.
array<
double>(
"q_vf");
293 xt::pyarray<double>& q_divU = args.
array<
double>(
"q_divU");
294 xt::pyarray<double>& q_vs = args.
array<
double>(
"q_vs");
295 xt::pyarray<double>& q_vos = args.
array<
double>(
"q_vos");
296 double rho_s = args.
scalar<
double>(
"rho_s");
297 xt::pyarray<double>& q_rho_f = args.
array<
double>(
"q_rho_f");
298 double rho_s_min = args.
scalar<
double>(
"rho_s_min");
299 double rho_f_min = args.
scalar<
double>(
"rho_f_min");
300 xt::pyarray<double>& ebqe_vf = args.
array<
double>(
"ebqe_vf");
301 xt::pyarray<double>& ebqe_vs = args.
array<
double>(
"ebqe_vs");
302 xt::pyarray<double>& ebqe_vos = args.
array<
double>(
"ebqe_vos");
303 xt::pyarray<double>& ebqe_rho_f = args.
array<
double>(
"ebqe_rho_f");
304 xt::pyarray<double>& q_u = args.
array<
double>(
"q_u");
305 xt::pyarray<double>& q_grad_u = args.
array<
double>(
"q_grad_u");
306 xt::pyarray<double>& ebqe_u = args.
array<
double>(
"ebqe_u");
307 xt::pyarray<double>& ebqe_grad_u = args.
array<
double>(
"ebqe_grad_u");
308 xt::pyarray<double>& ebqe_bc_u_ext = args.
array<
double>(
"ebqe_bc_u_ext");
309 xt::pyarray<double>& ebqe_adv_flux = args.
array<
double>(
"ebqe_adv_flux");
310 xt::pyarray<double>& ebqe_diff_flux = args.
array<
double>(
"ebqe_diff_flux");
311 xt::pyarray<double>& bc_adv_flux = args.
array<
double>(
"bc_adv_flux");
312 xt::pyarray<double>& bc_diff_flux = args.
array<
double>(
"bc_diff_flux");
313 int offset_u = args.
scalar<
int>(
"offset_u");
314 int stride_u = args.
scalar<
int>(
"stride_u");
315 xt::pyarray<double>& globalResidual = args.
array<
double>(
"globalResidual");
316 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
317 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
318 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
319 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
320 int INTEGRATE_BY_PARTS_DIV_U = args.
scalar<
int>(
"INTEGRATE_BY_PARTS_DIV_U");
321 xt::pyarray<double>& q_a = args.
array<
double>(
"q_a");
322 xt::pyarray<double>& ebqe_a = args.
array<
double>(
"ebqe_a");
323 double compatibility_condition=0.;
362 for(
int eN=0;eN<nElements_global;eN++)
365 register double elementResidual_u[nDOF_test_element],element_u[nDOF_trial_element];
366 for (
int i=0;i<nDOF_test_element;i++)
368 register int eN_i=eN*nDOF_test_element+i;
369 element_u[i] = u_dof.data()[u_l2g.data()[eN_i]];
372 mesh_grad_trial_ref.data(),
377 u_grad_trial_ref.data(),
379 u_grad_test_ref.data(),
380 mesh_trial_trace_ref.data(),
381 mesh_grad_trial_trace_ref.data(),
383 u_trial_trace_ref.data(),
384 u_grad_trial_trace_ref.data(),
385 u_test_trace_ref.data(),
386 u_grad_test_trace_ref.data(),
388 boundaryJac_ref.data(),
412 nExteriorElementBoundaries_global,
413 exteriorElementBoundariesArray.data(),
414 elementBoundaryElementsArray.data(),
415 elementBoundaryLocalElementBoundariesArray.data(),
418 compatibility_condition,
419 INTEGRATE_BY_PARTS_DIV_U,
424 for(
int i=0;i<nDOF_test_element;i++)
426 register int eN_i=eN*nDOF_test_element+i;
427 globalResidual.data()[offset_u+stride_u*u_l2g.data()[eN_i]]+=elementResidual_u[i];
436 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
438 register int ebN = exteriorElementBoundariesArray.data()[ebNE],
439 eN = elementBoundaryElementsArray.data()[ebN*2+0],
440 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0];
442 register double elementResidual_u[nDOF_test_element];
443 double element_u[nDOF_trial_element];
444 for (
int i=0;i<nDOF_test_element;i++)
446 register int eN_i=eN*nDOF_test_element+i;
447 element_u[i] = u_dof.data()[u_l2g.data()[eN_i]];
448 elementResidual_u[i] = 0.0;
450 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
452 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
453 ebNE_kb_nSpace = ebNE_kb*nSpace,
454 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
455 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
456 register double h_b=0.0,
465 jac_ext[nSpace*nSpace],
467 jacInv_ext[nSpace*nSpace],
468 boundaryJac[nSpace*(nSpace-1)],
469 metricTensor[(nSpace-1)*(nSpace-1)],
472 u_test_dS[nDOF_test_element],
473 u_grad_trial_trace[nDOF_trial_element*nSpace],
474 u_grad_test_dS[nDOF_test_element*nSpace],
475 normal[nSpace],x_ext,y_ext,z_ext,
476 G[nSpace*nSpace],G_dd_G,tr_G;
480 ck.calculateMapping_elementBoundary(eN,
486 mesh_trial_trace_ref.data(),
487 mesh_grad_trial_trace_ref.data(),
488 boundaryJac_ref.data(),
498 dS = metricTensorDetSqrt*dS_ref.data()[kb];
501 ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
502 ck.calculateGScale(G,normal,h_b);
506 ck.gradTrialFromRef(&u_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,u_grad_trial_trace);
508 ck.valFromElementDOF(element_u,&u_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],u_ext);
509 ck.gradFromElementDOF(element_u,u_grad_trial_trace,grad_u_ext);
511 for (
int j=0;j<nDOF_trial_element;j++)
513 u_test_dS[j] = u_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
514 for (
int I=0;I<nSpace;I++)
515 u_grad_test_dS[j*nSpace+I] = u_grad_trial_trace[j*nSpace+I]*dS;
520 bc_u_ext = isDOFBoundary.data()[ebNE_kb]*ebqe_bc_u_ext.data()[ebNE_kb]+(1-isDOFBoundary.data()[ebNE_kb])*u_ext;
526 &ebqe_vf.data()[ebNE_kb_nSpace],
527 &ebqe_vs.data()[ebNE_kb_nSpace],
528 q_vos.data()[ebNE_kb],
533 ebqe_u.data()[ebNE_kb] = u_ext;
534 for (
int I=0;I<nSpace;I++)
535 ebqe_grad_u.data()[ebNE_kb_nSpace+I] = grad_u_ext[I];
540 bc_adv_flux.data()[ebNE_kb],
545 isFluxBoundary.data()[ebNE_kb],
551 bc_diff_flux.data()[ebNE_kb],
554 if (isDOFBoundary.data()[ebNE_kb] != 1)
561 ebqe_a.data()[ebNE_kb] = a_ext;
562 ebqe_adv_flux.data()[ebNE_kb] = adv_flux_ext;
563 ebqe_diff_flux.data()[ebNE_kb] = diff_flux_ext;
567 for (
int i=0;i<nDOF_test_element;i++)
569 elementResidual_u[i] +=
570 (INTEGRATE_BY_PARTS_DIV_U == 1 ?
ck.ExteriorElementBoundaryFlux(adv_flux_ext,u_test_dS[i]) : 0.)
571 +
ck.ExteriorElementBoundaryFlux(diff_flux_ext,u_test_dS[i])
572 +
ck.ExteriorElementBoundaryScalarDiffusionAdjoint(isDOFBoundary.data()[ebNE_kb],
580 &u_grad_test_dS[i*nSpace]);
586 for (
int i=0;i<nDOF_test_element;i++)
588 int eN_i = eN*nDOF_test_element+i;
589 globalResidual.data()[offset_u+stride_u*u_l2g.data()[eN_i]] += elementResidual_u[i];
596 double* mesh_trial_ref,
597 double* mesh_grad_trial_ref,
602 double* u_grad_trial_ref,
604 double* u_grad_test_ref,
606 double* mesh_trial_trace_ref,
607 double* mesh_grad_trial_trace_ref,
609 double* u_trial_trace_ref,
610 double* u_grad_trial_trace_ref,
611 double* u_test_trace_ref,
612 double* u_grad_test_trace_ref,
614 double* boundaryJac_ref,
616 int nElements_global,
627 double* elementJacobian_u_u,
631 for (
int i=0;i<nDOF_test_element;i++)
632 for (
int j=0;j<nDOF_trial_element;j++)
634 elementJacobian_u_u[i*nDOF_trial_element+j]=0.0;
636 for (
int k=0;k<nQuadraturePoints_element;k++)
638 int eN_k = eN*nQuadraturePoints_element+k,
639 eN_k_nSpace = eN_k*nSpace;
643 register double u=0.0,
649 jacInv[nSpace*nSpace],
650 u_grad_trial[nDOF_trial_element*nSpace],
652 u_grad_test_dV[nDOF_test_element*nSpace],
654 G[nSpace*nSpace],G_dd_G,tr_G;
658 ck.calculateMapping_element(eN,
669 dV = fabs(jacDet)*dV_ref[k];
670 ck.calculateG(jacInv,G,G_dd_G,tr_G);
672 ck.gradTrialFromRef(&u_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
674 ck.valFromElementDOF(element_u,&u_trial_ref[k*nDOF_trial_element],
u);
676 ck.gradFromElementDOF(element_u,u_grad_trial,grad_u);
678 for (
int j=0;j<nDOF_trial_element;j++)
680 for (
int I=0;I<nSpace;I++)
682 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
696 for(
int i=0;i<nDOF_test_element;i++)
700 int i_nSpace=i*nSpace;
701 for(
int j=0;j<nDOF_trial_element;j++)
705 int j_nSpace = j*nSpace;
706 elementJacobian_u_u[i*nDOF_trial_element+j] +=
707 ck.NumericalDiffusionJacobian(a,&u_grad_trial[j_nSpace],&u_grad_test_dV[i_nSpace]);
715 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
716 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
717 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
718 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
719 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
720 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
721 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
722 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
723 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
724 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
725 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
726 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
727 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
728 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
729 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
730 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
731 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
732 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
733 int nElements_global = args.
scalar<
int>(
"nElements_global");
734 xt::pyarray<int>& isDOFBoundary = args.
array<
int>(
"isDOFBoundary");
735 xt::pyarray<int>& isFluxBoundary = args.
array<
int>(
"isFluxBoundary");
736 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
737 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
738 double alphaBDF = args.
scalar<
double>(
"alphaBDF");
739 xt::pyarray<double>& q_vf = args.
array<
double>(
"q_vf");
740 xt::pyarray<double>& q_vs = args.
array<
double>(
"q_vs");
741 xt::pyarray<double>& q_vos = args.
array<
double>(
"q_vos");
742 double rho_s = args.
scalar<
double>(
"rho_s");
743 xt::pyarray<double>& q_rho_f = args.
array<
double>(
"q_rho_f");
744 double rho_s_min = args.
scalar<
double>(
"rho_s_min");
745 double rho_f_min = args.
scalar<
double>(
"rho_f_min");
746 xt::pyarray<double>& ebqe_vf = args.
array<
double>(
"ebqe_vf");
747 xt::pyarray<double>& ebqe_vs = args.
array<
double>(
"ebqe_vs");
748 xt::pyarray<double>& ebqe_vos = args.
array<
double>(
"ebqe_vos");
749 xt::pyarray<double>& ebqe_rho_f = args.
array<
double>(
"ebqe_rho_f");
750 xt::pyarray<int>& csrRowIndeces_u_u = args.
array<
int>(
"csrRowIndeces_u_u");
751 xt::pyarray<int>& csrColumnOffsets_u_u = args.
array<
int>(
"csrColumnOffsets_u_u");
752 xt::pyarray<double>& globalJacobian = args.
array<
double>(
"globalJacobian");
753 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
754 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
755 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
756 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
757 xt::pyarray<int>& csrColumnOffsets_eb_u_u = args.
array<
int>(
"csrColumnOffsets_eb_u_u");
761 for(
int eN=0;eN<nElements_global;eN++)
763 register double elementJacobian_u_u[nDOF_test_element*nDOF_trial_element],element_u[nDOF_trial_element];
764 for (
int j=0;j<nDOF_trial_element;j++)
766 register int eN_j = eN*nDOF_trial_element+j;
767 element_u[j] = u_dof.data()[u_l2g.data()[eN_j]];
770 mesh_grad_trial_ref.data(),
775 u_grad_trial_ref.data(),
777 u_grad_test_ref.data(),
778 mesh_trial_trace_ref.data(),
779 mesh_grad_trial_trace_ref.data(),
781 u_trial_trace_ref.data(),
782 u_grad_trial_trace_ref.data(),
783 u_test_trace_ref.data(),
784 u_grad_test_trace_ref.data(),
786 boundaryJac_ref.data(),
804 for (
int i=0;i<nDOF_test_element;i++)
806 int eN_i = eN*nDOF_test_element+i;
807 for (
int j=0;j<nDOF_trial_element;j++)
809 int eN_i_j = eN_i*nDOF_trial_element+j;
810 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] += elementJacobian_u_u[i*nDOF_trial_element+j];
817 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
819 register int ebN = exteriorElementBoundariesArray.data()[ebNE];
820 register int eN = elementBoundaryElementsArray.data()[ebN*2+0],
821 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
822 eN_nDOF_trial_element = eN*nDOF_trial_element;
823 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
825 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
826 ebNE_kb_nSpace = ebNE_kb*nSpace,
827 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
828 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
829 register double h_b=0.0,
834 jac_ext[nSpace*nSpace],
836 jacInv_ext[nSpace*nSpace],
837 boundaryJac[nSpace*(nSpace-1)],
838 metricTensor[(nSpace-1)*(nSpace-1)],
841 u_test_dS[nDOF_test_element],
842 u_grad_trial_trace[nDOF_trial_element*nSpace],
843 u_grad_test_dS[nDOF_test_element*nSpace],
844 normal[nSpace],x_ext,y_ext,z_ext,
847 G[nSpace*nSpace],G_dd_G,tr_G;
852 for (
int I=0;I<nSpace;I++)
856 ck.calculateMapping_elementBoundary(eN,
862 mesh_trial_trace_ref.data(),
863 mesh_grad_trial_trace_ref.data(),
864 boundaryJac_ref.data(),
874 dS = metricTensorDetSqrt*dS_ref.data()[kb];
875 ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
876 ck.calculateGScale(G,normal,h_b);
880 ck.gradTrialFromRef(&u_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,u_grad_trial_trace);
882 ck.valFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],u_ext);
883 ck.gradFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],u_grad_trial_trace,grad_u_ext);
885 for (
int j=0;j<nDOF_trial_element;j++)
887 u_test_dS[j] = u_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
888 for (
int I=0;I<nSpace;I++)
889 u_grad_test_dS[j*nSpace+I] = u_grad_trial_trace[j*nSpace+I]*dS;
895 &ebqe_vf.data()[ebNE_kb_nSpace],
896 &ebqe_vs.data()[ebNE_kb_nSpace],
897 q_vos.data()[ebNE_kb],
905 for (
int i=0;i<nDOF_test_element;i++)
907 register int eN_i = eN*nDOF_test_element+i;
909 for (
int j=0;j<nDOF_trial_element;j++)
912 ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j,
915 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_eb_u_u.data()[ebN_i_j]] +=
917 isFluxBoundary.data()[ebNE_kb],
920 u_trial_trace_ref.data()[ebN_local_kb_j],
921 &u_grad_trial_trace[j_nSpace],
922 penalty)*u_test_dS[i]
924 ck.ExteriorElementBoundaryScalarDiffusionAdjointJacobian
925 (isDOFBoundary.data()[ebNE_kb],
926 isFluxBoundary.data()[ebNE_kb],
928 u_trial_trace_ref.data()[ebN_local_kb_j],
931 &u_grad_test_dS[i*nSpace]);
940 int nQuadraturePoints_elementIn,
941 int nDOF_mesh_trial_elementIn,
942 int nDOF_trial_elementIn,
943 int nDOF_test_elementIn,
944 int nQuadraturePoints_elementBoundaryIn,
948 return proteus::chooseAndAllocateDiscretization2D<cppPresInc_base,cppPresInc,CompKernel>(nSpaceIn,
949 nQuadraturePoints_elementIn,
950 nDOF_mesh_trial_elementIn,
951 nDOF_trial_elementIn,
953 nQuadraturePoints_elementBoundaryIn,
956 return proteus::chooseAndAllocateDiscretization<cppPresInc_base,cppPresInc,CompKernel>(nSpaceIn,
957 nQuadraturePoints_elementIn,
958 nDOF_mesh_trial_elementIn,
959 nDOF_trial_elementIn,
961 nQuadraturePoints_elementBoundaryIn,