36#include <AMReX_ParallelDescriptor.H> 
   38#include <boost/filesystem.hpp> 
   45                           const std::string& bsolver,
 
   46                           const std::string& prec,
 
   47                           const bool& rebalance,
 
   48                           const std::string& reuse,
 
   49                           const std::string& bcx,
 
   50                           const std::string& bcy,
 
   51                           const std::string& bcz,
 
   52                           const std::string& smoother,
 
   53                           const std::size_t& nSweeps,
 
   54                           const std::string& interp,
 
   55                           const std::string& norm)
 
   57    , comm_mp( new 
comm_t( amrex::ParallelDescriptor::Communicator() ) )
 
   70    , fname_m(
OpalData::getInstance()->getInputBasename() + 
std::string(
".solver"))
 
   71    , flag_m(
std::ios::out)
 
   77    const Boundary bcs[AMREX_SPACEDIM] = {
 
  103    if (boost::filesystem::exists(
fname_m)) {
 
  115                         unsigned short baseLevel,
 
  116                         unsigned short finestLevel,
 
  128    bool reset = !prevAsGuess;
 
  143    for (
int lev = 
nlevel_m - 1; lev > -1; --lev) {
 
  151    for (
int lev = 0; lev < 
nlevel_m; ++lev) {
 
  154        phi[ilev]->setVal(0.0, phi[ilev]->nGrow());
 
  174        throw OpalException(
"AmrMultiGrid::setMaxNumberOfIterations()",
 
  175                            "The max. number of iterations needs to be positive!");
 
  206    for (
unsigned int i = 0; i < AMREX_SPACEDIM; ++i) {
 
  208            case Boundary::DIRICHLET:
 
  214            case Boundary::PERIODIC:
 
  218                throw OpalException(
"AmrMultiGrid::initPhysicalBoundary_m()",
 
  219                                    "This type of boundary is not supported");
 
  222        go_t tmp = 
bc_m[i]->getNumberOfPoints();
 
  230                                const amrex::Vector<AmrGeometry_t>& geom,
 
  243    amrex::Periodicity period(
AmrIntVect_t(D_DECL(0, 0, 0)));
 
  247    for (
int lev = 0; lev < 
nlevel_m; ++lev) {
 
  253                                                         rho[ilev]->boxArray(),
 
  254                                                         rho[ilev]->DistributionMap(),
 
  267        mglevel_m[lev]->refmask->setVal(AmrMultiGridLevel_t::Refined::NO, 2);
 
  268        mglevel_m[lev]->refmask->FillBoundary(period);
 
  270        amrex::BoxArray ba = 
mglevel_m[lev]->grids;
 
  276        mglevel_m[lev]->crsemask->setVal(AmrMultiGridLevel_t::Refined::NO, 2);
 
  279    for (
int lev = 1; lev < 
nlevel_m; ++lev) {
 
  280        mglevel_m[lev]->crsemask->setVal(AmrMultiGridLevel_t::Refined::YES, 0);
 
  283        mglevel_m[lev]->crsemask->setDomainBndry(AmrMultiGridLevel_t::Mask::PHYSBNDRY,
 
  286        mglevel_m[lev]->crsemask->FillBoundary(period);
 
  292    for (
int lev = 0; lev < 
nlevel_m-1; ++lev) {
 
  294        amrex::BoxArray ba = 
mglevel_m[lev]->grids;
 
  296        ba = amrex::intersect(
mglevel_m[lev+1]->grids, ba);
 
  300        amrex::DistributionMapping dmap(ba, 
comm_mp->getSize());
 
  302        refined.setVal(AmrMultiGridLevel_t::Refined::YES);
 
  306        mglevel_m[lev]->refmask->copy(refined, 0, 0, 1, 0, 2);
 
  311        mglevel_m[lev]->refmask->setDomainBndry(AmrMultiGridLevel_t::Mask::PHYSBNDRY,
 
  314        mglevel_m[lev]->refmask->FillBoundary(period);
 
  320    for (
int lev = 0; lev < 
nlevel_m; ++lev) {
 
  333    for (
int lev = 0; lev < 
nlevel_m; ++lev)
 
  341    std::vector<scalar_t> rhsNorms;
 
  342    std::vector<scalar_t> resNorms;
 
  347                  [
this](
double& val){ val *= eps_m; });
 
  366        for (
int lev = 0; lev < 
nlevel_m; ++lev) {
 
  381        this->writeResidualNorm_m();
 
  387    return std::accumulate(resNorms.begin(),
 
  389                           std::plus<scalar_t>());
 
  394                                 std::vector<scalar_t>& resNorms)
 
  396    return std::equal(resNorms.begin(), resNorms.end(),
 
  398                      std::less<scalar_t>());
 
  403                              Teuchos::RCP<vector_t>& r,
 
  404                              const Teuchos::RCP<vector_t>& b,
 
  405                              const Teuchos::RCP<vector_t>& x)
 
  415        if ( 
mglevel_m[level]->Bfine_p != Teuchos::null ) {
 
  420        mglevel_m[level]->Awf_p->apply(*x, fine2crse,
 
  425        if ( 
mglevel_m[level]->Bcrse_p != Teuchos::null ) {
 
  434        Teuchos::RCP<vector_t> uncov_Ax = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p, 
true) );
 
  435        mglevel_m[level]->UnCovered_p->apply(fine2crse, *uncov_Ax);
 
  437        Teuchos::RCP<vector_t> uncov_b = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p, 
true) );
 
  439        mglevel_m[level]->UnCovered_p->apply(*b, *uncov_b);
 
  444        r->update(1.0, *uncov_b, -1.0, *uncov_Ax, 0.0);
 
  449        Teuchos::RCP<vector_t> Ax = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p, 
true) );
 
  452        if ( 
mglevel_m[level]->Bcrse_p != Teuchos::null ) {
 
  460        r->update(1.0, *b, -1.0, *Ax, 0.0);
 
  472            Teuchos::RCP<vector_t> Ax = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p, 
true) );
 
  487        Teuchos::RCP<vector_t> phi_save = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p) );
 
  488        Tpetra::deep_copy(*phi_save, *
mglevel_m[level]->phi_p);
 
  490        mglevel_m[level-1]->error_p->putScalar(0.0);
 
  514        Teuchos::RCP<vector_t> tmp = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p) );
 
  520        Tpetra::deep_copy(*
mglevel_m[level]->residual_p, *tmp);
 
  523        Teuchos::RCP<vector_t> derror = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p, 
true) );
 
  529        mglevel_m[level]->error_p->update(1.0, *derror, 1.0);
 
  532        mglevel_m[level]->phi_p->update(1.0, *phi_save, 1.0, *
mglevel_m[level]->error_p, 0.0);
 
  553                                      Teuchos::RCP<vector_t>& result,
 
  554                                      const Teuchos::RCP<vector_t>& rhs,
 
  555                                      const Teuchos::RCP<vector_t>& crs_rhs,
 
  556                                      const Teuchos::RCP<vector_t>& b)
 
  561    if ( 
mglevel_m[level]->Bcrse_p != Teuchos::null ) {
 
  562        mglevel_m[level]->Bcrse_p->apply(*crs_rhs, crse2fine);
 
  566    mglevel_m[level]->Anf_p->apply(*rhs, crse2fine,
 
  571    result->update(1.0, *b, -1.0, crse2fine, 0.0);
 
  576void AmrMultiGrid::writeResidualNorm_m() {
 
  581        out.open(
"residual.dat", std::ios::app);
 
  583    for (
int lev = 0; lev < 
nlevel_m; ++lev) {
 
  587            out << std::setw(15) << std::right << tmp;
 
  619                                "This type of norm not suppported.");
 
  626                                  std::vector<scalar_t>& resNorms)
 
  634    if ( 
comm_mp->getRank() == 0) {
 
  635        out.open(
"residual.dat", std::ios::out);
 
  637        for (
int lev = 0; lev < 
nlevel_m; ++lev)
 
  638            out << std::setw(14) << std::right << 
"level" << lev;
 
  643    for (
int lev = 0; lev < 
nlevel_m; ++lev) {
 
  653            out << std::setw(15) << std::right << resNorms.back();
 
  670    Teuchos::RCP<vector_t> efield_p = Teuchos::null;
 
  671    for (
int lev = 
nlevel_m - 1; lev > -1; --lev) {
 
  677        for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
 
  678            efield[ilev][d]->setVal(0.0, efield[ilev][d]->nGrow());
 
  679            efield_p->putScalar(0.0);
 
  691                           const amrex::Vector<AmrField_u>& phi,
 
  692                           const bool& matrices)
 
  720                                      const amrex::Vector<AmrField_u>& phi,
 
  721                                      const bool& matrices)
 
  728        D_DECL( invdx[0] * invdx[0],
 
  730                invdx[2] * invdx[2] )
 
  735             mfi.isValid(); ++mfi)
 
  737            const box_t&       tbx = mfi.tilebox();
 
  742            const int* lo = tbx.loVect();
 
  743            const int* hi = tbx.hiVect();
 
  745            for (
int i = lo[0]; i <= hi[0]; ++i) {
 
  746                for (
int j = lo[1]; j <= hi[1]; ++j) {
 
  747#if AMREX_SPACEDIM == 3 
  748                    for (
int k = lo[2]; k <= hi[2]; ++k) {
 
  761#if AMREX_SPACEDIM == 3 
  781                                     const amrex::Vector<AmrField_u>& phi,
 
  782                                     const bool& matrices)
 
  793    for (
int lev = 0; lev < 
nlevel_m; ++lev) {
 
  794        this->
open_m(lev, matrices);
 
  804            D_DECL( invdx[0] * invdx[0],
 
  806                    invdx[2] * invdx[2] )
 
  810            for (amrex::MFIter mfi(*
mglevel_m[lev]->mask, 
true);
 
  811                 mfi.isValid(); ++mfi)
 
  813                const box_t&       tbx = mfi.tilebox();
 
  820                const int* lo = tbx.loVect();
 
  821                const int* hi = tbx.hiVect();
 
  823                for (
int i = lo[0]; i <= hi[0]; ++i) {
 
  825                    for (
int j = lo[1]; j <= hi[1]; ++j) {
 
  827#if AMREX_SPACEDIM == 3 
  828                        for (
int k = lo[2]; k <= hi[2]; ++k) {
 
  835                                                           D_DECL(ii, jj, kk), rfab);
 
  853                            mglevel_m[lev]->rho_p->replaceGlobalValue(gidx, rhofab(iv, 0));
 
  854                            mglevel_m[lev]->phi_p->replaceGlobalValue(gidx, pfab(iv, 0));
 
  855#if AMREX_SPACEDIM == 3 
  870        if ( matrices && lev > 
lbase_m ) {
 
  879                          const bool& matrices)
 
  893                                                               Tpetra::StaticProfile) );
 
  902            mglevel_m[level]->Bcrse_p = Teuchos::rcp(
 
  904                             Tpetra::StaticProfile) );
 
  916            int nNeighbours = AMREX_D_TERM(2, * 2, * 2);
 
  920                             Tpetra::StaticProfile) );
 
  927            nNeighbours = 2 * AMREX_SPACEDIM * AMREX_D_TERM(2, * 2, * 2);
 
  929            mglevel_m[level]->Bfine_p = Teuchos::rcp(
 
  931                             Tpetra::StaticProfile) );
 
  939        int nPhysBoundary = 2 * AMREX_SPACEDIM * 
nBcPoints_m;
 
  942        int nIntBoundary = AMREX_SPACEDIM * 
interface_mp->getNumberOfPoints();
 
  944        int nEntries = (AMREX_SPACEDIM << 1) + 2  + nPhysBoundary + nIntBoundary;
 
  949                             Tpetra::StaticProfile) );
 
  956            nEntries = (AMREX_SPACEDIM << 1) + 5  + nPhysBoundary + nIntBoundary;
 
  960                             Tpetra::StaticProfile) );
 
  965            mglevel_m[level]->UnCovered_p = Teuchos::rcp(
 
  967                             Tpetra::StaticProfile) );
 
  976            for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
 
  979                                 Tpetra::StaticProfile) );
 
  995                           const bool& matrices)
 
 1017            mglevel_m[level]->Anf_p->fillComplete();
 
 1019            for (
int d = 0; d < AMREX_SPACEDIM; ++d)
 
 1020                mglevel_m[level]->G_p[d]->fillComplete();
 
 1024            mglevel_m[level]->Awf_p->fillComplete();
 
 1026            mglevel_m[level]->UnCovered_p->fillComplete();
 
 1055    for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
 
 1056        for (
int shift = -1; shift <= 1; shift += 2) {
 
 1060            switch ( mfab(biv) )
 
 1062                case AmrMultiGridLevel_t::Mask::INTERIOR:
 
 1063                case AmrMultiGridLevel_t::Mask::COVERED: 
 
 1065                    map[
mglevel_m[level]->serialize(biv)] += invdx2[d];
 
 1068                case AmrMultiGridLevel_t::Mask::BNDRY:
 
 1074                        throw OpalException(
"AmrMultiGrid::buildNoFinePoissonMatrix_m()",
 
 1075                                            "Error in mask for level " 
 1076                                            + std::to_string(level) + 
"!");
 
 1084                case AmrMultiGridLevel_t::Mask::PHYSBNDRY:
 
 1087                    mglevel_m[level]->applyBoundary(biv, d, map,
 
 1092                    throw OpalException(
"AmrMultiGrid::buildNoFinePoissonMatrix_m()",
 
 1093                                        "Error in mask for level " 
 1094                                        + std::to_string(level) + 
"!");
 
 1100    map[gidx] += AMREX_D_TERM(- 2.0 * invdx2[0],
 
 1106    mglevel_m[level]->Anf_p->insertGlobalValues(gidx,
 
 1125    if ( rfab(iv) == AmrMultiGridLevel_t::Refined::YES ) 
 
 1148    for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
 
 1149        for (
int shift = -1; shift <= 1; shift += 2) {
 
 1153            if ( rfab(biv) != AmrMultiGridLevel_t::Refined::YES )
 
 1158                switch ( mfab(biv) )
 
 1160                case AmrMultiGridLevel_t::Mask::COVERED:
 
 1162                case AmrMultiGridLevel_t::Mask::INTERIOR:
 
 1164                    map[
mglevel_m[level]->serialize(biv)] += invdx2[d];
 
 1165                    map[gidx] -= invdx2[d]; 
 
 1168                case AmrMultiGridLevel_t::Mask::BNDRY:
 
 1174                        throw OpalException(
"AmrMultiGrid::buildCompositePoissonMatrix_m()",
 
 1175                                            "Error in mask for level " 
 1176                                            + std::to_string(level) + 
"!");
 
 1191                    map[gidx] -= invdx2[d];
 
 1194                case AmrMultiGridLevel_t::Mask::PHYSBNDRY:
 
 1197                    mglevel_m[level]->applyBoundary(biv, d, map,
 
 1201                    map[gidx] -= invdx2[d];
 
 1205                    throw OpalException(
"AmrMultiGrid::buildCompositePoissonMatrix_m()",
 
 1206                                        "Error in mask for level " 
 1207                                        + std::to_string(level) + 
"!");
 
 1228                scalar_t invavg = AMREX_D_PICK(1.0, 0.5, 0.25);
 
 1229                scalar_t value = - invavg * invcdx[d] * invfdx[d];
 
 1231                for (
int d1 = 0; d1 < 2; ++d1) {
 
 1232#if AMREX_SPACEDIM == 3 
 1233                    for (
int d2 = 0; d2 < 2; ++d2) {
 
 1241                        fake[(d+1)%AMREX_SPACEDIM] = d1;
 
 1242#if AMREX_SPACEDIM == 3 
 1243                        fake[(d+2)%AMREX_SPACEDIM] = d2;
 
 1248#if AMREX_SPACEDIM == 3 
 1258    mglevel_m[level]->Awf_p->insertGlobalValues(gidx,
 
 1264    mglevel_m[level]->UnCovered_p->insertGlobalValues(gidx,
 
 1274                                            D_DECL(
const go_t& ii,
 
 1284    if ( rfab(iv) == AmrMultiGridLevel_t::Refined::NO || level == 
lfine_m )
 
 1296    indices.reserve(2 << (AMREX_SPACEDIM - 1));
 
 1298    values.reserve(2 << (AMREX_SPACEDIM -1));
 
 1301    for (
int iref = 0; iref < 2; ++iref) {
 
 1302        for (
int jref = 0; jref < 2; ++jref) {
 
 1303#if AMREX_SPACEDIM == 3 
 1304            for (
int kref = 0; kref < 2; ++kref) {
 
 1306                AmrIntVect_t riv(D_DECL(ii + iref, jj + jref, kk + kref));
 
 1309                values.push_back( AMREX_D_PICK(0.5, 0.25, 0.125) );
 
 1310#if AMREX_SPACEDIM == 3 
 1316    mglevel_m[level]->R_p->insertGlobalValues(gidx,
 
 1353    mglevel_m[level]->I_p->insertGlobalValues(gidx,
 
 1383    for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
 
 1384        for (
int shift = -1; shift <= 1; shift += 2) {
 
 1389            if ( mfab(niv) == AmrMultiGridLevel_t::Mask::BNDRY )
 
 1397                civ.coarsen(
mglevel_m[level]->refinement());
 
 1403                interface_mp->coarse(civ, map, invdx2[d], d, shift, cfab,
 
 1407            else if ( mfab(niv) == AmrMultiGridLevel_t::Mask::PHYSBNDRY ) {
 
 1408                throw OpalException(
"AmrMultiGrid::buildCrseBoundaryMatrix_m()",
 
 1409                                    "Fine meshes shouldn't be connected " 
 1410                                    "to physical (i.e. mesh) boundary!");
 
 1418    mglevel_m[level]->Bcrse_p->insertGlobalValues(gidx,
 
 1436    if ( rfab(iv) == AmrMultiGridLevel_t::Refined::YES || level == 
lfine_m )
 
 1443    scalar_t invavg = AMREX_D_PICK(1, 0.5, 0.25);
 
 1449    auto fill = [&](
umap_t& map,
 
 1450                    D_DECL(
int ii, 
int jj, 
int kk),
 
 1454        for (
int iref = ii - 
begin[0]; iref <= ii + 
end[0]; ++iref) {
 
 1455            for (
int jref = jj - 
begin[1]; jref <= jj + 
end[1]; ++jref) {
 
 1456#if AMREX_SPACEDIM == 3 
 1457                for (
int kref = kk - 
begin[2]; kref <= kk + 
end[2]; ++kref) {
 
 1464                    if ( (riv[d] >> 1)  == iv[d] ) {
 
 1468                        scalar_t value = - invavg * invcdx[d] * invfdx[d];
 
 1473                        scalar_t value = invavg * invcdx[d] * invfdx[d];
 
 1474                        map[
mglevel_m[level+1]->serialize(riv)] += value;
 
 1476#if AMREX_SPACEDIM == 3 
 1490    for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
 
 1491        for (
int shift = -1; shift <= 1; shift += 2) {
 
 1494            covered[d] += shift;
 
 1496            if ( rfab(covered) == AmrMultiGridLevel_t::Refined::YES &&
 
 1511                int begin[AMREX_SPACEDIM] = { D_DECL( 
int(d == 0), 
int(d == 1), 
int(d == 2) ) };
 
 1512                int end[AMREX_SPACEDIM]   = { D_DECL( 
int(d != 0), 
int(d != 1), 
int(d != 2) ) };
 
 1527                        int ii = iv[0] << 1; 
 
 1528                        int jj = iv[1] << 1; 
 
 1529#if AMREX_SPACEDIM == 3 
 1530                        int kk = iv[2] << 1; 
 
 1535                        fill(map, D_DECL(ii, jj, kk), &
begin[0], &
end[0], d, iv, shift);
 
 1542                        int ii = covered[0] << 1; 
 
 1543                        int jj = covered[1] << 1; 
 
 1544#if AMREX_SPACEDIM == 3 
 1545                        int kk = covered[2] << 1; 
 
 1547                        fill(map, D_DECL(ii, jj, kk), &
begin[0], &
end[0], d, iv, shift);
 
 1559    mglevel_m[level]->Bfine_p->insertGlobalValues(gidx,
 
 1597            case AmrMultiGridLevel_t::Mask::INTERIOR:
 
 1599            case AmrMultiGridLevel_t::Mask::COVERED:
 
 1601                map[
mglevel_m[level]->serialize(iv)] -= shift * 0.5 * invdx[dir];
 
 1603            case AmrMultiGridLevel_t::Mask::BNDRY:
 
 1608                    throw OpalException(
"AmrMultiGrid::buildGradientMatrix_m()",
 
 1609                                        "Error in mask for level " 
 1610                                        + std::to_string(level) + 
"!");
 
 1613                scalar_t value = - shift * 0.5 * invdx[dir];
 
 1619                map[
mglevel_m[level]->serialize(tmp)] += 2.0 * value;
 
 1623                map[
mglevel_m[level]->serialize(tmp)] -= value;
 
 1626            case AmrMultiGridLevel_t::Mask::PHYSBNDRY:
 
 1630                scalar_t value = - shift * 0.5 * invdx[dir];
 
 1632                mglevel_m[level]->applyBoundary(iv, dir,
 
 1641    for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
 
 1642        for (
int shift = -1; shift <= 1; shift += 2) {
 
 1645            check(niv, mfab, d, shift);
 
 1650        mglevel_m[level]->G_p[d]->insertGlobalValues(gidx,
 
 1661                                    Teuchos::RCP<vector_t>& mv)
 
 1666    for (amrex::MFIter mfi(mf, 
true); mfi.isValid(); ++mfi) {
 
 1667        const amrex::Box&          tbx  = mfi.tilebox();
 
 1668        const amrex::FArrayBox&    fab = mf[mfi];
 
 1670        const int* lo = tbx.loVect();
 
 1671        const int* hi = tbx.hiVect();
 
 1673        for (
int i = lo[0]; i <= hi[0]; ++i) {
 
 1674            for (
int j = lo[1]; j <= hi[1]; ++j) {
 
 1675#if AMREX_SPACEDIM == 3 
 1676                for (
int k = lo[2]; k <= hi[2]; ++k) {
 
 1682                    mv->replaceGlobalValue(gidx, fab(iv, comp));
 
 1683#if AMREX_SPACEDIM == 3 
 1695                                    const Teuchos::RCP<vector_t>& mv)
 
 1697    Teuchos::ArrayRCP<const amr::scalar_t> data =  mv->get1dView();
 
 1699    for (amrex::MFIter mfi(mf, 
true); mfi.isValid(); ++mfi) {
 
 1700        const amrex::Box&          tbx  = mfi.tilebox();
 
 1701        amrex::FArrayBox&          fab = mf[mfi];
 
 1703        const int* lo = tbx.loVect();
 
 1704        const int* hi = tbx.hiVect();
 
 1706        for (
int i = lo[0]; i <= hi[0]; ++i) {
 
 1707            for (
int j = lo[1]; j <= hi[1]; ++j) {
 
 1708#if AMREX_SPACEDIM == 3 
 1709                for (
int k = lo[2]; k <= hi[2]; ++k) {
 
 1716                    fab(iv, comp) = data[lidx];
 
 1718#if AMREX_SPACEDIM == 3 
 1733    indices.reserve(map.size());
 
 1734    values.reserve(map.size());
 
 1737                  [&](
const std::pair<const go_t, scalar_t>& entry)
 
 1740                      if ( entry.first < 0 ) {
 
 1741                          throw OpalException(
"AmrMultiGrid::map2vector_m()",
 
 1742                                              "Negative matrix index!");
 
 1746                      indices.push_back(entry.first);
 
 1747                      values.push_back(entry.second);
 
 1756                            Teuchos::RCP<vector_t>& 
e,
 
 1757                            Teuchos::RCP<vector_t>& r)
 
 1778    Teuchos::RCP<vector_t> tmp = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p) );
 
 1785    mglevel_m[level-1]->residual_p->putScalar(0.0);
 
 1801                                     fine2crse, Teuchos::NO_TRANS,
 
 1804    if ( 
mglevel_m[level-1]->Bcrse_p != Teuchos::null ) {
 
 1807                                           fine2crse, Teuchos::NO_TRANS,
 
 1811    Teuchos::RCP<vector_t> uncoveredRho = Teuchos::rcp( 
new vector_t(
mglevel_m[level-1]->map_p, 
true) );
 
 1817    Teuchos::RCP<vector_t> tmp2 = Teuchos::rcp( 
new vector_t(
mglevel_m[level-1]->map_p, 
true) );
 
 1818    mglevel_m[level-1]->UnCovered_p->apply(fine2crse, *tmp2);
 
 1821    mglevel_m[level-1]->residual_p->update(1.0, *uncoveredRho, -1.0, *tmp2, 1.0);
 
 1853    Teuchos::RCP<vector_t> phicrse = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p, 
false) );
 
 1858    Teuchos::RCP<vector_t> uncov_phi = Teuchos::rcp( 
new vector_t(
mglevel_m[level]->map_p, 
true) );
 
 1862    mglevel_m[level]->phi_p->update(1.0, *phicrse, 1.0, *uncov_phi, 0.0);
 
 1871        case Interpolater::TRILINEAR:
 
 1874        case Interpolater::LAGRANGE:
 
 1876                                "Not yet implemented.");
 
 1877        case Interpolater::PIECEWISE_CONST:
 
 1882                                "No such interpolater available.");
 
 1888    switch ( interface ) {
 
 1889        case Interpolater::TRILINEAR:
 
 1892        case Interpolater::LAGRANGE:
 
 1896        case Interpolater::PIECEWISE_CONST:
 
 1901                                "No such interpolater for the coarse-fine interface available.");
 
 1907                                    const bool& rebalance,
 
 1908                                    const std::string& reuse)
 
 1912        case BaseSolver::BICGSTAB:
 
 1915        case BaseSolver::MINRES:
 
 1918        case BaseSolver::PCPG:
 
 1921        case BaseSolver::CG:
 
 1924        case BaseSolver::GMRES:
 
 1927        case BaseSolver::STOCHASTIC_CG:
 
 1930        case BaseSolver::RECYCLING_CG:
 
 1933        case BaseSolver::RECYCLING_GMRES:
 
 1937#ifdef HAVE_AMESOS2_KLU2 
 1938        case BaseSolver::KLU2:
 
 1942#if HAVE_AMESOS2_SUPERLU 
 1943        case BaseSolver::SUPERLU:
 
 1947#ifdef HAVE_AMESOS2_UMFPACK 
 1948        case BaseSolver::UMFPACK:
 
 1952#ifdef HAVE_AMESOS2_PARDISO_MKL 
 1953        case BaseSolver::PARDISO_MKL:
 
 1957#ifdef HAVE_AMESOS2_MUMPS 
 1958        case BaseSolver::MUMPS:
 
 1962#ifdef HAVE_AMESOS2_LAPACK 
 1963        case BaseSolver::LAPACK:
 
 1975                                "No such bottom solver available.");
 
 1981                              const std::string& reuse)
 
 1999        case Preconditioner::NONE:
 
 2004                                "No such preconditioner available.");
 
 2011    std::map<std::string, Boundary> map;
 
 2013    map[
"DIRICHLET"]    = Boundary::DIRICHLET;
 
 2014    map[
"OPEN"]         = Boundary::OPEN;
 
 2015    map[
"PERIODIC"]     = Boundary::PERIODIC;
 
 2017    auto boundary = map.find(bc);
 
 2019    if ( boundary == map.end() )
 
 2020        throw OpalException(
"AmrMultiGrid::convertToEnumBoundary_m()",
 
 2021                            "No boundary type '" + bc + 
"'.");
 
 2022    return boundary->second;
 
 2027    std::map<std::string, Interpolater> map;
 
 2029    map[
"TRILINEAR"]    = Interpolater::TRILINEAR;
 
 2030    map[
"LAGRANGE"]     = Interpolater::LAGRANGE;
 
 2031    map[
"PC"]           = Interpolater::PIECEWISE_CONST;
 
 2033    auto interpolater = map.find(interp);
 
 2035    if ( interpolater == map.end() )
 
 2036        throw OpalException(
"AmrMultiGrid::convertToEnumInterpolater_m()",
 
 2037                            "No interpolater '" + interp + 
"'.");
 
 2038    return interpolater->second;
 
 2044    std::map<std::string, BaseSolver> map;
 
 2046    map[
"BICGSTAB"]         = BaseSolver::BICGSTAB;
 
 2047    map[
"MINRES"]           = BaseSolver::MINRES;
 
 2048    map[
"PCPG"]             = BaseSolver::PCPG;
 
 2049    map[
"CG"]               = BaseSolver::CG;
 
 2050    map[
"GMRES"]            = BaseSolver::GMRES;
 
 2051    map[
"STOCHASTIC_CG"]    = BaseSolver::STOCHASTIC_CG;
 
 2052    map[
"RECYCLING_CG"]     = BaseSolver::RECYCLING_GMRES;
 
 2053    map[
"RECYCLING_GMRES"]  = BaseSolver::RECYCLING_GMRES;
 
 2054#ifdef HAVE_AMESOS2_KLU2 
 2055    map[
"KLU2"]             = BaseSolver::KLU2;
 
 2057#ifdef HAVE_AMESOS2_SUPERLU 
 2058    map[
"SUPERLU"]          = BaseSolver::SUPERLU;
 
 2060#ifdef HAVE_AMESOS2_UMFPACK 
 2061    map[
"UMFPACK"]          = BaseSolver::UMFPACK;
 
 2063#ifdef HAVE_AMESOS2_PARDISO_MKL 
 2064    map[
"PARDISO_MKL"]      = BaseSolver::PARDISO_MKL;
 
 2066#ifdef HAVE_AMESOS2_MUMPS 
 2067    map[
"MUMPS"]            = BaseSolver::MUMPS;
 
 2069#ifdef HAVE_AMESOS2_LAPACK 
 2070    map[
"LAPACK"]           = BaseSolver::LAPACK;
 
 2074    auto solver = map.find(bsolver);
 
 2076    if ( solver == map.end() )
 
 2077        throw OpalException(
"AmrMultiGrid::convertToEnumBaseSolver_m()",
 
 2078                            "No bottom solver '" + bsolver + 
"'.");
 
 2079    return solver->second;
 
 2085    std::map<std::string, Preconditioner> map;
 
 2087    map[
"NONE"]         = Preconditioner::NONE;
 
 2093    auto precond = map.find(prec);
 
 2095    if ( precond == map.end() )
 
 2096        throw OpalException(
"AmrMultiGrid::convertToEnumPreconditioner_m()",
 
 2097                            "No preconditioner '" + prec + 
"'.");
 
 2098    return precond->second;
 
 2110    std::map<std::string, Norm> map;
 
 2112    map[
"L1_NORM"]   = Norm::L1;
 
 2113    map[
"L2_NORM"]   = Norm::L2;
 
 2114    map[
"LINF_NORM"] = Norm::LINF;
 
 2116    auto n = map.find(norm);
 
 2118    if ( 
n == map.end() )
 
 2120                            "No norm '" + norm + 
"'.");
 
 2128    std::string dateStr(simtimer.
date());
 
 2129    std::string timeStr(simtimer.
time());
 
 2130    std::string indent(
"        ");
 
 2133    outfile << 
"&description\n" 
 2135            << 
"' " << dateStr << 
"" << timeStr << 
"\",\n" 
 2136            << indent << 
"contents=\"solver info\"\n" 
 2138    outfile << 
"¶meter\n" 
 2139            << indent << 
"name=processors,\n" 
 2140            << indent << 
"type=long,\n" 
 2141            << indent << 
"description=\"Number of Cores used\"\n" 
 2143    outfile << 
"¶meter\n" 
 2144            << indent << 
"name=revision,\n" 
 2145            << indent << 
"type=string,\n" 
 2146            << indent << 
"description=\"git revision of opal\"\n" 
 2148    outfile << 
"¶meter\n" 
 2149            << indent << 
"name=flavor,\n" 
 2150            << indent << 
"type=string,\n" 
 2151            << indent << 
"description=\"OPAL flavor that wrote file\"\n" 
 2153    outfile << 
"&column\n" 
 2154            << indent << 
"name=t,\n" 
 2155            << indent << 
"type=double,\n" 
 2156            << indent << 
"units=ns,\n" 
 2157            << indent << 
"description=\"1 Time\"\n" 
 2159    outfile << 
"&column\n" 
 2160            << indent << 
"name=mg_iter,\n" 
 2161            << indent << 
"type=long,\n" 
 2162            << indent << 
"units=1,\n" 
 2163            << indent << 
"description=\"2 Number of Multigrid Iterations\"\n" 
 2165    outfile << 
"&column\n" 
 2166            << indent << 
"name=bottom_iter,\n" 
 2167            << indent << 
"type=long,\n" 
 2168            << indent << 
"units=1,\n" 
 2169            << indent << 
"description=\"3 Total Number of Bottom Solver Iterations\"\n" 
 2171    outfile << 
"&column\n" 
 2172            << indent << 
"name=regrid,\n" 
 2173            << indent << 
"type=bool,\n" 
 2174            << indent << 
"units=1,\n" 
 2175            << indent << 
"description=\"4 Regrid Step\"\n" 
 2177    outfile << 
"&column\n" 
 2178            << indent << 
"name=" + 
snorm_m + 
",\n" 
 2179            << indent << 
"type=double,\n" 
 2180            << indent << 
"units=1,\n" 
 2181            << indent << 
"description=\"5 Error\"\n" 
 2184            << indent << 
"mode=ascii,\n" 
 2185            << indent << 
"no_row_counts=1\n" 
 2198    unsigned int pwi = 10;
 
 2200    std::ofstream outfile;
 
 2202    if ( 
comm_mp->getRank() == 0 ) {
 
 2204        outfile.precision(15);
 
 2205        outfile.setf(std::ios::scientific, std::ios::floatfield);
 
 2207        if ( 
flag_m == std::ios::out ) {
 
 2213                << this->
nIter_m << std::setw(pwi) << 
'\t'                   
 2214                << this->
bIter_m << std::setw(pwi) << 
'\t'                   
 2215                << this->
regrid_m << std::setw(pwi) <<  
'\t'                 
 2225void AmrMultiGrid::initTimer_m() {
 
 2269    os << 
"* ********************* A M R M u l t i G r i d ********************** " << 
endl 
 2271       << 
"* ******************************************************************** " << 
endl;
 
#define OPAL_PROJECT_VERSION
 
#define OPAL_PROJECT_NAME
 
amr::AmrScalarFieldContainer_t AmrScalarFieldContainer_t
 
amr::AmrVectorFieldContainer_t AmrVectorFieldContainer_t
 
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
 
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
 
bool for_each(const BareFieldIterator< T, D > &p, SameFieldID s, C)
 
Inform & endl(Inform &inf)
 
void serialize(Param_t params, std::ostringstream &os)
serializes params using Boost archive
 
@ GS
Gauss-Seidel point relaxation.
 
@ JACOBI
Jacobi point relaxation.
 
@ SA
smoothed aggregation multigrid
 
@ BLOCK_JACOBI
Jacobi block relaxation.
 
@ BLOCK_GS
Gauss-Seidel block relaxation.
 
constexpr double e
The value of.
 
std::string getGitRevision()
 
The global OPAL structure.
 
std::string getInputFn()
get opals input filename
 
static OpalData * getInstance()
 
const Vector_t & getMeshScaling() const
 
void trilinos2amrex_m(const lo_t &level, const lo_t &comp, AmrField_t &mf, const Teuchos::RCP< vector_t > &mv)
 
void buildCrseBoundaryMatrix_m(const lo_t &level, const go_t &gidx, const AmrIntVect_t &iv, const basefab_t &mfab, const basefab_t &cfab, const scalar_t *invdx2)
 
amrex::BaseFab< int > basefab_t
 
void relax_m(const lo_t &level)
 
void initGuess_m(bool reset)
 
void close_m(const lo_t &level, const bool &matrices)
 
AmrMultiGrid(AmrBoxLib *itsAmrObject_p, const std::string &bsolver, const std::string &prec, const bool &rebalance, const std::string &reuse, const std::string &bcx, const std::string &bcy, const std::string &bcz, const std::string &smoother, const std::size_t &nSweeps, const std::string &interp, const std::string &norm)
 
double getZRangeMax(unsigned short level=0)
 
void restrict_m(const lo_t &level)
 
Boundary
Supported physical boundaries.
 
Boundary convertToEnumBoundary_m(const std::string &bc)
 
std::shared_ptr< bsolver_t > solver_mp
bottom solver
 
BaseSolver convertToEnumBaseSolver_m(const std::string &bsolver)
 
void setup_m(const amrex::Vector< AmrField_u > &rho, const amrex::Vector< AmrField_u > &phi, const bool &matrices=true)
 
double getXRangeMin(unsigned short level=0)
 
void initPhysicalBoundary_m(const Boundary *bc)
 
AmrMultiGridLevel_t::coefficients_t coefficients_t
 
Teuchos::RCP< comm_t > comm_mp
communicator
 
std::string fname_m
SDDS filename.
 
BaseSolver
Supported bottom solvers.
 
AmrMultiGridLevel_t::umap_t umap_t
 
amrex::FArrayBox farraybox_t
 
std::string snorm_m
norm for convergence criteria
 
std::size_t nSweeps_m
number of smoothing iterations
 
void map2vector_m(umap_t &map, indices_t &indices, coefficients_t &values)
 
void buildFineBoundaryMatrix_m(const lo_t &level, const go_t &gidx, const AmrIntVect_t &iv, const basefab_t &mfab, const basefab_t &rfab)
 
void writeSDDSHeader_m(std::ofstream &outfile)
 
std::vector< std::unique_ptr< AmrMultiGridLevel_t > > mglevel_m
container for levels
 
void amrex2trilinos_m(const lo_t &level, const lo_t &comp, const AmrField_t &mf, Teuchos::RCP< vector_t > &mv)
 
scalar_t getLevelResidualNorm(lo_t level)
 
scalar_t evalNorm_m(const Teuchos::RCP< const vector_t > &x)
 
void buildSingleLevel_m(const amrex::Vector< AmrField_u > &rho, const amrex::Vector< AmrField_u > &phi, const bool &matrices=true)
 
int lbase_m
base level (currently only 0 supported)
 
void initPrec_m(const Preconditioner &prec, const std::string &reuse)
 
void setVerbose(bool verbose)
 
void initInterpolater_m(const Interpolater &interp)
 
std::unique_ptr< AmrInterpolater< AmrMultiGridLevel_t > > interp_mp
interpolater without coarse-fine interface
 
void buildGradientMatrix_m(const lo_t &level, const go_t &gidx, const AmrIntVect_t &iv, const basefab_t &mfab, const scalar_t *invdx)
 
BelosBottomSolver< AmrMultiGridLevel_t > BelosSolver_t
 
void initCrseFineInterp_m(const Interpolater &interface)
 
std::shared_ptr< preconditioner_t > prec_mp
preconditioner for bottom solver
 
std::unique_ptr< AmrInterpolater< AmrMultiGridLevel_t > > interface_mp
interpolater for coarse-fine interface
 
Norm convertToEnumNorm_m(const std::string &norm)
 
Interpolater convertToEnumInterpolater_m(const std::string &interp)
 
amr::global_ordinal_t go_t
 
void averageDown_m(const lo_t &level)
 
Smoother convertToEnumSmoother_m(const std::string &smoother)
 
double getZRangeMin(unsigned short level=0)
 
Amesos2BottomSolver< AmrMultiGridLevel_t > Amesos2Solver_t
 
void buildPotentialVector_m(const lo_t &level, const AmrField_t &phi)
 
void residual_no_fine_m(const lo_t &level, Teuchos::RCP< vector_t > &result, const Teuchos::RCP< vector_t > &rhs, const Teuchos::RCP< vector_t > &crs_rhs, const Teuchos::RCP< vector_t > &b)
 
scalar_t eps_m
rhs scale for convergence
 
AmrMultiGridLevel_t::AmrField_t AmrField_t
 
std::size_t nIter_m
number of iterations till convergence
 
double getXRangeMax(unsigned short level=0)
 
Inform & print(Inform &os) const
 
AmrMultiGridLevel_t::AmrIntVect_t AmrIntVect_t
 
bool verbose_m
If true, a SDDS file is written.
 
std::size_t bIter_m
number of iterations of bottom solver
 
int nlevel_m
number of levelss
 
amr::local_ordinal_t lo_t
 
std::ios_base::openmode flag_m
std::ios::out or std::ios::app
 
void setNumberOfSweeps(const std::size_t &nSweeps)
 
void initResidual_m(std::vector< scalar_t > &rhsNorms, std::vector< scalar_t > &resNorms)
 
void buildMultiLevel_m(const amrex::Vector< AmrField_u > &rho, const amrex::Vector< AmrField_u > &phi, const bool &matrices=true)
 
void open_m(const lo_t &level, const bool &matrices)
 
void buildDensityVector_m(const lo_t &level, const AmrField_t &rho)
 
MueLuPreconditioner< AmrMultiGridLevel_t > MueLuPreconditioner_t
 
AmrMultiGridLevel< matrix_t, vector_t > AmrMultiGridLevel_t
 
std::size_t getNumIters()
 
std::size_t maxiter_m
maximum number of iterations allowed
 
void buildNoFinePoissonMatrix_m(const lo_t &level, const go_t &gidx, const AmrIntVect_t &iv, const basefab_t &mfab, const scalar_t *invdx2)
 
double getYRangeMin(unsigned short level=0)
 
void writeSDDSData_m(const scalar_t &error)
 
int nBcPoints_m
maximum number of stencils points for BC
 
void setMaxNumberOfIterations(const std::size_t &maxiter)
 
void initBaseSolver_m(const BaseSolver &solver, const bool &rebalance, const std::string &reuse)
 
Smoother smootherType_m
type of smoother
 
Norm
Supported convergence criteria.
 
void initLevels_m(const amrex::Vector< AmrField_u > &rho, const amrex::Vector< AmrGeometry_t > &geom, bool regrid)
 
void smooth_m(const lo_t &level, Teuchos::RCP< vector_t > &e, Teuchos::RCP< vector_t > &r)
 
Ifpack2Preconditioner< AmrMultiGridLevel_t > Ifpack2Preconditioner_t
 
boundary_t bc_m[AMREX_SPACEDIM]
boundary conditions
 
void residual_m(const lo_t &level, Teuchos::RCP< vector_t > &r, const Teuchos::RCP< vector_t > &b, const Teuchos::RCP< vector_t > &x)
 
std::vector< std::shared_ptr< AmrSmoother > > smoother_m
error smoother
 
void buildInterpolationMatrix_m(const lo_t &level, const go_t &gidx, const AmrIntVect_t &iv, const basefab_t &cfab)
 
void computeEfield_m(AmrVectorFieldContainer_t &efield)
 
AmrMultiGridLevel_t::indices_t indices_t
 
Interpolater
Supported interpolaters for prolongation operation.
 
void prolongate_m(const lo_t &level)
 
bool isConverged_m(std::vector< scalar_t > &rhsNorms, std::vector< scalar_t > &resNorms)
 
Norm norm_m
norm for convergence criteria (l1, l2, linf)
 
double getYRangeMax(unsigned short level=0)
 
void setTolerance(const scalar_t &eps)
 
void solve(AmrScalarFieldContainer_t &rho, AmrScalarFieldContainer_t &phi, AmrVectorFieldContainer_t &efield, unsigned short baseLevel, unsigned short finestLevel, bool prevAsGuess=true)
 
MueLuBottomSolver< AmrMultiGridLevel_t > MueLuSolver_t
 
void buildRestrictionMatrix_m(const lo_t &level, const go_t &gidx, const AmrIntVect_t &iv, D_DECL(const go_t &ii, const go_t &jj, const go_t &kk), const basefab_t &rfab)
 
Preconditioner convertToEnumPreconditioner_m(const std::string &prec)
 
void buildCompositePoissonMatrix_m(const lo_t &level, const go_t &gidx, const AmrIntVect_t &iv, const basefab_t &mfab, const basefab_t &rfab, const scalar_t *invdx2)
 
amrex::FabArray< basefab_t > mask_t
 
Smoother
All supported Ifpack2 smoothers.
 
static Smoother convertToEnumSmoother(const std::string &smoother)
 
static void fillMap(map_t &map)
 
static std::string convertToMueLuReuseOption(const std::string &reuse)
 
static std::string convertToMueLuReuseOption(const std::string &reuse)
 
static void fillMap(map_t &map)
 
bool regrid_m
is set to true by itsAmrObject_mp and reset to false by solver
 
AmrBoxLib * itsAmrObject_mp
 
The base class for all OPAL exceptions.
 
std::string date() const
Return date.
 
std::string time() const
Return time.
 
static TimerRef getTimer(const char *nm)
 
static void stopTimer(TimerRef t)
 
static void startTimer(TimerRef t)