9 #include "xtensor-python/pyarray.hpp"
11 namespace py = pybind11;
13 #define POWER_SMOOTHNESS_INDICATOR 2
14 #define IS_BETAij_ONE 0
28 inline double ENTROPY(
const double&
phi,
const double& phiL,
const double& phiR){
29 return 1./2.*std::pow(fabs(
phi),2.);
31 inline double DENTROPY(
const double&
phi,
const double& phiL,
const double& phiR){
32 return fabs(
phi)*(
phi>=0 ? 1 : -1);
35 inline double ENTROPY_LOG(
const double&
phi,
const double& phiL,
const double& phiR){
36 return std::log(fabs((
phi-phiL)*(phiR-
phi))+1E-14);
38 inline double DENTROPY_LOG(
const double&
phi,
const double& phiL,
const double& phiR){
39 return (phiL+phiR-2*
phi)*((
phi-phiL)*(phiR-
phi)>=0 ? 1 : -1)/(fabs((
phi-phiL)*(phiR-
phi))+1E-14);
61 template<
class CompKernelType,
63 int nQuadraturePoints_element,
64 int nDOF_mesh_trial_element,
65 int nDOF_trial_element,
66 int nDOF_test_element,
67 int nQuadraturePoints_elementBoundary>
80 const double df[nSpace],
86 for(
int I=0;I<nSpace;I++)
95 const double& porosity,
103 for (
int I=0; I < nSpace; I++)
105 f[I] =
v[I]*porosity*
u;
106 df[I] =
v[I]*porosity;
113 const double dH[nSpace],
117 double h,nrm_v,oneByAbsdt;
120 for(
int I=0;I<nSpace;I++)
124 oneByAbsdt = fabs(dmt);
125 tau = 1.0/(2.0*nrm_v/h + oneByAbsdt + 1.0e-8);
130 const double G[nSpace*nSpace],
132 const double Ai[nSpace],
137 for(
int I=0;I<nSpace;I++)
138 for (
int J=0;J<nSpace;J++)
139 v_d_Gv += Ai[I]*G[I*nSpace+J]*Ai[J];
141 tau_v = 1.0/sqrt(Ct_sge*A0*A0 + v_d_Gv + 1.0e-8);
146 const double& elementDiameter,
147 const double& strong_residual,
148 const double grad_u[nSpace],
157 for (
int I=0;I<nSpace;I++)
158 n_grad_u += grad_u[I]*grad_u[I];
159 num = shockCapturingDiffusion*0.5*h*fabs(strong_residual);
160 den = sqrt(n_grad_u) + 1.0e-8;
166 const int& isFluxBoundary_u,
167 const double n[nSpace],
169 const double& bc_flux_u,
171 const double velocity[nSpace],
176 for (
int I=0; I < nSpace; I++)
177 flow +=
n[I]*velocity[I];
179 if (isDOFBoundary_u == 1)
193 else if (isFluxBoundary_u == 1)
207 std::cout<<
"warning: VOF open boundary with no external trace, setting to zero for inflow"<<std::endl;
216 const int& isFluxBoundary_u,
217 const double n[nSpace],
218 const double velocity[nSpace],
222 for (
int I=0; I < nSpace; I++)
223 flow +=
n[I]*velocity[I];
226 if (isDOFBoundary_u == 1)
237 else if (isFluxBoundary_u == 1)
252 double dt = args.
scalar<
double>(
"dt");
253 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
254 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
255 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
256 xt::pyarray<double>& mesh_velocity_dof = args.
array<
double>(
"mesh_velocity_dof");
257 double MOVING_DOMAIN = args.
scalar<
double>(
"MOVING_DOMAIN");
258 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
259 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
260 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
261 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
262 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
263 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
264 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
265 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
266 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
267 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
268 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
269 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
270 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
271 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
272 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
273 int nElements_global = args.
scalar<
int>(
"nElements_global");
274 double useMetrics = args.
scalar<
double>(
"useMetrics");
275 double alphaBDF = args.
scalar<
double>(
"alphaBDF");
276 int lag_shockCapturing = args.
scalar<
int>(
"lag_shockCapturing");
277 double shockCapturingDiffusion = args.
scalar<
double>(
"shockCapturingDiffusion");
278 double sc_uref = args.
scalar<
double>(
"sc_uref");
279 double sc_alpha = args.
scalar<
double>(
"sc_alpha");
280 const xt::pyarray<double>& q_porosity = args.
array<
double>(
"q_porosity");
281 const xt::pyarray<double>& porosity_dof = args.
array<
double>(
"porosity_dof");
282 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
283 xt::pyarray<int>& r_l2g = args.
array<
int>(
"r_l2g");
284 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
285 double degree_polynomial = args.
scalar<
double>(
"degree_polynomial");
286 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
287 xt::pyarray<double>& u_dof_old = args.
array<
double>(
"u_dof_old");
288 xt::pyarray<double>& velocity = args.
array<
double>(
"velocity");
289 xt::pyarray<double>& q_m = args.
array<
double>(
"q_m");
290 xt::pyarray<double>& q_u = args.
array<
double>(
"q_u");
291 xt::pyarray<double>& q_m_betaBDF = args.
array<
double>(
"q_m_betaBDF");
292 xt::pyarray<double>& q_dV = args.
array<
double>(
"q_dV");
293 xt::pyarray<double>& q_dV_last = args.
array<
double>(
"q_dV_last");
294 xt::pyarray<double>& cfl = args.
array<
double>(
"cfl");
295 xt::pyarray<double>& edge_based_cfl = args.
array<
double>(
"edge_based_cfl");
296 xt::pyarray<double>& q_numDiff_u = args.
array<
double>(
"q_numDiff_u");
297 xt::pyarray<double>& q_numDiff_u_last = args.
array<
double>(
"q_numDiff_u_last");
298 int offset_u = args.
scalar<
int>(
"offset_u");
299 int stride_u = args.
scalar<
int>(
"stride_u");
300 xt::pyarray<double>& globalResidual = args.
array<
double>(
"globalResidual");
301 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
302 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
303 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
304 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
305 xt::pyarray<double>& ebqe_velocity_ext = args.
array<
double>(
"ebqe_velocity_ext");
306 const xt::pyarray<double>& ebqe_porosity_ext = args.
array<
double>(
"ebqe_porosity_ext");
307 xt::pyarray<int>& isDOFBoundary_u = args.
array<
int>(
"isDOFBoundary_u");
308 xt::pyarray<double>& ebqe_bc_u_ext = args.
array<
double>(
"ebqe_bc_u_ext");
309 xt::pyarray<int>& isFluxBoundary_u = args.
array<
int>(
"isFluxBoundary_u");
310 xt::pyarray<double>& ebqe_bc_flux_u_ext = args.
array<
double>(
"ebqe_bc_flux_u_ext");
311 xt::pyarray<double>& ebqe_phi = args.
array<
double>(
"ebqe_phi");
312 double epsFact = args.
scalar<
double>(
"epsFact");
313 xt::pyarray<double>& ebqe_u = args.
array<
double>(
"ebqe_u");
314 xt::pyarray<double>& ebqe_flux = args.
array<
double>(
"ebqe_flux");
315 int stage = args.
scalar<
int>(
"stage");
316 xt::pyarray<double>& uTilde_dof = args.
array<
double>(
"uTilde_dof");
317 double cE = args.
scalar<
double>(
"cE");
319 double cK = args.
scalar<
double>(
"cK");
320 double uL = args.
scalar<
double>(
"uL");
321 double uR = args.
scalar<
double>(
"uR");
322 int numDOFs = args.
scalar<
int>(
"numDOFs");
323 int NNZ = args.
scalar<
int>(
"NNZ");
324 xt::pyarray<int>& csrRowIndeces_DofLoops = args.
array<
int>(
"csrRowIndeces_DofLoops");
325 xt::pyarray<int>& csrColumnOffsets_DofLoops = args.
array<
int>(
"csrColumnOffsets_DofLoops");
326 xt::pyarray<int>& csrRowIndeces_CellLoops = args.
array<
int>(
"csrRowIndeces_CellLoops");
327 xt::pyarray<int>& csrColumnOffsets_CellLoops = args.
array<
int>(
"csrColumnOffsets_CellLoops");
328 xt::pyarray<int>& csrColumnOffsets_eb_CellLoops = args.
array<
int>(
"csrColumnOffsets_eb_CellLoops");
329 xt::pyarray<double>& ML = args.
array<
double>(
"ML");
330 int LUMPED_MASS_MATRIX = args.
scalar<
int>(
"LUMPED_MASS_MATRIX");
331 int STABILIZATION_TYPE = args.
scalar<
int>(
"STABILIZATION_TYPE");
332 int ENTROPY_TYPE = args.
scalar<
int>(
"ENTROPY_TYPE");
333 xt::pyarray<double>& uLow = args.
array<
double>(
"uLow");
334 xt::pyarray<double>& dLow = args.
array<
double>(
"dLow");
335 xt::pyarray<double>& dt_times_dH_minus_dL = args.
array<
double>(
"dt_times_dH_minus_dL");
336 xt::pyarray<double>& min_u_bc = args.
array<
double>(
"min_u_bc");
337 xt::pyarray<double>& max_u_bc = args.
array<
double>(
"max_u_bc");
338 xt::pyarray<double>& quantDOFs = args.
array<
double>(
"quantDOFs");
339 double meanEntropy = 0., meanOmega = 0., maxEntropy = -1E10, minEntropy = 1E10;
340 maxVel.resize(nElements_global, 0.0);
353 for(
int eN=0;eN<nElements_global;eN++)
356 register double elementResidual_u[nDOF_test_element];
357 for (
int i=0;i<nDOF_test_element;i++)
359 elementResidual_u[i]=0.0;
362 for (
int k=0;k<nQuadraturePoints_element;k++)
365 register int eN_k = eN*nQuadraturePoints_element+k,
366 eN_k_nSpace = eN_k*nSpace,
367 eN_nDOF_trial_element = eN*nDOF_trial_element;
369 entVisc_minus_artComp,
371 grad_u[nSpace],grad_u_old[nSpace],grad_uTilde[nSpace],
373 H=0.0,Hn=0.0,HTilde=0.0,
374 f[nSpace],fn[nSpace],
df[nSpace],
377 Lstar_u[nDOF_test_element],
379 tau=0.0,tau0=0.0,tau1=0.0,
380 numDiff0=0.0,numDiff1=0.0,
383 jacInv[nSpace*nSpace],
384 u_grad_trial[nDOF_trial_element*nSpace],
385 u_test_dV[nDOF_trial_element],
386 u_grad_test_dV[nDOF_test_element*nSpace],
391 G[nSpace*nSpace],G_dd_G,tr_G;
411 ck.calculateMapping_element(eN,
415 mesh_trial_ref.data(),
416 mesh_grad_trial_ref.data(),
421 ck.calculateMappingVelocity_element(eN,
423 mesh_velocity_dof.data(),
425 mesh_trial_ref.data(),
428 dV = fabs(jacDet)*dV_ref.data()[k];
429 ck.calculateG(jacInv,G,G_dd_G,tr_G);
431 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],
435 ck.valFromDOF(u_dof.data(),
436 &u_l2g.data()[eN_nDOF_trial_element],
437 &u_trial_ref.data()[k*nDOF_trial_element],
439 ck.valFromDOF(u_dof_old.data(),
440 &u_l2g.data()[eN_nDOF_trial_element],
441 &u_trial_ref.data()[k*nDOF_trial_element],
444 ck.gradFromDOF(u_dof.data(),
445 &u_l2g.data()[eN_nDOF_trial_element],
448 ck.gradFromDOF(u_dof_old.data(),
449 &u_l2g.data()[eN_nDOF_trial_element],
452 ck.gradFromDOF(uTilde_dof.data(),
453 &u_l2g.data()[eN_nDOF_trial_element],
457 for (
int j=0;j<nDOF_trial_element;j++)
459 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
460 for (
int I=0;I<nSpace;I++)
462 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
466 porosity = q_porosity.data()[eN_k];
483 double mesh_velocity[3];
484 mesh_velocity[0] =
xt;
485 mesh_velocity[1] = yt;
486 mesh_velocity[2] = zt;
488 for (
int I=0;I<nSpace;I++)
490 f[I] -= MOVING_DOMAIN*m*mesh_velocity[I];
491 df[I] -= MOVING_DOMAIN*dm*mesh_velocity[I];
496 if (q_dV_last.data()[eN_k] <= -100)
497 q_dV_last.data()[eN_k] = dV;
498 q_dV.data()[eN_k] = dV;
500 q_m_betaBDF.data()[eN_k]*q_dV_last.data()[eN_k]/dV,
506 if (STABILIZATION_TYPE==1)
508 double normVel=0., norm_grad_un=0.;
509 for (
int I=0;I<nSpace;I++)
511 Hn +=
df[I]*grad_u_old[I];
512 HTilde +=
df[I]*grad_uTilde[I];
513 fn[I] = porosity*
df[I]*un-MOVING_DOMAIN*m*mesh_velocity[I];
514 H +=
df[I]*grad_u[I];
515 normVel +=
df[I]*
df[I];
516 norm_grad_un += grad_u_old[I]*grad_u_old[I];
518 normVel = std::sqrt(normVel);
519 norm_grad_un = std::sqrt(norm_grad_un)+1E-10;
522 calculateCFL(elementDiameter.data()[eN]/degree_polynomial,
df,cfl.data()[eN_k]);
536 maxEntropy = fmax(maxEntropy,
ENTROPY(
u,0,1));
537 minEntropy = fmin(minEntropy,
ENTROPY(
u,0,1));
540 double hK=elementDiameter.data()[eN]/degree_polynomial;
541 entVisc_minus_artComp = fmax(1-cK*fmax(un*(1-un),0)/hK/norm_grad_un,0);
549 pdeResidual_u =
ck.Mass_strong(m_t) +
ck.Advection_strong(
df,grad_u);
551 for (
int i=0;i<nDOF_test_element;i++)
555 register int i_nSpace = i*nSpace;
556 Lstar_u[i] =
ck.Advection_adjoint(
df,&u_grad_test_dV[i_nSpace]);
566 tau = useMetrics*tau1+(1.0-useMetrics)*tau0;
568 subgridError_u = -tau*pdeResidual_u;
573 ck.calculateNumericalDiffusion(shockCapturingDiffusion,
574 elementDiameter.data()[eN],
579 ck.calculateNumericalDiffusion(shockCapturingDiffusion,
587 q_numDiff_u.data()[eN_k] = useMetrics*numDiff1+(1.0-useMetrics)*numDiff0;
604 for(
int i=0;i<nDOF_test_element;i++)
608 register int i_nSpace=i*nSpace;
609 if (STABILIZATION_TYPE==1)
612 elementResidual_u[i] +=
613 ck.Mass_weak(dt*m_t,u_test_dV[i]) +
614 1./3*dt*
ck.Advection_weak(fn,&u_grad_test_dV[i_nSpace]) +
615 1./9*dt*dt*
ck.NumericalDiffusion(Hn,
df,&u_grad_test_dV[i_nSpace]) +
616 1./3*dt*entVisc_minus_artComp*
ck.NumericalDiffusion(q_numDiff_u_last.data()[eN_k],
618 &u_grad_test_dV[i_nSpace]);
621 elementResidual_u[i] +=
622 ck.Mass_weak(dt*m_t,u_test_dV[i]) +
623 dt*
ck.Advection_weak(fn,&u_grad_test_dV[i_nSpace]) +
624 0.5*dt*dt*
ck.NumericalDiffusion(HTilde,
df,&u_grad_test_dV[i_nSpace]) +
625 dt*entVisc_minus_artComp*
ck.NumericalDiffusion(q_numDiff_u_last.data()[eN_k],
627 &u_grad_test_dV[i_nSpace]);
631 elementResidual_u[i] +=
632 ck.Mass_weak(m_t,u_test_dV[i]) +
633 ck.Advection_weak(
f,&u_grad_test_dV[i_nSpace]) +
634 ck.SubgridError(subgridError_u,Lstar_u[i]) +
635 ck.NumericalDiffusion(q_numDiff_u_last.data()[eN_k],
637 &u_grad_test_dV[i_nSpace]);
645 q_u.data()[eN_k] =
u;
646 q_m.data()[eN_k] = m;
651 for(
int i=0;i<nDOF_test_element;i++)
653 register int eN_i=eN*nDOF_test_element+i;
654 globalResidual.data()[offset_u+stride_u*r_l2g.data()[eN_i]] += elementResidual_u[i];
663 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
665 register int ebN = exteriorElementBoundariesArray.data()[ebNE],
666 eN = elementBoundaryElementsArray.data()[ebN*2+0],
667 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
668 eN_nDOF_trial_element = eN*nDOF_trial_element;
669 register double elementResidual_u[nDOF_test_element];
670 for (
int i=0;i<nDOF_test_element;i++)
672 elementResidual_u[i]=0.0;
674 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
676 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
677 ebNE_kb_nSpace = ebNE_kb*nSpace,
678 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
679 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
680 register double u_ext=0.0,
693 jac_ext[nSpace*nSpace],
695 jacInv_ext[nSpace*nSpace],
696 boundaryJac[nSpace*(nSpace-1)],
697 metricTensor[(nSpace-1)*(nSpace-1)],
700 u_test_dS[nDOF_test_element],
701 u_grad_trial_trace[nDOF_trial_element*nSpace],
702 normal[nSpace],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
706 G[nSpace*nSpace],G_dd_G,tr_G;
711 ck.calculateMapping_elementBoundary(eN,
717 mesh_trial_trace_ref.data(),
718 mesh_grad_trial_trace_ref.data(),
719 boundaryJac_ref.data(),
729 ck.calculateMappingVelocity_elementBoundary(eN,
733 mesh_velocity_dof.data(),
735 mesh_trial_trace_ref.data(),
736 xt_ext,yt_ext,zt_ext,
742 dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt + MOVING_DOMAIN*integralScaling)*dS_ref.data()[kb];
745 ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
748 ck.gradTrialFromRef(&u_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],
752 if (STABILIZATION_TYPE==1)
754 ck.valFromDOF(u_dof_old.data(),
755 &u_l2g.data()[eN_nDOF_trial_element],
756 &u_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],
758 ck.gradFromDOF(u_dof_old.data(),
759 &u_l2g.data()[eN_nDOF_trial_element],
765 ck.valFromDOF(u_dof.data(),
766 &u_l2g.data()[eN_nDOF_trial_element],
767 &u_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],
769 ck.gradFromDOF(u_dof.data(),
770 &u_l2g.data()[eN_nDOF_trial_element],
775 for (
int j=0;j<nDOF_trial_element;j++)
777 u_test_dS[j] = u_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
782 bc_u_ext = isDOFBoundary_u.data()[ebNE_kb]*ebqe_bc_u_ext.data()[ebNE_kb]+(1-isDOFBoundary_u.data()[ebNE_kb])*u_ext;
784 porosity_ext = ebqe_porosity_ext.data()[ebNE_kb];
810 double mesh_velocity[3];
811 mesh_velocity[0] = xt_ext;
812 mesh_velocity[1] = yt_ext;
813 mesh_velocity[2] = zt_ext;
815 for (
int I=0;I<nSpace;I++)
818 f_ext[I] -= MOVING_DOMAIN*m_ext*mesh_velocity[I];
819 df_ext[I] -= MOVING_DOMAIN*dm_ext*mesh_velocity[I];
820 bc_f_ext[I] -= MOVING_DOMAIN*bc_m_ext*mesh_velocity[I];
821 bc_df_ext[I] -= MOVING_DOMAIN*bc_dm_ext*mesh_velocity[I];
827 isFluxBoundary_u.data()[ebNE_kb],
830 ebqe_bc_flux_u_ext.data()[ebNE_kb],
834 ebqe_flux.data()[ebNE_kb] = flux_ext;
837 ebqe_u.data()[ebNE_kb] = u_ext;
839 ebqe_u.data()[ebNE_kb] = bc_u_ext;
841 if (STABILIZATION_TYPE==1)
850 for (
int i=0;i<nDOF_test_element;i++)
853 elementResidual_u[i] +=
ck.ExteriorElementBoundaryFlux(flux_ext,u_test_dS[i]);
859 for (
int i=0;i<nDOF_test_element;i++)
861 int eN_i = eN*nDOF_test_element+i;
862 globalResidual.data()[offset_u+stride_u*r_l2g.data()[eN_i]] += elementResidual_u[i];
865 if (STABILIZATION_TYPE==1)
867 meanEntropy /= meanOmega;
868 double norm_factor = fmax(fabs(maxEntropy - meanEntropy), fabs(meanEntropy-minEntropy));
869 for(
int eN=0;eN<nElements_global;eN++)
871 double hK=elementDiameter.data()[eN]/degree_polynomial;
873 double entropy_viscosity =
cE*hK*hK*
maxEntRes[eN]/norm_factor;
874 for (
int k=0;k<nQuadraturePoints_element;k++)
876 register int eN_k = eN*nQuadraturePoints_element+k;
877 q_numDiff_u.data()[eN_k] = fmin(linear_viscosity,entropy_viscosity);
886 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
887 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
888 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
889 xt::pyarray<double>& mesh_velocity_dof = args.
array<
double>(
"mesh_velocity_dof");
890 double MOVING_DOMAIN = args.
scalar<
double>(
"MOVING_DOMAIN");
891 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
892 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
893 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
894 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
895 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
896 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
897 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
898 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
899 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
900 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
901 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
902 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
903 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
904 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
905 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
906 int nElements_global = args.
scalar<
int>(
"nElements_global");
907 double useMetrics = args.
scalar<
double>(
"useMetrics");
908 double alphaBDF = args.
scalar<
double>(
"alphaBDF");
909 int lag_shockCapturing = args.
scalar<
int>(
"lag_shockCapturing");
910 double shockCapturingDiffusion = args.
scalar<
double>(
"shockCapturingDiffusion");
911 const xt::pyarray<double>& q_porosity = args.
array<
double>(
"q_porosity");
912 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
913 xt::pyarray<int>& r_l2g = args.
array<
int>(
"r_l2g");
914 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
915 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
916 xt::pyarray<double>& velocity = args.
array<
double>(
"velocity");
917 xt::pyarray<double>& q_m_betaBDF = args.
array<
double>(
"q_m_betaBDF");
918 xt::pyarray<double>& cfl = args.
array<
double>(
"cfl");
919 xt::pyarray<double>& q_numDiff_u_last = args.
array<
double>(
"q_numDiff_u_last");
920 xt::pyarray<int>& csrRowIndeces_u_u = args.
array<
int>(
"csrRowIndeces_u_u");
921 xt::pyarray<int>& csrColumnOffsets_u_u = args.
array<
int>(
"csrColumnOffsets_u_u");
922 xt::pyarray<double>& globalJacobian = args.
array<
double>(
"globalJacobian");
923 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
924 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
925 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
926 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
927 xt::pyarray<double>& ebqe_velocity_ext = args.
array<
double>(
"ebqe_velocity_ext");
928 const xt::pyarray<double>& ebqe_porosity_ext = args.
array<
double>(
"ebqe_porosity_ext");
929 xt::pyarray<int>& isDOFBoundary_u = args.
array<
int>(
"isDOFBoundary_u");
930 xt::pyarray<double>& ebqe_bc_u_ext = args.
array<
double>(
"ebqe_bc_u_ext");
931 xt::pyarray<int>& isFluxBoundary_u = args.
array<
int>(
"isFluxBoundary_u");
932 xt::pyarray<double>& ebqe_bc_flux_u_ext = args.
array<
double>(
"ebqe_bc_flux_u_ext");
933 xt::pyarray<int>& csrColumnOffsets_eb_u_u = args.
array<
int>(
"csrColumnOffsets_eb_u_u");
934 int STABILIZATION_TYPE = args.
scalar<
int>(
"STABILIZATION_TYPE");
940 for(
int eN=0;eN<nElements_global;eN++)
942 register double elementJacobian_u_u[nDOF_test_element][nDOF_trial_element];
943 for (
int i=0;i<nDOF_test_element;i++)
944 for (
int j=0;j<nDOF_trial_element;j++)
946 elementJacobian_u_u[i][j]=0.0;
948 for (
int k=0;k<nQuadraturePoints_element;k++)
950 int eN_k = eN*nQuadraturePoints_element+k,
951 eN_k_nSpace = eN_k*nSpace,
952 eN_nDOF_trial_element = eN*nDOF_trial_element;
955 register double u=0.0,
958 f[nSpace],
df[nSpace],
960 dpdeResidual_u_u[nDOF_trial_element],
961 Lstar_u[nDOF_test_element],
962 dsubgridError_u_u[nDOF_trial_element],
963 tau=0.0,tau0=0.0,tau1=0.0,
966 jacInv[nSpace*nSpace],
967 u_grad_trial[nDOF_trial_element*nSpace],
969 u_test_dV[nDOF_test_element],
970 u_grad_test_dV[nDOF_test_element*nSpace],
975 G[nSpace*nSpace],G_dd_G,tr_G;
997 ck.calculateMapping_element(eN,
1001 mesh_trial_ref.data(),
1002 mesh_grad_trial_ref.data(),
1007 ck.calculateMappingVelocity_element(eN,
1009 mesh_velocity_dof.data(),
1011 mesh_trial_ref.data(),
1014 dV = fabs(jacDet)*dV_ref.data()[k];
1015 ck.calculateG(jacInv,G,G_dd_G,tr_G);
1017 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
1019 ck.valFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],
u);
1021 ck.gradFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],u_grad_trial,grad_u);
1023 for (
int j=0;j<nDOF_trial_element;j++)
1025 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1026 for (
int I=0;I<nSpace;I++)
1028 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
1032 porosity = q_porosity.data()[eN_k];
1049 double mesh_velocity[3];
1050 mesh_velocity[0] =
xt;
1051 mesh_velocity[1] = yt;
1052 mesh_velocity[2] = zt;
1054 for(
int I=0;I<nSpace;I++)
1057 f[I] -= MOVING_DOMAIN*m*mesh_velocity[I];
1058 df[I] -= MOVING_DOMAIN*dm*mesh_velocity[I];
1064 q_m_betaBDF.data()[eN_k],
1073 for (
int i=0;i<nDOF_test_element;i++)
1077 register int i_nSpace = i*nSpace;
1078 Lstar_u[i]=
ck.Advection_adjoint(
df,&u_grad_test_dV[i_nSpace]);
1081 for (
int j=0;j<nDOF_trial_element;j++)
1085 int j_nSpace = j*nSpace;
1086 dpdeResidual_u_u[j]=
ck.MassJacobian_strong(dm_t,u_trial_ref.data()[k*nDOF_trial_element+j]) +
1087 ck.AdvectionJacobian_strong(
df,&u_grad_trial[j_nSpace]);
1102 tau = useMetrics*tau1+(1.0-useMetrics)*tau0;
1104 for(
int j=0;j<nDOF_trial_element;j++)
1105 dsubgridError_u_u[j] = -tau*dpdeResidual_u_u[j];
1107 for(
int i=0;i<nDOF_test_element;i++)
1111 for(
int j=0;j<nDOF_trial_element;j++)
1115 int j_nSpace = j*nSpace;
1116 int i_nSpace = i*nSpace;
1117 if (STABILIZATION_TYPE==0)
1119 elementJacobian_u_u[i][j] +=
1120 ck.MassJacobian_weak(dm_t,
1121 u_trial_ref.data()[k*nDOF_trial_element+j],
1123 ck.AdvectionJacobian_weak(
df,
1124 u_trial_ref.data()[k*nDOF_trial_element+j],
1125 &u_grad_test_dV[i_nSpace]) +
1126 ck.SubgridErrorJacobian(dsubgridError_u_u[j],Lstar_u[i]) +
1127 ck.NumericalDiffusionJacobian(q_numDiff_u_last.data()[eN_k],
1128 &u_grad_trial[j_nSpace],
1129 &u_grad_test_dV[i_nSpace]);
1133 elementJacobian_u_u[i][j] +=
1134 ck.MassJacobian_weak(1.0,
1135 u_trial_ref.data()[k*nDOF_trial_element+j],
1144 for (
int i=0;i<nDOF_test_element;i++)
1146 int eN_i = eN*nDOF_test_element+i;
1147 for (
int j=0;j<nDOF_trial_element;j++)
1149 int eN_i_j = eN_i*nDOF_trial_element+j;
1150 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] += elementJacobian_u_u[i][j];
1157 if (STABILIZATION_TYPE==0)
1158 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
1160 register int ebN = exteriorElementBoundariesArray.data()[ebNE];
1161 register int eN = elementBoundaryElementsArray.data()[ebN*2+0],
1162 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
1163 eN_nDOF_trial_element = eN*nDOF_trial_element;
1164 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
1166 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
1167 ebNE_kb_nSpace = ebNE_kb*nSpace,
1168 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
1169 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
1170 register double u_ext=0.0,
1183 fluxJacobian_u_u[nDOF_trial_element],
1184 jac_ext[nSpace*nSpace],
1186 jacInv_ext[nSpace*nSpace],
1187 boundaryJac[nSpace*(nSpace-1)],
1188 metricTensor[(nSpace-1)*(nSpace-1)],
1189 metricTensorDetSqrt,
1191 u_test_dS[nDOF_test_element],
1192 u_grad_trial_trace[nDOF_trial_element*nSpace],
1193 normal[nSpace],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
1197 G[nSpace*nSpace],G_dd_G,tr_G;
1219 ck.calculateMapping_elementBoundary(eN,
1225 mesh_trial_trace_ref.data(),
1226 mesh_grad_trial_trace_ref.data(),
1227 boundaryJac_ref.data(),
1233 metricTensorDetSqrt,
1237 ck.calculateMappingVelocity_elementBoundary(eN,
1241 mesh_velocity_dof.data(),
1243 mesh_trial_trace_ref.data(),
1244 xt_ext,yt_ext,zt_ext,
1250 dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt + MOVING_DOMAIN*integralScaling)*dS_ref.data()[kb];
1252 ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
1255 ck.gradTrialFromRef(&u_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,u_grad_trial_trace);
1257 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);
1258 ck.gradFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],u_grad_trial_trace,grad_u_ext);
1260 for (
int j=0;j<nDOF_trial_element;j++)
1262 u_test_dS[j] = u_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
1267 bc_u_ext = isDOFBoundary_u.data()[ebNE_kb]*ebqe_bc_u_ext.data()[ebNE_kb]+(1-isDOFBoundary_u.data()[ebNE_kb])*u_ext;
1269 porosity_ext = ebqe_porosity_ext.data()[ebNE_kb];
1295 double mesh_velocity[3];
1296 mesh_velocity[0] = xt_ext;
1297 mesh_velocity[1] = yt_ext;
1298 mesh_velocity[2] = zt_ext;
1300 for (
int I=0;I<nSpace;I++)
1303 f_ext[I] -= MOVING_DOMAIN*m_ext*mesh_velocity[I];
1304 df_ext[I] -= MOVING_DOMAIN*dm_ext*mesh_velocity[I];
1305 bc_f_ext[I] -= MOVING_DOMAIN*bc_m_ext*mesh_velocity[I];
1306 bc_df_ext[I] -= MOVING_DOMAIN*bc_dm_ext*mesh_velocity[I];
1312 isFluxBoundary_u.data()[ebNE_kb],
1319 for (
int j=0;j<nDOF_trial_element;j++)
1322 register int ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j;
1323 fluxJacobian_u_u[j]=
ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_u_u_ext,u_trial_trace_ref.data()[ebN_local_kb_j]);
1328 for (
int i=0;i<nDOF_test_element;i++)
1330 register int eN_i = eN*nDOF_test_element+i;
1332 for (
int j=0;j<nDOF_trial_element;j++)
1335 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_eb_u_u.data()[ebN_i_j]] += fluxJacobian_u_u[j]*u_test_dS[i];
1344 double dt = args.
scalar<
double>(
"dt");
1345 int NNZ = args.
scalar<
int>(
"NNZ");
1346 int numDOFs = args.
scalar<
int>(
"numDOFs");
1347 xt::pyarray<double>& lumped_mass_matrix = args.
array<
double>(
"lumped_mass_matrix");
1348 xt::pyarray<double>& soln = args.
array<
double>(
"soln");
1349 xt::pyarray<double>& solH = args.
array<
double>(
"solH");
1350 xt::pyarray<double>& uLow = args.
array<
double>(
"uLow");
1351 xt::pyarray<double>& dLow = args.
array<
double>(
"dLow");
1352 xt::pyarray<double>& limited_solution = args.
array<
double>(
"limited_solution");
1353 xt::pyarray<int>& csrRowIndeces_DofLoops = args.
array<
int>(
"csrRowIndeces_DofLoops");
1354 xt::pyarray<int>& csrColumnOffsets_DofLoops = args.
array<
int>(
"csrColumnOffsets_DofLoops");
1355 xt::pyarray<double>& MassMatrix = args.
array<
double>(
"MassMatrix");
1356 xt::pyarray<double>& dt_times_dH_minus_dL = args.
array<
double>(
"dt_times_dH_minus_dL");
1357 xt::pyarray<double>& min_u_bc = args.
array<
double>(
"min_u_bc");
1358 xt::pyarray<double>& max_u_bc = args.
array<
double>(
"max_u_bc");
1359 int LUMPED_MASS_MATRIX = args.
scalar<
int>(
"LUMPED_MASS_MATRIX");
1360 int STABILIZATION_TYPE = args.
scalar<
int>(
"STABILIZATION_TYPE");
1361 Rpos.resize(numDOFs,0.0);
1362 Rneg.resize(numDOFs,0.0);
1368 for (
int i=0; i<numDOFs; i++)
1371 double solHi = solH.data()[i];
1372 double solni = soln.data()[i];
1373 double mi = lumped_mass_matrix.data()[i];
1374 double uLowi = uLow.data()[i];
1375 double uDotLowi = (uLowi - solni)/dt;
1376 double mini=min_u_bc.data()[i], maxi=max_u_bc.data()[i];
1383 double Pposi=0, Pnegi=0;
1385 for (
int offset=csrRowIndeces_DofLoops.data()[i]; offset<csrRowIndeces_DofLoops.data()[i+1]; offset++)
1387 int j = csrColumnOffsets_DofLoops.data()[offset];
1388 double solnj = soln.data()[j];
1394 mini = fmin(mini,solnj);
1395 maxi = fmax(maxi,solnj);
1397 double uLowj = uLow.data()[j];
1398 double uDotLowj = (uLowj - solnj)/dt;
1400 if (STABILIZATION_TYPE==4)
1403 + dLow.data()[ij]*(uLowi-uLowj));
1407 double ML_minus_MC =
1408 (LUMPED_MASS_MATRIX == 1 ? 0. : (i==j ? 1. : 0.)*mi - MassMatrix.data()[ij]);
1410 + dt_times_dH_minus_dL.data()[ij]*(solnj-solni);
1425 double Qposi = mi*(maxi-uLow.data()[i]);
1426 double Qnegi = mi*(mini-uLow.data()[i]);
1431 Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi));
1432 Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi));
1439 for (
int i=0; i<numDOFs; i++)
1441 double ith_Limiter_times_FluxCorrectionMatrix = 0.;
1442 double Rposi =
Rpos[i], Rnegi =
Rneg[i];
1444 for (
int offset=csrRowIndeces_DofLoops.data()[i]; offset<csrRowIndeces_DofLoops.data()[i+1]; offset++)
1446 int j = csrColumnOffsets_DofLoops.data()[offset];
1453 limited_solution.data()[i] = uLow.data()[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix;
1459 double dt = args.
scalar<
double>(
"dt");
1460 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
1461 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
1462 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
1463 xt::pyarray<double>& mesh_velocity_dof = args.
array<
double>(
"mesh_velocity_dof");
1464 double MOVING_DOMAIN = args.
scalar<
double>(
"MOVING_DOMAIN");
1465 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
1466 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
1467 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
1468 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
1469 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
1470 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
1471 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
1472 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
1473 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
1474 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
1475 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
1476 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
1477 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
1478 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
1479 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
1480 int nElements_global = args.
scalar<
int>(
"nElements_global");
1481 double useMetrics = args.
scalar<
double>(
"useMetrics");
1482 double alphaBDF = args.
scalar<
double>(
"alphaBDF");
1483 int lag_shockCapturing = args.
scalar<
int>(
"lag_shockCapturing");
1484 double shockCapturingDiffusion = args.
scalar<
double>(
"shockCapturingDiffusion");
1485 double sc_uref = args.
scalar<
double>(
"sc_uref");
1486 double sc_alpha = args.
scalar<
double>(
"sc_alpha");
1487 const xt::pyarray<double>& q_porosity = args.
array<
double>(
"q_porosity");
1488 const xt::pyarray<double>& porosity_dof = args.
array<
double>(
"porosity_dof");
1489 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
1490 xt::pyarray<int>& r_l2g = args.
array<
int>(
"r_l2g");
1491 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
1492 double degree_polynomial = args.
scalar<
double>(
"degree_polynomial");
1493 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
1494 xt::pyarray<double>& u_dof_old = args.
array<
double>(
"u_dof_old");
1495 xt::pyarray<double>& velocity = args.
array<
double>(
"velocity");
1496 xt::pyarray<double>& q_m = args.
array<
double>(
"q_m");
1497 xt::pyarray<double>& q_u = args.
array<
double>(
"q_u");
1498 xt::pyarray<double>& q_m_betaBDF = args.
array<
double>(
"q_m_betaBDF");
1499 xt::pyarray<double>& q_dV = args.
array<
double>(
"q_dV");
1500 xt::pyarray<double>& q_dV_last = args.
array<
double>(
"q_dV_last");
1501 xt::pyarray<double>& cfl = args.
array<
double>(
"cfl");
1502 xt::pyarray<double>& edge_based_cfl = args.
array<
double>(
"edge_based_cfl");
1503 xt::pyarray<double>& q_numDiff_u = args.
array<
double>(
"q_numDiff_u");
1504 xt::pyarray<double>& q_numDiff_u_last = args.
array<
double>(
"q_numDiff_u_last");
1505 int offset_u = args.
scalar<
int>(
"offset_u");
1506 int stride_u = args.
scalar<
int>(
"stride_u");
1507 xt::pyarray<double>& globalResidual = args.
array<
double>(
"globalResidual");
1508 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
1509 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
1510 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
1511 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
1512 xt::pyarray<double>& ebqe_velocity_ext = args.
array<
double>(
"ebqe_velocity_ext");
1513 const xt::pyarray<double>& ebqe_porosity_ext = args.
array<
double>(
"ebqe_porosity_ext");
1514 xt::pyarray<int>& isDOFBoundary_u = args.
array<
int>(
"isDOFBoundary_u");
1515 xt::pyarray<double>& ebqe_bc_u_ext = args.
array<
double>(
"ebqe_bc_u_ext");
1516 xt::pyarray<int>& isFluxBoundary_u = args.
array<
int>(
"isFluxBoundary_u");
1517 xt::pyarray<double>& ebqe_bc_flux_u_ext = args.
array<
double>(
"ebqe_bc_flux_u_ext");
1518 xt::pyarray<double>& ebqe_phi = args.
array<
double>(
"ebqe_phi");
1519 double epsFact = args.
scalar<
double>(
"epsFact");
1520 xt::pyarray<double>& ebqe_u = args.
array<
double>(
"ebqe_u");
1521 xt::pyarray<double>& ebqe_flux = args.
array<
double>(
"ebqe_flux");
1522 int stage = args.
scalar<
int>(
"stage");
1523 xt::pyarray<double>& uTilde_dof = args.
array<
double>(
"uTilde_dof");
1524 double cE = args.
scalar<
double>(
"cE");
1526 double cK = args.
scalar<
double>(
"cK");
1527 double uL = args.
scalar<
double>(
"uL");
1528 double uR = args.
scalar<
double>(
"uR");
1529 int numDOFs = args.
scalar<
int>(
"numDOFs");
1530 int NNZ = args.
scalar<
int>(
"NNZ");
1531 xt::pyarray<int>& csrRowIndeces_DofLoops = args.
array<
int>(
"csrRowIndeces_DofLoops");
1532 xt::pyarray<int>& csrColumnOffsets_DofLoops = args.
array<
int>(
"csrColumnOffsets_DofLoops");
1533 xt::pyarray<int>& csrRowIndeces_CellLoops = args.
array<
int>(
"csrRowIndeces_CellLoops");
1534 xt::pyarray<int>& csrColumnOffsets_CellLoops = args.
array<
int>(
"csrColumnOffsets_CellLoops");
1535 xt::pyarray<int>& csrColumnOffsets_eb_CellLoops = args.
array<
int>(
"csrColumnOffsets_eb_CellLoops");
1536 xt::pyarray<double>& ML = args.
array<
double>(
"ML");
1537 int LUMPED_MASS_MATRIX = args.
scalar<
int>(
"LUMPED_MASS_MATRIX");
1538 int STABILIZATION_TYPE = args.
scalar<
int>(
"STABILIZATION_TYPE");
1539 int ENTROPY_TYPE = args.
scalar<
int>(
"ENTROPY_TYPE");
1540 xt::pyarray<double>& uLow = args.
array<
double>(
"uLow");
1541 xt::pyarray<double>& dLow = args.
array<
double>(
"dLow");
1542 xt::pyarray<double>& dt_times_dH_minus_dL = args.
array<
double>(
"dt_times_dH_minus_dL");
1543 xt::pyarray<double>& min_u_bc = args.
array<
double>(
"min_u_bc");
1544 xt::pyarray<double>& max_u_bc = args.
array<
double>(
"max_u_bc");
1545 xt::pyarray<double>& quantDOFs = args.
array<
double>(
"quantDOFs");
1552 psi.resize(numDOFs,0.0);
1553 eta.resize(numDOFs,0.0);
1557 for (
int i=0; i<numDOFs; i++)
1560 if (STABILIZATION_TYPE==2)
1562 double porosity_times_solni = porosity_dof.data()[i]*u_dof_old.data()[i];
1563 eta[i] = ENTROPY_TYPE == 0 ?
ENTROPY(porosity_times_solni,uL,uR) :
ENTROPY_LOG(porosity_times_solni,uL,uR);
1577 for(
int eN=0;eN<nElements_global;eN++)
1581 elementResidual_u[nDOF_test_element],
1582 element_entropy_residual[nDOF_test_element];
1583 register double elementTransport[nDOF_test_element][nDOF_trial_element];
1584 register double elementTransposeTransport[nDOF_test_element][nDOF_trial_element];
1585 for (
int i=0;i<nDOF_test_element;i++)
1587 elementResidual_u[i]=0.0;
1588 element_entropy_residual[i]=0.0;
1589 for (
int j=0;j<nDOF_trial_element;j++)
1591 elementTransport[i][j]=0.0;
1592 elementTransposeTransport[i][j]=0.0;
1596 for (
int k=0;k<nQuadraturePoints_element;k++)
1599 register int eN_k = eN*nQuadraturePoints_element+k,
1600 eN_k_nSpace = eN_k*nSpace,
1601 eN_nDOF_trial_element = eN*nDOF_trial_element;
1604 aux_entropy_residual=0., DENTROPY_un, DENTROPY_uni,
1606 u=0.0, un=0.0, grad_un[nSpace], porosity_times_velocity[nSpace],
1607 u_test_dV[nDOF_trial_element],
1608 u_grad_trial[nDOF_trial_element*nSpace],
1609 u_grad_test_dV[nDOF_test_element*nSpace],
1611 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
1616 ck.calculateMapping_element(eN,
1620 mesh_trial_ref.data(),
1621 mesh_grad_trial_ref.data(),
1626 ck.calculateMappingVelocity_element(eN,
1628 mesh_velocity_dof.data(),
1630 mesh_trial_ref.data(),
1632 dV = fabs(jacDet)*dV_ref.data()[k];
1634 ck.valFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],
u);
1636 ck.valFromDOF(u_dof_old.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],un);
1638 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
1639 ck.gradFromDOF(u_dof_old.data(),&u_l2g.data()[eN_nDOF_trial_element],u_grad_trial,grad_un);
1642 for (
int j=0;j<nDOF_trial_element;j++)
1644 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1645 for (
int I=0;I<nSpace;I++)
1646 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
1650 if (q_dV_last.data()[eN_k] <= -100)
1651 q_dV_last.data()[eN_k] = dV;
1652 q_dV.data()[eN_k] = dV;
1654 porosity = q_porosity.data()[eN_k];
1658 double mesh_velocity[3];
1659 mesh_velocity[0] =
xt;
1660 mesh_velocity[1] = yt;
1661 mesh_velocity[2] = zt;
1663 for (
int I=0;I<nSpace;I++)
1664 porosity_times_velocity[I] = porosity*(velocity.data()[eN_k_nSpace+I]-MOVING_DOMAIN*mesh_velocity[I]);
1669 calculateCFL(elementDiameter.data()[eN]/degree_polynomial,porosity_times_velocity,cfl.data()[eN_k]);
1674 if (STABILIZATION_TYPE==2)
1676 for (
int I=0;I<nSpace;I++)
1677 aux_entropy_residual += porosity_times_velocity[I]*grad_un[I];
1683 for(
int i=0;i<nDOF_test_element;i++)
1686 int eN_i=eN*nDOF_test_element+i;
1687 if (STABILIZATION_TYPE==2)
1689 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1690 double porosity_times_uni = porosity_dof.data()[gi]*u_dof_old.data()[gi];
1691 DENTROPY_uni = ENTROPY_TYPE == 0 ?
DENTROPY(porosity_times_uni,uL,uR) :
DENTROPY_LOG(porosity_times_uni,uL,uR);
1692 element_entropy_residual[i] += (DENTROPY_un - DENTROPY_uni)*aux_entropy_residual*u_test_dV[i];
1694 elementResidual_u[i] += porosity*(
u-un)*u_test_dV[i];
1698 for(
int j=0;j<nDOF_trial_element;j++)
1700 int j_nSpace = j*nSpace;
1701 int i_nSpace = i*nSpace;
1702 elementTransport[i][j] +=
1703 ck.AdvectionJacobian_weak(porosity_times_velocity,
1704 u_trial_ref.data()[k*nDOF_trial_element+j],&u_grad_test_dV[i_nSpace]);
1705 elementTransposeTransport[i][j] +=
1706 ck.AdvectionJacobian_weak(porosity_times_velocity,
1707 u_trial_ref.data()[k*nDOF_trial_element+i],&u_grad_test_dV[j_nSpace]);
1711 q_u.data()[eN_k] =
u;
1712 q_m.data()[eN_k] = porosity*
u;
1717 for(
int i=0;i<nDOF_test_element;i++)
1719 int eN_i=eN*nDOF_test_element+i;
1720 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1723 globalResidual.data()[gi] += elementResidual_u[i];
1725 if (STABILIZATION_TYPE==2)
1729 for (
int j=0;j<nDOF_trial_element;j++)
1731 int eN_i_j = eN_i*nDOF_trial_element+j;
1733 csrColumnOffsets_CellLoops.data()[eN_i_j]] += elementTransport[i][j];
1735 csrColumnOffsets_CellLoops.data()[eN_i_j]]
1736 += elementTransposeTransport[i][j];
1745 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
1747 double min_u_bc_local = 1E10, max_u_bc_local = -1E10;
1748 register int ebN = exteriorElementBoundariesArray.data()[ebNE];
1749 register int eN = elementBoundaryElementsArray.data()[ebN*2+0],
1750 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
1751 eN_nDOF_trial_element = eN*nDOF_trial_element;
1752 register double elementResidual_u[nDOF_test_element];
1753 for (
int i=0;i<nDOF_test_element;i++)
1754 elementResidual_u[i]=0.0;
1756 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
1758 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
1759 ebNE_kb_nSpace = ebNE_kb*nSpace,
1760 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
1761 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
1763 u_ext=0.0, bc_u_ext=0.0,
1764 porosity_times_velocity[nSpace],
1765 flux_ext=0.0, dflux_ext=0.0,
1766 fluxTransport[nDOF_trial_element],
1767 jac_ext[nSpace*nSpace],
1769 jacInv_ext[nSpace*nSpace],
1770 boundaryJac[nSpace*(nSpace-1)],
1771 metricTensor[(nSpace-1)*(nSpace-1)],
1772 metricTensorDetSqrt,
1774 u_test_dS[nDOF_test_element],
1775 normal[nSpace],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,porosity_ext;
1777 ck.calculateMapping_elementBoundary(eN,
1783 mesh_trial_trace_ref.data(),
1784 mesh_grad_trial_trace_ref.data(),
1785 boundaryJac_ref.data(),
1791 metricTensorDetSqrt,
1795 ck.calculateMappingVelocity_elementBoundary(eN,
1799 mesh_velocity_dof.data(),
1801 mesh_trial_trace_ref.data(),
1802 xt_ext,yt_ext,zt_ext,
1807 dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt + MOVING_DOMAIN*integralScaling)*dS_ref.data()[kb];
1809 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);
1811 for (
int j=0;j<nDOF_trial_element;j++)
1812 u_test_dS[j] = u_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
1815 porosity_ext = ebqe_porosity_ext.data()[ebNE_kb];
1819 double mesh_velocity[3];
1820 mesh_velocity[0] = xt_ext;
1821 mesh_velocity[1] = yt_ext;
1822 mesh_velocity[2] = zt_ext;
1824 for (
int I=0;I<nSpace;I++)
1825 porosity_times_velocity[I] = porosity_ext*(ebqe_velocity_ext.data()[ebNE_kb_nSpace+I] - MOVING_DOMAIN*mesh_velocity[I]);
1830 for (
int I=0; I < nSpace; I++)
1831 flow += normal[I]*porosity_times_velocity[I];
1838 ebqe_u.data()[ebNE_kb] = u_ext;
1844 ebqe_u.data()[ebNE_kb] = isDOFBoundary_u.data()[ebNE_kb]*ebqe_bc_u_ext.data()[ebNE_kb]+(1-isDOFBoundary_u.data()[ebNE_kb])*u_ext;
1845 if (isDOFBoundary_u.data()[ebNE_kb] == 1)
1846 flux_ext = ebqe_bc_u_ext.data()[ebNE_kb]*flow;
1847 else if (isFluxBoundary_u.data()[ebNE_kb] == 1)
1848 flux_ext = ebqe_bc_flux_u_ext.data()[ebNE_kb];
1851 std::cout<<
"warning: VOF open boundary with no external trace, setting to zero for inflow"<<std::endl;
1856 for (
int j=0;j<nDOF_trial_element;j++)
1860 elementResidual_u[j] += flux_ext*u_test_dS[j];
1861 register int ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j;
1862 fluxTransport[j] = dflux_ext*u_trial_trace_ref.data()[ebN_local_kb_j];
1867 for (
int i=0;i<nDOF_test_element;i++)
1869 register int eN_i = eN*nDOF_test_element+i;
1870 for (
int j=0;j<nDOF_trial_element;j++)
1873 TransportMatrix[csrRowIndeces_CellLoops.data()[eN_i] + csrColumnOffsets_eb_CellLoops.data()[ebN_i_j]]
1874 += fluxTransport[j]*u_test_dS[i];
1876 += fluxTransport[i]*u_test_dS[j];
1880 min_u_bc_local = fmin(ebqe_u.data()[ebNE_kb], min_u_bc_local);
1881 max_u_bc_local = fmax(ebqe_u.data()[ebNE_kb], max_u_bc_local);
1884 for (
int i=0;i<nDOF_test_element;i++)
1886 int eN_i = eN*nDOF_test_element+i;
1887 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1888 globalResidual.data()[gi] += dt*elementResidual_u[i];
1890 min_u_bc[gi] = fmin(min_u_bc_local,min_u_bc[gi]);
1891 max_u_bc[gi] = fmax(max_u_bc_local,max_u_bc[gi]);
1901 for (
int i=0; i<numDOFs; i++)
1903 double etaMaxi, etaMini;
1904 if (STABILIZATION_TYPE==2)
1907 etaMaxi = fabs(
eta[i]);
1908 etaMini = fabs(
eta[i]);
1910 double porosity_times_solni = porosity_dof.data()[i]*u_dof_old.data()[i];
1912 double alpha_numerator = 0., alpha_denominator = 0.;
1913 for (
int offset=csrRowIndeces_DofLoops.data()[i]; offset<csrRowIndeces_DofLoops.data()[i+1]; offset++)
1915 int j = csrColumnOffsets_DofLoops.data()[offset];
1916 if (STABILIZATION_TYPE==2)
1919 etaMaxi = fmax(etaMaxi,fabs(
eta[j]));
1920 etaMini = fmin(etaMini,fabs(
eta[j]));
1922 double porosity_times_solnj = porosity_dof.data()[j]*u_dof_old.data()[j];
1923 alpha_numerator += porosity_times_solni - porosity_times_solnj;
1924 alpha_denominator += fabs(porosity_times_solni - porosity_times_solnj);
1928 if (STABILIZATION_TYPE==2)
1935 double alphai = alpha_numerator/(alpha_denominator+1E-15);
1936 quantDOFs[i] = alphai;
1947 for (
int i=0; i<numDOFs; i++)
1950 double solni = u_dof_old.data()[i];
1951 double porosityi = porosity_dof.data()[i];
1952 double ith_dissipative_term = 0;
1953 double ith_low_order_dissipative_term = 0;
1954 double ith_flux_term = 0;
1958 for (
int offset=csrRowIndeces_DofLoops.data()[i]; offset<csrRowIndeces_DofLoops.data()[i+1]; offset++)
1960 int j = csrColumnOffsets_DofLoops.data()[offset];
1961 double solnj = u_dof_old.data()[j];
1962 double porosityj = porosity_dof.data()[j];
1963 double dLowij, dLij, dEVij, dHij;
1969 double solij = 0.5*(porosityi*solni+porosityj*solnj);
1970 double Compij = cK*fmax(solij*(1.0-solij),0.0)/(fabs(porosityi*solni-porosityj*solnj)+1E-14);
1975 dLij = dLowij*fmax(
psi[i],
psi[j]);
1976 if (STABILIZATION_TYPE==2)
1980 dHij = fmin(dLowij,dEVij) * fmax(1.0-Compij,0.0);
1984 dHij = dLij * fmax(1.0-Compij,0.0);
1987 ith_dissipative_term += dHij*(solnj-solni);
1988 ith_low_order_dissipative_term += dLowij*(solnj-solni);
1990 dt_times_dH_minus_dL[ij] = dt*(dHij - dLowij);
1998 dt_times_dH_minus_dL[ij]=0;
2004 double mi = ML.data()[i];
2006 edge_based_cfl.data()[i] = 2.*fabs(dLii)/mi;
2007 uLow[i] = u_dof_old.data()[i] - dt/mi*(ith_flux_term
2009 - ith_low_order_dissipative_term);
2012 if (LUMPED_MASS_MATRIX==1)
2013 globalResidual.data()[i] = u_dof_old.data()[i] - dt/mi*(ith_flux_term
2015 - ith_dissipative_term);
2017 globalResidual.data()[i] += dt*(ith_flux_term - ith_dissipative_term);
2023 int nQuadraturePoints_elementIn,
2024 int nDOF_mesh_trial_elementIn,
2025 int nDOF_trial_elementIn,
2026 int nDOF_test_elementIn,
2027 int nQuadraturePoints_elementBoundaryIn,
2031 return proteus::chooseAndAllocateDiscretization2D<VOF_base,VOF,CompKernel>(nSpaceIn,
2032 nQuadraturePoints_elementIn,
2033 nDOF_mesh_trial_elementIn,
2034 nDOF_trial_elementIn,
2035 nDOF_test_elementIn,
2036 nQuadraturePoints_elementBoundaryIn,
2039 return proteus::chooseAndAllocateDiscretization<VOF_base,VOF,CompKernel>(nSpaceIn,
2040 nQuadraturePoints_elementIn,
2041 nDOF_mesh_trial_elementIn,
2042 nDOF_trial_elementIn,
2043 nDOF_test_elementIn,
2044 nQuadraturePoints_elementBoundaryIn,