9 #include "xtensor-python/pyarray.hpp"
11 namespace py = pybind11;
13 #define USE_SIGN_FUNCTION 1
14 #define IMPLICIT_BCs 0
15 #define LAMBDA_SCALING 0
21 return (
z>0 ? 1. : (
z<0 ? 0. : 0.5));
23 inline double Sign(
const double&
z){
24 return (
z>0 ? 1. : (
z<0 ? -1. : 0.));
38 virtual std::tuple<double, double, double, double, double, double, double, double, double, double, double>
48 template<
class CompKernelType,
50 int nQuadraturePoints_element,
51 int nDOF_mesh_trial_element,
52 int nDOF_trial_element,
53 int nDOF_test_element,
54 int nQuadraturePoints_elementBoundary>
67 const double df[nSpace],
73 for(
int I=0;I<nSpace;I++)
80 const double df[nSpace],
81 const double norm_factor_lagged,
82 const double epsFactHeaviside,
83 const double lambdaFact,
89 for(
int I=0;I<nSpace;I++)
91 cfl = nrm2_v*norm_factor_lagged/(epsFactHeaviside*lambdaFact*h*h*h);
96 const int& isFluxBoundary_u,
97 const double n[nSpace],
99 const double& bc_flux_u,
101 const double velocity[nSpace],
105 for (
int I=0; I < nSpace; I++)
106 flow +=
n[I]*velocity[I];
107 if (isDOFBoundary_u == 1)
118 else if (isFluxBoundary_u == 1)
130 std::cout<<
"warning: CLSVOF open boundary with no external trace, setting to zero for inflow"<<std::endl;
138 const int& isFluxBoundary_u,
139 const double n[nSpace],
141 const double velocity[nSpace],
145 for (
int I=0; I < nSpace; I++)
146 flow +=
n[I]*velocity[I];
148 if (isDOFBoundary_u == 1)
159 else if (isFluxBoundary_u == 1)
186 H = 0.5*(1.0 +
u/eps + sin(M_PI*
u/eps)/M_PI);
198 d = 0.5*(1.0 + cos(M_PI*
u/eps))/eps;
210 d = 0.5*(1.0 + cos(M_PI*
u/eps));
224 H = 0.5*(1.0 +
u/eps + sin(M_PI*
u/eps)/M_PI);
239 d = 0.5*(1.0 + cos(M_PI*
u/eps))/eps;
248 double dt = args.
scalar<
double>(
"dt");
249 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
250 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
251 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
252 xt::pyarray<double>& mesh_velocity_dof = args.
array<
double>(
"mesh_velocity_dof");
253 double MOVING_DOMAIN = args.
scalar<
double>(
"MOVING_DOMAIN");
254 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
255 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
256 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
257 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
258 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
259 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
260 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
261 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
262 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
263 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
264 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
265 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
266 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
267 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
268 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
269 int nElements_global = args.
scalar<
int>(
"nElements_global");
270 int nElements_owned = args.
scalar<
int>(
"nElements_owned");
271 double useMetrics = args.
scalar<
double>(
"useMetrics");
272 const xt::pyarray<double>& q_vos = args.
array<
double>(
"q_vos");
273 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
274 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
275 xt::pyarray<double>& nodeDiametersArray = args.
array<
double>(
"nodeDiametersArray");
276 int degree_polynomial = args.
scalar<
int>(
"degree_polynomial");
277 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
278 xt::pyarray<double>& u_dof_old = args.
array<
double>(
"u_dof_old");
279 xt::pyarray<double>& velocity = args.
array<
double>(
"velocity");
280 xt::pyarray<double>& velocity_old = args.
array<
double>(
"velocity_old");
281 xt::pyarray<double>& q_m = args.
array<
double>(
"q_m");
282 xt::pyarray<double>& q_u = args.
array<
double>(
"q_u");
283 xt::pyarray<double>& q_n = args.
array<
double>(
"q_n");
284 xt::pyarray<double>& q_H = args.
array<
double>(
"q_H");
285 xt::pyarray<double>& q_mH = args.
array<
double>(
"q_mH");
286 xt::pyarray<double>& q_dV = args.
array<
double>(
"q_dV");
287 xt::pyarray<double>& q_dV_last = args.
array<
double>(
"q_dV_last");
288 xt::pyarray<double>& cfl = args.
array<
double>(
"cfl");
289 int offset_u = args.
scalar<
int>(
"offset_u");
290 int stride_u = args.
scalar<
int>(
"stride_u");
291 xt::pyarray<double>& globalResidual = args.
array<
double>(
"globalResidual");
292 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
293 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
294 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
295 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
296 xt::pyarray<double>& ebqe_velocity_ext = args.
array<
double>(
"ebqe_velocity_ext");
297 const xt::pyarray<double>& ebqe_vos_ext = args.
array<
double>(
"ebqe_vos_ext");
298 xt::pyarray<int>& isDOFBoundary_u = args.
array<
int>(
"isDOFBoundary_u");
299 xt::pyarray<double>& ebqe_bc_u_ext = args.
array<
double>(
"ebqe_bc_u_ext");
300 xt::pyarray<int>& isFluxBoundary_u = args.
array<
int>(
"isFluxBoundary_u");
301 xt::pyarray<double>& ebqe_bc_flux_u_ext = args.
array<
double>(
"ebqe_bc_flux_u_ext");
302 xt::pyarray<double>& ebqe_u = args.
array<
double>(
"ebqe_u");
303 xt::pyarray<double>& ebqe_n = args.
array<
double>(
"ebqe_n");
304 xt::pyarray<double>& ebqe_H = args.
array<
double>(
"ebqe_H");
305 xt::pyarray<double>& ebqe_flux = args.
array<
double>(
"ebqe_flux");
306 int timeOrder = args.
scalar<
int>(
"timeOrder");
307 int timeStage = args.
scalar<
int>(
"timeStage");
308 double epsFactHeaviside = args.
scalar<
double>(
"epsFactHeaviside");
309 double epsFactDirac = args.
scalar<
double>(
"epsFactDirac");
310 double epsFactRedist = args.
scalar<
double>(
"epsFactRedist");
311 double lambdaFact = args.
scalar<
double>(
"lambdaFact");
312 xt::pyarray<double>& min_distance = args.
array<
double>(
"min_distance");
313 xt::pyarray<double>& max_distance = args.
array<
double>(
"max_distance");
314 xt::pyarray<double>& mean_distance = args.
array<
double>(
"mean_distance");
315 xt::pyarray<double>& volume_domain = args.
array<
double>(
"volume_domain");
316 double norm_factor_lagged = args.
scalar<
double>(
"norm_factor_lagged");
317 double VelMax = args.
scalar<
double>(
"VelMax");
318 xt::pyarray<double>& projected_qx_tn = args.
array<
double>(
"projected_qx_tn");
319 xt::pyarray<double>& projected_qy_tn = args.
array<
double>(
"projected_qy_tn");
320 xt::pyarray<double>& projected_qz_tn = args.
array<
double>(
"projected_qz_tn");
321 xt::pyarray<double>& projected_qx_tStar = args.
array<
double>(
"projected_qx_tStar");
322 xt::pyarray<double>& projected_qy_tStar = args.
array<
double>(
"projected_qy_tStar");
323 xt::pyarray<double>& projected_qz_tStar = args.
array<
double>(
"projected_qz_tStar");
324 int numDOFs = args.
scalar<
int>(
"numDOFs");
325 xt::pyarray<double>& lumped_mass_matrix = args.
array<
double>(
"lumped_mass_matrix");
326 xt::pyarray<double>& H_dof = args.
array<
double>(
"H_dof");
327 int preRedistancingStage = args.
scalar<
int>(
"preRedistancingStage");
328 xt::pyarray<double>& interface_locator = args.
array<
double>(
"interface_locator");
329 double alpha = args.
scalar<
double>(
"alpha");
330 min_distance.data()[0] = 1E10;
331 max_distance.data()[0] = -1E10;
332 mean_distance.data()[0] = 0.;
333 volume_domain.data()[0] = 0.;
335 for(
int eN=0;eN<nElements_global;eN++)
338 register double elementResidual_u[nDOF_test_element], element_rhs_L2proj_H[nDOF_test_element];
339 for (
int i=0;i<nDOF_test_element;i++)
341 elementResidual_u[i]=0.0;
342 element_rhs_L2proj_H[i]=0.0;
345 for (
int k=0;k<nQuadraturePoints_element;k++)
348 register int eN_k = eN*nQuadraturePoints_element+k,
349 eN_k_nSpace = eN_k*nSpace,
350 eN_nDOF_trial_element = eN*nDOF_trial_element;
353 u, un, grad_u[nSpace], grad_un[nSpace],
356 u_test_dV[nDOF_trial_element],
357 u_grad_trial[nDOF_trial_element*nSpace],
358 u_grad_test_dV[nDOF_test_element*nSpace],
360 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
361 dV,x,y,
z,
xt,yt,zt,h_phi,
364 ck.calculateMapping_element(eN,
368 mesh_trial_ref.data(),
369 mesh_grad_trial_ref.data(),
374 ck.calculateH_element(eN,
376 nodeDiametersArray.data(),
378 mesh_trial_ref.data(),
380 ck.calculateMappingVelocity_element(eN,
382 mesh_velocity_dof.data(),
384 mesh_trial_ref.data(),
386 dV = fabs(jacDet)*dV_ref.data()[k];
387 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],
391 ck.valFromDOF(projected_qx_tn.data(),
392 &u_l2g.data()[eN_nDOF_trial_element],
393 &u_trial_ref.data()[k*nDOF_trial_element],
395 ck.valFromDOF(projected_qy_tn.data(),
396 &u_l2g.data()[eN_nDOF_trial_element],
397 &u_trial_ref.data()[k*nDOF_trial_element],
399 ck.valFromDOF(projected_qz_tn.data(),
400 &u_l2g.data()[eN_nDOF_trial_element],
401 &u_trial_ref.data()[k*nDOF_trial_element],
416 ck.valFromDOF(u_dof.data(),
417 &u_l2g.data()[eN_nDOF_trial_element],
418 &u_trial_ref.data()[k*nDOF_trial_element],
421 ck.valFromDOF(u_dof_old.data(),
422 &u_l2g.data()[eN_nDOF_trial_element],
423 &u_trial_ref.data()[k*nDOF_trial_element],
426 ck.gradFromDOF(u_dof.data(),
427 &u_l2g.data()[eN_nDOF_trial_element],
430 ck.gradFromDOF(u_dof_old.data(),
431 &u_l2g.data()[eN_nDOF_trial_element],
435 for (
int j=0;j<nDOF_trial_element;j++)
437 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
438 for (
int I=0;I<nSpace;I++)
439 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
441 double hK=(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN])/degree_polynomial;
443 porosity=1.0-q_vos.data()[eN_k];
470 if (q_dV_last.data()[eN_k] <= -100)
471 q_dV_last.data()[eN_k] = dV;
472 q_dV.data()[eN_k] = dV;
474 double delta, residualEikonal, tau, backgroundDissipation=0.1*hK;
475 double time_derivative_residual, fnHalf[nSpace], lambda, Hnp1;
478 if (preRedistancingStage==1)
483 double norm_grad_u=0, norm_grad_un=0;
484 for (
int I=0;I<nSpace; I++)
486 norm_grad_u += grad_u[I]*grad_u[I];
487 norm_grad_un += grad_un[I]*grad_un[I];
489 norm_grad_u = std::sqrt(norm_grad_u)+1E-10;
490 norm_grad_un = std::sqrt(norm_grad_un)+1E-10;
492 double epsRedist = epsFactRedist*hK;
494 residualEikonal = Si*(norm_grad_u-1.0);
500 for (
int I=0; I < nSpace; I++)
502 Un[I] = Si*grad_un[I]/norm_grad_un;
503 normUn += Un[I]*Un[I];
505 normUn = sqrt(normUn)+1E-10;
517 double mesh_velocity[3];
518 mesh_velocity[0] =
xt;
519 mesh_velocity[1] = yt;
520 mesh_velocity[2] = zt;
525 double epsHeaviside = epsFactHeaviside*hK;
533 lambda = lambdaFact*hK/norm_factor_lagged;
537 lambda = lambdaFact*deltaHat;
543 time_derivative_residual = porosity*(Snp1-Sn)/dt;
548 double relative_velocity[nSpace], relative_velocity_old[nSpace];
549 for (
int I=0;I<nSpace;I++)
552 relative_velocity[I] = (velocity.data()[eN_k_nSpace+I]
553 -MOVING_DOMAIN*mesh_velocity[I]);
554 relative_velocity_old[I] = (velocity_old.data()[eN_k_nSpace+I]
555 -MOVING_DOMAIN*mesh_velocity[I]);
560 fnHalf[I] = 0.5*relative_velocity[I]*porosity*(Snp1+Sn);
566 calculateCFL(elementDiameter.data()[eN]/degree_polynomial,relative_velocity,cfl.data()[eN_k]);
577 if (eN<nElements_owned)
579 min_distance.data()[0] = fmin(min_distance.data()[0],fabs(
u));
580 max_distance.data()[0] = fmax(max_distance.data()[0],fabs(
u));
581 mean_distance.data()[0] += fabs(
u)*dV;
585 volume_domain.data()[0] += dV;
590 q_u.data()[eN_k] =
u;
591 q_m.data()[eN_k] = porosity*Hnp1;
592 q_H.data()[eN_k] = Hnp1;
593 q_mH.data()[eN_k] = porosity*Hnp1;
595 for (
int I=0;I<nSpace;I++)
596 q_n.data()[eN_k_nSpace+I] = grad_u[I];
602 for(
int i=0;i<nDOF_test_element;i++)
604 int eN_i=eN*nDOF_test_element+i;
605 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
606 register int i_nSpace=i*nSpace;
607 if (preRedistancingStage==1)
612 elementResidual_u[i] +=
613 alpha*(u_dof.data()[gi]-u_dof_old.data()[gi])*delta*u_test_dV[i]
614 + residualEikonal*u_test_dV[i]
616 +
ck.NumericalDiffusion(tau+backgroundDissipation,
618 &u_grad_test_dV[i_nSpace])
619 -
ck.NumericalDiffusion(tau,
621 &u_grad_test_dV[i_nSpace]);
630 else if (same_sign==1)
632 same_sign =
sign ==
Sign(u_dof.data()[gi]) ? 1 : 0;
638 element_rhs_L2proj_H[i] += Hnp1*u_test_dV[i];
644 elementResidual_u[i] +=
646 time_derivative_residual*u_test_dV[i]
648 +
ck.Advection_weak(fnHalf,&u_grad_test_dV[i_nSpace])
650 + lambda*(
ck.NumericalDiffusion(1.0,
652 &u_grad_test_dV[i_nSpace])
654 -
ck.NumericalDiffusion(1.0,
656 &u_grad_test_dV[i_nSpace]));
676 if (preRedistancingStage==0)
680 for(
int i=0;i<nDOF_test_element;i++)
682 int gi = offset_u+stride_u*u_l2g.data()[eN*nDOF_test_element+i];
683 interface_locator.data()[gi] = 1.0;
691 for(
int i=0;i<nDOF_test_element;i++)
693 int eN_i=eN*nDOF_test_element+i;
694 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
696 globalResidual.data()[gi] += elementResidual_u[i];
697 if (preRedistancingStage==0)
698 H_dof.data()[gi] += element_rhs_L2proj_H[i];
701 if (preRedistancingStage==0)
704 for (
int i=0; i<numDOFs; i++)
705 H_dof.data()[i] /= lumped_mass_matrix.data()[i];
714 if (preRedistancingStage==0)
715 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
717 register int ebN = exteriorElementBoundariesArray.data()[ebNE],
718 eN = elementBoundaryElementsArray.data()[ebN*2+0],
719 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
720 eN_nDOF_trial_element = eN*nDOF_trial_element;
721 register double elementResidual_u[nDOF_test_element];
722 for (
int i=0;i<nDOF_test_element;i++)
724 elementResidual_u[i]=0.0;
726 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
728 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
729 ebNE_kb_nSpace = ebNE_kb*nSpace,
730 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
731 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
733 u_ext=0.0,un_ext=0.0,grad_u_ext[nSpace],
737 jac_ext[nSpace*nSpace],
739 jacInv_ext[nSpace*nSpace],
740 boundaryJac[nSpace*(nSpace-1)],
741 metricTensor[(nSpace-1)*(nSpace-1)],
744 u_test_dS[nDOF_test_element],
745 u_grad_trial_trace[nDOF_trial_element*nSpace],
746 normal[nSpace],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
753 ck.calculateMapping_elementBoundary(eN,
759 mesh_trial_trace_ref.data(),
760 mesh_grad_trial_trace_ref.data(),
761 boundaryJac_ref.data(),
771 ck.calculateMappingVelocity_elementBoundary(eN,
775 mesh_velocity_dof.data(),
777 mesh_trial_trace_ref.data(),
778 xt_ext,yt_ext,zt_ext,
783 dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt
784 + MOVING_DOMAIN*integralScaling)*dS_ref.data()[kb];
785 ck.gradTrialFromRef(&u_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],
789 ck.valFromDOF(u_dof.data(),
790 &u_l2g.data()[eN_nDOF_trial_element],
791 &u_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],
793 ck.valFromDOF(u_dof_old.data(),
794 &u_l2g.data()[eN_nDOF_trial_element],
795 &u_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],
797 ck.gradFromDOF(u_dof.data(),
798 &u_l2g.data()[eN_nDOF_trial_element],
802 for (
int j=0;j<nDOF_trial_element;j++)
803 u_test_dS[j] = u_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
807 double hK = elementDiameter.data()[eN]/degree_polynomial;
808 double epsHeaviside = epsFactHeaviside*hK;
814 2*ebqe_bc_u_ext.data()[ebNE_kb] - 1);
816 bc_u_ext = (isDOFBoundary_u.data()[ebNE_kb]*SuBC
817 +(1-isDOFBoundary_u.data()[ebNE_kb])*Su_ext);
819 bc_u_ext = (isDOFBoundary_u.data()[ebNE_kb]*SuBC
820 +(1-isDOFBoundary_u.data()[ebNE_kb])*Sun_ext);
822 porosity_ext = 1.-ebqe_vos_ext.data()[ebNE_kb];
827 double mesh_velocity[3];
828 mesh_velocity[0] = xt_ext;
829 mesh_velocity[1] = yt_ext;
830 mesh_velocity[2] = zt_ext;
832 for (
int I=0;I<nSpace;I++)
833 df_ext[I] = porosity_ext*(ebqe_velocity_ext.data()[ebNE_kb_nSpace+I]
834 - MOVING_DOMAIN*mesh_velocity[I]);
839 isFluxBoundary_u.data()[ebNE_kb],
842 ebqe_bc_flux_u_ext.data()[ebNE_kb],
846 ebqe_flux.data()[ebNE_kb] = flux_ext;
851 ebqe_u.data()[ebNE_kb] = u_ext;
855 for (
int I=0;I<nSpace;I++)
856 ebqe_n.data()[ebNE_kb_nSpace+I] = grad_u_ext[I];
861 for (
int i=0;i<nDOF_test_element;i++)
863 elementResidual_u[i] +=
ck.ExteriorElementBoundaryFlux(flux_ext,u_test_dS[i]);
869 for (
int i=0;i<nDOF_test_element;i++)
871 int eN_i = eN*nDOF_test_element+i;
872 globalResidual.data()[offset_u+stride_u*u_l2g.data()[eN_i]] += elementResidual_u[i];
880 double dt = args.
scalar<
double>(
"dt");
881 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
882 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
883 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
884 xt::pyarray<double>& mesh_velocity_dof = args.
array<
double>(
"mesh_velocity_dof");
885 double MOVING_DOMAIN = args.
scalar<
double>(
"MOVING_DOMAIN");
886 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
887 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
888 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
889 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
890 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
891 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
892 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
893 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
894 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
895 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
896 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
897 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
898 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
899 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
900 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
901 int nElements_global = args.
scalar<
int>(
"nElements_global");
902 double useMetrics = args.
scalar<
double>(
"useMetrics");
903 const xt::pyarray<double>& q_vos = args.
array<
double>(
"q_vos");
904 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
905 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
906 xt::pyarray<double>& nodeDiametersArray = args.
array<
double>(
"nodeDiametersArray");
907 int degree_polynomial = args.
scalar<
int>(
"degree_polynomial");
908 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
909 xt::pyarray<double>& u_dof_old = args.
array<
double>(
"u_dof_old");
910 xt::pyarray<double>& velocity = args.
array<
double>(
"velocity");
911 xt::pyarray<double>& cfl = args.
array<
double>(
"cfl");
912 xt::pyarray<int>& csrRowIndeces_u_u = args.
array<
int>(
"csrRowIndeces_u_u");
913 xt::pyarray<int>& csrColumnOffsets_u_u = args.
array<
int>(
"csrColumnOffsets_u_u");
914 xt::pyarray<double>& globalJacobian = args.
array<
double>(
"globalJacobian");
915 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
916 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
917 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
918 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
919 xt::pyarray<double>& ebqe_velocity_ext = args.
array<
double>(
"ebqe_velocity_ext");
920 const xt::pyarray<double>& ebqe_vos_ext = args.
array<
double>(
"ebqe_vos_ext");
921 xt::pyarray<int>& isDOFBoundary_u = args.
array<
int>(
"isDOFBoundary_u");
922 xt::pyarray<double>& ebqe_bc_u_ext = args.
array<
double>(
"ebqe_bc_u_ext");
923 xt::pyarray<int>& isFluxBoundary_u = args.
array<
int>(
"isFluxBoundary_u");
924 xt::pyarray<double>& ebqe_bc_flux_u_ext = args.
array<
double>(
"ebqe_bc_flux_u_ext");
925 xt::pyarray<int>& csrColumnOffsets_eb_u_u = args.
array<
int>(
"csrColumnOffsets_eb_u_u");
926 int timeOrder = args.
scalar<
int>(
"timeOrder");
927 int timeStage = args.
scalar<
int>(
"timeStage");
928 double epsFactHeaviside = args.
scalar<
double>(
"epsFactHeaviside");
929 double epsFactDirac = args.
scalar<
double>(
"epsFactDirac");
930 double epsFactRedist = args.
scalar<
double>(
"epsFactRedist");
931 double lambdaFact = args.
scalar<
double>(
"lambdaFact");
932 int preRedistancingStage = args.
scalar<
int>(
"preRedistancingStage");
933 double norm_factor_lagged = args.
scalar<
double>(
"norm_factor_lagged");
934 double alpha = args.
scalar<
double>(
"alpha");
935 for(
int eN=0;eN<nElements_global;eN++)
937 register double elementJacobian_u_u[nDOF_test_element][nDOF_trial_element];
938 for (
int i=0;i<nDOF_test_element;i++)
939 for (
int j=0;j<nDOF_trial_element;j++)
940 elementJacobian_u_u[i][j]=0.0;
941 for (
int k=0;k<nQuadraturePoints_element;k++)
943 int eN_k = eN*nQuadraturePoints_element+k,
944 eN_k_nSpace = eN_k*nSpace,
945 eN_nDOF_trial_element = eN*nDOF_trial_element;
948 u, un, u_grad_trial[nDOF_trial_element*nSpace],
949 grad_u[nSpace], grad_un[nSpace],
950 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
951 u_test_dV[nDOF_test_element], u_grad_test_dV[nDOF_test_element*nSpace],
952 dV, x,y,
z,
xt,yt,zt,h_phi,
955 ck.calculateMapping_element(eN,
959 mesh_trial_ref.data(),
960 mesh_grad_trial_ref.data(),
965 ck.calculateH_element(eN,
967 nodeDiametersArray.data(),
969 mesh_trial_ref.data(),
971 ck.calculateMappingVelocity_element(eN,
973 mesh_velocity_dof.data(),
975 mesh_trial_ref.data(),
978 dV = fabs(jacDet)*dV_ref.data()[k];
980 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],
984 ck.valFromDOF(u_dof.data(),
985 &u_l2g.data()[eN_nDOF_trial_element],
986 &u_trial_ref.data()[k*nDOF_trial_element],
988 ck.valFromDOF(u_dof_old.data(),
989 &u_l2g.data()[eN_nDOF_trial_element],
990 &u_trial_ref.data()[k*nDOF_trial_element],
993 ck.gradFromDOF(u_dof.data(),
994 &u_l2g.data()[eN_nDOF_trial_element],
997 ck.gradFromDOF(u_dof_old.data(),
998 &u_l2g.data()[eN_nDOF_trial_element],
1002 for (
int j=0;j<nDOF_trial_element;j++)
1004 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1005 for (
int I=0;I<nSpace;I++)
1006 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
1008 double hK=(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN])/degree_polynomial;
1010 porosity=1.0-q_vos.data()[eN_k];
1012 double delta, dH[nSpace], tau, backgroundDissipation=0.1*hK;
1013 double lambda, time_derivative_jacobian,
df[nSpace];
1014 if (preRedistancingStage==1)
1019 double norm_grad_u=0, norm_grad_un=0;
1020 for (
int I=0;I<nSpace; I++)
1022 norm_grad_u += grad_u[I]*grad_u[I];
1023 norm_grad_un += grad_un[I]*grad_un[I];
1025 norm_grad_u = std::sqrt(norm_grad_u)+1E-10;
1026 norm_grad_un = std::sqrt(norm_grad_un)+1E-10;
1028 double epsRedist = epsFactRedist*hK;
1030 for (
int I=0; I<nSpace;I++)
1031 dH[I] = Si*grad_u[I]/norm_grad_u;
1037 for (
int I=0; I < nSpace; I++)
1039 Un[I] = Si*grad_un[I]/norm_grad_un;
1040 normUn += Un[I]*Un[I];
1042 normUn = sqrt(normUn)+1E-10;
1054 double mesh_velocity[3];
1055 mesh_velocity[0] =
xt;
1056 mesh_velocity[1] = yt;
1057 mesh_velocity[2] = zt;
1062 double epsDirac = epsFactDirac*hK;
1068 lambda = lambdaFact*hK/norm_factor_lagged;
1072 lambda = lambdaFact*deltaHat;
1078 time_derivative_jacobian = porosity*dSnp1/dt;
1083 double relative_velocity[nSpace];
1084 for (
int I=0;I<nSpace;I++)
1086 relative_velocity[I] = (velocity.data()[eN_k_nSpace+I]
1087 -MOVING_DOMAIN*mesh_velocity[I]);
1088 df[I] = relative_velocity[I]*porosity*dSnp1;
1095 for(
int i=0;i<nDOF_test_element;i++)
1097 for(
int j=0;j<nDOF_trial_element;j++)
1099 int j_nSpace = j*nSpace;
1100 int i_nSpace = i*nSpace;
1102 if (preRedistancingStage==1)
1107 elementJacobian_u_u[i][j] +=
1108 (i == j ? alpha*delta*u_test_dV[i] : 0.)
1109 +
ck.HamiltonianJacobian_weak(dH,
1110 &u_grad_trial[j_nSpace],
1113 +
ck.NumericalDiffusionJacobian(tau+backgroundDissipation,
1114 &u_grad_trial[j_nSpace],
1115 &u_grad_test_dV[i_nSpace]);
1122 elementJacobian_u_u[i][j] +=
1124 time_derivative_jacobian*(u_trial_ref.data()[k*nDOF_trial_element+j]
1127 + 0.5*
ck.AdvectionJacobian_weak(
df,
1128 u_trial_ref.data()[k*nDOF_trial_element+j],
1129 &u_grad_test_dV[i_nSpace])
1130 + lambda*
ck.NumericalDiffusionJacobian(1.0,
1131 &u_grad_trial[j_nSpace],
1132 &u_grad_test_dV[i_nSpace]);
1140 for (
int i=0;i<nDOF_test_element;i++)
1142 int eN_i = eN*nDOF_test_element+i;
1143 for (
int j=0;j<nDOF_trial_element;j++)
1145 int eN_i_j = eN_i*nDOF_trial_element+j;
1146 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] +=
1147 elementJacobian_u_u[i][j];
1156 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
1158 register int ebN = exteriorElementBoundariesArray.data()[ebNE];
1159 register int eN = elementBoundaryElementsArray.data()[ebN*2+0],
1160 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
1161 eN_nDOF_trial_element = eN*nDOF_trial_element;
1162 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
1164 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
1165 ebNE_kb_nSpace = ebNE_kb*nSpace,
1166 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
1167 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
1168 register double u_ext=0.0,
1180 fluxJacobian_u_u[nDOF_trial_element],
1181 jac_ext[nSpace*nSpace],
1183 jacInv_ext[nSpace*nSpace],
1184 boundaryJac[nSpace*(nSpace-1)],
1185 metricTensor[(nSpace-1)*(nSpace-1)],
1186 metricTensorDetSqrt,
1188 u_test_dS[nDOF_test_element],
1189 u_grad_trial_trace[nDOF_trial_element*nSpace],
1190 normal[nSpace],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
1193 ck.calculateMapping_elementBoundary(eN,
1199 mesh_trial_trace_ref.data(),
1200 mesh_grad_trial_trace_ref.data(),
1201 boundaryJac_ref.data(),
1207 metricTensorDetSqrt,
1211 ck.calculateMappingVelocity_elementBoundary(eN,
1215 mesh_velocity_dof.data(),
1217 mesh_trial_trace_ref.data(),
1218 xt_ext,yt_ext,zt_ext,
1223 dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt
1224 + MOVING_DOMAIN*integralScaling)*dS_ref.data()[kb];
1225 ck.gradTrialFromRef(&u_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],
1227 u_grad_trial_trace);
1228 ck.valFromDOF(u_dof.data(),
1229 &u_l2g.data()[eN_nDOF_trial_element],
1230 &u_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],
1232 ck.gradFromDOF(u_dof.data(),
1233 &u_l2g.data()[eN_nDOF_trial_element],
1237 for (
int j=0;j<nDOF_trial_element;j++)
1238 u_test_dS[j] = u_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
1242 double hK = elementDiameter.data()[eN]/degree_polynomial;
1243 double epsHeaviside = epsFactHeaviside*hK;
1246 porosity_ext = 1.-ebqe_vos_ext.data()[ebNE_kb];
1250 double mesh_velocity[3];
1251 mesh_velocity[0] = xt_ext;
1252 mesh_velocity[1] = yt_ext;
1253 mesh_velocity[2] = zt_ext;
1255 for (
int I=0;I<nSpace;I++)
1256 df_ext[I] = porosity_ext*(ebqe_velocity_ext.data()[ebNE_kb_nSpace+I]
1257 - MOVING_DOMAIN*mesh_velocity[I]);
1262 isFluxBoundary_u.data()[ebNE_kb],
1270 for (
int j=0;j<nDOF_trial_element;j++)
1273 register int ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j;
1274 fluxJacobian_u_u[j]=
1275 ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_u_u_ext,
1276 u_trial_trace_ref.data()[ebN_local_kb_j]);
1281 for (
int i=0;i<nDOF_test_element;i++)
1283 register int eN_i = eN*nDOF_test_element+i;
1285 for (
int j=0;j<nDOF_trial_element;j++)
1288 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_eb_u_u.data()[ebN_i_j]]+=
1289 fluxJacobian_u_u[j]*u_test_dS[i];
1296 std::tuple<double, double, double, double, double, double, double, double, double, double, double>
1299 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
1300 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
1301 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
1302 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
1303 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
1304 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
1305 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
1306 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
1307 int nElements_global = args.
scalar<
int>(
"nElements_global");
1308 int nElements_owned = args.
scalar<
int>(
"nElements_owned");
1309 int useMetrics = args.
scalar<
int>(
"useMetrics");
1310 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
1311 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
1312 xt::pyarray<double>& nodeDiametersArray = args.
array<
double>(
"nodeDiametersArray");
1313 double degree_polynomial = args.
scalar<
double>(
"degree_polynomial");
1314 double epsFactHeaviside = args.
scalar<
double>(
"epsFactHeaviside");
1315 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
1316 xt::pyarray<double>& u0_dof = args.
array<
double>(
"u0_dof");
1317 xt::pyarray<double>& u_exact = args.
array<
double>(
"u_exact");
1318 int offset_u = args.
scalar<
int>(
"offset_u");
1319 int stride_u = args.
scalar<
int>(
"stride_u");
1320 double global_I_err = 0.0;
1321 double global_sI_err = 0.0;
1322 double global_V = 0.0;
1323 double global_V0 = 0.0;
1324 double global_sV = 0.0;
1325 double global_sV0 = 0.0;
1326 double global_D_err = 0.0;
1327 double global_L2_err = 0.0;
1328 double global_L2Banded_err = 0.0;
1329 double global_area_band = 0.0;
1330 double global_sH_L2_err = 0.0;
1334 for(
int eN=0;eN<nElements_global;eN++)
1336 if (eN<nElements_owned)
1340 cell_I_err = 0., cell_sI_err = 0.,
1341 cell_V = 0., cell_V0 = 0., cell_sV = 0., cell_sV0 = 0.,
1344 cell_L2Banded_err = 0., cell_area_band = 0.,
1345 cell_sH_L2_err = 0.;
1348 for (
int k=0;k<nQuadraturePoints_element;k++)
1351 register int eN_k = eN*nQuadraturePoints_element+k,
1352 eN_k_nSpace = eN_k*nSpace,
1353 eN_nDOF_trial_element = eN*nDOF_trial_element;
1356 u_grad_trial[nDOF_trial_element*nSpace],
1359 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
1362 ck.calculateMapping_element(eN,
1366 mesh_trial_ref.data(),
1367 mesh_grad_trial_ref.data(),
1372 ck.calculateH_element(eN,
1374 nodeDiametersArray.data(),
1376 mesh_trial_ref.data(),
1378 dV = fabs(jacDet)*dV_ref.data()[k];
1380 ck.valFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],uh);
1381 ck.valFromDOF(u0_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],u0);
1382 u = u_exact.data()[eN_k];
1384 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
1385 ck.gradFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],u_grad_trial,grad_uh);
1387 double epsHeaviside = epsFactHeaviside*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN])/degree_polynomial;
1399 cell_I_err += fabs(Hu - Huh)*dV;
1400 cell_sI_err += fabs(sHu - sHuh)*dV;
1402 cell_L2_err += std::pow(
u-uh,2)*dV;
1403 if (fabs(uh) <= 2*epsHeaviside)
1405 cell_L2Banded_err += std::pow(
u-uh,2)*dV;
1406 cell_area_band += dV;
1409 cell_sH_L2_err += std::pow(sHu-sHuh,2)*dV;
1414 cell_sV0 += sHu0*dV;
1416 double norm2_grad_uh = 0.;
1417 for (
int I=0; I<nSpace; I++)
1418 norm2_grad_uh += grad_uh[I]*grad_uh[I];
1419 cell_D_err += std::pow(std::sqrt(norm2_grad_uh) - 1, 2.)*dV;
1422 global_V0 += cell_V0;
1423 global_sV += cell_sV;
1424 global_sV0 += cell_sV0;
1426 global_I_err += cell_I_err;
1427 global_sI_err += cell_sI_err;
1428 global_D_err += cell_D_err;
1429 global_L2_err += cell_L2_err;
1430 global_L2Banded_err += cell_L2Banded_err;
1431 global_area_band += cell_area_band;
1432 global_sH_L2_err += cell_sH_L2_err;
1435 global_D_err *= 0.5;
1437 return std::tuple<double, double, double, double, double, double, double, double, double, double, double>(global_I_err, global_sI_err, global_V, global_V0, global_sV, global_sV0, global_D_err, global_L2_err, global_L2Banded_err, global_area_band, global_sH_L2_err);
1442 double dt = args.
scalar<
double>(
"dt");
1443 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
1444 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
1445 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
1446 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
1447 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
1448 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
1449 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
1450 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
1451 int nElements_global = args.
scalar<
int>(
"nElements_global");
1452 int nElements_owned = args.
scalar<
int>(
"nElements_owned");
1453 int useMetrics = args.
scalar<
int>(
"useMetrics");
1454 xt::pyarray<double>& q_vos = args.
array<
double>(
"q_vos");
1455 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
1456 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
1457 xt::pyarray<double>& nodeDiametersArray = args.
array<
double>(
"nodeDiametersArray");
1458 double degree_polynomial = args.
scalar<
double>(
"degree_polynomial");
1459 double epsFactHeaviside = args.
scalar<
double>(
"epsFactHeaviside");
1460 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
1461 xt::pyarray<double>& u_dof_old = args.
array<
double>(
"u_dof_old");
1462 xt::pyarray<double>& u0_dof = args.
array<
double>(
"u0_dof");
1463 xt::pyarray<double>& velocity = args.
array<
double>(
"velocity");
1464 int offset_u = args.
scalar<
int>(
"offset_u");
1465 int stride_u = args.
scalar<
int>(
"stride_u");
1466 int numDOFs = args.
scalar<
int>(
"numDOFs");
1467 xt::pyarray<double>& R_vector = args.
array<
double>(
"R_vector");
1468 xt::pyarray<double>& sR_vector = args.
array<
double>(
"sR_vector");
1469 double global_V = 0.0;
1470 double global_V0 = 0.0;
1471 double global_sV = 0.0;
1472 double global_sV0 = 0.0;
1473 double global_D_err = 0.0;
1477 for(
int eN=0;eN<nElements_global;eN++)
1480 register double element_R[nDOF_test_element], element_sR[nDOF_test_element];
1481 for (
int i=0;i<nDOF_test_element;i++)
1487 cell_V = 0., cell_V0 = 0., cell_sV = 0., cell_sV0 = 0.,
1490 for (
int k=0;k<nQuadraturePoints_element;k++)
1493 register int eN_k = eN*nQuadraturePoints_element+k,
1494 eN_k_nSpace = eN_k*nSpace,
1495 eN_nDOF_trial_element = eN*nDOF_trial_element;
1498 grad_unp1[nSpace], sFlux_np1[nSpace], Flux_np1[nSpace],
1499 u_grad_trial[nDOF_trial_element*nSpace],
1500 u_grad_test_dV[nDOF_test_element*nSpace],
1501 u_test_dV[nDOF_trial_element],
1503 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
1507 ck.calculateMapping_element(eN,
1511 mesh_trial_ref.data(),
1512 mesh_grad_trial_ref.data(),
1517 ck.calculateH_element(eN,
1519 nodeDiametersArray.data(),
1521 mesh_trial_ref.data(),
1523 dV = fabs(jacDet)*dV_ref.data()[k];
1525 ck.valFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],unp1);
1526 ck.valFromDOF(u_dof_old.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],un);
1527 ck.valFromDOF(u0_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],&u_trial_ref.data()[k*nDOF_trial_element],u0);
1529 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
1530 ck.gradFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],u_grad_trial,grad_unp1);
1532 for (
int j=0;j<nDOF_trial_element;j++)
1534 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1535 for (
int I=0;I<nSpace;I++)
1536 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
1539 porosity = 1.0-q_vos.data()[eN_k];
1541 double epsHeaviside = epsFactHeaviside*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN])/degree_polynomial;
1549 cell_V += porosity*Hunp1*dV;
1550 cell_V0 += porosity*Hu0*dV;
1551 cell_sV += porosity*sHunp1*dV;
1552 cell_sV0 += porosity*sHu0*dV;
1554 double norm2_grad_unp1 = 0.;
1555 for (
int I=0; I<nSpace; I++)
1556 norm2_grad_unp1 += grad_unp1[I]*grad_unp1[I];
1557 cell_D_err += std::pow(std::sqrt(norm2_grad_unp1) - 1, 2.)*dV;
1559 double Sunp1 =
Sign(unp1);
1560 double Sun =
Sign(un);
1563 for (
int I=0; I<nSpace; I++)
1565 Flux_np1[I] = velocity.data()[eN_k_nSpace+I]*Sunp1;
1566 sFlux_np1[I] = velocity.data()[eN_k_nSpace+I]*sSunp1;
1569 for(
int i=0;i<nDOF_test_element;i++)
1571 register int i_nSpace=i*nSpace;
1572 element_R[i] += ((Sunp1-Sun)/dt*u_test_dV[i]
1573 +
ck.Advection_weak(Flux_np1,&u_grad_test_dV[i_nSpace]));
1574 element_sR[i] += ((sSunp1-sSun)/dt*u_test_dV[i]
1575 +
ck.Advection_weak(sFlux_np1,&u_grad_test_dV[i_nSpace]));
1579 for(
int i=0;i<nDOF_test_element;i++)
1581 int eN_i=eN*nDOF_test_element+i;
1582 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1583 R_vector.data()[gi] += element_R[i];
1584 sR_vector.data()[gi] += element_sR[i];
1586 if (eN<nElements_owned)
1589 global_V0 += cell_V0;
1590 global_sV += cell_sV;
1591 global_sV0 += cell_sV0;
1592 global_D_err += cell_D_err;
1595 global_D_err *= 0.5;
1597 return std::tuple<double, double, double, double, double>(global_V, global_V0, global_sV, global_sV0, global_D_err);
1602 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
1603 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
1604 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
1605 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
1606 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
1607 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
1608 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
1609 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
1610 int nElements_global = args.
scalar<
int>(
"nElements_global");
1611 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
1612 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
1613 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
1614 int offset_u = args.
scalar<
int>(
"offset_u");
1615 int stride_u = args.
scalar<
int>(
"stride_u");
1616 int numDOFs = args.
scalar<
int>(
"numDOFs");
1617 xt::pyarray<double>& weighted_lumped_mass_matrix = args.
array<
double>(
"weighted_lumped_mass_matrix");
1618 xt::pyarray<double>& rhs_qx = args.
array<
double>(
"rhs_qx");
1619 xt::pyarray<double>& rhs_qy = args.
array<
double>(
"rhs_qy");
1620 xt::pyarray<double>& rhs_qz = args.
array<
double>(
"rhs_qz");
1621 xt::pyarray<int>& csrRowIndeces_u_u = args.
array<
int>(
"csrRowIndeces_u_u");
1622 xt::pyarray<int>& csrColumnOffsets_u_u = args.
array<
int>(
"csrColumnOffsets_u_u");
1623 xt::pyarray<double>& weighted_mass_matrix = args.
array<
double>(
"weighted_mass_matrix");
1624 for (
int i=0; i<numDOFs; i++)
1626 weighted_lumped_mass_matrix.data()[i]=0.;
1627 rhs_qx.data()[i]=0.;
1628 rhs_qy.data()[i]=0.;
1629 rhs_qz.data()[i]=0.;
1631 for(
int eN=0;eN<nElements_global;eN++)
1635 element_weighted_lumped_mass_matrix[nDOF_test_element],
1636 element_rhsx_normal_reconstruction[nDOF_test_element],
1637 element_rhsy_normal_reconstruction[nDOF_test_element],
1638 element_rhsz_normal_reconstruction[nDOF_test_element];
1639 register double element_weighted_mass_matrix[nDOF_test_element][nDOF_trial_element];
1640 for (
int i=0;i<nDOF_test_element;i++)
1642 element_weighted_lumped_mass_matrix[i]=0.0;
1643 element_rhsx_normal_reconstruction[i]=0.0;
1644 element_rhsy_normal_reconstruction[i]=0.0;
1645 element_rhsz_normal_reconstruction[i]=0.0;
1646 for (
int j=0;j<nDOF_trial_element;j++)
1647 element_weighted_mass_matrix[i][j]=0.0;
1650 for(
int k=0;k<nQuadraturePoints_element;k++)
1653 register int eN_k = eN*nQuadraturePoints_element+k,
1654 eN_k_nSpace = eN_k*nSpace,
1655 eN_nDOF_trial_element = eN*nDOF_trial_element;
1659 u_grad_trial[nDOF_trial_element*nSpace],
1660 u_test_dV[nDOF_trial_element],
1662 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
1665 ck.calculateMapping_element(eN,
1669 mesh_trial_ref.data(),
1670 mesh_grad_trial_ref.data(),
1675 dV = fabs(jacDet)*dV_ref.data()[k];
1676 ck.gradTrialFromRef(&u_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
1677 ck.gradFromDOF(u_dof.data(),&u_l2g.data()[eN_nDOF_trial_element],u_grad_trial,grad_u);
1679 for (
int j=0;j<nDOF_trial_element;j++)
1680 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1682 double rhsx = grad_u[0];
1683 double rhsy = grad_u[1];
1688 double norm_grad_u = 0;
1689 for (
int I=0;I<nSpace; I++)
1690 norm_grad_u += grad_u[I]*grad_u[I];
1691 norm_grad_u = std::sqrt(norm_grad_u)+1E-10;
1693 for(
int i=0;i<nDOF_test_element;i++)
1695 element_weighted_lumped_mass_matrix[i] += norm_grad_u*u_test_dV[i];
1696 element_rhsx_normal_reconstruction[i] += rhsx*u_test_dV[i];
1697 element_rhsy_normal_reconstruction[i] += rhsy*u_test_dV[i];
1698 element_rhsz_normal_reconstruction[i] += rhsz*u_test_dV[i];
1699 for(
int j=0;j<nDOF_trial_element;j++)
1700 element_weighted_mass_matrix[i][j] +=
1701 norm_grad_u*u_trial_ref.data()[k*nDOF_trial_element+j]*u_test_dV[i];
1705 for(
int i=0;i<nDOF_test_element;i++)
1707 int eN_i=eN*nDOF_test_element+i;
1708 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1710 weighted_lumped_mass_matrix.data()[gi] += element_weighted_lumped_mass_matrix[i];
1712 rhs_qx.data()[gi] += element_rhsx_normal_reconstruction[i];
1713 rhs_qy.data()[gi] += element_rhsy_normal_reconstruction[i];
1714 rhs_qz.data()[gi] += element_rhsz_normal_reconstruction[i];
1715 for (
int j=0;j<nDOF_trial_element;j++)
1717 int eN_i_j = eN_i*nDOF_trial_element+j;
1718 weighted_mass_matrix.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]]
1719 += element_weighted_mass_matrix[i][j];
1727 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
1728 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
1729 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
1730 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
1731 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
1732 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
1733 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
1734 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
1735 int nElements_global = args.
scalar<
int>(
"nElements_global");
1736 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
1737 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
1738 double he_for_disc_ICs = args.
scalar<
double>(
"he_for_disc_ICs");
1739 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
1740 int offset_u = args.
scalar<
int>(
"offset_u");
1741 int stride_u = args.
scalar<
int>(
"stride_u");
1742 int numDOFs = args.
scalar<
int>(
"numDOFs");
1743 xt::pyarray<double>& rhs_l2_proj = args.
array<
double>(
"rhs_l2_proj");
1744 for (
int i=0; i<numDOFs; i++)
1745 rhs_l2_proj.data()[i]=0.;
1746 for(
int eN=0;eN<nElements_global;eN++)
1749 register double element_rhs_l2_proj[nDOF_test_element];
1750 for (
int i=0;i<nDOF_test_element;i++)
1751 element_rhs_l2_proj[i]=0.0;
1754 for(
int k=0;k<nQuadraturePoints_element;k++)
1757 register int eN_k = eN*nQuadraturePoints_element+k,
1758 eN_k_nSpace = eN_k*nSpace,
1759 eN_nDOF_trial_element = eN*nDOF_trial_element;
1761 u,u_test_dV[nDOF_trial_element],
1763 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
1766 ck.calculateMapping_element(eN,
1770 mesh_trial_ref.data(),
1771 mesh_grad_trial_ref.data(),
1776 dV = fabs(jacDet)*dV_ref.data()[k];
1777 ck.valFromDOF(u_dof.data(),
1778 &u_l2g.data()[eN_nDOF_trial_element],
1779 &u_trial_ref.data()[k*nDOF_trial_element],
1782 for (
int j=0;j<nDOF_trial_element;j++)
1783 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1785 for(
int i=0;i<nDOF_test_element;i++)
1786 element_rhs_l2_proj[i] += he_for_disc_ICs*
u*u_test_dV[i];
1790 for(
int i=0;i<nDOF_test_element;i++)
1792 int eN_i=eN*nDOF_test_element+i;
1793 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1794 rhs_l2_proj.data()[gi] += element_rhs_l2_proj[i];
1801 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
1802 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
1803 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
1804 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
1805 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
1806 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
1807 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
1808 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
1809 int nElements_global = args.
scalar<
int>(
"nElements_global");
1810 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
1811 xt::pyarray<double>& elementDiameter = args.
array<
double>(
"elementDiameter");
1812 xt::pyarray<double>& lumped_mass_matrix = args.
array<
double>(
"lumped_mass_matrix");
1813 int offset_u = args.
scalar<
int>(
"offset_u");
1814 int stride_u = args.
scalar<
int>(
"stride_u");
1815 for(
int eN=0;eN<nElements_global;eN++)
1818 register double element_lumped_mass_matrix[nDOF_test_element];
1819 for (
int i=0;i<nDOF_test_element;i++)
1820 element_lumped_mass_matrix[i]=0.0;
1822 for(
int k=0;k<nQuadraturePoints_element;k++)
1825 register int eN_k = eN*nQuadraturePoints_element+k,
1826 eN_k_nSpace = eN_k*nSpace,
1827 eN_nDOF_trial_element = eN*nDOF_trial_element;
1830 u_test_dV[nDOF_trial_element],
1832 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
1835 ck.calculateMapping_element(eN,
1839 mesh_trial_ref.data(),
1840 mesh_grad_trial_ref.data(),
1845 dV = fabs(jacDet)*dV_ref.data()[k];
1847 for (
int j=0;j<nDOF_trial_element;j++)
1848 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1850 for(
int i=0;i<nDOF_test_element;i++)
1851 element_lumped_mass_matrix[i] += u_test_dV[i];
1854 for(
int i=0;i<nDOF_test_element;i++)
1856 int eN_i=eN*nDOF_test_element+i;
1857 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1858 lumped_mass_matrix.data()[gi] += element_lumped_mass_matrix[i];
1865 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
1866 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
1867 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
1868 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
1869 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
1870 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
1871 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
1872 int nElements_global = args.
scalar<
int>(
"nElements_global");
1873 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
1874 xt::pyarray<double>& uInitial = args.
array<
double>(
"uInitial");
1875 int offset_u = args.
scalar<
int>(
"offset_u");
1876 int stride_u = args.
scalar<
int>(
"stride_u");
1877 xt::pyarray<double>& globalResidual = args.
array<
double>(
"globalResidual");
1878 xt::pyarray<int>& csrRowIndeces_u_u = args.
array<
int>(
"csrRowIndeces_u_u");
1879 xt::pyarray<int>& csrColumnOffsets_u_u = args.
array<
int>(
"csrColumnOffsets_u_u");
1880 xt::pyarray<double>& globalMassMatrix = args.
array<
double>(
"globalMassMatrix");
1881 for(
int eN=0;eN<nElements_global;eN++)
1884 elementResidual_u[nDOF_test_element],
1885 elementMassMatrix_u_u[nDOF_test_element][nDOF_trial_element];
1886 for (
int i=0;i<nDOF_test_element;i++)
1888 elementResidual_u[i]=0;
1889 for (
int j=0;j<nDOF_trial_element;j++)
1890 elementMassMatrix_u_u[i][j]=0.0;
1892 for (
int k=0;k<nQuadraturePoints_element;k++)
1894 int eN_k = eN*nQuadraturePoints_element+k,
1895 eN_nDOF_trial_element = eN*nDOF_trial_element;
1898 jac[nSpace*nSpace], jacDet, jacInv[nSpace*nSpace],
1899 u_test_dV[nDOF_test_element],
1902 ck.calculateMapping_element(eN,
1906 mesh_trial_ref.data(),
1907 mesh_grad_trial_ref.data(),
1913 dV = fabs(jacDet)*dV_ref.data()[k];
1915 for (
int j=0;j<nDOF_trial_element;j++)
1916 u_test_dV[j] = u_test_ref.data()[k*nDOF_trial_element+j]*dV;
1921 for(
int i=0;i<nDOF_test_element;i++)
1923 elementResidual_u[i] += uInitial.data()[eN_k]*u_test_dV[i];
1924 for(
int j=0;j<nDOF_trial_element;j++)
1926 elementMassMatrix_u_u[i][j] +=
1927 u_trial_ref.data()[k*nDOF_trial_element+j]*u_test_dV[i];
1934 for (
int i=0;i<nDOF_test_element;i++)
1936 int eN_i = eN*nDOF_test_element+i;
1937 int gi = offset_u+stride_u*u_l2g.data()[eN_i];
1938 globalResidual.data()[gi] += elementResidual_u[i];
1939 for (
int j=0;j<nDOF_trial_element;j++)
1941 int eN_i_j = eN_i*nDOF_trial_element+j;
1942 globalMassMatrix.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] +=
1943 elementMassMatrix_u_u[i][j];
1951 int NNZ = args.
scalar<
int>(
"NNZ");
1952 int numDOFs = args.
scalar<
int>(
"numDOFs");
1953 xt::pyarray<double>& lumped_mass_matrix = args.
array<
double>(
"lumped_mass_matrix");
1954 xt::pyarray<double>& soln = args.
array<
double>(
"soln");
1955 xt::pyarray<double>& solH = args.
array<
double>(
"solH");
1956 xt::pyarray<double>& solL = args.
array<
double>(
"solL");
1957 xt::pyarray<double>& limited_solution = args.
array<
double>(
"limited_solution");
1958 xt::pyarray<int>& csrRowIndeces_DofLoops = args.
array<
int>(
"csrRowIndeces_DofLoops");
1959 xt::pyarray<int>& csrColumnOffsets_DofLoops = args.
array<
int>(
"csrColumnOffsets_DofLoops");
1960 xt::pyarray<double>& MassMatrix = args.
array<
double>(
"matrix");
1961 Rpos.resize(numDOFs, 0.0);
1962 Rneg.resize(numDOFs, 0.0);
1968 for (
int i=0; i<numDOFs; i++)
1971 double solHi = solH.data()[i];
1972 double solLi = solL.data()[i];
1973 double mi = lumped_mass_matrix.data()[i];
1975 double mini=-1.0, maxi=1.0;
1977 double Pposi=0, Pnegi=0;
1979 for (
int offset=csrRowIndeces_DofLoops.data()[i]; offset<csrRowIndeces_DofLoops.data()[i+1]; offset++)
1981 int j = csrColumnOffsets_DofLoops.data()[offset];
1983 FluxCorrectionMatrix[ij] = ((i==j ? 1. : 0.)*mi - MassMatrix.data()[ij]) * (solH.data()[j]-solHi);
2000 double Qposi = mi*(maxi-solLi);
2001 double Qnegi = mi*(mini-solLi);
2006 Rpos[i] = ((Pposi==0) ? 1. :
std::min(1.0,Qposi/Pposi));
2007 Rneg[i] = ((Pnegi==0) ? 1. :
std::min(1.0,Qnegi/Pnegi));
2014 for (
int i=0; i<numDOFs; i++)
2016 double ith_Limiter_times_FluxCorrectionMatrix = 0.;
2017 double Rposi =
Rpos[i], Rnegi =
Rneg[i];
2019 for (
int offset=csrRowIndeces_DofLoops.data()[i]; offset<csrRowIndeces_DofLoops.data()[i+1]; offset++)
2021 int j = csrColumnOffsets_DofLoops.data()[offset];
2022 ith_Limiter_times_FluxCorrectionMatrix +=
2029 limited_solution.data()[i] = solL.data()[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix;
2035 int nQuadraturePoints_elementIn,
2036 int nDOF_mesh_trial_elementIn,
2037 int nDOF_trial_elementIn,
2038 int nDOF_test_elementIn,
2039 int nQuadraturePoints_elementBoundaryIn,
2043 return proteus::chooseAndAllocateDiscretization2D<CLSVOF_base,CLSVOF,CompKernel>(nSpaceIn,
2044 nQuadraturePoints_elementIn,
2045 nDOF_mesh_trial_elementIn,
2046 nDOF_trial_elementIn,
2047 nDOF_test_elementIn,
2048 nQuadraturePoints_elementBoundaryIn,
2051 return proteus::chooseAndAllocateDiscretization<CLSVOF_base,CLSVOF,CompKernel>(nSpaceIn,
2052 nQuadraturePoints_elementIn,
2053 nDOF_mesh_trial_elementIn,
2054 nDOF_trial_elementIn,
2055 nDOF_test_elementIn,
2056 nQuadraturePoints_elementBoundaryIn,