8 #include "xtensor-python/pyarray.hpp"
10 namespace py = pybind11;
22 template<
class CompKernelType,
24 int nQuadraturePoints_element,
25 int nDOF_mesh_trial_element,
26 int nDOF_trial_element,
27 int nDOF_test_element,
28 int nQuadraturePoints_elementBoundary>
84 const double* materialProperties,
90 const double strainTrace=(strain[
sXX]+strain[
sYY]+strain[
sZZ]),
91 E=materialProperties[0]/det_J,
92 nu=materialProperties[1];
94 const double shear = E/(1.0+nu);
95 const double bulk = shear*(nu/(1.0-2.0*nu));
100 stress[
sXX] = shear*strain[
sXX] + bulk*strainTrace;
105 stress[
sYY] = shear*strain[
sYY] + bulk*strainTrace;
110 stress[
sZZ] = shear*strain[
sZZ] + bulk*strainTrace;
115 stress[
sYZ] = shear*0.5*strain[
sYZ];
118 stress[
sXZ] = shear*0.5*strain[
sXZ];
121 stress[
sXY] = shear*0.5*strain[
sXY];
126 const int& isDOFBoundary_v,
127 const int& isDOFBoundary_w,
128 const int& isStressFluxBoundary_u,
129 const int& isStressFluxBoundary_v,
130 const int& isStressFluxBoundary_w,
131 const double& penalty,
138 const double& bc_stressFlux_u,
139 const double& bc_stressFlux_v,
140 const double& bc_stressFlux_w,
141 const double* stress,
142 const double* normal,
143 double& stressFlux_u,
144 double& stressFlux_v,
145 double& stressFlux_w)
147 if (isDOFBoundary_u == 1)
149 stressFlux_u = -(stress[
sXX]*normal[
X] + stress[
sXY]*normal[
Y] + stress[
sXZ]*normal[
Z] - penalty*(
u - bc_u));
151 else if(isStressFluxBoundary_u == 1)
153 stressFlux_u = bc_stressFlux_u;
160 if (isDOFBoundary_v == 1)
162 stressFlux_v = -(stress[
sYX]*normal[
X] + stress[
sYY]*normal[
Y] + stress[
sYZ]*normal[
Z] - penalty*(
v - bc_v));
164 else if(isStressFluxBoundary_v == 1)
166 stressFlux_v = bc_stressFlux_v;
173 if (isDOFBoundary_w == 1)
175 stressFlux_w = -(stress[
sZX]*normal[
X] + stress[
sZY]*normal[
Y] + stress[
sZZ]*normal[
Z] - penalty*(
w - bc_w));
177 else if(isStressFluxBoundary_w == 1)
179 stressFlux_w = bc_stressFlux_w;
188 const int& isDOFBoundary_v,
189 const int& isDOFBoundary_w,
190 const double* normal,
191 const double* dstress,
192 const double& penalty,
193 const double& disp_trial,
194 const double* disp_grad_trial,
195 double& dstressFlux_u_u,
196 double& dstressFlux_u_v,
197 double& dstressFlux_u_w,
198 double& dstressFlux_v_u,
199 double& dstressFlux_v_v,
200 double& dstressFlux_v_w,
201 double& dstressFlux_w_u,
202 double& dstressFlux_w_v,
203 double& dstressFlux_w_w)
206 if (isDOFBoundary_u == 1)
225 dstressFlux_u_u = 0.0;
226 dstressFlux_u_v = 0.0;
227 dstressFlux_u_w = 0.0;
230 if (isDOFBoundary_v == 1)
249 dstressFlux_v_u = 0.0;
250 dstressFlux_v_v = 0.0;
251 dstressFlux_v_w = 0.0;
254 if (isDOFBoundary_w == 1)
273 dstressFlux_w_u = 0.0;
274 dstressFlux_w_v = 0.0;
275 dstressFlux_w_w = 0.0;
282 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
283 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
284 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
285 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
286 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
287 xt::pyarray<double>& disp_trial_ref = args.
array<
double>(
"disp_trial_ref");
288 xt::pyarray<double>& disp_grad_trial_ref = args.
array<
double>(
"disp_grad_trial_ref");
289 xt::pyarray<double>& disp_test_ref = args.
array<
double>(
"disp_test_ref");
290 xt::pyarray<double>& disp_grad_test_ref = args.
array<
double>(
"disp_grad_test_ref");
291 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
292 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
293 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
294 xt::pyarray<double>& disp_trial_trace_ref = args.
array<
double>(
"disp_trial_trace_ref");
295 xt::pyarray<double>& disp_grad_trial_trace_ref = args.
array<
double>(
"disp_grad_trial_trace_ref");
296 xt::pyarray<double>& disp_test_trace_ref = args.
array<
double>(
"disp_test_trace_ref");
297 xt::pyarray<double>& disp_grad_test_trace_ref = args.
array<
double>(
"disp_grad_test_trace_ref");
298 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
299 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
300 int nElements_global = args.
scalar<
int>(
"nElements_global");
301 xt::pyarray<int>& materialTypes = args.
array<
int>(
"materialTypes");
302 int nMaterialProperties = args.
scalar<
int>(
"nMaterialProperties");
303 xt::pyarray<double>& materialProperties = args.
array<
double>(
"materialProperties");
304 xt::pyarray<int>& disp_l2g = args.
array<
int>(
"disp_l2g");
305 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
306 xt::pyarray<double>& v_dof = args.
array<
double>(
"v_dof");
307 xt::pyarray<double>& w_dof = args.
array<
double>(
"w_dof");
308 xt::pyarray<double>& bodyForce = args.
array<
double>(
"bodyForce");
309 int offset_u = args.
scalar<
int>(
"offset_u");
310 int offset_v = args.
scalar<
int>(
"offset_v");
311 int offset_w = args.
scalar<
int>(
"offset_w");
312 int stride_u = args.
scalar<
int>(
"stride_u");
313 int stride_v = args.
scalar<
int>(
"stride_v");
314 int stride_w = args.
scalar<
int>(
"stride_w");
315 xt::pyarray<double>& globalResidual = args.
array<
double>(
"globalResidual");
316 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
317 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
318 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
319 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
320 xt::pyarray<int>& isDOFBoundary_u = args.
array<
int>(
"isDOFBoundary_u");
321 xt::pyarray<int>& isDOFBoundary_v = args.
array<
int>(
"isDOFBoundary_v");
322 xt::pyarray<int>& isDOFBoundary_w = args.
array<
int>(
"isDOFBoundary_w");
323 xt::pyarray<int>& isStressFluxBoundary_u = args.
array<
int>(
"isStressFluxBoundary_u");
324 xt::pyarray<int>& isStressFluxBoundary_v = args.
array<
int>(
"isStressFluxBoundary_v");
325 xt::pyarray<int>& isStressFluxBoundary_w = args.
array<
int>(
"isStressFluxBoundary_w");
326 xt::pyarray<double>& ebqe_bc_u_ext = args.
array<
double>(
"ebqe_bc_u_ext");
327 xt::pyarray<double>& ebqe_bc_v_ext = args.
array<
double>(
"ebqe_bc_v_ext");
328 xt::pyarray<double>& ebqe_bc_w_ext = args.
array<
double>(
"ebqe_bc_w_ext");
329 xt::pyarray<double>& ebqe_bc_stressFlux_u_ext = args.
array<
double>(
"ebqe_bc_stressFlux_u_ext");
330 xt::pyarray<double>& ebqe_bc_stressFlux_v_ext = args.
array<
double>(
"ebqe_bc_stressFlux_v_ext");
331 xt::pyarray<double>& ebqe_bc_stressFlux_w_ext = args.
array<
double>(
"ebqe_bc_stressFlux_w_ext");
335 for(
int eN=0;eN<nElements_global;eN++)
339 elementResidual_u[nDOF_test_element],
340 elementResidual_v[nDOF_test_element],
341 elementResidual_w[nDOF_test_element];
342 for (
int i=0;i<nDOF_test_element;i++)
344 elementResidual_u[i]=0.0;
345 elementResidual_v[i]=0.0;
346 elementResidual_w[i]=0.0;
351 for(
int k=0;k<nQuadraturePoints_element;k++)
356 eN_nDOF_trial_element = eN*nDOF_trial_element;
357 register double u=0.0,
v=0.0,
w=0.0,
361 *grad_w(&
D[2*nSpace]),
364 jacInv[nSpace*nSpace],
365 disp_grad_trial[nDOF_trial_element*nSpace],
366 disp_test_dV[nDOF_trial_element],
367 disp_grad_test_dV[nDOF_test_element*nSpace],
369 G[nSpace*nSpace],G_dd_G,tr_G,
370 strain[
ck.nSymTen],stress[
ck.nSymTen],dstress[
ck.nSymTen*
ck.nSymTen];
372 ck.calculateMapping_element(eN,
376 mesh_trial_ref.data(),
377 mesh_grad_trial_ref.data(),
383 dV = fabs(jacDet)*dV_ref.data()[k];
384 ck.calculateG(jacInv,G,G_dd_G,tr_G);
386 ck.gradTrialFromRef(&disp_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,disp_grad_trial);
388 ck.valFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_ref.data()[k*nDOF_trial_element],
u);
389 ck.valFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_ref.data()[k*nDOF_trial_element],
v);
390 ck.valFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_ref.data()[k*nDOF_trial_element],
w);
392 ck.gradFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial,grad_u);
393 ck.gradFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial,grad_v);
394 ck.gradFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial,grad_w);
396 for (
int j=0;j<nDOF_trial_element;j++)
398 disp_test_dV[j] = disp_test_ref.data()[k*nDOF_trial_element+j]*dV;
399 for (
int I=0;I<nSpace;I++)
401 disp_grad_test_dV[j*nSpace+I] = disp_grad_trial[j*nSpace+I]*dV;
411 &materialProperties.data()[materialTypes.data()[eN]*nMaterialProperties],
418 for(
int i=0;i<nDOF_test_element;i++)
420 register int i_nSpace=i*nSpace;
422 elementResidual_u[i] +=
ck.Stress_u_weak(stress,&disp_grad_test_dV[i_nSpace]);
423 elementResidual_v[i] +=
ck.Stress_v_weak(stress,&disp_grad_test_dV[i_nSpace]);
424 elementResidual_w[i] +=
ck.Stress_w_weak(stress,&disp_grad_test_dV[i_nSpace]);
430 for(
int i=0;i<nDOF_test_element;i++)
432 register int eN_i=eN*nDOF_test_element+i;
434 globalResidual.data()[offset_u+stride_u*disp_l2g.data()[eN_i]] += elementResidual_u[i];
435 globalResidual.data()[offset_v+stride_v*disp_l2g.data()[eN_i]] += elementResidual_v[i];
436 globalResidual.data()[offset_w+stride_w*disp_l2g.data()[eN_i]] += elementResidual_w[i];
445 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
447 register int ebN = exteriorElementBoundariesArray.data()[ebNE],
448 eN = elementBoundaryElementsArray.data()[ebN*2+0],
449 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
450 eN_nDOF_trial_element = eN*nDOF_trial_element;
451 register double elementResidual_u[nDOF_test_element],
452 elementResidual_v[nDOF_test_element],
453 elementResidual_w[nDOF_test_element];
454 for (
int i=0;i<nDOF_test_element;i++)
456 elementResidual_u[i]=0.0;
457 elementResidual_v[i]=0.0;
458 elementResidual_w[i]=0.0;
460 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
462 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
463 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
464 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
465 register double u_ext=0.0,
470 *grad_v_ext(&
D[nSpace]),
471 *grad_w_ext(&
D[2*nSpace]),
475 jac_ext[nSpace*nSpace],
477 jacInv_ext[nSpace*nSpace],
478 boundaryJac[nSpace*(nSpace-1)],
479 metricTensor[(nSpace-1)*(nSpace-1)],
481 dS,disp_test_dS[nDOF_test_element],
482 disp_grad_trial_trace[nDOF_trial_element*nSpace],
483 normal[3],x_ext,y_ext,z_ext,
484 G[nSpace*nSpace],G_dd_G,tr_G,h_penalty,
485 strain[
ck.nSymTen],stress[
ck.nSymTen],dstress[
ck.nSymTen*
ck.nSymTen],
486 stressFlux_u,stressFlux_v,stressFlux_w;
488 ck.calculateMapping_elementBoundary(eN,
494 mesh_trial_trace_ref.data(),
495 mesh_grad_trial_trace_ref.data(),
496 boundaryJac_ref.data(),
506 dS = metricTensorDetSqrt*dS_ref.data()[kb];
509 ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
512 ck.gradTrialFromRef(&disp_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,disp_grad_trial_trace);
514 ck.valFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],u_ext);
515 ck.valFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],v_ext);
516 ck.valFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],w_ext);
517 ck.gradFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial_trace,grad_u_ext);
518 ck.gradFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial_trace,grad_v_ext);
519 ck.gradFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial_trace,grad_w_ext);
521 for (
int j=0;j<nDOF_trial_element;j++)
523 disp_test_dS[j] = disp_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
528 bc_u_ext = isDOFBoundary_u.data()[ebNE_kb]*ebqe_bc_u_ext.data()[ebNE_kb]+(1-isDOFBoundary_u.data()[ebNE_kb])*u_ext;
529 bc_v_ext = isDOFBoundary_v.data()[ebNE_kb]*ebqe_bc_v_ext.data()[ebNE_kb]+(1-isDOFBoundary_v.data()[ebNE_kb])*v_ext;
530 bc_w_ext = isDOFBoundary_w.data()[ebNE_kb]*ebqe_bc_w_ext.data()[ebNE_kb]+(1-isDOFBoundary_w.data()[ebNE_kb])*w_ext;
536 &materialProperties.data()[materialTypes.data()[eN]*nMaterialProperties],
546 ck.calculateGScale(G,normal,h_penalty);
548 h_penalty = 100.0/h_penalty;
550 isDOFBoundary_v.data()[ebNE_kb],
551 isDOFBoundary_w.data()[ebNE_kb],
552 isStressFluxBoundary_u.data()[ebNE_kb],
553 isStressFluxBoundary_v.data()[ebNE_kb],
554 isStressFluxBoundary_w.data()[ebNE_kb],
562 ebqe_bc_stressFlux_u_ext.data()[ebNE_kb],
563 ebqe_bc_stressFlux_v_ext.data()[ebNE_kb],
564 ebqe_bc_stressFlux_w_ext.data()[ebNE_kb],
573 for (
int i=0;i<nDOF_test_element;i++)
575 elementResidual_u[i] +=
ck.ExteriorElementBoundaryStressFlux(stressFlux_u,disp_test_dS[i]);
576 elementResidual_v[i] +=
ck.ExteriorElementBoundaryStressFlux(stressFlux_v,disp_test_dS[i]);
577 elementResidual_w[i] +=
ck.ExteriorElementBoundaryStressFlux(stressFlux_w,disp_test_dS[i]);
583 for (
int i=0;i<nDOF_test_element;i++)
585 int eN_i = eN*nDOF_test_element+i;
587 globalResidual.data()[offset_u+stride_u*disp_l2g.data()[eN_i]]+=elementResidual_u[i];
588 globalResidual.data()[offset_v+stride_v*disp_l2g.data()[eN_i]]+=elementResidual_v[i];
589 globalResidual.data()[offset_w+stride_w*disp_l2g.data()[eN_i]]+=elementResidual_w[i];
596 xt::pyarray<double>& mesh_trial_ref = args.
array<
double>(
"mesh_trial_ref");
597 xt::pyarray<double>& mesh_grad_trial_ref = args.
array<
double>(
"mesh_grad_trial_ref");
598 xt::pyarray<double>& mesh_dof = args.
array<
double>(
"mesh_dof");
599 xt::pyarray<int>& mesh_l2g = args.
array<
int>(
"mesh_l2g");
600 xt::pyarray<double>& dV_ref = args.
array<
double>(
"dV_ref");
601 xt::pyarray<double>& disp_trial_ref = args.
array<
double>(
"disp_trial_ref");
602 xt::pyarray<double>& disp_grad_trial_ref = args.
array<
double>(
"disp_grad_trial_ref");
603 xt::pyarray<double>& disp_test_ref = args.
array<
double>(
"disp_test_ref");
604 xt::pyarray<double>& disp_grad_test_ref = args.
array<
double>(
"disp_grad_test_ref");
605 xt::pyarray<double>& mesh_trial_trace_ref = args.
array<
double>(
"mesh_trial_trace_ref");
606 xt::pyarray<double>& mesh_grad_trial_trace_ref = args.
array<
double>(
"mesh_grad_trial_trace_ref");
607 xt::pyarray<double>& dS_ref = args.
array<
double>(
"dS_ref");
608 xt::pyarray<double>& disp_trial_trace_ref = args.
array<
double>(
"disp_trial_trace_ref");
609 xt::pyarray<double>& disp_grad_trial_trace_ref = args.
array<
double>(
"disp_grad_trial_trace_ref");
610 xt::pyarray<double>& disp_test_trace_ref = args.
array<
double>(
"disp_test_trace_ref");
611 xt::pyarray<double>& disp_grad_test_trace_ref = args.
array<
double>(
"disp_grad_test_trace_ref");
612 xt::pyarray<double>& normal_ref = args.
array<
double>(
"normal_ref");
613 xt::pyarray<double>& boundaryJac_ref = args.
array<
double>(
"boundaryJac_ref");
614 int nElements_global = args.
scalar<
int>(
"nElements_global");
615 xt::pyarray<int>& materialTypes = args.
array<
int>(
"materialTypes");
616 int nMaterialProperties = args.
scalar<
int>(
"nMaterialProperties");
617 xt::pyarray<double>& materialProperties = args.
array<
double>(
"materialProperties");
618 xt::pyarray<int>& disp_l2g = args.
array<
int>(
"disp_l2g");
619 xt::pyarray<double>& u_dof = args.
array<
double>(
"u_dof");
620 xt::pyarray<double>& v_dof = args.
array<
double>(
"v_dof");
621 xt::pyarray<double>& w_dof = args.
array<
double>(
"w_dof");
622 xt::pyarray<double>& bodyForce = args.
array<
double>(
"bodyForce");
623 xt::pyarray<int>& csrRowIndeces_u_u = args.
array<
int>(
"csrRowIndeces_u_u");
624 xt::pyarray<int>& csrColumnOffsets_u_u = args.
array<
int>(
"csrColumnOffsets_u_u");
625 xt::pyarray<int>& csrRowIndeces_u_v = args.
array<
int>(
"csrRowIndeces_u_v");
626 xt::pyarray<int>& csrColumnOffsets_u_v = args.
array<
int>(
"csrColumnOffsets_u_v");
627 xt::pyarray<int>& csrRowIndeces_u_w = args.
array<
int>(
"csrRowIndeces_u_w");
628 xt::pyarray<int>& csrColumnOffsets_u_w = args.
array<
int>(
"csrColumnOffsets_u_w");
629 xt::pyarray<int>& csrRowIndeces_v_u = args.
array<
int>(
"csrRowIndeces_v_u");
630 xt::pyarray<int>& csrColumnOffsets_v_u = args.
array<
int>(
"csrColumnOffsets_v_u");
631 xt::pyarray<int>& csrRowIndeces_v_v = args.
array<
int>(
"csrRowIndeces_v_v");
632 xt::pyarray<int>& csrColumnOffsets_v_v = args.
array<
int>(
"csrColumnOffsets_v_v");
633 xt::pyarray<int>& csrRowIndeces_v_w = args.
array<
int>(
"csrRowIndeces_v_w");
634 xt::pyarray<int>& csrColumnOffsets_v_w = args.
array<
int>(
"csrColumnOffsets_v_w");
635 xt::pyarray<int>& csrRowIndeces_w_u = args.
array<
int>(
"csrRowIndeces_w_u");
636 xt::pyarray<int>& csrColumnOffsets_w_u = args.
array<
int>(
"csrColumnOffsets_w_u");
637 xt::pyarray<int>& csrRowIndeces_w_v = args.
array<
int>(
"csrRowIndeces_w_v");
638 xt::pyarray<int>& csrColumnOffsets_w_v = args.
array<
int>(
"csrColumnOffsets_w_v");
639 xt::pyarray<int>& csrRowIndeces_w_w = args.
array<
int>(
"csrRowIndeces_w_w");
640 xt::pyarray<int>& csrColumnOffsets_w_w = args.
array<
int>(
"csrColumnOffsets_w_w");
641 xt::pyarray<double>& globalJacobian = args.
array<
double>(
"globalJacobian");
642 int nExteriorElementBoundaries_global = args.
scalar<
int>(
"nExteriorElementBoundaries_global");
643 xt::pyarray<int>& exteriorElementBoundariesArray = args.
array<
int>(
"exteriorElementBoundariesArray");
644 xt::pyarray<int>& elementBoundaryElementsArray = args.
array<
int>(
"elementBoundaryElementsArray");
645 xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.
array<
int>(
"elementBoundaryLocalElementBoundariesArray");
646 xt::pyarray<int>& isDOFBoundary_u = args.
array<
int>(
"isDOFBoundary_u");
647 xt::pyarray<int>& isDOFBoundary_v = args.
array<
int>(
"isDOFBoundary_v");
648 xt::pyarray<int>& isDOFBoundary_w = args.
array<
int>(
"isDOFBoundary_w");
649 xt::pyarray<int>& isStressFluxBoundary_u = args.
array<
int>(
"isStressFluxBoundary_u");
650 xt::pyarray<int>& isStressFluxBoundary_v = args.
array<
int>(
"isStressFluxBoundary_v");
651 xt::pyarray<int>& isStressFluxBoundary_w = args.
array<
int>(
"isStressFluxBoundary_w");
652 xt::pyarray<int>& csrColumnOffsets_eb_u_u = args.
array<
int>(
"csrColumnOffsets_eb_u_u");
653 xt::pyarray<int>& csrColumnOffsets_eb_u_v = args.
array<
int>(
"csrColumnOffsets_eb_u_v");
654 xt::pyarray<int>& csrColumnOffsets_eb_u_w = args.
array<
int>(
"csrColumnOffsets_eb_u_w");
655 xt::pyarray<int>& csrColumnOffsets_eb_v_u = args.
array<
int>(
"csrColumnOffsets_eb_v_u");
656 xt::pyarray<int>& csrColumnOffsets_eb_v_v = args.
array<
int>(
"csrColumnOffsets_eb_v_v");
657 xt::pyarray<int>& csrColumnOffsets_eb_v_w = args.
array<
int>(
"csrColumnOffsets_eb_v_w");
658 xt::pyarray<int>& csrColumnOffsets_eb_w_u = args.
array<
int>(
"csrColumnOffsets_eb_w_u");
659 xt::pyarray<int>& csrColumnOffsets_eb_w_v = args.
array<
int>(
"csrColumnOffsets_eb_w_v");
660 xt::pyarray<int>& csrColumnOffsets_eb_w_w = args.
array<
int>(
"csrColumnOffsets_eb_w_w");
666 for(
int eN=0;eN<nElements_global;eN++)
669 elementJacobian_u_u[nDOF_test_element][nDOF_trial_element],
670 elementJacobian_u_v[nDOF_test_element][nDOF_trial_element],
671 elementJacobian_u_w[nDOF_test_element][nDOF_trial_element],
672 elementJacobian_v_u[nDOF_test_element][nDOF_trial_element],
673 elementJacobian_v_v[nDOF_test_element][nDOF_trial_element],
674 elementJacobian_v_w[nDOF_test_element][nDOF_trial_element],
675 elementJacobian_w_u[nDOF_test_element][nDOF_trial_element],
676 elementJacobian_w_v[nDOF_test_element][nDOF_trial_element],
677 elementJacobian_w_w[nDOF_test_element][nDOF_trial_element];
678 for (
int i=0;i<nDOF_test_element;i++)
679 for (
int j=0;j<nDOF_trial_element;j++)
681 elementJacobian_u_u[i][j]=0.0;
682 elementJacobian_u_v[i][j]=0.0;
683 elementJacobian_u_w[i][j]=0.0;
684 elementJacobian_v_u[i][j]=0.0;
685 elementJacobian_v_v[i][j]=0.0;
686 elementJacobian_v_w[i][j]=0.0;
687 elementJacobian_w_u[i][j]=0.0;
688 elementJacobian_w_v[i][j]=0.0;
689 elementJacobian_w_w[i][j]=0.0;
691 for (
int k=0;k<nQuadraturePoints_element;k++)
694 eN_nDOF_trial_element = eN*nDOF_trial_element;
697 register double u=0.0,
v=0.0,
w=0.0,
701 *grad_w(&
D[2*nSpace]),
704 jacInv[nSpace*nSpace],
705 disp_grad_trial[nDOF_trial_element*nSpace],
707 disp_test_dV[nDOF_test_element],
708 disp_grad_test_dV[nDOF_test_element*nSpace],
710 G[nSpace*nSpace],G_dd_G,tr_G,
711 strain[
nSymTen],stress[
nSymTen],dstress[nSpace*nSpace*nSpace*nSpace];
713 ck.calculateMapping_element(eN,
717 mesh_trial_ref.data(),
718 mesh_grad_trial_ref.data(),
724 dV = fabs(jacDet)*dV_ref.data()[k];
725 ck.calculateG(jacInv,G,G_dd_G,tr_G);
727 ck.gradTrialFromRef(&disp_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,disp_grad_trial);
729 ck.valFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_ref.data()[k*nDOF_trial_element],
u);
730 ck.valFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_ref.data()[k*nDOF_trial_element],
v);
731 ck.valFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_ref.data()[k*nDOF_trial_element],
w);
733 ck.gradFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial,grad_u);
734 ck.gradFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial,grad_v);
735 ck.gradFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial,grad_w);
737 for (
int j=0;j<nDOF_trial_element;j++)
739 disp_test_dV[j] = disp_test_ref.data()[k*nDOF_trial_element+j]*dV;
740 for (
int I=0;I<nSpace;I++)
742 disp_grad_test_dV[j*nSpace+I] = disp_grad_trial[j*nSpace+I]*dV;
747 &materialProperties.data()[materialTypes.data()[eN]*nMaterialProperties],
754 for(
int i=0;i<nDOF_test_element;i++)
756 register int i_nSpace = i*nSpace;
757 for(
int j=0;j<nDOF_trial_element;j++)
759 register int j_nSpace = j*nSpace;
761 elementJacobian_u_u[i][j] +=
ck.StressJacobian_u_u_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
762 elementJacobian_u_v[i][j] +=
ck.StressJacobian_u_v_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
763 elementJacobian_u_w[i][j] +=
ck.StressJacobian_u_w_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
765 elementJacobian_v_u[i][j] +=
ck.StressJacobian_v_u_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
766 elementJacobian_v_v[i][j] +=
ck.StressJacobian_v_v_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
767 elementJacobian_v_w[i][j] +=
ck.StressJacobian_v_w_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
769 elementJacobian_w_u[i][j] +=
ck.StressJacobian_w_u_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
770 elementJacobian_w_v[i][j] +=
ck.StressJacobian_w_v_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
771 elementJacobian_w_w[i][j] +=
ck.StressJacobian_w_w_weak(dstress,&disp_grad_trial[j_nSpace],&disp_grad_test_dV[i_nSpace]);
778 for (
int i=0;i<nDOF_test_element;i++)
780 register int eN_i = eN*nDOF_test_element+i;
781 for (
int j=0;j<nDOF_trial_element;j++)
783 register int eN_i_j = eN_i*nDOF_trial_element+j;
785 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] += elementJacobian_u_u[i][j];
786 globalJacobian.data()[csrRowIndeces_u_v.data()[eN_i] + csrColumnOffsets_u_v.data()[eN_i_j]] += elementJacobian_u_v[i][j];
787 globalJacobian.data()[csrRowIndeces_u_w.data()[eN_i] + csrColumnOffsets_u_w.data()[eN_i_j]] += elementJacobian_u_w[i][j];
789 globalJacobian.data()[csrRowIndeces_v_u.data()[eN_i] + csrColumnOffsets_v_u.data()[eN_i_j]] += elementJacobian_v_u[i][j];
790 globalJacobian.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_v_v.data()[eN_i_j]] += elementJacobian_v_v[i][j];
791 globalJacobian.data()[csrRowIndeces_v_w.data()[eN_i] + csrColumnOffsets_v_w.data()[eN_i_j]] += elementJacobian_v_w[i][j];
793 globalJacobian.data()[csrRowIndeces_w_u.data()[eN_i] + csrColumnOffsets_w_u.data()[eN_i_j]] += elementJacobian_w_u[i][j];
794 globalJacobian.data()[csrRowIndeces_w_v.data()[eN_i] + csrColumnOffsets_w_v.data()[eN_i_j]] += elementJacobian_w_v[i][j];
795 globalJacobian.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_w_w.data()[eN_i_j]] += elementJacobian_w_w[i][j];
802 for (
int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
804 register int ebN = exteriorElementBoundariesArray.data()[ebNE],
805 eN = elementBoundaryElementsArray.data()[ebN*2+0],
806 eN_nDOF_trial_element = eN*nDOF_trial_element,
807 ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0];
808 for (
int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
810 register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
811 ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
812 ebN_local_kb_nSpace = ebN_local_kb*nSpace;
818 D_ext[nSpace*nSpace],
819 *grad_u_ext(&D_ext[0]),
820 *grad_v_ext(&D_ext[nSpace]),
821 *grad_w_ext(&D_ext[2*nSpace]),
822 fluxJacobian_u_u[nDOF_trial_element],
823 fluxJacobian_u_v[nDOF_trial_element],
824 fluxJacobian_u_w[nDOF_trial_element],
825 fluxJacobian_v_u[nDOF_trial_element],
826 fluxJacobian_v_v[nDOF_trial_element],
827 fluxJacobian_v_w[nDOF_trial_element],
828 fluxJacobian_w_u[nDOF_trial_element],
829 fluxJacobian_w_v[nDOF_trial_element],
830 fluxJacobian_w_w[nDOF_trial_element],
831 jac_ext[nSpace*nSpace],
833 jacInv_ext[nSpace*nSpace],
834 boundaryJac[nSpace*(nSpace-1)],
835 metricTensor[(nSpace-1)*(nSpace-1)],
837 disp_grad_trial_trace[nDOF_trial_element*nSpace],
839 disp_test_dS[nDOF_test_element],
842 G[nSpace*nSpace],G_dd_G,tr_G,h_penalty,
846 ck.calculateMapping_elementBoundary(eN,
852 mesh_trial_trace_ref.data(),
853 mesh_grad_trial_trace_ref.data(),
854 boundaryJac_ref.data(),
864 dS = metricTensorDetSqrt*dS_ref.data()[kb];
865 ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
868 ck.gradTrialFromRef(&disp_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,disp_grad_trial_trace);
870 ck.valFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],u_ext);
871 ck.valFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],v_ext);
872 ck.valFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],&disp_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],w_ext);
873 ck.gradFromDOF(u_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial_trace,grad_u_ext);
874 ck.gradFromDOF(v_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial_trace,grad_v_ext);
875 ck.gradFromDOF(w_dof.data(),&disp_l2g.data()[eN_nDOF_trial_element],disp_grad_trial_trace,grad_w_ext);
877 for (
int j=0;j<nDOF_trial_element;j++)
879 disp_test_dS[j] = disp_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
886 &materialProperties.data()[materialTypes.data()[eN]*nMaterialProperties],
893 ck.calculateGScale(G,normal,h_penalty);
895 h_penalty = 100.0/h_penalty;
899 for (
int j=0;j<nDOF_trial_element;j++)
901 register int j_nSpace = j*nSpace;
904 isDOFBoundary_v.data()[ebNE_kb],
905 isDOFBoundary_w.data()[ebNE_kb],
909 disp_trial_trace_ref.data()[ebN_local_kb*nDOF_trial_element+j],
910 &disp_grad_trial_trace[j_nSpace],
919 fluxJacobian_w_w[j]);
924 for (
int i=0;i<nDOF_test_element;i++)
926 register int eN_i = eN*nDOF_test_element+i;
927 for (
int j=0;j<nDOF_trial_element;j++)
931 globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_eb_u_u.data()[ebN_i_j]] += fluxJacobian_u_u[j]*disp_test_dS[i];
932 globalJacobian.data()[csrRowIndeces_u_v.data()[eN_i] + csrColumnOffsets_eb_u_v.data()[ebN_i_j]] += fluxJacobian_u_v[j]*disp_test_dS[i];
933 globalJacobian.data()[csrRowIndeces_u_w.data()[eN_i] + csrColumnOffsets_eb_u_w.data()[ebN_i_j]] += fluxJacobian_u_w[j]*disp_test_dS[i];
935 globalJacobian.data()[csrRowIndeces_v_u.data()[eN_i] + csrColumnOffsets_eb_v_u.data()[ebN_i_j]] += fluxJacobian_v_u[j]*disp_test_dS[i];
936 globalJacobian.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_eb_v_v.data()[ebN_i_j]] += fluxJacobian_v_v[j]*disp_test_dS[i];
937 globalJacobian.data()[csrRowIndeces_v_w.data()[eN_i] + csrColumnOffsets_eb_v_w.data()[ebN_i_j]] += fluxJacobian_v_w[j]*disp_test_dS[i];
939 globalJacobian.data()[csrRowIndeces_w_u.data()[eN_i] + csrColumnOffsets_eb_w_u.data()[ebN_i_j]] += fluxJacobian_w_u[j]*disp_test_dS[i];
940 globalJacobian.data()[csrRowIndeces_w_v.data()[eN_i] + csrColumnOffsets_eb_w_v.data()[ebN_i_j]] += fluxJacobian_w_v[j]*disp_test_dS[i];
941 globalJacobian.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_eb_w_w.data()[ebN_i_j]] += fluxJacobian_w_w[j]*disp_test_dS[i];
952 Ainv[0*3+0] = Amat[1*3+1] * Amat[2*3+2] - Amat[2*3+1] * Amat[1*3+2];
953 Ainv[0*3+1] = Amat[2*3+1] * Amat[0*3+2] - Amat[0*3+1] * Amat[2*3+2];
954 Ainv[0*3+2] = Amat[0*3+1] * Amat[1*3+2] - Amat[0*3+2] * Amat[1*3+1];
956 double tmp = 1.0 / ( Ainv[0*3+0] * Amat[0*3+0]
957 + Ainv[0*3+1] * Amat[1*3+0]
958 + Ainv[0*3+2] * Amat[2*3+0] );
959 Ainv[0*3+0] = Ainv[0*3+0] * tmp;
960 Ainv[0*3+1] = Ainv[0*3+1] * tmp;
961 Ainv[0*3+2] = Ainv[0*3+2] * tmp;
963 Ainv[1*3+0] = (Amat[1*3+2] * Amat[2*3+0] - Amat[1*3+0] * Amat[2*3+2]) * tmp;
964 Ainv[1*3+1] = (Amat[0*3+0] * Amat[2*3+2] - Amat[2*3+0] * Amat[0*3+2]) * tmp;
965 Ainv[1*3+2] = (Amat[1*3+0] * Amat[0*3+2] - Amat[0*3+0] * Amat[1*3+2]) * tmp;
967 Ainv[2*3+0] = (Amat[1*3+0] * Amat[2*3+1] - Amat[1*3+1] * Amat[2*3+0]) * tmp;
968 Ainv[2*3+1] = (Amat[2*3+0] * Amat[0*3+1] - Amat[0*3+0] * Amat[2*3+1]) * tmp;
969 Ainv[2*3+2] = (Amat[0*3+0] * Amat[1*3+1] - Amat[0*3+1] * Amat[1*3+0]) * tmp;
1168 int nQuadraturePoints_elementIn,
1169 int nDOF_mesh_trial_elementIn,
1170 int nDOF_trial_elementIn,
1171 int nDOF_test_elementIn,
1172 int nQuadraturePoints_elementBoundaryIn,
1175 return proteus::chooseAndAllocateDiscretization<MoveMesh_base,MoveMesh,CompKernel>(nSpaceIn,
1176 nQuadraturePoints_elementIn,
1177 nDOF_mesh_trial_elementIn,
1178 nDOF_trial_elementIn,
1179 nDOF_test_elementIn,
1180 nQuadraturePoints_elementBoundaryIn,