From 88fb33367088127da5e00d83ab4451a12390958b Mon Sep 17 00:00:00 2001 From: dtgraves Date: Mon, 23 Mar 2020 10:28:33 -0700 Subject: [PATCH] added an example that uses Proto --- lib/mk/Make.defs.config | 6 +- lib/mk/Make.defs.defaults | 3 + lib/mk/local/Make.defs.ANAG | 2 +- lib/mk/local/Make.defs.igor | 16 +- lib/src/BoxTools/ProtoInterface.H | 60 +++ lib/src/BoxTools/ProtoInterface.cpp | 64 +++ .../Proto/Poisson/doc/proto_poisson.pdf | Bin 0 -> 99491 bytes .../Proto/Poisson/doc/proto_poisson.tex | 96 +++++ .../Proto/Poisson/exec/GNUmakefile | 22 + .../Proto/Poisson/exec/Multigrid.cpp | 343 ++++++++++++++++ .../Proto/Poisson/exec/mpi_run_anag.sh | 23 ++ .../Proto/Poisson/exec/periodic.inputs | 21 + .../Proto/Poisson/exec/threadrun.sh | 36 ++ .../Proto/Poisson/src/SGMultigrid.H | 188 +++++++++ .../Proto/Poisson/src/SGMultigrid.cpp | 387 ++++++++++++++++++ 15 files changed, 1258 insertions(+), 9 deletions(-) create mode 100644 lib/src/BoxTools/ProtoInterface.H create mode 100644 lib/src/BoxTools/ProtoInterface.cpp create mode 100644 releasedExamples/Proto/Poisson/doc/proto_poisson.pdf create mode 100644 releasedExamples/Proto/Poisson/doc/proto_poisson.tex create mode 100644 releasedExamples/Proto/Poisson/exec/GNUmakefile create mode 100644 releasedExamples/Proto/Poisson/exec/Multigrid.cpp create mode 100755 releasedExamples/Proto/Poisson/exec/mpi_run_anag.sh create mode 100644 releasedExamples/Proto/Poisson/exec/periodic.inputs create mode 100755 releasedExamples/Proto/Poisson/exec/threadrun.sh create mode 100644 releasedExamples/Proto/Poisson/src/SGMultigrid.H create mode 100644 releasedExamples/Proto/Poisson/src/SGMultigrid.cpp diff --git a/lib/mk/Make.defs.config b/lib/mk/Make.defs.config index 767bdb7a..3ca341dc 100644 --- a/lib/mk/Make.defs.config +++ b/lib/mk/Make.defs.config @@ -1,4 +1,3 @@ -# -*- Mode: Makefile; -*- ## Set the configuration string used in filenames. ## `Make.rules' is the only Chombo makefile that uses this file, but @@ -71,14 +70,15 @@ _md := $(subst FALSE,,$(subst TRUE,md,$(MULTIDIM))) _pic := $(subst FALSE,,$(subst TRUE,.pic,$(PIC))) _openmpcc := $(subst FALSE,,$(subst TRUE,.OPENMPCC,$(OPENMPCC))) _openmpfc := $(subst FALSE,,$(subst TRUE,.OPENMPFC,$(OPENMPFC))) +_proto := $(subst FALSE,,$(subst TRUE,.PROTO,$(USE_PROTO))) # configuration string for multidim executable builds -- also use as a base # for the other config strings -newconfig := $(shell echo $(system)$(_obj64).$(_cxxname).$(_fname)$(_precision)$(_debug)$(_opt)$(_profile)$(_mpi)$(_openmpcc)$(_openmpfc)$(_petsc)$(_rose)$(_gpu)$(_pic)$(XTRACONFIG) | sed -e 's/ //g' -e 's/ //g') +newconfig := $(shell echo $(system)$(_obj64).$(_cxxname).$(_fname)$(_precision)$(_debug)$(_opt)$(_profile)$(_mpi)$(_openmpcc)$(_openmpfc)$(_proto)$(_petsc)$(_rose)$(_gpu)$(_pic)$(XTRACONFIG) | sed -e 's/ //g' -e 's/ //g') # create a base for all of the other config strings -baseconfig := $(shell echo d$(_ch)$(_md).$(system)$(_obj64).$(_cxxname).$(_fname)$(_precision)$(_debug)$(_opt)$(_profile)$(_mpi)$(_openmpcc)$(_openmpfc)$(_petsc)$(_rose)$(_gpu)$(_pic)$(XTRACONFIG) | sed -e 's/ //g' -e 's/ //g') +baseconfig := $(shell echo d$(_ch)$(_md).$(system)$(_obj64).$(_cxxname).$(_fname)$(_precision)$(_debug)$(_opt)$(_profile)$(_mpi)$(_openmpcc)$(_openmpfc)$(_proto)$(_petsc)$(_rose)$(_gpu)$(_pic)$(XTRACONFIG) | sed -e 's/ //g' -e 's/ //g') #these are config strings needed by multidim builds 1dconfig := 1$(baseconfig) diff --git a/lib/mk/Make.defs.defaults b/lib/mk/Make.defs.defaults index 591468a4..418fd280 100644 --- a/lib/mk/Make.defs.defaults +++ b/lib/mk/Make.defs.defaults @@ -29,6 +29,7 @@ ## CXXFLAGS options for compiling C++ code ## FFLAGS options for compiling Fortran code ## LDFLAGS options for linking +## CXXSTD chombo default is C++11. Set to 14 for C++14, etc. ## USE_64 if TRUE, use 64bit pointers on systems where 32bits is the default ## USE_COMPLEX if TRUE, enable the 'Complex' type ## (default is TRUE, disable only if compiler doesn't allow it) @@ -99,8 +100,10 @@ CXXFLAGS?= CHFFLAGS?= FFLAGS?= LDFLAGS?= +OUTPUT?=EXEC # Chombo optional features +CXXSTD?=11# # C++ 11 standard USE_64?=TRUE# #64bit pointers USE_MT?=TRUE# #memory tracking # USE_SETVAL?=TRUE# #initialize FAB data diff --git a/lib/mk/local/Make.defs.ANAG b/lib/mk/local/Make.defs.ANAG index da4286ce..48684608 100644 --- a/lib/mk/local/Make.defs.ANAG +++ b/lib/mk/local/Make.defs.ANAG @@ -223,6 +223,6 @@ ifneq ($(ANAG_OPENMPI_DIR),) endif ifeq ($(USE_PROTO),TRUE) - XTRACPPFLAGS += -I$(PROTO_HOME)/include -DDIM=$(DIM) -DUSE_PROTO=1 + XTRACPPFLAGS += -I$(PROTO_HOME)/include -DDIM=$(DIM) -DUSE_PROTO=1 -DPR_TURN_OFF_TIMERS=1 endif diff --git a/lib/mk/local/Make.defs.igor b/lib/mk/local/Make.defs.igor index a6c952c5..92b32c18 100644 --- a/lib/mk/local/Make.defs.igor +++ b/lib/mk/local/Make.defs.igor @@ -1,15 +1,21 @@ #it is prounouced eye-gore makefiles+=local/Make.defs.igor -USE_HDF=TRUE +PROTO_HOME=/home/dtgraves/_proto/proto +USE_PROTO=TRUE +OPENMPCC=TRUE +USE_HDF=FALSE USE_MF=TRUE USE_EB=TRUE USE_64=TRUE CXX=g++ CPP=cpp FC=gfortran -HDFINCFLAGS = -I/home/graves/_hdf5/include -HDFLIBFLAGS = -L/home/graves/_hdf5/lib -lhdf5 -lhdf5_hl -ldl -lz -HDFMPIINCFLAGS= -I/home/graves/_hdf5/include -HDFMPILIBFLAGS= -L/home/graves/_hdf5/lib -lhdf5 -lhdf5_hl -ldl -lz +HDFINCFLAGS = -I/home/dtgraves/_hdf5/include +HDFLIBFLAGS = -L/home/dtgraves/_hdf5/lib -lhdf5 -lhdf5_hl -ldl +HDFMPIINCFLAGS= -I/home/dtgraves/_hdf5/include +HDFMPILIBFLAGS= -L/home/dtgraves/_hdf5/lib -lhdf5 -lhdf5_hl -ldl +ifeq ($(USE_PROTO),TRUE) + XTRACPPFLAGS += -I$(PROTO_HOME)/include -DDIM=$(DIM) -DUSE_PROTO=1 -DPR_TURN_OFF_TIMERS=1 +endif diff --git a/lib/src/BoxTools/ProtoInterface.H b/lib/src/BoxTools/ProtoInterface.H new file mode 100644 index 00000000..6ce08f73 --- /dev/null +++ b/lib/src/BoxTools/ProtoInterface.H @@ -0,0 +1,60 @@ +#ifdef CH_LANG_CC +/* + * _______ __ + * / ___/ / ___ __ _ / / ___ + * / /__/ _ \/ _ \/ V \/ _ \/ _ \ + * \___/_//_/\___/_/_/_/_.__/\___/ + * Please refer to Copyright.txt, in Chombo's root directory. + */ +#endif + +#ifndef _PROTOINTERFACE_H_ +#define _PROTOINTERFACE_H_ + +#ifdef USE_PROTO +#include "Proto.H" +#endif +#include "IntVect.H" +#include "Box.H" +#include "BaseFab.H" + + + +#ifdef USE_PROTO + + +using Proto::Point; +using Proto::BoxData; +using Proto::Var; +///these functions are meant to interface with the Proto language. +namespace ProtoCh +{ + + +///get point from intvect + extern Point getPoint( const IntVect& a_iv); + +/// gets proto box from chombo box + extern Proto::Box getProtoBox( const Box& a_box); + +///get intvect from point + extern IntVect getIntVect(const Point & a_pt); + +///get chombo box from proto box + extern Box getBox(const Proto::Box & a_bx); + +/// + template + void aliasBoxData(BoxData & a_boxdata, const BaseFab& a_bfr, const int a_startcomp = 0) + { + CH_assert( a_bfr.nComp() == (ncomp + a_startcomp)); + Proto::Box region = getProtoBox(a_bfr.box()); + a_boxdata.define(a_bfr.dataPtr(a_startcomp), region, ncomp); + } + + +} + +#endif + +#endif diff --git a/lib/src/BoxTools/ProtoInterface.cpp b/lib/src/BoxTools/ProtoInterface.cpp new file mode 100644 index 00000000..15a2e6b7 --- /dev/null +++ b/lib/src/BoxTools/ProtoInterface.cpp @@ -0,0 +1,64 @@ +#ifdef CH_LANG_CC +/* + * _______ __ + * / ___/ / ___ __ _ / / ___ + * / /__/ _ \/ _ \/ V \/ _ \/ _ \ + * \___/_//_/\___/_/_/_/_.__/\___/ + * Please refer to Copyright.txt, in Chombo's root directory. + */ +#endif + +#include "ProtoInterface.H" +#include "SPACE.H" +#include "UsingNamespace.H" + +#ifdef USE_PROTO + +///get point from intvect +Point +ProtoCh::getPoint( const IntVect& a_iv) +{ + Point retval; + for(int idir = 0; idir < SpaceDim; idir++) + { + retval[idir] = a_iv[idir]; + } + return retval; + +} + +/// gets proto box from chombo box +Proto::Box +ProtoCh::getProtoBox( const Box& a_box) +{ + Point ptlo = getPoint(a_box.smallEnd()); + Point pthi = getPoint(a_box.bigEnd()); + return Proto::Box(ptlo, pthi); +} + +///get intvect from point +IntVect +ProtoCh::getIntVect(const Point & a_pt) +{ + IntVect retval; + for(int idir = 0; idir < SpaceDim; idir++) + { + retval[idir] = a_pt[idir]; + } + return retval; +} + +///get chombo box from proto box +Box +ProtoCh::getBox(const Proto::Box & a_bx) +{ + IntVect ivlo = getIntVect(a_bx.low()); + IntVect ivhi = getIntVect(a_bx.high()); + return Box(ivlo, ivhi); +} + + + +#endif + + diff --git a/releasedExamples/Proto/Poisson/doc/proto_poisson.pdf b/releasedExamples/Proto/Poisson/doc/proto_poisson.pdf new file mode 100644 index 0000000000000000000000000000000000000000..924d7d470007b4b4e59efc2ef162792e30de9651 GIT binary patch literal 99491 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⪚BqiDYJugq0{I;Is)I%r!);c*(6Im!UkJ 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

