345 using namespace amrex;
349 "MatrixPC::Assemble() called on undefined object" );
352 const RT thetaDt =
m_ops->GetThetaForPC()*this->
m_dt;
356 <<
": theta*dt = " << thetaDt <<
", "
358 <<
"alpha = " <<
alpha <<
"\n";
362 const auto& dofs_obj = a_U.getDOFsObject();
363 const auto& dofs_mfarrvec = dofs_obj->m_array;
383 auto a_ij_ptr =
m_a_ij.data();
386 auto nnz_actual = nnz_max;
390 auto ncomp = dofs_mfarrvec[lev][0]->nComp();
393 const auto& geom =
m_geom[lev];
394 const auto dxi = geom.InvCellSizeArray();
397 auto* nnz_actual_ptr = nnz_actual_d.
data();
399 for (
int dir = 0; dir < 3; dir++) {
403 for (
amrex::MFIter mfi(*dofs_mfarrvec[lev][dir]); mfi.isValid(); ++mfi) {
405 auto bx = mfi.tilebox();
408 auto BC_mask_Edir_arr = BC_mask_Edir->
const_array(mfi);
410 auto dof_arr = dofs_mfarrvec[lev][dir]->const_array(mfi);
412#if defined(WARPX_DIM_RCYLINDER)
415#elif defined(WARPX_DIM_RSPHERE)
418#elif defined(WARPX_DIM_RZ)
421#elif defined(WARPX_DIM_XZ)
423 if (dir == 0) { tdir = 2; }
424 else if (dir == 2) { tdir = 0; }
426 auto dof_tdir_arr = dofs_mfarrvec[lev][tdir]->const_array(mfi);
427#elif defined(WARPX_DIM_3D)
428 int tdir1 = (dir + 1) % 3;
429 int tdir2 = (dir + 2) % 3;
431 const dof_arrays {{
AMREX_D_DECL( dofs_mfarrvec[lev][dir]->const_array(mfi),
432 dofs_mfarrvec[lev][tdir1]->const_array(mfi),
433 dofs_mfarrvec[lev][tdir2]->const_array(mfi) ) }};
434#elif !defined(WARPX_DIM_1D_Z)
443 int ridx_l = dof_arr(i,j,k,0);
444 if (ridx_l < 0) {
return; }
447 int ridx_g = dof_arr(i,j,k,1);
449 r_indices_g_ptr[ridx_l] = ridx_g;
452 int cidx_g_lhs = dof_arr(i,j,k,1);
455 &c_indices_g_ptr[ridx_l*nnz_max],
456 &a_ij_ptr[ridx_l*nnz_max],
461#if defined(WARPX_DIM_1D_Z)
464 int cidx_g_rhs = dof_arr(i,j,k,1);
467 &c_indices_g_ptr[ridx_l*nnz_max],
468 &a_ij_ptr[ridx_l*nnz_max],
473 int cidx_g_rhs = dof_arr(i-1,j,k,1);
476 &c_indices_g_ptr[ridx_l*nnz_max],
477 &a_ij_ptr[ridx_l*nnz_max],
482 int cidx_g_rhs = dof_arr(i+1,j,k,1);
485 &c_indices_g_ptr[ridx_l*nnz_max],
486 &a_ij_ptr[ridx_l*nnz_max],
491#elif defined(WARPX_DIM_XZ)
493 int cidx_g_rhs = dof_arr(i,j,k,1);
496 val += 2.0_rt*
alpha * dxi[1]*dxi[1] * BC_mask_Edir_arr(i,j,k,0);
497 }
else if (dir == 2) {
498 val += 2.0_rt*
alpha * dxi[0]*dxi[0] * BC_mask_Edir_arr(i,j,k,0);
500 val += 2.0_rt*
alpha * ( dxi[0]*dxi[0] * BC_mask_Edir_arr(i,j,k,0)
501 + dxi[1]*dxi[1] * BC_mask_Edir_arr(i,j,k,2) );
504 &c_indices_g_ptr[ridx_l*nnz_max],
505 &a_ij_ptr[ridx_l*nnz_max],
509 if ((dir == 0) || (dir == 2)) {
511 int cidx_g_rhs = (dir == 0 ? dof_arr(i,j-1,k,1) : dof_arr(i-1,j,k,1));
512 amrex::Real val = -
alpha * dxi[dir==0?1:0] * dxi[dir==0?1:0] * BC_mask_Edir_arr(i,j,k,1);
514 &c_indices_g_ptr[ridx_l*nnz_max],
515 &a_ij_ptr[ridx_l*nnz_max],
520 int cidx_g_rhs = (dir == 0 ? dof_arr(i,j+1,k,1) : dof_arr(i+1,j,k,1));
521 amrex::Real val = -
alpha * dxi[dir==0?1:0] * dxi[dir==0?1:0] * BC_mask_Edir_arr(i,j,k,1);
523 &c_indices_g_ptr[ridx_l*nnz_max],
524 &a_ij_ptr[ridx_l*nnz_max],
532 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i,j-1,k,1) : dof_tdir_arr(i-1,j,k,1));
535 &c_indices_g_ptr[ridx_l*nnz_max],
536 &a_ij_ptr[ridx_l*nnz_max],
541 int cidx_g_rhs = dof_tdir_arr(i,j,k,1);
544 &c_indices_g_ptr[ridx_l*nnz_max],
545 &a_ij_ptr[ridx_l*nnz_max],
550 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i+1,j-1,k,1) : dof_tdir_arr(i-1,j+1,k,1));
553 &c_indices_g_ptr[ridx_l*nnz_max],
554 &a_ij_ptr[ridx_l*nnz_max],
559 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i+1,j,k,1) : dof_tdir_arr(i,j+1,k,1));
562 &c_indices_g_ptr[ridx_l*nnz_max],
563 &a_ij_ptr[ridx_l*nnz_max],
568 for (
int jdir = 0; jdir <= 2; jdir+=2) {
570 int cidx_g_rhs = (jdir == 0 ? dof_arr(i-1,j,k,1) : dof_arr(i,j-1,k,1));
571 amrex::Real val = -
alpha * dxi[jdir==0?0:1] * dxi[jdir==0?0:1] * BC_mask_Edir_arr(i,j,k,jdir+1);
573 &c_indices_g_ptr[ridx_l*nnz_max],
574 &a_ij_ptr[ridx_l*nnz_max],
579 int cidx_g_rhs = (jdir == 0 ? dof_arr(i+1,j,k,1) : dof_arr(i,j+1,k,1));
580 amrex::Real val = -
alpha * dxi[jdir==0?0:1] * dxi[jdir==0?0:1] * BC_mask_Edir_arr(i,j,k,jdir+1);
582 &c_indices_g_ptr[ridx_l*nnz_max],
583 &a_ij_ptr[ridx_l*nnz_max],
589#elif defined(WARPX_DIM_3D)
593 int cidx_g_rhs = dof_arrays[0](ic,1);
594 amrex::Real val = 2.0_rt *
alpha * ( dxi[dvec[1]]*dxi[dvec[1]] * BC_mask_Edir_arr(i,j,k,0)
595 + dxi[dvec[2]]*dxi[dvec[2]] * BC_mask_Edir_arr(i,j,k,3) );
597 &c_indices_g_ptr[ridx_l*nnz_max],
598 &a_ij_ptr[ridx_l*nnz_max],
602 for (
int ctr = -1; ctr <= 1; ctr += 2) {
603 for (
int tdir = 1; tdir <= 2; tdir++) {
604 auto iv = ic; iv[dvec[tdir]] += ctr;
605 int cidx_g_rhs = dof_arrays[0](iv,1);
606 const int comp_shift = (dvec[tdir] == tdir1) ? 0:3;
607 amrex::Real val = -
alpha * dxi[dvec[tdir]]*dxi[dvec[tdir]] * BC_mask_Edir_arr(i,j,k,comp_shift+1);
609 &c_indices_g_ptr[ridx_l*nnz_max],
610 &a_ij_ptr[ridx_l*nnz_max],
615 for (
int ctr_dir = -1; ctr_dir <= 0; ctr_dir++) {
616 for (
int ctr_tdir = -1; ctr_tdir <= 0; ctr_tdir++) {
617 for (
int tdir = 1; tdir <= 2; tdir++) {
618 auto iv = ic; iv[dvec[0]] += (ctr_dir+1); iv[dvec[tdir]] += ctr_tdir;
619 auto sign = std::copysign(1,ctr_dir) * std::copysign(1,ctr_tdir);
620 int cidx_g_rhs = dof_arrays[tdir](iv,1);
621 const int comp_shift = (dvec[tdir] == tdir1) ? 0:3;
624 &c_indices_g_ptr[ridx_l*nnz_max],
625 &a_ij_ptr[ridx_l*nnz_max],
632 num_nz_ptr[ridx_l] = icol;
641 auto sigma_ii_arr = (*m_bcoefs)[lev][dir]->const_array(mfi);
645 int ridx_l = dof_arr(i,j,k,0);
646 if (ridx_l < 0) {
return; }
648 int icol = num_nz_ptr[ridx_l];
651 int cidx_g_lhs = dof_arr(i,j,k,1);
654 &c_indices_g_ptr[ridx_l*nnz_max],
655 &a_ij_ptr[ridx_l*nnz_max],
663 num_nz_ptr[ridx_l] = icol;
670 nnz_actual = std::max(nnz_actual, *(nnz_actual_d.copyToHost()));
674 return (nnz_actual - nnz_max);