9 #include "xtensor-python/pyarray.hpp"
59 xt::pyarray<double>& mesh_trial_ref,
60 xt::pyarray<double>& mesh_grad_trial_ref,
61 xt::pyarray<double>& mesh_dof,
62 xt::pyarray<int>& mesh_l2g,
63 xt::pyarray<double>& dV_ref,
64 xt::pyarray<double>& u_trial_ref,
65 xt::pyarray<double>& u_grad_trial_ref,
66 xt::pyarray<double>& u_test_ref,
67 xt::pyarray<double>& u_grad_test_ref,
69 xt::pyarray<double>& mesh_trial_trace_ref,
70 xt::pyarray<double>& mesh_grad_trial_trace_ref,
71 xt::pyarray<double>& dS_ref,
72 xt::pyarray<double>& u_trial_trace_ref,
73 xt::pyarray<double>& u_grad_trial_trace_ref,
74 xt::pyarray<double>& u_test_trace_ref,
75 xt::pyarray<double>& u_grad_test_trace_ref,
76 xt::pyarray<double>& normal_ref,
77 xt::pyarray<double>& boundaryJac_ref,
80 xt::pyarray<int>& u_l2g,
81 xt::pyarray<double>& u_dof,
82 xt::pyarray<double>& q_rho,
83 xt::pyarray<int>& csrRowIndeces_u_u,
84 xt::pyarray<int>& csrColumnOffsets_u_u,
85 xt::pyarray<double>& globalJacobian,
86 int nExteriorElementBoundaries_global,
87 xt::pyarray<int>& exteriorElementBoundariesArray,
88 xt::pyarray<int>& elementBoundaryElementsArray,
89 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray,
90 xt::pyarray<int>& csrColumnOffsets_eb_u_u)=0;
93 template<
class CompKernelType,
95 int nQuadraturePoints_element,
96 int nDOF_mesh_trial_element,
97 int nDOF_trial_element,
98 int nDOF_test_element,
99 int nQuadraturePoints_elementBoundary>
106 nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element),
118 const double a[nSpace],
123 if (isBodyBoundary == 1) {
124 for (
int I=0;I<nSpace;I++) {
131 double* mesh_trial_ref,
132 double* mesh_grad_trial_ref,
137 double* u_grad_trial_ref,
139 double* u_grad_test_ref,
141 double* mesh_trial_trace_ref,
142 double* mesh_grad_trial_trace_ref,
144 double* u_trial_trace_ref,
145 double* u_grad_trial_trace_ref,
146 double* u_test_trace_ref,
147 double* u_grad_test_trace_ref,
149 double* boundaryJac_ref,
151 int nElements_global,
157 double* elementResidual_u,
158 int nExteriorElementBoundaries_global,
159 int* exteriorElementBoundariesArray,
160 int* elementBoundaryElementsArray,
161 int* elementBoundaryLocalElementBoundariesArray,
165 for (
int i=0;i<nDOF_test_element;i++)
167 elementResidual_u[i]=0.0;
170 for (
int k=0;k<nQuadraturePoints_element;k++)
173 register int eN_k = eN*nQuadraturePoints_element+k;
174 register double u=0.0,grad_u[nSpace],
178 jacInv[nSpace*nSpace],
179 u_grad_trial[nDOF_trial_element*nSpace],
180 u_grad_test_dV[nDOF_test_element*nSpace],
182 G[nSpace*nSpace],G_dd_G,tr_G;
186 ck.calculateMapping_element(eN,
197 dV = fabs(jacDet)*dV_ref[k];
198 ck.calculateG(jacInv,G,G_dd_G,tr_G);
200 ck.gradTrialFromRef(&u_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
202 ck.valFromElementDOF(element_u,&u_trial_ref[k*nDOF_trial_element],
u);
204 ck.gradFromElementDOF(element_u,u_grad_trial,grad_u);
206 for (
int j=0;j<nDOF_trial_element;j++)
208 for (
int I=0;I<nSpace;I++)
210 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
216 evaluateCoefficients(q_rho[eN_k], a);
220 for(
int i=0;i<nDOF_test_element;i++)
224 register int i_nSpace=i*nSpace;
225 elementResidual_u[i] += ck.NumericalDiffusion(a,grad_u,&u_grad_test_dV[i_nSpace]);
270 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
271 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
272 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
273 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
274 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
275 xt::pyarray<double>& u_trial_ref = args.
array<
double>(
"u_trial_ref");
276 xt::pyarray<double>& u_grad_trial_ref = args.
array<
double>(
"u_grad_trial_ref");
277 xt::pyarray<double>& u_test_ref = args.
array<
double>(
"u_test_ref");
278 xt::pyarray<double>& u_grad_test_ref = args.
array<
double>(
"u_grad_test_ref");
280 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
281 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
282 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
283 xt::pyarray<double>& u_trial_trace_ref = args.
array<
double>(
"u_trial_trace_ref");
284 xt::pyarray<double>& u_grad_trial_trace_ref = args.
array<
double>(
"u_grad_trial_trace_ref");
285 xt::pyarray<double>& u_test_trace_ref = args.
array<
double>(
"u_test_trace_ref");
286 xt::pyarray<double>& u_grad_test_trace_ref = args.
array<
double>(
"u_grad_test_trace_ref");
287 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
288 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
290 int nElements_global = args.
scalar<
int>(
"nElements_global");
291 int nElementBoundaries_owned = args.
scalar<
int>(
"nElementBoundaries_owned");
292 xt::pyarray<int>& u_l2g = args.
array<
int>(
"u_l2g");
293 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
294 xt::pyarray<double>& q_rho = args.
array<
double>(
"q_rho");
295 int offset_u = args.
scalar<
int>(
"offset_u");
296 int stride_u = args.
scalar<
int>(
"stride_u");
297 xt::pyarray<double>& globalResidual = args.
array<
double>(
"globalResidual");
298 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
299 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
300 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
301 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
302 xt::pyarray<int>& elementBoundaryMaterialTypesArray = args.
array<
int>(
"elementBoundaryMaterialTypesArray");
303 xt::pyarray<double>& Aij = args.
array<
double>(
"Aij");
304 int added_mass_i = args.
scalar<
int>(
"added_mass_i");
305 xt::pyarray<double>& barycenters = args.
array<
double>(
"barycenters");
306 xt::pyarray<int>& flags_rigidbody = args.
array<
int>(
"flags_rigidbody");
307 for(
int eN=0;eN<nElements_global;eN++)
309 for (
int k=0;k<nQuadraturePoints_element;k++)
314 jacInv[nSpace*nSpace],
316 ck.calculateMapping_element(eN,
320 mesh_trial_ref.data(),
321 mesh_grad_trial_ref.data(),
338 for(
int eN=0;eN<nElements_global;eN++)
341 register double elementResidual_u[nDOF_test_element],element_u[nDOF_trial_element];
342 for (
int i=0;i<nDOF_test_element;i++)
344 register int eN_i=eN*nDOF_test_element+i;
345 element_u[i] = u_dof[u_l2g[eN_i]];
347 calculateElementResidual(mesh_trial_ref.data(),
348 mesh_grad_trial_ref.data(),
353 u_grad_trial_ref.data(),
355 u_grad_test_ref.data(),
356 mesh_trial_trace_ref.data(),
357 mesh_grad_trial_trace_ref.data(),
359 u_trial_trace_ref.data(),
360 u_grad_trial_trace_ref.data(),
361 u_test_trace_ref.data(),
362 u_grad_test_trace_ref.data(),
364 boundaryJac_ref.data(),
372 nExteriorElementBoundaries_global,
373 exteriorElementBoundariesArray.data(),
374 elementBoundaryElementsArray.data(),
375 elementBoundaryLocalElementBoundariesArray.data(),
381 for(
int i=0;i<nDOF_test_element;i++)
383 register int eN_i=eN*nDOF_test_element+i;
384 globalResidual[offset_u+stride_u*u_l2g[eN_i]]+=elementResidual_u[i];
393 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
395 register int ebN = exteriorElementBoundariesArray[ebNE],
396 eN = elementBoundaryElementsArray[ebN*2+0],
397 ebN_local = elementBoundaryLocalElementBoundariesArray[ebN*2+0];
399 register double elementResidual_u[nDOF_test_element];
400 double element_u[nDOF_trial_element];
401 for (
int i=0;i<nDOF_test_element;i++)
403 register int eN_i=eN*nDOF_test_element+i;
404 element_u[i] = u_dof[u_l2g[eN_i]];
405 elementResidual_u[i] = 0.0;
407 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
409 register int ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
410 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
411 register double penalty=0.0,
414 jac_ext[nSpace*nSpace],
416 jacInv_ext[nSpace*nSpace],
417 boundaryJac[nSpace*(nSpace-1)],
418 metricTensor[(nSpace-1)*(nSpace-1)],
421 u_test_dS[nDOF_test_element],
422 u_grad_trial_trace[nDOF_trial_element*nSpace],
423 normal[nSpace],x_ext,y_ext,z_ext=0.0,
424 G[nSpace*nSpace],G_dd_G,tr_G;
428 ck.calculateMapping_elementBoundary(eN,
434 mesh_trial_trace_ref.data(),
435 mesh_grad_trial_trace_ref.data(),
436 boundaryJac_ref.data(),
446 dS = metricTensorDetSqrt*dS_ref[kb];
449 ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
450 ck.calculateGScale(G,normal,penalty);
453 ck.gradTrialFromRef(&u_grad_trial_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,u_grad_trial_trace);
455 ck.valFromElementDOF(element_u,&u_trial_trace_ref[ebN_local_kb*nDOF_test_element],u_ext);
458 for (
int j=0;j<nDOF_trial_element;j++)
460 u_test_dS[j] = u_test_trace_ref[ebN_local_kb*nDOF_test_element+j]*dS;
465 int eBMT = elementBoundaryMaterialTypesArray[ebN];
467 rx = x_ext-barycenters[3*eBMT+0];
468 ry = y_ext-barycenters[3*eBMT+1];
469 rz = z_ext-barycenters[3*eBMT+2];
470 double added_mass_a[3] = {0.0, 0.0, 0.0};
473 switch (added_mass_i)
476 added_mass_a[0] = 1.0;
479 added_mass_a[1] = 1.0;
482 added_mass_a[2] = 1.0;
485 added_mass_a[1] = -rz;
486 added_mass_a[2] = ry;
489 added_mass_a[0] = rz;
490 added_mass_a[2] = -rx;
493 added_mass_a[0] = -ry;
494 added_mass_a[1] = rx;
511 exteriorNumericalDiffusiveFlux(normal,
513 flags_rigidbody[eBMT],
518 for (
int i=0;i<nDOF_test_element;i++)
520 elementResidual_u[i] +=
521 + ck.ExteriorElementBoundaryFlux(diff_flux_ext,u_test_dS[i]);
524 if (ebN < nElementBoundaries_owned)
527 px = u_ext*normal[0];
528 py = u_ext*normal[1];
530 pz = u_ext*normal[2];
533 Aij[36*eBMT+added_mass_i+6*0] += px*dS;
534 Aij[36*eBMT+added_mass_i+6*1] += py*dS;
535 Aij[36*eBMT+added_mass_i+6*2] += pz*dS;
536 Aij[36*eBMT+added_mass_i+6*3] += (ry*pz-rz*py)*dS;
537 Aij[36*eBMT+added_mass_i+6*4] += (rz*px-rx*pz)*dS;
538 Aij[36*eBMT+added_mass_i+6*5] += (rx*py-ry*px)*dS;
544 for (
int i=0;i<nDOF_test_element;i++)
546 int eN_i = eN*nDOF_test_element+i;
547 globalResidual[offset_u+stride_u*u_l2g[eN_i]] += elementResidual_u[i];
554 double* mesh_trial_ref,
555 double* mesh_grad_trial_ref,
560 double* u_grad_trial_ref,
562 double* u_grad_test_ref,
564 double* mesh_trial_trace_ref,
565 double* mesh_grad_trial_trace_ref,
567 double* u_trial_trace_ref,
568 double* u_grad_trial_trace_ref,
569 double* u_test_trace_ref,
570 double* u_grad_test_trace_ref,
572 double* boundaryJac_ref,
574 int nElements_global,
578 double* elementJacobian_u_u,
582 for (
int i=0;i<nDOF_test_element;i++)
583 for (
int j=0;j<nDOF_trial_element;j++)
585 elementJacobian_u_u[i*nDOF_trial_element+j]=0.0;
587 for (
int k=0;k<nQuadraturePoints_element;k++)
589 int eN_k = eN*nQuadraturePoints_element+k;
592 register double u=0.0,
597 jacInv[nSpace*nSpace],
598 u_grad_trial[nDOF_trial_element*nSpace],
600 u_grad_test_dV[nDOF_test_element*nSpace],
602 G[nSpace*nSpace],G_dd_G,tr_G;
606 ck.calculateMapping_element(eN,
617 dV = fabs(jacDet)*dV_ref[k];
618 ck.calculateG(jacInv,G,G_dd_G,tr_G);
620 ck.gradTrialFromRef(&u_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,u_grad_trial);
622 ck.valFromElementDOF(element_u,&u_trial_ref[k*nDOF_trial_element],
u);
624 ck.gradFromElementDOF(element_u,u_grad_trial,grad_u);
626 for (
int j=0;j<nDOF_trial_element;j++)
628 for (
int I=0;I<nSpace;I++)
630 u_grad_test_dV[j*nSpace+I] = u_grad_trial[j*nSpace+I]*dV;
636 evaluateCoefficients(q_rho[eN_k], a);
637 for(
int i=0;i<nDOF_test_element;i++)
641 int i_nSpace=i*nSpace;
642 for(
int j=0;j<nDOF_trial_element;j++)
646 int j_nSpace = j*nSpace;
647 elementJacobian_u_u[i*nDOF_trial_element+j] +=
648 ck.NumericalDiffusionJacobian(a,&u_grad_trial[j_nSpace],&u_grad_test_dV[i_nSpace]);
655 xt::pyarray<double>& mesh_trial_ref,
656 xt::pyarray<double>& mesh_grad_trial_ref,
657 xt::pyarray<double>& mesh_dof,
658 xt::pyarray<int>& mesh_l2g,
659 xt::pyarray<double>& dV_ref,
660 xt::pyarray<double>& u_trial_ref,
661 xt::pyarray<double>& u_grad_trial_ref,
662 xt::pyarray<double>& u_test_ref,
663 xt::pyarray<double>& u_grad_test_ref,
665 xt::pyarray<double>& mesh_trial_trace_ref,
666 xt::pyarray<double>& mesh_grad_trial_trace_ref,
667 xt::pyarray<double>& dS_ref,
668 xt::pyarray<double>& u_trial_trace_ref,
669 xt::pyarray<double>& u_grad_trial_trace_ref,
670 xt::pyarray<double>& u_test_trace_ref,
671 xt::pyarray<double>& u_grad_test_trace_ref,
672 xt::pyarray<double>& normal_ref,
673 xt::pyarray<double>& boundaryJac_ref,
675 int nElements_global,
676 xt::pyarray<int>& u_l2g,
677 xt::pyarray<double>& u_dof,
678 xt::pyarray<double>& q_rho,
679 xt::pyarray<int>& csrRowIndeces_u_u,xt::pyarray<int>& csrColumnOffsets_u_u,
680 xt::pyarray<double>& globalJacobian,
681 int nExteriorElementBoundaries_global,
682 xt::pyarray<int>& exteriorElementBoundariesArray,
683 xt::pyarray<int>& elementBoundaryElementsArray,
684 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray,
685 xt::pyarray<int>& csrColumnOffsets_eb_u_u)
690 for(
int eN=0;eN<nElements_global;eN++)
692 register double elementJacobian_u_u[nDOF_test_element*nDOF_trial_element],element_u[nDOF_trial_element];
693 for (
int j=0;j<nDOF_trial_element;j++)
695 register int eN_j = eN*nDOF_trial_element+j;
696 element_u[j] = u_dof[u_l2g[eN_j]];
698 calculateElementJacobian(mesh_trial_ref.data(),
699 mesh_grad_trial_ref.data(),
704 u_grad_trial_ref.data(),
706 u_grad_test_ref.data(),
707 mesh_trial_trace_ref.data(),
708 mesh_grad_trial_trace_ref.data(),
710 u_trial_trace_ref.data(),
711 u_grad_trial_trace_ref.data(),
712 u_test_trace_ref.data(),
713 u_grad_test_trace_ref.data(),
715 boundaryJac_ref.data(),
726 for (
int i=0;i<nDOF_test_element;i++)
728 int eN_i = eN*nDOF_test_element+i;
729 for (
int j=0;j<nDOF_trial_element;j++)
731 int eN_i_j = eN_i*nDOF_trial_element+j;
732 globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_u_u[eN_i_j]] += elementJacobian_u_u[i*nDOF_trial_element+j];
740 int nQuadraturePoints_elementIn,
741 int nDOF_mesh_trial_elementIn,
742 int nDOF_trial_elementIn,
743 int nDOF_test_elementIn,
744 int nQuadraturePoints_elementBoundaryIn,
748 return proteus::chooseAndAllocateDiscretization2D<cppAddedMass_base,cppAddedMass,CompKernel>(nSpaceIn,
749 nQuadraturePoints_elementIn,
750 nDOF_mesh_trial_elementIn,
751 nDOF_trial_elementIn,
753 nQuadraturePoints_elementBoundaryIn,
756 return proteus::chooseAndAllocateDiscretization<cppAddedMass_base,cppAddedMass,CompKernel>(nSpaceIn,
757 nQuadraturePoints_elementIn,
758 nDOF_mesh_trial_elementIn,
759 nDOF_trial_elementIn,
761 nQuadraturePoints_elementBoundaryIn,