7Vravh`^-zOS@dKzi$%w++|#YIrpT#^ zc{|ObJBm1h%Y6E%GyGH@4MxSO@IuDevdAhYoR3=~LDI>Ew!8DTtWxEvMT#X%vy2U+ z>e_MGU!~NDWof31u?eyDb@B?sX&xK=pf-HPTIvHV9A?&eyN&ye;~Xl(ZbMzv-Hu`- ziW8m({x8{RS3(c(^~w^}#Qtq7F7jGNThG?Cx3B%_yPbL3PSIK(i{Nnm8xsnxc(-9% zaoSsq_W?PGxqkWk18j3s58)dzd_jj+*Ov~At;f4G0nr4E49|S?d%YD**culR)&h%fi5?h`Al2)BDzoz$w^C+-yJ0T4YOSMC3eO+-*t@Dv}Yx31ze~c^xSxpeOI<--V-Yl8hc0X zakzez(^7m@6O(@*nlU?ev$e3kTvN|>lJKzP-H>I^+}ECe`dH|_fqi0+AlPyqII&{G zv`LOT_%HHI9GC#&p*Wx%h1Q$iAxBCBLy_-Sz&9)Wu6sDSIJ@))_CW`%!e=i}FUmfR z20lRtx~vgOGJ>uGC;74}$NyQC>9Bew#^C#?-#A+m;mW-U9kd{^ z1tTnaEqifa(*$hIH#0c+m}T@S;=g>YV6A@DTx+JBghYMx=JK8FQUkU)j8{!A_yx){k~<6mQ+salJS+JJW$;L1h8XocSF?-c#PTpaR{| z8+`6ijWm#a(kOZ}Nn0G$YTVFq>Hk^ zqPd6hZwr!E6;G2Mj}edlw@<;=)(MY^`FFm;f80%M@tFQ|LH&;*gr~_RAi}~zFT^Im z$WO;2B*;R?!ph1oLdPP&#!Sa1BE&$)gZF=T`CUcI*v8b!>^HHF;eTh${XZ0b!k(Ol z@3%u6+S|tK`5tl=f@3b@Lqvy#v~%670#HpR0~9R;x2Ee%HT8Lz=>fQn^y32rf>3g# zhi8nBC>|RUI6Qniu*at$AlMJIRg_0&hL7wp3o9`TZvhu_d#x6%a;>3}x6y{Mm(u3m zcX53RznNslYpk>sv)QSEZ>QBZtS69_jZ4Myg^Y)b`9F8u(MjLI$<5(+kJ;Jj*x4b8 KiG^iFApaM|e0D+r literal 0 HcmV?d00001 diff --git a/releasedExamples/Proto/Poisson/doc/proto_poisson.tex b/releasedExamples/Proto/Poisson/doc/proto_poisson.tex new file mode 100644 index 00000000..86c134c6 --- /dev/null +++ b/releasedExamples/Proto/Poisson/doc/proto_poisson.tex @@ -0,0 +1,96 @@ +\documentclass[12pt,a4paper]{article} +\title{Chombo/Proto Poisson example } +\date{} +\begin{document} +\maketitle + +\begin{abstract} + +Given a charge distribution $\rho$, and a field $\phi$ +the spatial Helmoltz equation is given by +\begin{equation} +(\alpha I + \beta \nabla) \phi = \rho. +\end{equation} +where $\alpha$ and $\beta$ are constants. +The Chombo Proto example solves the spatial Helmholtz equation in two +or three dimensions using geometric multigrid with standard V-cycles. + +We present the performance for a single level calculation on a single +node of a Cori Haswell node. The boundary conditions are periodic +and the charge distribution has compact support of $r = 0.2$. +Further parameters are as follows. +\begin{itemize} +\item Identity coefficient, $\alpha = 1$. +\item Laplacian coefficient, $\beta = -0.1$. +\item Number of smoothings per relaxation, $n_{s} = 4$. +\item Grid dimensions = $512^3$. +\item Domain size $L_x=L_y=L_z =1$. +\end{itemize} + +All calculations are done with a varying number of threads, keeping +the number of computational units constant. If $N_t$ is the number +of OpenMP threads and $N_m$ is the number of MPI processes, for all +calculations, $N_t N_m = 32$. Floating point rates are calculated as +a post-processing step. + +\end{abstract} + + +\begin{table}[h] +\begin{center} +\begin{tabular}{|c|c||c|c|} \hline +$N_t$ & $N_m$ & $T_{vcycle}$ & $F_{resid}$ \\ +\hline +1 & 32 & 1.223 & 78.1 GFlop \\ +2 & 16 & 2.450 & 39.0 GFlop \\ +4 & 8 & 2.480 & 30.6 GFlop \\ +8 & 4 & 2.334 & 18.4 GFlop \\ +16 & 2 & 2.695 & 10.5 GFlop \\ +32 & 1 & 2.361 & 6.5 MFlop \\ +\hline +\end{tabular} +\end{center} +\caption{AMRPoisson performance. } +\label{fig::solut2dl0} +\end{table} + + +\begin{table}[h] +\begin{center} +\begin{tabular}{|c|c||c|c|} \hline +$N_t$ & $N_m$ & $T_{vcycle}$ & $F_{resid}$ \\ +\hline +1 & 32 & 3.89 & 20.1 GFlop\\ +2 & 16 & 6.53 & 12.7 GFlop\\ +4 & 8 & 6.47 & 12.6 GFlop\\ +8 & 4 & 6.27 & 12.6 GFlop\\ +16 & 2 & 6.00 & 12.6 GFlop\\ +32 & 1 & 5.85 & 12.7 GFlop\\ +\hline +\end{tabular} +\end{center} +\caption{7 point stencil proto performance. Same stencil as AMRPoisson} +\label{fig::solut2dl0} +\end{table} + + +\begin{table}[h] +\begin{center} +\begin{tabular}{|c|c||c|c|} \hline +$N_t$ & $N_m$ & $T_{vcycle}$ & $F_{resid}$\\ +\hline +1 & 32 & 12.4 & 22.9 GFlop\\ +2 & 16 & 20.7 & 14.7 GFlop\\ +4 & 8 & 20.7 & 14.4 GFlop\\ +8 & 4 & 19.7 & 14.7 GFlop\\ +16 & 2 & 18.8 & 14.9 GFlop\\ +32 & 1 & 18.6 & 14.9 GFlop\\ +\hline +\end{tabular} +\end{center} +\caption{27 point stencil proto performance. } +\label{fig::solut2dl0} +\end{table} + + +\end{document} diff --git a/releasedExamples/Proto/Poisson/exec/GNUmakefile b/releasedExamples/Proto/Poisson/exec/GNUmakefile new file mode 100644 index 00000000..986d88f5 --- /dev/null +++ b/releasedExamples/Proto/Poisson/exec/GNUmakefile @@ -0,0 +1,22 @@ + +ebase = Multigrid + +# the location of the Chombo "lib" directory +CHOMBO_HOME = ../../../../lib + +# names of Chombo libraries needed by this program, in order of search. +LibNames = BoxTools + +# the locations of the source code directories +base_dir = . +src_dirs = ../src + + +# input file for 'run' target +INPUT = regression.inputs +# shared code for building example programs +include $(CHOMBO_HOME)/mk/Make.example + +# application-specific variables + +# application-specific targets diff --git a/releasedExamples/Proto/Poisson/exec/Multigrid.cpp b/releasedExamples/Proto/Poisson/exec/Multigrid.cpp new file mode 100644 index 00000000..6414e357 --- /dev/null +++ b/releasedExamples/Proto/Poisson/exec/Multigrid.cpp @@ -0,0 +1,343 @@ +#ifdef CH_LANG_CC +/* + * _______ __ + * / ___/ / ___ __ _ / / ___ + * / /__/ _ \/ _ \/ V \/ _ \/ _ \ + * \___/_//_/\___/_/_/_/_.__/\___/ + * Please refer to Copyright.txt, in Chombo's root directory. + */ +#endif + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "SGMultigrid.H" +#include "LevelData.H" +#include "BaseFab.H" +#include "ParmParse.H" +#include "Proto.H" +#include "ProtoInterface.H" +#include "BRMeshRefine.H" +#include "LoadBalance.H" +#include "DebugDump.H" +#include "AMRIO.H" + + + +typedef Proto::Var Scalar; +typedef Proto::Box Bx; +using Proto::Point; +using Proto::BoxData; +using std::cout; +using std::endl; + +#define PI 3.141592653589793 + +class SolveParams +{ +public: + SolveParams() + { + relaxOnly = 0; + maxiter = 27; + numsmooth = 4; + nx = 64; + domsize = 1.0; + tol = 1.0e-9; + alpha = 1.0; + beta = -1.0; + blobrad = 0.1; + maxgrid = 16; + dofileio = 0; + useDenseStencil = 0; + resetDx(); + } + + int useDenseStencil; + int relaxOnly; + int maxiter; + int numsmooth; + int nstepmax; + int nx; + int maxgrid; + int dofileio; + double domsize; + double tol; + double dx; + double alpha; + double beta; + double blobrad; + double blobloc[DIM]; + + void resetDx() + { + dx = domsize/nx; + + for(int idir = 0; idir < DIM; idir++) + { + blobloc[idir] = domsize/2.; + } + } + + void print() const + { + pout() << "Multigrid Solve of alpha I + beta Lapl phi = rhs with periodic boundary conditions " << endl; + + pout() << "multigrid solve parameters: " << endl; + pout() << "max iterations = " << maxiter << endl; + pout() << "num smooths = " << numsmooth << endl; + pout() << "nx = " << nx << endl; + pout() << "max_grid = " << maxgrid << endl; + pout() << "domain size = " << domsize << endl; + pout() << "tolerance = " << tol << endl; + pout() << "dx = " << dx << endl; + pout() << "alpha = " << alpha << endl; + pout() << "beta = " << beta << endl; + pout() << "blobrad = " << blobrad << endl; + pout() << "using multicolor gauss seidel smoothing " << endl; + if(relaxOnly == 1) + { + pout() << "doing relax only" << endl; + } + else + { + pout() << "doing full multigrid solve" << endl; + } + if(dofileio == 0) + { + pout() << "file output turned off" << endl; + } + else + { + pout() << "file output turned on" << endl; + } + if(useDenseStencil == 0) + { + pout() << "using standard sparse Laplacian stencil" << endl; + } + else if(DIM==2) + { + pout() << "using dense (9 pt) Laplacian stencil" << endl; + } + else + { + pout() << "using dense (27 pt) Laplacian stencil" << endl; + } + } +}; +//////////// +void +parseInputs(SolveParams & a_params) +{ + ParmParse pp; + pp.get("nx" , a_params.nx); + pp.get("do_file_output", a_params.dofileio); + pp.get("use_dense_stencil", a_params.useDenseStencil); + pp.get("max_iter" , a_params.maxiter); + pp.get("relax_only" , a_params.relaxOnly); + pp.get("num_smooth" , a_params.numsmooth); + pp.get("domain_size", a_params.domsize); + pp.get("tolerance" , a_params.tol); + pp.get("alpha" , a_params.alpha); + pp.get("beta" , a_params.beta); + pp.get("max_grid" , a_params.maxgrid); + pp.get("blob_rad" , a_params.blobrad); + a_params.resetDx(); + a_params.print(); +} + +/****************/ +PROTO_KERNEL_START unsigned int setRHSF(Point& a_p, + Scalar & a_rhs, + SolveParams a_params) +{ + double x[DIM]; + for(int idir = 0; idir < DIM; idir++) + { + x[idir] = (a_p[idir] + 0.5)*a_params.dx; + } + + double rad0sq = a_params.blobrad*a_params.blobrad; + const double* const x0 = a_params.blobloc; + double radsq = 0; + for(int idir = 0; idir < DIM; idir++) + { + radsq += (x[idir]-x0[idir])*(x[idir]- x0[idir]); + } + if(radsq < rad0sq) + { + double cosval = cos(0.5*PI*(radsq/rad0sq)); + //an attempt at having a rhs that sums to zero + double rhsval = (x[0]-x0[0])*cosval*cosval; + + a_rhs(0) = rhsval; + } + else + { + a_rhs(0) = 0.0; + } + return 0; +} +PROTO_KERNEL_END(setRHSF, setRHS) + +PROTO_KERNEL_START void initParabolaT(Point& p, Scalar& data) +{ + data(0) = 0; + for(int idir = 0; idir < DIM; idir ++) + { + data(0) += p[idir]*p[idir]; + } +} +PROTO_KERNEL_END(initParabolaT, initParabola) + +/***/ +double absMax(const LevelData& a_resid) +{ + double absmaxval = 0; + DataIterator dit = a_resid.dataIterator(); +#pragma omp parallel for + for(int ibox = 0; ibox < dit.size(); ibox++) + { + BoxData resbd; + ProtoCh::aliasBoxData(resbd, a_resid[dit[ibox]]); + double maxgrid = resbd.absMax(); +#pragma omp critical + absmaxval = std::max(maxgrid, absmaxval); + } + +#ifdef CH_MPI + double recv; + int result = MPI_Allreduce(&absmaxval, &recv, 1, MPI_DOUBLE, + MPI_MAX, Chombo_MPI::comm); + if (result != MPI_SUCCESS) + { + MayDay::Error("sorry, but I had a communcation error on absmax"); + } + absmaxval = recv; +#endif + + return absmaxval; +} +/***/ +void +multigridSolve(const SolveParams& a_params) +{ + CH_TIME("Multigrid_Solve"); + SolveParams params = a_params; + + IntVect domLo = IntVect::Zero; + IntVect domHi = (a_params.nx - 1)*IntVect::Unit; + constexpr bool is_periodic[] = {true, true, true}; + + ProblemDomain domain(domLo, domHi, is_periodic); + + Vector boxes; + unsigned int blockfactor = 8; + domainSplit(domain, boxes, a_params.maxgrid, blockfactor); + Vector procs; + LoadBalance(procs, boxes); + DisjointBoxLayout grids(boxes, procs, domain); + LevelData phi(grids, 1, IntVect::Unit); + LevelData rhs(grids, 1, IntVect::Zero); + LevelData res(grids, 1, IntVect::Zero); + + DataIterator dit = grids.dataIterator(); +#pragma omp parallel + for(int ibox = 0; ibox < dit.size(); ibox++) + { + Bx patch = ProtoCh::getProtoBox(grids[dit[ibox]]); + BoxData rhsbd; + ProtoCh::aliasBoxData(rhsbd, rhs[dit[ibox]]); + forallInPlace_p(setRHS, patch, rhsbd, params); + phi[dit[ibox]].setVal(0.); + } + + + SGMultigrid::s_numSmoothUp = a_params.numsmooth; + SGMultigrid::s_numSmoothDown = a_params.numsmooth; + SGMultigrid::s_numSmoothBottom = 16*a_params.numsmooth; + + int iter = 0; + double rhsabsmax = absMax(rhs); + double resStart = rhsabsmax; + resStart = std::max(resStart, a_params.tol); + double resIter = resStart; + pout() << "iter = " << iter << ", ||resid|| = " << resIter << endl; + bool useDense = (a_params.useDenseStencil != 0); + SGMultigrid solver(a_params.alpha, a_params.beta, a_params.dx, grids, useDense); + if(a_params.relaxOnly == 0) + { + CH_TIME("full_multigrid_solve"); + while((resIter > a_params.tol*resStart) && (iter < a_params.maxiter)) + { + solver.vCycle(phi, rhs); + solver.residual(res, phi, rhs); + + iter++; + resIter = absMax(res); + pout() << "iter = " << iter << ", ||resid|| = " << resIter << endl; + } + } + else + { + CH_TIME("relaxation"); + for(int irelax = 0; irelax " << endl; + exit(0); + } + char* in_file = argv[1]; + ParmParse pp(argc-2,argv+2,NULL,in_file); + + SolveParams params; + parseInputs(params); + + multigridSolve(params); + } + //end scoping trick + +#ifdef CH_MPI + dumpmemoryatexit(); + CH_TIMER_REPORT(); + MPI_Finalize(); +#endif + + return 0; + +} diff --git a/releasedExamples/Proto/Poisson/exec/mpi_run_anag.sh b/releasedExamples/Proto/Poisson/exec/mpi_run_anag.sh new file mode 100755 index 00000000..7fd0d4fa --- /dev/null +++ b/releasedExamples/Proto/Poisson/exec/mpi_run_anag.sh @@ -0,0 +1,23 @@ +#!/bin/csh -f +if ($#argv != 4) then + echo "Usage: mpirun_anag exec inputs threads procs" + exit 1 +endif + +set exec = $1 +set inputs = $2 +set threads = $4 +set procs = $4 +echo "executable name = $exec" +echo "input file name = $inputs" +echo "number of procs = $procs" +echo "number of threads = $threads" + +set command = "setenv OMP_NUM_THREADS $procs" +echo $command +$command + +set command = "mpirun -np $procs $exec $inputs" +echo $command +$command + diff --git a/releasedExamples/Proto/Poisson/exec/periodic.inputs b/releasedExamples/Proto/Poisson/exec/periodic.inputs new file mode 100644 index 00000000..70df7301 --- /dev/null +++ b/releasedExamples/Proto/Poisson/exec/periodic.inputs @@ -0,0 +1,21 @@ +#grid size (nx = ny=nz) +nx = 512 +do_file_output = 0 +use_dense_stencil = 1 +#max grid size in domain decomposition +max_grid = 32 +#maximum number of v cycles +max_iter = 27 +#set to 1 to turn off coarsening/refining steps of multigrid +relax_only = 0 +#number of smoothing iterations in relaxation +num_smooth = 4 +#physical size of the domain +domain_size = 1. +#factor by which to reduce the residual +tolerance = 1.0e-9 +#solving alpha I + beta lap = rhs +alpha = 0. +beta = 1. +#support of rhs (must be < 0.5*domain_size) +blob_rad = 0.2 diff --git a/releasedExamples/Proto/Poisson/exec/threadrun.sh b/releasedExamples/Proto/Poisson/exec/threadrun.sh new file mode 100755 index 00000000..3a004ce2 --- /dev/null +++ b/releasedExamples/Proto/Poisson/exec/threadrun.sh @@ -0,0 +1,36 @@ +#!/bin/csh -f +if ($#argv != 5) then + echo "Usage: threadrun minthread maxthread timedir exec inputs " + exit 1 +endif + +set minProcs = $1 +set maxProcs = $2 + +set timedir = $3 +set exec = $4 +set inputs = $5 + +set procs = $minProcs +echo "executable name = $exec" +echo "input file name = $inputs" +echo "time directory = $timedir" + +if (! -e $timedir) then + mkdir $timedir +endif + +while ($procs <= $maxProcs) + echo "number of threads = $procs" + echo "setenv OMP_NUM_THREADS $procs" + setenv OMP_NUM_THREADS $procs + echo "$exec $inputs" + $exec $inputs + set pprocs = `echo $procs | awk '{printf("%06d",$1);}'` + echo "mv time.table $timedir/amrg.time.$pprocs.thread" + mv time.table $timedir/amrg.time.$pprocs.thread + +# echo $dir + + set procs = `expr 1 + $procs` +end diff --git a/releasedExamples/Proto/Poisson/src/SGMultigrid.H b/releasedExamples/Proto/Poisson/src/SGMultigrid.H new file mode 100644 index 00000000..4f271c40 --- /dev/null +++ b/releasedExamples/Proto/Poisson/src/SGMultigrid.H @@ -0,0 +1,188 @@ +#ifdef CH_LANG_CC +/* + * _______ __ + * / ___/ / ___ __ _ / / ___ + * / /__/ _ \/ _ \/ V \/ _ \/ _ \ + * \___/_//_/\___/_/_/_/_.__/\___/ + * Please refer to Copyright.txt, in Chombo's root directory. + */ +#endif + +#ifndef _SGMULTIGRID_H_ +#define _SGMULTIGRID_H_ + +#include +#include +#include "Proto.H" +#include "LevelData.H" +#include "Copier.H" +#include "BaseFab.H" + +#if DIM==2 +#define MG_NUM_COLORS 4 +#else +#define MG_NUM_COLORS 8 +#endif + +using Proto::Stencil; +using Proto::Point; +using std::array; +/// Multigrid: solve a FV discretization of Poisson's equation on a rectangle. periodic boundary conditions. +class SGMultigridLevel +{ +public: + + /// called from the finest level + SGMultigridLevel(const double & a_alpha, + const double & a_beta, + const double & a_dx, + const DisjointBoxLayout & a_grids, + bool useDenseStencil); + + + /// + ~SGMultigridLevel() + { + } + + /// + void residual(LevelData & a_res, + const LevelData & a_phi, + const LevelData & a_rhs); + + + /// + void relax(LevelData & a_phi, + const LevelData& a_rhs); + + + /// average down residual to next coarser level. + void restrictResidual(LevelData & a_resc, + const LevelData& a_res); + + /// Piecewise constant interpolation of coarse correction to increment fine solution. + void prolongIncrement(LevelData & a_phiFine, + const LevelData& a_deltaCoarse); + + + /// + void applyOp(LevelData & a_lph, + const LevelData & a_phi); + + /// Multigrid v-cycle. + void vCycle(LevelData & a_phi, + const LevelData& a_rhs); + + void + enforceBoundaryConditions(const LevelData& a_phi) + { + CH_TIME("enforce_bcs"); + LevelData& phi = const_cast& >(a_phi); + phi.exchange(m_exchangeCopier); + } + + std::shared_ptr m_coarser; + +private: + void defineStencils(); + void defineCoarserObjects(); + void getMultiColors(); + + /// weak construction introduces unnecessary complications + SGMultigridLevel() + { + } + + bool m_useDenseStencil; + bool m_hasCoarser; //not strictly necessary--could check the pointer + double m_alpha; + double m_beta; + double m_dx; + DisjointBoxLayout m_grids; + Copier m_exchangeCopier; + double m_lambda; //relaxation coeff + array s_colors; + Stencil m_negoperator; //always need -Lap(phi) + Stencil m_restrict; + + array, MG_NUM_COLORS> m_relaxOpPhi; + array, MG_NUM_COLORS> m_updateOpPhi; + array, MG_NUM_COLORS> m_relaxOpRhs; + array, MG_NUM_COLORS> m_prolong; + + LevelData m_resid; + LevelData m_residC; + LevelData m_deltaC; + // for flop counts + unsigned long long int numPointsThisProc(const DisjointBoxLayout& a_dbl) const + { + unsigned long long int retval = a_dbl.numPointsThisProc(); + return retval; + } + unsigned long long int m_numPointsThisProc; // for flop counts +}; + + +///class that outsiders actually call +class SGMultigrid +{ +public: + static int s_numSmoothDown ; + static int s_numSmoothUp ; + static int s_numSmoothBottom; + + /// + SGMultigrid(const double & a_alpha, + const double & a_beta, + const double & a_dx, + const DisjointBoxLayout & a_grids, + bool a_useDenseStencil); + + /// + void residual(LevelData & a_res, + const LevelData & a_phi, + const LevelData & a_rhs); + + /// + void applyOp(LevelData & a_lph, + const LevelData & a_phi); + + /// Multigrid v-cycle. + void vCycle(LevelData & a_phi, + const LevelData& a_rhs); + + /// average down residual to next coarser level. + void restrictResidual(LevelData & a_resc, + const LevelData& a_res) + { + m_finest->m_coarser->restrictResidual(a_resc, a_res); + } + + /// Piecewise constant interpolation of coarse correction to increment fine solution. + void prolongIncrement(LevelData & a_phiFine, + const LevelData& a_deltaCoarse) + { + m_finest->m_coarser->prolongIncrement(a_phiFine, a_deltaCoarse); + } + + /// + void relax(LevelData & a_phi, + const LevelData& a_rhs) + { + m_finest->relax(a_phi, a_rhs); + } + /// + void + enforceBoundaryConditions(LevelData& a_phi) + { + m_finest->enforceBoundaryConditions(a_phi); + } +private: + /// weak construction introduces unnecessary complications + SGMultigrid() + { + } + + std::shared_ptr m_finest; +}; +#endif diff --git a/releasedExamples/Proto/Poisson/src/SGMultigrid.cpp b/releasedExamples/Proto/Poisson/src/SGMultigrid.cpp new file mode 100644 index 00000000..27b4b346 --- /dev/null +++ b/releasedExamples/Proto/Poisson/src/SGMultigrid.cpp @@ -0,0 +1,387 @@ +#ifdef CH_LANG_CC +/* + * _______ __ + * / ___/ / ___ __ _ / / ___ + * / /__/ _ \/ _ \/ V \/ _ \/ _ \ + * \___/_//_/\___/_/_/_/_.__/\___/ + * Please refer to Copyright.txt, in Chombo's root directory. + */ +#endif + +#include "SGMultigrid.H" +#include "Proto.H" +#include "ProtoInterface.H" +#include "BoxLayout.H" + +int SGMultigrid::s_numSmoothDown = 2; +int SGMultigrid::s_numSmoothUp = 2; +int SGMultigrid::s_numSmoothBottom = 16; +typedef Proto::Box Bx; +using Proto::BoxData; +using Proto::Stencil; +using Proto::Shift; +/****/ +void +SGMultigridLevel:: +applyOp(LevelData & a_lph, + const LevelData & a_phi) + +{ + enforceBoundaryConditions(a_phi); + { + CH_TIME("sgmg::applyop_no_comm"); + DataIterator dit = m_grids.dataIterator(); +#pragma omp parallel for + for(int ibox = 0; ibox < dit.size(); ibox++) + { + Bx grid = ProtoCh::getProtoBox(m_grids[dit[ibox]]); + BoxData lphbd, phibd; + ProtoCh::aliasBoxData(lphbd, a_lph[dit[ibox]]); + ProtoCh::aliasBoxData(phibd, a_phi[dit[ibox]]); + + lphbd |= m_negoperator(phibd, grid); + lphbd *= -1.0; + } + ch_flops() += 3*m_numPointsThisProc*m_negoperator.size(); + } +} +/****/ +void +SGMultigrid:: +applyOp(LevelData & a_lph, + const LevelData & a_phi) +{ + return m_finest->applyOp(a_lph, a_phi); +} +/***/ +SGMultigrid:: +SGMultigrid(const double & a_alpha, + const double & a_beta, + const double & a_dx, + const DisjointBoxLayout & a_grids, + bool a_useDenseStencil) +{ + m_finest = std::shared_ptr(new SGMultigridLevel(a_alpha, a_beta, a_dx, a_grids, a_useDenseStencil)); +} +/***/ +void +SGMultigrid:: +residual(LevelData & a_res, + const LevelData & a_phi, + const LevelData & a_rhs) +{ + CH_TIME("sgmg::resid"); + return m_finest->residual(a_res, a_phi, a_rhs); +} +/***/ +void +SGMultigrid:: +vCycle(LevelData & a_phi, + const LevelData & a_rhs) +{ + CH_TIME("sgmg::vcycle"); + return m_finest->vCycle(a_phi, a_rhs); +} +/***/ +void +SGMultigridLevel:: +getMultiColors() +{ +// Color offsets are grouped into "red"=even number of nonzeros (first 2^(DIM-1)) +// and "black= odd number of nonzeros (the rest). +#if DIM==2 + s_colors[0] = Point::Zeros();//(0,0) + s_colors[1] = Point::Ones();//(1,1) + s_colors[2] = Point::Zeros() + Point::Basis(1);//(0,1) + s_colors[3] = Point::Zeros() + Point::Basis(0);//(1,0) +#elif DIM==3 + s_colors[0] = Point::Zeros();//(0,0,0) + s_colors[1] = Point::Zeros() + Point::Basis(0) + Point::Basis(1);//(1,1,0) + s_colors[2] = Point::Zeros() + Point::Basis(1) + Point::Basis(2);//(0,1,1) + s_colors[3] = Point::Zeros() + Point::Basis(0) + Point::Basis(2);//(1,0,1) + s_colors[4] = Point::Zeros() + Point::Basis(1);//(0,1,0) + s_colors[5] = Point::Zeros() + Point::Basis(0);//(1,0,0) + s_colors[6] = Point::Zeros() + Point::Basis(2);//(0,0,1) + s_colors[7] = Point::Ones();//(1,1,1) +#else + compiler_error_this_code_is_only_written_for_dim_2_or_3(); +#endif +} +/***/ +SGMultigridLevel:: +SGMultigridLevel(const double & a_alpha, + const double & a_beta, + const double & a_dx, + const DisjointBoxLayout & a_grids, + bool a_useDenseStencil) +{ + m_alpha = a_alpha; + m_beta = a_beta; + m_dx = a_dx; + m_grids = a_grids; + m_useDenseStencil = a_useDenseStencil; + m_exchangeCopier.exchangeDefine(m_grids, IntVect::Unit); + m_resid.define(m_grids,1, IntVect::Zero); + m_numPointsThisProc = numPointsThisProc(a_grids); + + defineStencils(); + + defineCoarserObjects(); +} +/***/ +void +SGMultigridLevel:: +defineCoarserObjects() +{ + CH_TIME("sgmglevel::defineCoarser"); + if(m_grids.coarsenable(4)) + { + DisjointBoxLayout gridsCoar; + coarsen(gridsCoar, m_grids, 2); + m_residC.define(gridsCoar, 1, IntVect::Zero); + m_deltaC.define(gridsCoar, 1, IntVect::Unit); + m_coarser = std::shared_ptr(new SGMultigridLevel(m_alpha, m_beta, 2*m_dx, gridsCoar, m_useDenseStencil)); + m_hasCoarser = true; + } + else + { + m_hasCoarser= false; + } +} +/***/ +void +SGMultigridLevel:: +defineStencils() +{ + CH_TIME("sgmglevel::definestencils"); + getMultiColors(); + + //always need -lapl(phi) so store that. + if((m_useDenseStencil) && (DIM > 1) && (DIM < 4)) + { +#if DIM==2 + m_negoperator = (-m_alpha)*Shift(Point::Zeros()) + (-m_beta/(m_dx*m_dx))*(Stencil::Laplacian_9()); +#else + m_negoperator = (-m_alpha)*Shift(Point::Zeros()) + (-m_beta/(m_dx*m_dx))*(Stencil::Laplacian_27()); +#endif + } + else + { + m_negoperator = (-m_alpha)*Shift(Point::Zeros()) + (-m_beta/(m_dx*m_dx))*(Stencil::Laplacian()); + } + +// cout << "2/dx/dx = " << 2./m_dx/m_dx << ", 1/dx/dx=" << 1./m_dx/m_dx << ", neg operator = "; +// m_negoperator.print(); + double safety = 1.0; + double diag = m_alpha + (m_beta*(-2.*DIM)/(m_dx*m_dx)); + m_lambda = safety/diag; + + + m_restrict = Stencil(); + double numpts = double(MG_NUM_COLORS); + for(int icolor = 0; icolor < MG_NUM_COLORS; icolor++) + { + m_relaxOpPhi[icolor] = (m_lambda)*m_negoperator; + m_relaxOpPhi[icolor] *= (1.0)*Shift(s_colors[icolor]); + + m_relaxOpRhs[icolor] = (m_lambda)*Shift(s_colors[icolor]); + m_updateOpPhi[icolor] = (1.0)*Shift(Point::Zeros()); + + m_relaxOpPhi[icolor].destRatio() = Point::Ones(1); + m_relaxOpPhi[icolor].srcRatio() = Point::Ones(2); + + m_updateOpPhi[icolor].destRatio() = Point::Ones(2); + m_updateOpPhi[icolor].srcRatio() = Point::Ones(1); + m_updateOpPhi[icolor].destShift() = s_colors[icolor]; + + m_relaxOpRhs[icolor].destRatio() = Point::Ones(1); + m_relaxOpRhs[icolor].srcRatio() = Point::Ones(2); + + m_prolong[icolor] = (1.0)*Shift(Point::Zeros()); + m_prolong[icolor].destRatio() = Point::Ones(2); + m_prolong[icolor].destShift() = s_colors[icolor]; + + m_restrict += (1.0/numpts)*Shift(s_colors[icolor]); + } + m_restrict.srcRatio() = Point::Ones(2); +} +/****/ +void +SGMultigridLevel:: +residual(LevelData & a_res, + const LevelData & a_phi, + const LevelData & a_rhs) + +{ + enforceBoundaryConditions(a_phi); + { + CH_TIME("sgmglevel::residual"); + DataIterator dit = m_grids.dataIterator(); +#pragma omp parallel for + for(int ibox = 0; ibox < dit.size(); ibox++) + { + Bx grid = ProtoCh::getProtoBox(m_grids[dit[ibox]]); + BoxData resbd, phibd, rhsbd; + ProtoCh::aliasBoxData(resbd, a_res[dit[ibox]]); + ProtoCh::aliasBoxData(rhsbd, a_rhs[dit[ibox]]); + ProtoCh::aliasBoxData(phibd, a_phi[dit[ibox]]); + resbd |= m_negoperator(phibd, grid); + resbd += rhsbd; + } + } +} +/****/ +void +SGMultigridLevel:: +relax(LevelData & a_phi, + const LevelData & a_rhs) +{ + CH_TIME("sgmglevel::relax"); + // GSRB. As implemented here, only correct for second-order 5 / 7 point operators. + // To go to higher order, need to use full multicolor algorithm. + DataIterator dit = m_grids.dataIterator(); + if(m_useDenseStencil) + { + + for(int icolor =0; icolor < MG_NUM_COLORS; icolor++) + { + enforceBoundaryConditions(a_phi); + { + CH_TIME("smglevel::relax_one_multi_no_comm"); +#pragma omp parallel for + for(int ibox = 0; ibox < dit.size(); ibox++) + { + Bx grid = ProtoCh::getProtoBox(m_grids[dit[ibox]]); + BoxData rhsbd, phibd; + ProtoCh::aliasBoxData(rhsbd, a_rhs[dit[ibox]]); + ProtoCh::aliasBoxData(phibd, a_phi[dit[ibox]]); + Bx coarDom = grid.coarsen(2); + BoxData phisrc(coarDom); + //needs to be coarse domain because of the whole gsrb thing + phisrc |= m_relaxOpPhi[icolor](phibd, coarDom); + phisrc += m_relaxOpRhs[icolor](rhsbd, coarDom); + phibd += m_updateOpPhi[icolor](phisrc, coarDom); + } + } + } + } + else + { + // Loop over red, black colors. + for (int evenOdd=0;evenOdd < 2 ; evenOdd++) + { + enforceBoundaryConditions(a_phi); + { + CH_TIME("smglevel::relax_one_redblack_no_comm"); +#pragma omp parallel for + for(int ibox = 0; ibox < dit.size(); ibox++) + { + Bx grid = ProtoCh::getProtoBox(m_grids[dit[ibox]]); + BoxData rhsbd, phibd; + ProtoCh::aliasBoxData(rhsbd, a_rhs[dit[ibox]]); + ProtoCh::aliasBoxData(phibd, a_phi[dit[ibox]]); + Bx coarDom = grid.coarsen(2); + BoxData phisrc(coarDom); + // loop over 2^(DIM-1) coarsened domains in each color. + for(int icolor = evenOdd*MG_NUM_COLORS/2; icolor < evenOdd*MG_NUM_COLORS/2 + MG_NUM_COLORS/2; icolor++) + { + //needs to be coarse domain because of the whole gsrb thing + phisrc |= m_relaxOpPhi[icolor](phibd, coarDom); + phisrc += m_relaxOpRhs[icolor](rhsbd, coarDom); + phibd += m_updateOpPhi[icolor](phisrc, coarDom); + } + } + } + } + } + unsigned long long int stensize = m_relaxOpPhi.size() + m_relaxOpRhs.size() + m_updateOpPhi.size(); + ch_flops() += 3*m_numPointsThisProc*stensize; +} +/****/ +void +SGMultigridLevel:: +restrictResidual(LevelData & a_resc, + const LevelData & a_res) +{ + CH_TIME("sgmglevel::restrict"); + DataIterator dit = m_grids.dataIterator(); +#pragma omp parallel for + for(int ibox = 0; ibox < dit.size(); ibox++) + { + Bx grid = ProtoCh::getProtoBox(m_grids[dit[ibox]]); + BoxData rescbd, resfbd; + ProtoCh::aliasBoxData(rescbd, a_resc[dit[ibox]]); + ProtoCh::aliasBoxData(resfbd, a_res[dit[ibox]]); + //called by the coarser mg level + rescbd |= m_restrict(resfbd, grid); + } + ch_flops() += 3*m_numPointsThisProc*(m_restrict.size()); +} +/****/ +void +SGMultigridLevel:: +prolongIncrement(LevelData & a_phi, + const LevelData& a_delta) +{ + CH_TIME("sgmglevel::prolong"); + //called by the coarser mg level + DataIterator dit = m_grids.dataIterator(); + int nbox = dit.size(); + for(int icolor = 0; icolor < MG_NUM_COLORS; icolor++) + { +#pragma omp parallel for + for(int ibox = 0; ibox < nbox; ibox++) + { + Bx grid = ProtoCh::getProtoBox(m_grids[dit[ibox]]); + BoxData phibd, deltabd; + ProtoCh::aliasBoxData(phibd , a_phi[dit[ibox]]); + ProtoCh::aliasBoxData(deltabd, a_delta[dit[ibox]]); + phibd += m_prolong[icolor](deltabd, grid); + } + } + //prolong size = 1 per fine grid point + ch_flops() += 3*m_numPointsThisProc*MG_NUM_COLORS; + +} +/****/ +void +SGMultigridLevel:: +vCycle(LevelData & a_phi, + const LevelData & a_rhs) +{ + CH_TIME("sgmglevel::vcycle"); + for(int irelax = 0; irelax < SGMultigrid::s_numSmoothDown; irelax++) + { + relax(a_phi,a_rhs); + } + + if (m_hasCoarser) + { + residual(m_resid,a_phi,a_rhs); + m_coarser->restrictResidual(m_residC,m_resid); + + DataIterator dit = m_grids.dataIterator(); +#pragma omp parallel for + for(int ibox = 0; ibox < dit.size(); ibox++) + { + m_deltaC[dit[ibox]].setVal(0.); + } + + m_coarser->vCycle(m_deltaC,m_residC); + m_coarser->prolongIncrement(a_phi,m_deltaC); + } + else + { + for(int irelax = 0; irelax < SGMultigrid::s_numSmoothBottom; irelax++) + { + relax(a_phi,a_rhs); + } + } + + for(int irelax = 0; irelax < SGMultigrid::s_numSmoothUp; irelax++) + { + relax(a_phi,a_rhs); + } + +} +/****/