|
| 1 | + |
| 2 | +#include <AMReX.H> |
| 3 | +#include <AMReX_ParmParse.H> |
| 4 | +#include <AMReX_EBMultiFabUtil.H> |
| 5 | +#include <AMReX_EB2.H> |
| 6 | +#include <AMReX_EB2_IF.H> |
| 7 | +#include <AMReX_MLEBABecLap.H> |
| 8 | +#include <AMReX_MLEBNodeFDLaplacian.H> |
| 9 | +#include <AMReX_PlotFileUtil.H> |
| 10 | +#include <AMReX_MultiFabUtil.H> |
| 11 | +#include <AMReX_MLMG.H> |
| 12 | + |
| 13 | +#include "Poisson.H" |
| 14 | + |
| 15 | +using namespace amrex; |
| 16 | + |
| 17 | +int main (int argc, char* argv[]) |
| 18 | +{ |
| 19 | + amrex::Initialize(argc, argv); |
| 20 | + |
| 21 | + { |
| 22 | + int verbose = 1; |
| 23 | + int n_cell = 128; |
| 24 | + int max_grid_size = 32; |
| 25 | + |
| 26 | + // read parameters |
| 27 | + { |
| 28 | + ParmParse pp; |
| 29 | + pp.query("verbose", verbose); |
| 30 | + pp.query("n_cell", n_cell); |
| 31 | + pp.query("max_grid_size", max_grid_size); |
| 32 | + } |
| 33 | + |
| 34 | + Geometry geom; |
| 35 | + BoxArray grids; |
| 36 | + DistributionMapping dmap; |
| 37 | + { |
| 38 | + RealBox rb({AMREX_D_DECL(0.,0.,0.)}, {AMREX_D_DECL(1.,1.,1.)}); |
| 39 | + Array<int,AMREX_SPACEDIM> is_periodic{AMREX_D_DECL(1,1,1)}; |
| 40 | + Box domain(IntVect{AMREX_D_DECL(0,0,0)}, |
| 41 | + IntVect{AMREX_D_DECL(n_cell-1,n_cell-1,n_cell-1)}); |
| 42 | + geom.define(domain, rb, CoordSys::cartesian, is_periodic); |
| 43 | + |
| 44 | + grids.define(domain); // define the BoxArray to be a single grid |
| 45 | + grids.maxSize(max_grid_size); // chop domain up into boxes with length max_Grid_size |
| 46 | + |
| 47 | + dmap.define(grids); // create a processor distribution mapping given the BoxARray |
| 48 | + } |
| 49 | + |
| 50 | + int required_coarsening_level = 0; // typically the same as the max AMR level index |
| 51 | + int max_coarsening_level = 100; // typically a huge number so MG coarsens as much as possible |
| 52 | + // build a simple geometry using the "eb2." parameters in the inputs file |
| 53 | + EB2::Build(geom, required_coarsening_level, max_coarsening_level); |
| 54 | + |
| 55 | + const EB2::IndexSpace& eb_is = EB2::IndexSpace::top(); |
| 56 | + const EB2::Level& eb_level = eb_is.getLevel(geom); |
| 57 | + |
| 58 | + // options are basic, volume, or full |
| 59 | + EBSupport ebs = EBSupport::full; |
| 60 | + |
| 61 | + // number of ghost cells for each of the 3 EBSupport types |
| 62 | + Vector<int> ng_ebs = {2,2,2}; |
| 63 | + |
| 64 | + // This object provides access to the EB database in the format of basic AMReX objects |
| 65 | + // such as BaseFab, FArrayBox, FabArray, and MultiFab |
| 66 | + EBFArrayBoxFactory factory(eb_level, geom, grids, dmap, ng_ebs, ebs); |
| 67 | + |
| 68 | + // charge density and electric potential are nodal |
| 69 | + const BoxArray& nba = amrex::convert(grids, IntVect::TheNodeVector()); |
| 70 | + MultiFab q (nba, dmap, 1, 0, MFInfo(), factory); |
| 71 | + MultiFab phi(nba, dmap, 1, 0, MFInfo(), factory); |
| 72 | + |
| 73 | + InitData(q); |
| 74 | + |
| 75 | + LPInfo info; |
| 76 | + |
| 77 | +// MLEBABecLap mlebabec({geom},{grids},{dmap},info,{&factory}); |
| 78 | + MLEBNodeFDLaplacian linop({geom},{grids},{dmap},info,{&factory}); |
| 79 | + |
| 80 | + // define array of LinOpBCType for domain boundary conditions |
| 81 | + std::array<LinOpBCType,AMREX_SPACEDIM> bc_lo; |
| 82 | + std::array<LinOpBCType,AMREX_SPACEDIM> bc_hi; |
| 83 | + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) { |
| 84 | + bc_lo[idim] = LinOpBCType::Periodic; |
| 85 | + bc_hi[idim] = LinOpBCType::Periodic; |
| 86 | + } |
| 87 | + |
| 88 | + // Boundary of the whole domain. This functions must be called, |
| 89 | + // and must be called before other bc functions. |
| 90 | + linop.setDomainBC(bc_lo,bc_hi); |
| 91 | + |
| 92 | + // see AMReX_MLLinOp.H for an explanation |
| 93 | + linop.setLevelBC(0, nullptr); |
| 94 | + |
| 95 | + //// operator looks like (ACoef - div BCoef grad) phi = rhs |
| 96 | + |
| 97 | + //// set ACoef to zero |
| 98 | + //MultiFab acoef(grids, dmap, 1, 0, MFInfo(), factory); |
| 99 | + //acoef.setVal(0.); |
| 100 | + //mlebabec.setACoeffs(0, acoef); |
| 101 | + |
| 102 | + //// set BCoef to 1.0 (and array of face-centered coefficients) |
| 103 | + //Array<MultiFab,AMREX_SPACEDIM> bcoef; |
| 104 | + //for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) { |
| 105 | + // bcoef[idim].define(amrex::convert(grids,IntVect::TheDimensionVector(idim)), dmap, 1, 0, MFInfo(), factory); |
| 106 | + // bcoef[idim].setVal(1.0); |
| 107 | + //} |
| 108 | + //mlebabec.setBCoeffs(0, amrex::GetArrOfConstPtrs(bcoef)); |
| 109 | + |
| 110 | + //// scaling factors; these multiply ACoef and BCoef |
| 111 | + //Real ascalar = 0.0; |
| 112 | + //Real bscalar = 1.0; |
| 113 | + //mlebabec.setScalars(ascalar, bscalar); |
| 114 | + |
| 115 | + //// think of this beta as the "BCoef" associated with an EB face |
| 116 | + //MultiFab beta(nba, dmap, 1, 0, MFInfo(), factory); |
| 117 | + //beta.setVal(1.); |
| 118 | + |
| 119 | + // set homogeneous Dirichlet BC for EB |
| 120 | + linop.setEBDirichlet(0.); |
| 121 | + |
| 122 | + MLMG mlmg(linop); |
| 123 | + |
| 124 | + // relative and absolute tolerances for linear solve |
| 125 | + const Real tol_rel = 1.e-10; |
| 126 | + const Real tol_abs = 0.0; |
| 127 | + |
| 128 | + mlmg.setVerbose(verbose); |
| 129 | + |
| 130 | + // Solve linear system |
| 131 | + phi.setVal(0.0); // initial guess for phi |
| 132 | + mlmg.solve({&phi}, {&q}, tol_rel, tol_abs); |
| 133 | + |
| 134 | + //// store plotfile variables; q and phi |
| 135 | + //MultiFab plotfile_mf(grids, dmap, 2, 0, MFInfo(), factory); |
| 136 | + //MultiFab::Copy(plotfile_mf, q,0,0,1,0); |
| 137 | + //MultiFab::Copy(plotfile_mf,phi,0,1,1,0); |
| 138 | + |
| 139 | + //EB_WriteSingleLevelPlotfile("plt", plotfile_mf, {"q", "phi"}, geom, 0.0, 0); |
| 140 | + } |
| 141 | + |
| 142 | + amrex::Finalize(); |
| 143 | +} |
0 commit comments