333 using namespace amrex;
337 "MatrixPC::Assemble() called on undefined object" );
340 const RT thetaDt =
m_ops->GetThetaForPC()*this->
m_dt;
344 <<
": theta*dt = " << thetaDt <<
", "
346 <<
"alpha = " <<
alpha <<
"\n";
350 const auto& dofs_obj = a_U.getDOFsObject();
351 const auto& dofs_mfarrvec = dofs_obj->m_array;
371 auto a_ij_ptr =
m_a_ij.data();
374 auto nnz_actual = nnz_max;
378 auto ncomp = dofs_mfarrvec[lev][0]->nComp();
381 const auto& geom =
m_geom[lev];
382 const auto dxi = geom.InvCellSizeArray();
385 auto* nnz_actual_ptr = nnz_actual_d.
data();
387 for (
int dir = 0; dir < 3; dir++) {
391 for (
amrex::MFIter mfi(*dofs_mfarrvec[lev][dir]); mfi.isValid(); ++mfi) {
397 const auto BC_mask_Edir_arr = BC_mask_Edir->
const_array(mfi);
399 auto dof_arr = dofs_mfarrvec[lev][dir]->const_array(mfi);
401#if defined(WARPX_DIM_RCYLINDER)
404#elif defined(WARPX_DIM_RSPHERE)
407#elif defined(WARPX_DIM_RZ)
410#elif defined(WARPX_DIM_XZ)
412 if (dir == 0) { tdir = 2; }
413 else if (dir == 2) { tdir = 0; }
415 auto dof_tdir_arr = dofs_mfarrvec[lev][tdir]->const_array(mfi);
416#elif defined(WARPX_DIM_3D)
417 int tdir1 = (dir + 1) % 3;
418 int tdir2 = (dir + 2) % 3;
420 const dof_arrays {{
AMREX_D_DECL( dofs_mfarrvec[lev][dir]->const_array(mfi),
421 dofs_mfarrvec[lev][tdir1]->const_array(mfi),
422 dofs_mfarrvec[lev][tdir2]->const_array(mfi) ) }};
423#elif !defined(WARPX_DIM_1D_Z)
432 int ridx_l = dof_arr(i,j,k,0);
433 if (ridx_l < 0) {
return; }
436 int ridx_g = dof_arr(i,j,k,1);
438 r_indices_g_ptr[ridx_l] = ridx_g;
441 int cidx_g_lhs = dof_arr(i,j,k,1);
444 &c_indices_g_ptr[ridx_l*nnz_max],
445 &a_ij_ptr[ridx_l*nnz_max],
450#if defined(WARPX_DIM_1D_Z)
453 int cidx_g_rhs = dof_arr(i,j,k,1);
456 &c_indices_g_ptr[ridx_l*nnz_max],
457 &a_ij_ptr[ridx_l*nnz_max],
462 int cidx_g_rhs = dof_arr(i-1,j,k,1);
465 &c_indices_g_ptr[ridx_l*nnz_max],
466 &a_ij_ptr[ridx_l*nnz_max],
471 int cidx_g_rhs = dof_arr(i+1,j,k,1);
474 &c_indices_g_ptr[ridx_l*nnz_max],
475 &a_ij_ptr[ridx_l*nnz_max],
480#elif defined(WARPX_DIM_XZ)
482 int cidx_g_rhs = dof_arr(i,j,k,1);
485 val += 2.0_rt*
alpha * dxi[1]*dxi[1] * BC_mask_Edir_arr(i,j,k,0);
486 }
else if (dir == 2) {
487 val += 2.0_rt*
alpha * dxi[0]*dxi[0] * BC_mask_Edir_arr(i,j,k,0);
488 }
else if (dir == 1) {
489 val += 2.0_rt*
alpha * ( dxi[0]*dxi[0] * BC_mask_Edir_arr(i,j,k,0)
490 + dxi[1]*dxi[1] * BC_mask_Edir_arr(i,j,k,2) );
493 &c_indices_g_ptr[ridx_l*nnz_max],
494 &a_ij_ptr[ridx_l*nnz_max],
498 if ((dir == 0) || (dir == 2)) {
500 int cidx_g_rhs = (dir == 0 ? dof_arr(i,j-1,k,1) : dof_arr(i-1,j,k,1));
501 amrex::Real val = -
alpha * dxi[dir==0?1:0] * dxi[dir==0?1:0] * BC_mask_Edir_arr(i,j,k,1);
503 &c_indices_g_ptr[ridx_l*nnz_max],
504 &a_ij_ptr[ridx_l*nnz_max],
509 int cidx_g_rhs = (dir == 0 ? dof_arr(i,j+1,k,1) : dof_arr(i+1,j,k,1));
510 amrex::Real val = -
alpha * dxi[dir==0?1:0] * dxi[dir==0?1:0] * BC_mask_Edir_arr(i,j,k,1);
512 &c_indices_g_ptr[ridx_l*nnz_max],
513 &a_ij_ptr[ridx_l*nnz_max],
521 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i,j-1,k,1) : dof_tdir_arr(i-1,j,k,1));
524 &c_indices_g_ptr[ridx_l*nnz_max],
525 &a_ij_ptr[ridx_l*nnz_max],
530 int cidx_g_rhs = dof_tdir_arr(i,j,k,1);
533 &c_indices_g_ptr[ridx_l*nnz_max],
534 &a_ij_ptr[ridx_l*nnz_max],
539 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i+1,j-1,k,1) : dof_tdir_arr(i-1,j+1,k,1));
542 &c_indices_g_ptr[ridx_l*nnz_max],
543 &a_ij_ptr[ridx_l*nnz_max],
548 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i+1,j,k,1) : dof_tdir_arr(i,j+1,k,1));
551 &c_indices_g_ptr[ridx_l*nnz_max],
552 &a_ij_ptr[ridx_l*nnz_max],
557 for (
int jdir = 0; jdir <= 2; jdir+=2) {
559 int cidx_g_rhs = (jdir == 0 ? dof_arr(i-1,j,k,1) : dof_arr(i,j-1,k,1));
560 amrex::Real val = -
alpha * dxi[jdir==0?0:1] * dxi[jdir==0?0:1] * BC_mask_Edir_arr(i,j,k,jdir+1);
562 &c_indices_g_ptr[ridx_l*nnz_max],
563 &a_ij_ptr[ridx_l*nnz_max],
568 int cidx_g_rhs = (jdir == 0 ? dof_arr(i+1,j,k,1) : dof_arr(i,j+1,k,1));
569 amrex::Real val = -
alpha * dxi[jdir==0?0:1] * dxi[jdir==0?0:1] * BC_mask_Edir_arr(i,j,k,jdir+1);
571 &c_indices_g_ptr[ridx_l*nnz_max],
572 &a_ij_ptr[ridx_l*nnz_max],
578#elif defined(WARPX_DIM_3D)
582 int cidx_g_rhs = dof_arrays[0](ic,1);
583 amrex::Real val = 2.0_rt *
alpha * ( dxi[dvec[1]]*dxi[dvec[1]] * BC_mask_Edir_arr(i,j,k,0)
584 + dxi[dvec[2]]*dxi[dvec[2]] * BC_mask_Edir_arr(i,j,k,3) );
586 &c_indices_g_ptr[ridx_l*nnz_max],
587 &a_ij_ptr[ridx_l*nnz_max],
591 for (
int ctr = -1; ctr <= 1; ctr += 2) {
592 for (
int tdir = 1; tdir <= 2; tdir++) {
593 auto iv = ic; iv[dvec[tdir]] += ctr;
594 int cidx_g_rhs = dof_arrays[0](iv,1);
595 const int comp_shift = (dvec[tdir] == tdir1) ? 0:3;
596 amrex::Real val = -
alpha * dxi[dvec[tdir]]*dxi[dvec[tdir]] * BC_mask_Edir_arr(i,j,k,comp_shift+1);
598 &c_indices_g_ptr[ridx_l*nnz_max],
599 &a_ij_ptr[ridx_l*nnz_max],
604 for (
int ctr_dir = -1; ctr_dir <= 0; ctr_dir++) {
605 for (
int ctr_tdir = -1; ctr_tdir <= 0; ctr_tdir++) {
606 for (
int tdir = 1; tdir <= 2; tdir++) {
607 auto iv = ic; iv[dvec[0]] += (ctr_dir+1); iv[dvec[tdir]] += ctr_tdir;
608 auto sign = std::copysign(1,ctr_dir) * std::copysign(1,ctr_tdir);
609 int cidx_g_rhs = dof_arrays[tdir](iv,1);
610 const int comp_shift = (dvec[tdir] == tdir1) ? 0:3;
613 &c_indices_g_ptr[ridx_l*nnz_max],
614 &a_ij_ptr[ridx_l*nnz_max],
621 num_nz_ptr[ridx_l] = icol;
637 auto sigma_ii_arr = (*m_bcoefs)[lev][dir]->const_array(mfi);
640 for (
int space_dir=0; space_dir<AMREX_SPACEDIM; space_dir++) {
641 MM_ncomp[space_dir] =
m_ops->GetMassMatricesPCnComp(dir,space_dir);
642 MM_width[space_dir] = (MM_ncomp[space_dir] - 1)/2;
647 int ridx_l = dof_arr(i,j,k,0);
648 if (ridx_l < 0) {
return; }
651 int icol = num_nz_ptr[ridx_l];
654 for (
int comp2 = 0; comp2 < MM_ncomp[2]; comp2++) {
655 [[maybe_unused]]
const int kk0 = comp2 - MM_width[2];
656 for (
int comp1 = 0; comp1 < MM_ncomp[1]; comp1++) {
657 [[maybe_unused]]
const int jj0 = comp1 - MM_width[1];
658 for (
int comp0 = 0; comp0 < MM_ncomp[0]; comp0++) {
659 const int ii0 = comp0 - MM_width[0];
661 if (full_bx.
contains(iv_base + iv_shift)) {
662 int cidx_g_rhs = dof_arr(iv_base + iv_shift,1);
665 &c_indices_g_ptr[ridx_l*nnz_max],
666 &a_ij_ptr[ridx_l*nnz_max],
675 num_nz_ptr[ridx_l] = icol;
682 nnz_actual = std::max(nnz_actual, *(nnz_actual_d.copyToHost()));
686 return (nnz_actual - nnz_max);