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;
364 const auto& dofs_lhs_mfarrvec = dofs_obj->m_array_lhs;
384 auto a_ij_ptr =
m_a_ij.data();
389 auto nnz_actual = nnz_max;
393 auto ncomp = dofs_mfarrvec[lev][0]->nComp();
396 const auto& geom =
m_geom[lev];
397 const auto dxi = geom.InvCellSizeArray();
400 auto* nnz_actual_ptr = nnz_actual_d.
data();
402 for (
int dir = 0; dir < 3; dir++) {
404 for (
amrex::MFIter mfi(*dofs_mfarrvec[lev][dir]); mfi.isValid(); ++mfi) {
406 auto bx = mfi.tilebox();
407 auto dof_lhs_arr = dofs_lhs_mfarrvec[lev][dir]->const_array(mfi);
409#if defined(WARPX_DIM_1D_Z)
410 auto dof_arr = dofs_mfarrvec[lev][dir]->const_array(mfi);
411#elif defined(WARPX_DIM_RCYLINDER)
414#elif defined(WARPX_DIM_RSPHERE)
417#elif defined(WARPX_DIM_RZ)
420#elif defined(WARPX_DIM_XZ)
421 auto dof_arr = dofs_mfarrvec[lev][dir]->const_array(mfi);
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) ) }};
444 int ridx_l = dof_lhs_arr(i,j,k,0);
445 int ridx_g = dof_lhs_arr(i,j,k,1);
449 r_indices_g_ptr[ridx_l] = ridx_g;
452 int cidx_g_lhs = dof_lhs_arr(i,j,k,1);
453 amrex::Real val = 1.0;
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);
465 amrex::Real val = 2.0_rt*
alpha * dxi[0]*dxi[0];
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);
474 amrex::Real val = -
alpha * dxi[0]*dxi[0];
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);
483 amrex::Real val = -
alpha * dxi[0]*dxi[0];
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);
494 amrex::Real val = 0.0;
496 val += 2.0_rt*
alpha * dxi[1]*dxi[1];
497 }
else if (dir == 2) {
498 val += 2.0_rt*
alpha * dxi[0]*dxi[0];
500 val += 2.0_rt*
alpha *(dxi[0]*dxi[0] + dxi[1]*dxi[1]);
503 &c_indices_g_ptr[ridx_l*nnz_max],
504 &a_ij_ptr[ridx_l*nnz_max],
508 if ((dir == 0) || (dir == 2)) {
510 int cidx_g_rhs = (dir == 0 ? dof_arr(i,j-1,k,1) : dof_arr(i-1,j,k,1));
511 amrex::Real val = -
alpha * dxi[dir==0?1:0] * dxi[dir==0?1:0];
513 &c_indices_g_ptr[ridx_l*nnz_max],
514 &a_ij_ptr[ridx_l*nnz_max],
519 int cidx_g_rhs = (dir == 0 ? dof_arr(i,j+1,k,1) : dof_arr(i+1,j,k,1));
520 amrex::Real val = -
alpha * dxi[dir==0?1:0] * dxi[dir==0?1:0];
522 &c_indices_g_ptr[ridx_l*nnz_max],
523 &a_ij_ptr[ridx_l*nnz_max],
531 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i,j-1,k,1) : dof_tdir_arr(i-1,j,k,1));
532 amrex::Real val =
alpha * dxi[0] * dxi[1];
534 &c_indices_g_ptr[ridx_l*nnz_max],
535 &a_ij_ptr[ridx_l*nnz_max],
540 int cidx_g_rhs = dof_tdir_arr(i,j,k,1);
541 amrex::Real val = -
alpha * dxi[0] * dxi[1];
543 &c_indices_g_ptr[ridx_l*nnz_max],
544 &a_ij_ptr[ridx_l*nnz_max],
549 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i+1,j-1,k,1) : dof_tdir_arr(i-1,j+1,k,1));
550 amrex::Real val = -
alpha * dxi[0] * dxi[1];
552 &c_indices_g_ptr[ridx_l*nnz_max],
553 &a_ij_ptr[ridx_l*nnz_max],
558 int cidx_g_rhs = (dir == 0 ? dof_tdir_arr(i+1,j,k,1) : dof_tdir_arr(i,j+1,k,1));
559 amrex::Real val =
alpha * dxi[0] * dxi[1];
561 &c_indices_g_ptr[ridx_l*nnz_max],
562 &a_ij_ptr[ridx_l*nnz_max],
567 for (
int jdir = 0; jdir <= 2; jdir+=2) {
569 int cidx_g_rhs = (jdir == 0 ? dof_arr(i-1,j,k,1) : dof_arr(i,j-1,k,1));
570 amrex::Real val = -
alpha * dxi[jdir==0?0:1] * dxi[jdir==0?0:1];
572 &c_indices_g_ptr[ridx_l*nnz_max],
573 &a_ij_ptr[ridx_l*nnz_max],
578 int cidx_g_rhs = (jdir == 0 ? dof_arr(i+1,j,k,1) : dof_arr(i,j+1,k,1));
579 amrex::Real val = -
alpha * dxi[jdir==0?0:1] * dxi[jdir==0?0:1];
581 &c_indices_g_ptr[ridx_l*nnz_max],
582 &a_ij_ptr[ridx_l*nnz_max],
588#elif defined(WARPX_DIM_3D)
592 int cidx_g_rhs = dof_arrays[0](ic,1);
593 amrex::Real val = 2.0_rt *
alpha * (dxi[dvec[1]]*dxi[dvec[1]] + dxi[dvec[2]]*dxi[dvec[2]]);
595 &c_indices_g_ptr[ridx_l*nnz_max],
596 &a_ij_ptr[ridx_l*nnz_max],
600 for (
int ctr = -1; ctr <= 1; ctr += 2) {
601 for (
int tdir = 1; tdir <= 2; tdir++) {
602 auto iv = ic; iv[dvec[tdir]] += ctr;
603 int cidx_g_rhs = dof_arrays[0](iv,1);
604 amrex::Real val = -
alpha * dxi[dvec[tdir]]*dxi[dvec[tdir]];
606 &c_indices_g_ptr[ridx_l*nnz_max],
607 &a_ij_ptr[ridx_l*nnz_max],
612 for (
int ctr_dir = -1; ctr_dir <= 0; ctr_dir++) {
613 for (
int ctr_tdir = -1; ctr_tdir <= 0; ctr_tdir++) {
614 for (
int tdir = 1; tdir <= 2; tdir++) {
615 auto iv = ic; iv[dvec[0]] += (ctr_dir+1); iv[dvec[tdir]] += ctr_tdir;
616 auto sign = std::copysign(1,ctr_dir) * std::copysign(1,ctr_tdir);
617 int cidx_g_rhs = dof_arrays[tdir](iv,1);
618 amrex::Real val = amrex::Real(sign) *
alpha * dxi[dvec[0]]*dxi[dvec[tdir]];
620 &c_indices_g_ptr[ridx_l*nnz_max],
621 &a_ij_ptr[ridx_l*nnz_max],
628 num_nz_ptr[ridx_l] = icol;
637 auto sigma_ii_arr = (*m_bcoefs)[lev][dir]->const_array(mfi);
641 int ridx_l = dof_lhs_arr(i,j,k,0);
643 int icol = num_nz_ptr[ridx_l];
646 int cidx_g_lhs = dof_lhs_arr(i,j,k,1);
647 amrex::Real val = sigma_ii_arr(i,j,k,0) - 1.0;
649 &c_indices_g_ptr[ridx_l*nnz_max],
650 &a_ij_ptr[ridx_l*nnz_max],
658 num_nz_ptr[ridx_l] = icol;
665 nnz_actual = std::max(nnz_actual, *(nnz_actual_d.copyToHost()));
669 return (nnz_actual - nnz_max);