1#ifndef AMREX_ML_CURL_CURL_K_H_
2#define AMREX_ML_CURL_CURL_K_H_
3#include <AMReX_Config.H>
185struct CurlCurlDirichletInfo
189#if (AMREX_SPACEDIM < 3)
194 bool is_dirichlet_node (
int i,
int j,
int k)
const
196#if (AMREX_SPACEDIM == 1)
198 return (i == dirichlet_lo[0]) || (i == dirichlet_hi[0]);
199#elif (AMREX_SPACEDIM == 2)
201 return (i == dirichlet_lo[0]) || (i == dirichlet_hi[0])
202 || (j == dirichlet_lo[1]) || (j == dirichlet_hi[1]);
204 return (i == dirichlet_lo[0]) || (i == dirichlet_hi[0])
205 || (j == dirichlet_lo[1]) || (j == dirichlet_hi[1])
206 || (k == dirichlet_lo[2]) || (k == dirichlet_hi[2]);
211 bool is_dirichlet_x_edge (
int,
int j,
int k)
const
213#if (AMREX_SPACEDIM == 1)
216#elif (AMREX_SPACEDIM == 2)
218 return (j == dirichlet_lo[1]) || (j == dirichlet_hi[1]);
220 return (j == dirichlet_lo[1]) || (j == dirichlet_hi[1])
221 || (k == dirichlet_lo[2]) || (k == dirichlet_hi[2]);
226 bool is_dirichlet_y_edge (
int i,
int,
int k)
const
228#if (AMREX_SPACEDIM < 3)
230 return (i == dirichlet_lo[0]) || (i == dirichlet_hi[0]);
232 return (i == dirichlet_lo[0]) || (i == dirichlet_hi[0])
233 || (k == dirichlet_lo[2]) || (k == dirichlet_hi[2]);
238 bool is_dirichlet_z_edge (
int i,
int j,
int)
const
240#if (AMREX_SPACEDIM == 1)
242 if ((i == 0) && (coord == 1)) {
245 return (i == dirichlet_lo[0]) || (i == dirichlet_hi[0]);
248 return (i == dirichlet_lo[0]) || (i == dirichlet_hi[0])
249 || (j == dirichlet_lo[1]) || (j == dirichlet_hi[1]);
254 bool is_dirichlet_edge (
int dim,
int i,
int j,
int k)
const
257 return is_dirichlet_x_edge(i,j,k);
258 }
else if (dim == 1) {
259 return is_dirichlet_y_edge(i,j,k);
261 return is_dirichlet_z_edge(i,j,k);
266struct CurlCurlSymmetryInfo
272 bool xlo_is_symmetric (
int i)
const
274 return i == symmetry_lo[0];
278 bool xhi_is_symmetric (
int i)
const
280 return i == symmetry_hi[0];
283#if (AMREX_SPACEDIM > 1)
285 bool ylo_is_symmetric (
int j)
const
287 return j == symmetry_lo[1];
291 bool yhi_is_symmetric (
int j)
const
293 return j == symmetry_hi[1];
297#if (AMREX_SPACEDIM == 3)
299 bool zlo_is_symmetric (
int k)
const
301 return k == symmetry_lo[2];
305 bool zhi_is_symmetric (
int k)
const
307 return k == symmetry_hi[2];
311 [[nodiscard]]
bool is_symmetric (
int dir,
int side,
int idx)
const
313#if (AMREX_SPACEDIM == 1)
315 return (side == 0) ? xlo_is_symmetric(idx) : xhi_is_symmetric(idx);
316#elif (AMREX_SPACEDIM == 2)
318 return (side == 0) ? xlo_is_symmetric(idx) : xhi_is_symmetric(idx);
320 return (side == 0) ? ylo_is_symmetric(idx) : yhi_is_symmetric(idx);
324 return (side == 0) ? xlo_is_symmetric(idx) : xhi_is_symmetric(idx);
325 }
else if (dir == 1) {
326 return (side == 0) ? ylo_is_symmetric(idx) : yhi_is_symmetric(idx);
328 return (side == 0) ? zlo_is_symmetric(idx) : zhi_is_symmetric(idx);
334enum struct CurlCurlStateType {
x, b, r };
345#if (AMREX_SPACEDIM == 1)
348#elif (AMREX_SPACEDIM == 2)
350 Real dyy = adxinv[1] * adxinv[1];
351 Real dxy = adxinv[0] * adxinv[1];
352 Real ccex = ex(i ,j ,k ) * dyy *
Real(2.0)
353 - dyy * (ex(i ,j-1,k ) +
355 + dxy * (ey(i ,j-1,k )
359#elif (AMREX_SPACEDIM == 3)
360 Real dyy = adxinv[1] * adxinv[1];
361 Real dzz = adxinv[2] * adxinv[2];
362 Real dxy = adxinv[0] * adxinv[1];
363 Real dxz = adxinv[0] * adxinv[2];
364 Real ccex = ex(i ,j ,k ) * (dyy+dzz)*
Real(2.0)
365 - dyy * (ex(i ,j-1,k ) +
367 - dzz * (ex(i ,j ,k+1) +
369 + dxy * (ey(i ,j-1,k )
373 + dxz * (ez(i ,j ,k-1)
378 Ax(i,j,k) = ccex + beta * ex(i,j,k);
387#
if (AMREX_SPACEDIM < 3)
392#if (AMREX_SPACEDIM == 1)
396 ccey = ey(i ,j,k) *
Real(2.0)
399 }
else if (coord == 1) {
406 ccey = ey(i ,j,k) *
Real(2.0)
410 ccey *= adxinv[0] * adxinv[0];
411#elif (AMREX_SPACEDIM == 2)
413 Real dxx = adxinv[0] * adxinv[0];
414 Real dxy = adxinv[0] * adxinv[1];
415 Real ccey = ey(i ,j ,k ) * dxx *
Real(2.0)
416 - dxx * (ey(i-1,j ,k ) +
418 + dxy * (ex(i-1,j ,k )
422#elif (AMREX_SPACEDIM == 3)
423 Real dxx = adxinv[0] * adxinv[0];
424 Real dzz = adxinv[2] * adxinv[2];
425 Real dxy = adxinv[0] * adxinv[1];
426 Real dyz = adxinv[1] * adxinv[2];
427 Real ccey = ey(i ,j ,k ) * (dxx+dzz)*
Real(2.0)
428 - dxx * (ey(i-1,j ,k ) +
430 - dzz * (ey(i ,j ,k-1) +
432 + dxy * (ex(i-1,j ,k )
436 + dyz * (ez(i ,j ,k-1)
441 Ay(i,j,k) = ccey + beta * ey(i,j,k);
450#
if (AMREX_SPACEDIM < 3)
455#if (AMREX_SPACEDIM == 1)
459 ccez = ez(i ,j,k) *
Real(2.0)
462 }
else if (coord == 1) {
464 ccez =
Real(4.0) * (ez(0,0,0) - ez(1,0,0));
466 ccez = ez(i ,j,k) *
Real(2.0)
471 ccez = ez(i ,j,k) *
Real(2.0)
475 ccez *= adxinv[0] * adxinv[0];
476#elif (AMREX_SPACEDIM == 2)
478 Real dxx = adxinv[0] * adxinv[0];
479 Real dyy = adxinv[1] * adxinv[1];
480 Real ccez = ez(i ,j ,k ) * (dxx+dyy)*
Real(2.0)
481 - dxx * (ez(i-1,j ,k ) +
483 - dyy * (ez(i ,j-1,k ) +
485#elif (AMREX_SPACEDIM == 3)
486 Real dxx = adxinv[0] * adxinv[0];
487 Real dyy = adxinv[1] * adxinv[1];
488 Real dxz = adxinv[0] * adxinv[2];
489 Real dyz = adxinv[1] * adxinv[2];
490 Real ccez = ez(i ,j ,k ) * (dxx+dyy)*
Real(2.0)
491 - dxx * (ez(i-1,j ,k ) +
493 - dyy * (ez(i ,j-1,k ) +
495 + dxz * (ex(i-1,j ,k )
499 + dyz * (ey(i ,j-1,k )
504 Az(i,j,k) = ccez + beta * ez(i,j,k);
507#if (AMREX_SPACEDIM == 1)
509void mlcurlcurl_smooth_1d (
int i,
int j,
int k,
510 Array4<Real>
const& ex,
511 Array4<Real>
const& ey,
512 Array4<Real>
const& ez,
513 Array4<Real const>
const& rhsx,
514 Array4<Real const>
const& rhsy,
515 Array4<Real const>
const& rhsz,
517 GpuArray<Real,AMREX_SPACEDIM>
const& adxinv,
519 CurlCurlDirichletInfo
const& dinfo,
bool valid_x,
522 Real dxx = adxinv[0] * adxinv[0];
526 if (my_color == color)
529 ex(i,j,k) = rhsx(i,j,k) / beta;
534 if (dinfo.is_dirichlet_node(i,j,k)) {
return; }
539 Real gamma = dxx *
Real(2.0) + beta;
541 Real ccey = cm * ey(i-1,j,k) + cp * ey(i+1,j,k);
542 Real res_y = rhsy(i,j,k) - ( gamma * ey(i,j,k) + ccey );
543 ey(i,j,k) += res_y/gamma;
545 Real ccez = cm * ez(i-1,j,k) + cp * ez(i+1,j,k);
546 Real res_z = rhsz(i,j,k) - ( gamma * ez(i,j,k) + ccez );
547 ez(i,j,k) += res_z/gamma;
551 if ((i > 0) && ! dinfo.is_dirichlet_node(i,j,k)) {
557 Real ccey = cm * ey(i-1,j,k) + cp * ey(i+1,j,k);
558 Real res_y = rhsy(i,j,k) - ( gamma * ey(i,j,k) + ccey );
559 ey(i,j,k) += res_y/gamma;
561 gamma = dxx *
Real(2.0) + beta;
563 Real ccez = cm * ez(i-1,j,k) + cp * ez(i+1,j,k);
564 Real res_z = rhsz(i,j,k) - ( gamma * ez(i,j,k) + ccez );
565 ez(i,j,k) += res_z/gamma;
567 if ((i == 0) || (i == 1)) {
568 ez(0,0,0) = (rhsz(0,0,0) +
Real(4.0)*dxx*ez(1,0,0))
569 / (beta +
Real(4.0)*dxx);
574 if (i == 0 || dinfo.is_dirichlet_node(i,j,k)) {
return; }
579 Real gamma = dxx *
Real(2.0) + beta;
581 Real ccey = cm * ey(i-1,j,k) + cp * ey(i+1,j,k);
582 Real res_y = rhsy(i,j,k) - ( gamma * ey(i,j,k) + ccey );
583 ey(i,j,k) += res_y/gamma;
585 Real ccez = cm * ez(i-1,j,k) + cp * ez(i+1,j,k);
586 Real res_z = rhsz(i,j,k) - ( gamma * ez(i,j,k) + ccez );
587 ez(i,j,k) += res_z/gamma;
594void mlcurlcurl_smooth_1d (
int i,
int j,
int k,
595 Array4<Real>
const& ex,
596 Array4<Real>
const& ey,
597 Array4<Real>
const& ez,
598 Array4<Real const>
const& rhsx,
599 Array4<Real const>
const& rhsy,
600 Array4<Real const>
const& rhsz,
601 Array4<Real const>
const& betax,
602 Array4<Real const>
const& betay,
603 Array4<Real const>
const& betaz,
604 GpuArray<Real,AMREX_SPACEDIM>
const& adxinv,
606 CurlCurlDirichletInfo
const& dinfo,
bool valid_x,
609 Real dxx = adxinv[0] * adxinv[0];
613 if (my_color == color)
616 ex(i,j,k) = rhsx(i,j,k) / betax(i,j,k);
621 if (dinfo.is_dirichlet_node(i,j,k)) {
return; }
626 Real gamma_y = dxx *
Real(2.0) + betay(i,j,k);
627 Real ccey = cm * ey(i-1,j,k) + cp * ey(i+1,j,k);
628 Real res_y = rhsy(i,j,k) - ( gamma_y * ey(i,j,k) + ccey );
629 ey(i,j,k) += res_y/gamma_y;
631 Real gamma_z = dxx *
Real(2.0) + betaz(i,j,k);
632 Real ccez = cm * ez(i-1,j,k) + cp * ez(i+1,j,k);
633 Real res_z = rhsz(i,j,k) - ( gamma_z * ez(i,j,k) + ccez );
634 ez(i,j,k) += res_z/gamma_z;
638 if ((i > 0) && ! dinfo.is_dirichlet_node(i,j,k)) {
644 Real ccey = cm * ey(i-1,j,k) + cp * ey(i+1,j,k);
645 Real res_y = rhsy(i,j,k) - ( gamma * ey(i,j,k) + ccey );
646 ey(i,j,k) += res_y/gamma;
650 ez(0,0,0) = (rhsz(0,0,0) +
Real(4.0)*dxx*ez(1,0,0)) / (betaz(0,0,0) +
Real(4.0)*dxx);
651 }
else if (! dinfo.is_dirichlet_node(i,j,k)) {
655 Real gamma = dxx *
Real(2.0) + betaz(i,j,k);
657 Real ccez = cm * ez(i-1,j,k) + cp * ez(i+1,j,k);
658 Real res_z = rhsz(i,j,k) - ( gamma * ez(i,j,k) + ccez );
659 ez(i,j,k) += res_z/gamma;
664 if (dinfo.is_dirichlet_node(i,j,k)) {
return; }
669 Real gamma_y = dxx *
Real(2.0) + betay(i,j,k);
670 Real ccey = cm * ey(i-1,j,k) + cp * ey(i+1,j,k);
671 Real res_y = rhsy(i,j,k) - ( gamma_y * ey(i,j,k) + ccey );
672 ey(i,j,k) += res_y/gamma_y;
674 Real gamma_z = dxx *
Real(2.0) + betaz(i,j,k);
675 Real ccez = cm * ez(i-1,j,k) + cp * ez(i+1,j,k);
676 Real res_z = rhsz(i,j,k) - ( gamma_z * ez(i,j,k) + ccez );
677 ez(i,j,k) += res_z/gamma_z;
685#if (AMREX_SPACEDIM > 1)
695#
if (AMREX_SPACEDIM == 2)
700 CurlCurlDirichletInfo
const& dinfo,
701 CurlCurlSymmetryInfo
const& sinfo)
703 if (dinfo.is_dirichlet_node(i,j,k)) {
return; }
705 int my_color = i%2 + 2*(j%2);
707 my_color = 3 - my_color;
710#if (AMREX_SPACEDIM == 2)
712 Real dxx = adxinv[0] * adxinv[0];
713 Real dyy = adxinv[1] * adxinv[1];
715 if (((my_color == 0 || my_color == 3) && (color == 0 || color == 3)) ||
716 ((my_color == 1 || my_color == 2) && (color == 1 || color == 2)))
718 Real gamma = (dxx+dyy)*
Real(2.0) + beta;
719 Real ccez = - dxx * (ez(i-1,j ,k ) +
721 - dyy * (ez(i ,j-1,k ) +
723 Real res = rhsz(i,j,k) - (gamma*ez(i,j,k) + ccez);
725 ez(i,j,k) += omega/gamma * res;
728 if (my_color != color) {
return; }
730 Real dxy = adxinv[0]*adxinv[1];
733 {rhsx(i-1,j,k) - (-dyy * ( ex(i-1,j-1,k ) +
735 + dxy * ( ey(i-1,j-1,k )
737 rhsx(i ,j,k) - (-dyy * ( ex(i ,j-1,k ) +
739 + dxy * (-ey(i+1,j-1,k )
741 rhsy(i,j-1,k) - (-dxx * ( ey(i-1,j-1,k ) +
743 + dxy * ( ex(i-1,j-1,k )
745 rhsy(i,j ,k) - (-dxx * ( ey(i-1,j ,k ) +
747 + dxy * (-ex(i-1,j+1,k )
750 if (sinfo.xlo_is_symmetric(i)) {
752 }
else if (sinfo.xhi_is_symmetric(i)) {
756 if (sinfo.ylo_is_symmetric(j)) {
758 }
else if (sinfo.yhi_is_symmetric(j)) {
763 lusolver(
x.data(), b.data());
764 ex(i-1,j ,k ) =
x[0];
766 ey(i ,j-1,k ) =
x[2];
769#elif (AMREX_SPACEDIM == 3)
771 if (my_color != color) {
return; }
773 Real dxx = adxinv[0]*adxinv[0];
774 Real dyy = adxinv[1]*adxinv[1];
775 Real dzz = adxinv[2]*adxinv[2];
776 Real dxy = adxinv[0]*adxinv[1];
777 Real dxz = adxinv[0]*adxinv[2];
778 Real dyz = adxinv[1]*adxinv[2];
781 {rhsx(i-1,j,k) - (-dyy * ( ex(i-1,j-1,k ) +
783 - dzz * ( ex(i-1,j ,k+1) +
785 + dxy * ( ey(i-1,j-1,k )
787 + dxz * ( ez(i-1,j ,k-1)
789 rhsx(i ,j,k) - (-dyy * ( ex(i ,j-1,k ) +
791 - dzz * ( ex(i ,j ,k+1) +
793 + dxy * (-ey(i+1,j-1,k )
795 + dxz * (-ez(i+1,j ,k-1)
797 rhsy(i,j-1,k) - (-dxx * ( ey(i-1,j-1,k ) +
799 - dzz * ( ey(i ,j-1,k-1) +
801 + dxy * ( ex(i-1,j-1,k )
803 + dyz * ( ez(i ,j-1,k-1)
805 rhsy(i,j ,k) - (-dxx * ( ey(i-1,j ,k ) +
807 - dzz * ( ey(i ,j ,k-1) +
809 + dxy * (-ex(i-1,j+1,k )
811 + dyz * (-ez(i ,j+1,k-1)
813 rhsz(i,j,k-1) - (-dxx * ( ez(i-1,j ,k-1) +
815 - dyy * ( ez(i ,j-1,k-1) +
817 + dxz * ( ex(i-1,j ,k-1)
819 + dyz * ( ey(i ,j-1,k-1)
821 rhsz(i,j,k ) - (-dxx * ( ez(i-1,j ,k ) +
823 - dyy * ( ez(i ,j-1,k ) +
825 + dxz * (-ex(i-1,j ,k+1)
827 + dyz * (-ey(i ,j-1,k+1)
830 if (sinfo.xlo_is_symmetric(i)) {
832 }
else if (sinfo.xhi_is_symmetric(i)) {
836 if (sinfo.ylo_is_symmetric(j)) {
838 }
else if (sinfo.yhi_is_symmetric(j)) {
842 if (sinfo.zlo_is_symmetric(k)) {
844 }
else if (sinfo.zhi_is_symmetric(k)) {
849 lusolver(
x.data(), b.data());
850 ex(i-1,j ,k ) =
x[0];
852 ey(i ,j-1,k ) =
x[2];
854 ez(i ,j ,k-1) =
x[4];
873 CurlCurlDirichletInfo
const& dinfo,
874 CurlCurlSymmetryInfo
const& sinfo)
876 if (dinfo.is_dirichlet_node(i,j,k)) {
return; }
878 int my_color = i%2 + 2*(j%2);
880 my_color = 3 - my_color;
883#if (AMREX_SPACEDIM == 2)
885 Real dxx = adxinv[0] * adxinv[0];
886 Real dyy = adxinv[1] * adxinv[1];
888 if (((my_color == 0 || my_color == 3) && (color == 0 || color == 3)) ||
889 ((my_color == 1 || my_color == 2) && (color == 1 || color == 2)))
891 Real gamma = (dxx+dyy)*
Real(2.0) + betaz(i,j,k);
892 Real ccez = - dxx * (ez(i-1,j ,k ) +
894 - dyy * (ez(i ,j-1,k ) +
896 Real res = rhsz(i,j,k) - (gamma*ez(i,j,k) + ccez);
898 ez(i,j,k) += omega/gamma * res;
901 if (my_color != color) {
return; }
903 Real dxy = adxinv[0]*adxinv[1];
906 {rhsx(i-1,j,k) - (-dyy * ( ex(i-1,j-1,k ) +
908 + dxy * ( ey(i-1,j-1,k )
910 rhsx(i ,j,k) - (-dyy * ( ex(i ,j-1,k ) +
912 + dxy * (-ey(i+1,j-1,k )
914 rhsy(i,j-1,k) - (-dxx * ( ey(i-1,j-1,k ) +
916 + dxy * ( ex(i-1,j-1,k )
918 rhsy(i,j ,k) - (-dxx * ( ey(i-1,j ,k ) +
920 + dxy * (-ex(i-1,j+1,k )
925 if (sinfo.xlo_is_symmetric(i)) {
927 beta[0] = beta[1] = betax(i,j,k);
928 }
else if (sinfo.xhi_is_symmetric(i)) {
930 beta[0] = beta[1] = betax(i-1,j,k);
932 beta[0] = betax(i-1,j,k);
933 beta[1] = betax(i ,j,k);
936 if (sinfo.ylo_is_symmetric(j)) {
938 beta[2] = beta[3] = betay(i,j,k);
939 }
else if (sinfo.yhi_is_symmetric(j)) {
941 beta[2] = beta[3] = betay(i,j-1,k);
943 beta[2] = betay(i,j-1,k);
944 beta[3] = betay(i,j ,k);
948 Real diagInv[4] = {
Real(1.0) / (dyy*
Real(2.0) + beta[0]),
949 Real(1.0) / (dyy*
Real(2.0) + beta[1]),
950 Real(1.0) / (dxx*
Real(2.0) + beta[2]),
951 Real(1.0) / (dxx*
Real(2.0) + beta[3])};
955 for (
int m = 0; m < 4; ++m) {
z[m] = r[m] * diagInv[m]; }
960 Av[0] = (dyy*
Real(2.0) + beta[0]) * v[0] - dxy * v[2] + dxy * v[3];
961 Av[1] = (dyy*
Real(2.0) + beta[1]) * v[1] + dxy * v[2] - dxy * v[3];
962 Av[2] = -dxy * v[0] + dxy * v[1] + (dxx*
Real(2.0) + beta[2]) * v[2];
963 Av[3] = dxy * v[0] - dxy * v[1] + (dxx*
Real(2.0) + beta[3]) * v[3];
965 Real sol[4] = {0, 0, 0, 0};
966 pcg_solve<4>(sol, b.data(), mat, precond, 8,
Real(1.e-8));
967 ex(i-1,j ,k ) = sol[0];
968 ex(i ,j ,k ) = sol[1];
969 ey(i ,j-1,k ) = sol[2];
970 ey(i ,j ,k ) = sol[3];
973 ({dyy*
Real(2.0) + beta[0],
979 dyy*
Real(2.0) + beta[1],
985 dxx*
Real(2.0) + beta[2],
991 dxx*
Real(2.0) + beta[3]});
992 lusolver(beta.
data(), b.data());
993 ex(i-1,j ,k ) = beta[0];
994 ex(i ,j ,k ) = beta[1];
995 ey(i ,j-1,k ) = beta[2];
996 ey(i ,j ,k ) = beta[3];
999#elif (AMREX_SPACEDIM == 3)
1001 if (my_color != color) {
return; }
1003 Real dxx = adxinv[0]*adxinv[0];
1004 Real dyy = adxinv[1]*adxinv[1];
1005 Real dzz = adxinv[2]*adxinv[2];
1006 Real dxy = adxinv[0]*adxinv[1];
1007 Real dxz = adxinv[0]*adxinv[2];
1008 Real dyz = adxinv[1]*adxinv[2];
1011 {rhsx(i-1,j,k) - (-dyy * ( ex(i-1,j-1,k ) +
1013 - dzz * ( ex(i-1,j ,k+1) +
1015 + dxy * ( ey(i-1,j-1,k )
1017 + dxz * ( ez(i-1,j ,k-1)
1019 rhsx(i ,j,k) - (-dyy * ( ex(i ,j-1,k ) +
1021 - dzz * ( ex(i ,j ,k+1) +
1023 + dxy * (-ey(i+1,j-1,k )
1025 + dxz * (-ez(i+1,j ,k-1)
1027 rhsy(i,j-1,k) - (-dxx * ( ey(i-1,j-1,k ) +
1029 - dzz * ( ey(i ,j-1,k-1) +
1031 + dxy * ( ex(i-1,j-1,k )
1033 + dyz * ( ez(i ,j-1,k-1)
1035 rhsy(i,j ,k) - (-dxx * ( ey(i-1,j ,k ) +
1037 - dzz * ( ey(i ,j ,k-1) +
1039 + dxy * (-ex(i-1,j+1,k )
1041 + dyz * (-ez(i ,j+1,k-1)
1043 rhsz(i,j,k-1) - (-dxx * ( ez(i-1,j ,k-1) +
1045 - dyy * ( ez(i ,j-1,k-1) +
1047 + dxz * ( ex(i-1,j ,k-1)
1049 + dyz * ( ey(i ,j-1,k-1)
1051 rhsz(i,j,k ) - (-dxx * ( ez(i-1,j ,k ) +
1053 - dyy * ( ez(i ,j-1,k ) +
1055 + dxz * (-ex(i-1,j ,k+1)
1057 + dyz * (-ey(i ,j-1,k+1)
1062 if (sinfo.xlo_is_symmetric(i)) {
1064 beta[0] = beta[1] = betax(i,j,k);
1065 }
else if (sinfo.xhi_is_symmetric(i)) {
1067 beta[0] = beta[1] = betax(i-1,j,k);
1069 beta[0] = betax(i-1,j,k);
1070 beta[1] = betax(i ,j,k);
1073 if (sinfo.ylo_is_symmetric(j)) {
1075 beta[2] = beta[3] = betay(i,j,k);
1076 }
else if (sinfo.yhi_is_symmetric(j)) {
1078 beta[2] = beta[3] = betay(i,j-1,k);
1080 beta[2] = betay(i,j-1,k);
1081 beta[3] = betay(i,j ,k);
1084 if (sinfo.zlo_is_symmetric(k)) {
1086 beta[4] = beta[5] = betaz(i,j,k);
1087 }
else if (sinfo.zhi_is_symmetric(k)) {
1089 beta[4] = beta[5] = betaz(i,j,k-1);
1091 beta[4] = betaz(i,j,k-1);
1092 beta[5] = betaz(i,j,k );
1095 if constexpr (PCG) {
1096 Real diagInv[6] = {
Real(1.0) / ((dyy+dzz)*
Real(2.0) + beta[0]),
1097 Real(1.0) / ((dyy+dzz)*
Real(2.0) + beta[1]),
1098 Real(1.0) / ((dxx+dzz)*
Real(2.0) + beta[2]),
1099 Real(1.0) / ((dxx+dzz)*
Real(2.0) + beta[3]),
1100 Real(1.0) / ((dxx+dyy)*
Real(2.0) + beta[4]),
1101 Real(1.0) / ((dxx+dyy)*
Real(2.0) + beta[5])};
1105 for (
int m = 0; m < 6; ++m) {
z[m] = r[m] * diagInv[m]; }
1110 Av[0] = ((dyy+dzz)*
Real(2.0) + beta[0]) * v[0] - dxy * v[2]
1111 + dxy * v[3] - dxz * v[4] + dxz * v[5];
1112 Av[1] = ((dyy+dzz)*
Real(2.0) + beta[1]) * v[1] + dxy * v[2]
1113 - dxy * v[3] + dxz * v[4] - dxz * v[5];
1114 Av[2] = -dxy * v[0] + dxy * v[1] + ((dxx+dzz)*
Real(2.0) + beta[2]) * v[2]
1115 - dyz * v[4] + dyz * v[5];
1116 Av[3] = dxy * v[0] - dxy * v[1] + ((dxx+dzz)*
Real(2.0) + beta[3]) * v[3]
1117 + dyz * v[4] - dyz * v[5];
1118 Av[4] = -dxz * v[0] + dxz * v[1] - dyz * v[2] + dyz * v[3]
1119 + ((dxx+dyy)*
Real(2.0) + beta[4]) * v[4];
1120 Av[5] = dxz * v[0] - dxz * v[1] + dyz * v[2] - dyz * v[3]
1121 + ((dxx+dyy)*
Real(2.0) + beta[5]) * v[5];
1123 Real sol[6] = {0, 0, 0, 0, 0, 0};
1124 pcg_solve<6>(sol, b.data(), mat, precond, 8,
Real(1.e-8));
1125 ex(i-1,j ,k ) = sol[0];
1126 ex(i ,j ,k ) = sol[1];
1127 ey(i ,j-1,k ) = sol[2];
1128 ey(i ,j ,k ) = sol[3];
1129 ez(i ,j ,k-1) = sol[4];
1130 ez(i ,j ,k ) = sol[5];
1133 ({(dyy+dzz)*
Real(2.0) + beta[0],
1141 (dyy+dzz)*
Real(2.0) + beta[1],
1149 (dxx+dzz)*
Real(2.0) + beta[2],
1157 (dxx+dzz)*
Real(2.0) + beta[3],
1165 (dxx+dyy)*
Real(2.0) + beta[4],
1173 (dxx+dyy)*
Real(2.0) + beta[5]});
1174 lusolver(beta.
data(), b.data());
1175 ex(i-1,j ,k ) = beta[0];
1176 ex(i ,j ,k ) = beta[1];
1177 ey(i ,j-1,k ) = beta[2];
1178 ey(i ,j ,k ) = beta[3];
1179 ez(i ,j ,k-1) = beta[4];
1180 ez(i ,j ,k ) = beta[5];
1196 bool j_is_odd = (jc*2 != j);
1197 bool k_is_odd = (kc*2 != k);
1198 if (j_is_odd && k_is_odd) {
1200 (
crse(ic,jc,kc ) +
crse(ic,jc+1,kc ) +
1201 crse(ic,jc,kc+1) +
crse(ic,jc+1,kc+1));
1202 }
else if (j_is_odd) {
1204 }
else if (k_is_odd) {
1209 }
else if (dir == 1) {
1210 bool i_is_odd = (ic*2 != i);
1211 bool k_is_odd = (kc*2 != k);
1212 if (i_is_odd && k_is_odd) {
1214 (
crse(ic ,jc,kc ) +
crse(ic+1,jc,kc ) +
1215 crse(ic ,jc,kc+1) +
crse(ic+1,jc,kc+1));
1216 }
else if (i_is_odd) {
1218 }
else if (k_is_odd) {
1224 bool i_is_odd = (ic*2 != i);
1225 bool j_is_odd = (jc*2 != j);
1226 if (i_is_odd && j_is_odd) {
1228 (
crse(ic ,jc ,kc) +
crse(ic+1,jc ,kc) +
1229 crse(ic ,jc+1,kc) +
crse(ic+1,jc+1,kc));
1230 }
else if (i_is_odd) {
1232 }
else if (j_is_odd) {
1244 CurlCurlDirichletInfo
const& dinfo)
1249 if (dinfo.is_dirichlet_edge(dir,ii,jj,kk)) {
1254#if (AMREX_SPACEDIM == 3)
1258 fine(ii ,jj+1,kk-1) +
1262 fine(ii ,jj-1,kk+1) +
1264 fine(ii ,jj+1,kk+1) +
1265 fine(ii+1,jj-1,kk-1) +
1267 fine(ii+1,jj+1,kk-1) +
1271 fine(ii+1,jj-1,kk+1) +
1273 fine(ii+1,jj+1,kk+1) );
1274 }
else if (dir == 1) {
1277 fine(ii+1,jj ,kk-1) +
1281 fine(ii-1,jj ,kk+1) +
1283 fine(ii+1,jj ,kk+1) +
1284 fine(ii-1,jj+1,kk-1) +
1286 fine(ii+1,jj+1,kk-1) +
1290 fine(ii-1,jj+1,kk+1) +
1292 fine(ii+1,jj+1,kk+1) );
1296 fine(ii+1,jj-1,kk ) +
1300 fine(ii-1,jj+1,kk ) +
1302 fine(ii+1,jj+1,kk ) +
1303 fine(ii-1,jj-1,kk+1) +
1305 fine(ii+1,jj-1,kk+1) +
1309 fine(ii-1,jj+1,kk+1) +
1311 fine(ii+1,jj+1,kk+1) );
1313#elif (AMREX_SPACEDIM == 2)
1320 fine(ii+1,jj+1,0) );
1321 }
else if (dir == 1) {
1327 fine(ii+1,jj+1,0) );
1335#elif (AMREX_SPACEDIM == 1)
1338 }
else if (i == 0 && dir == 2 && dinfo.coord == 1) {
1364 a(i,j,k) = sign * a(i+
offset,j,k);
1365 }
else if (
idir == 1) {
1366 a(i,j,k) = sign * a(i,j+
offset,k);
1368 a(i,j,k) = sign * a(i,j,k+
offset);
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition AMReX_Extension.H:32
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
int idir
Definition AMReX_HypreMLABecLap.cpp:1093
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1089
Array4< Real > fine
Definition AMReX_InterpFaceRegister.cpp:90
Array4< Real const > crse
Definition AMReX_InterpFaceRegister.cpp:92
__host__ __device__ bool cellCentered() const noexcept
True if the IndexTypeND is CELL based in all directions.
Definition AMReX_IndexType.H:104
Definition AMReX_LUSolver.H:16
Encapsulation of the Orientation of the Faces of a Box.
Definition AMReX_Orientation.H:29
__host__ __device__ bool isLow() const noexcept
Returns true if Orientation is low.
Definition AMReX_Orientation.H:89
__host__ __device__ int coordDir() const noexcept
Returns the coordinate direction.
Definition AMReX_Orientation.H:83
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:79
__host__ __device__ BoxND< dim > coarsen(const BoxND< dim > &b, int ref_ratio) noexcept
Coarsen BoxND by given (positive) coarsening ratio.
Definition AMReX_Box.H:1409
Definition AMReX_Amr.cpp:49
__device__ void mlcurlcurl_restriction(int dir, int i, int j, int k, Array4< Real > const &crse, Array4< Real const > const &fine, CurlCurlDirichletInfo const &dinfo)
Definition AMReX_MLCurlCurl_K.H:1241
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:138
__device__ void mlcurlcurl_gs4_lu(int i, int j, int k, Array4< Real > const &ex, Array4< Real > const &ey, Array4< Real > const &ez, Array4< Real const > const &rhsx, Array4< Real const > const &rhsy, Array4< Real const > const &rhsz, GpuArray< Real, 3 > const &adxinv, int color, LUSolver< 3 *2, Real > const &lusolver, CurlCurlDirichletInfo const &dinfo, CurlCurlSymmetryInfo const &sinfo)
Definition AMReX_MLCurlCurl_K.H:688
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:30
__device__ void mlcurlcurl_bc_symmetry(int i, int j, int k, Orientation face, IndexType it, Array4< Real > const &a)
Definition AMReX_MLCurlCurl_K.H:1350
__device__ void mlcurlcurl_interpadd(int dir, int i, int j, int k, Array4< Real > const &fine, Array4< Real const > const &crse)
Definition AMReX_MLCurlCurl_K.H:1188
__device__ void mlcurlcurl_adotx_z(int i, int j, int k, Array4< Real > const &Az, Array4< Real const > const &ex, Array4< Real const > const &ey, Array4< Real const > const &ez, Real beta, GpuArray< Real, 3 > const &adxinv)
Definition AMReX_MLCurlCurl_K.H:445
__device__ void mlcurlcurl_gs4(int i, int j, int k, Array4< Real > const &ex, Array4< Real > const &ey, Array4< Real > const &ez, Array4< Real const > const &rhsx, Array4< Real const > const &rhsy, Array4< Real const > const &rhsz, GpuArray< Real, 3 > const &adxinv, int color, Array4< Real const > const &betax, Array4< Real const > const &betay, Array4< Real const > const &betaz, CurlCurlDirichletInfo const &dinfo, CurlCurlSymmetryInfo const &sinfo)
Definition AMReX_MLCurlCurl_K.H:861
__device__ void mlcurlcurl_adotx_x(int i, int j, int k, Array4< Real > const &Ax, Array4< Real const > const &ex, Array4< Real const > const &ey, Array4< Real const > const &ez, Real beta, GpuArray< Real, 3 > const &adxinv)
Definition AMReX_MLCurlCurl_K.H:339
__device__ void mlcurlcurl_adotx_y(int i, int j, int k, Array4< Real > const &Ay, Array4< Real const > const &ex, Array4< Real const > const &ey, Array4< Real const > const &ez, Real beta, GpuArray< Real, 3 > const &adxinv)
Definition AMReX_MLCurlCurl_K.H:382
Definition AMReX_Array4.H:61
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:40
__host__ __device__ const T * data() const noexcept
Definition AMReX_Array.H:72