/*
** (c) 1996-2000 The Regents of the University of California (through
** E.O. Lawrence Berkeley National Laboratory), subject to approval by
** the U.S. Department of Energy.  Your use of this software is under
** license -- the license agreement is attached and included in the
** directory as license.txt or you may contact Berkeley Lab's Technology
** Transfer Department at TTD@lbl.gov.  NOTICE OF U.S. GOVERNMENT RIGHTS.
** The Software was developed under funding from the U.S. Government
** which consequently retains certain rights as follows: the
** U.S. Government has been granted for itself and others acting on its
** behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
** Software to reproduce, prepare derivative works, and perform publicly
** and display publicly.  Beginning five (5) years after the date
** permission to assert copyright is obtained from the U.S. Department of
** Energy, and subject to any subsequent five (5) year renewals, the
** U.S. Government is granted for itself and others acting on its behalf
** a paid-up, nonexclusive, irrevocable, worldwide license in the
** Software to reproduce, prepare derivative works, distribute copies to
** the public, perform publicly and display publicly, and to permit
** others to do so.
*/

#ifndef _MACPROJ_H_
#define _MACPROJ_H_

#include "multigrid.H"

//
//@Man:
//@Memo: Projection class for intermediate MAC projection
/*@ManDoc: This class handles the MAC projection of the intermediate
           edge-based advection velocity.  It computes RHS = D(V),
           and sends the RHS and coefficients sigma = 1/rho to the
           macprojection_mg class, which solves the linear system
           using multigrid.
*/

class mac_projector {

//@ManDoc: Problem domain broken up into multiple grids.
  BoxArray grids;

//@ManDoc: Geometry object.
  Geometry geom;

//@ManDoc: Area arrays.
  const MultiFab* area;

//@ManDoc: Volume arrays.
  const MultiFab& vol;

//@ManDoc: Tolerance to which DG(phi) = RHS should be solved
  Real tol;

//@ManDoc: Number of smoothing steps as you coarsen
  static int numSmoothCoarsen;

//@ManDoc: Number of smoothing steps as you refine
  static int numSmoothRefine;

//@ManDoc: Number of extra ghost cells.
  static int ng;

 public:

//@ManDoc: Constructor
  mac_projector(const BoxArray& grids, const Geometry& geom,
                MultiFab* area, MultiFab& volume);

//@ManDoc: Destructor
  ~mac_projector();

//@ManDoc: Do the MAC projection
  void project(MultiFab * uadv, 
               MultiFab * vadv, 
#if (BL_SPACEDIM == 3)
               MultiFab * wadv, 
#endif
               MultiFab * state,
               MultiFab * divu_src);
};

//@ManDoc: Multigrid solver for the intermediate MAC projection
class macprojection_mg : public multigrid {

//@Memo: Multigrid solver for MAC projection

//@ManDoc: Coefficient array.
  MultiFab * sigma[BL_SPACEDIM];

//@ManDoc: Next coarser multigrid level
  macprojection_mg *Next;

//@ManDoc: Scratch space for the conjugate gradient bottom solver.
  MultiFab *cgwork;

//@ManDoc: Compute the residual R = RHS - DG(phi).
  Real residual();

//@ManDoc: Relax on the residual equation, updating phi.
  void step(int);

//@ManDoc: Coarsen the residual to the next coarser multigrid level.
  void Restrict();

//@ManDoc: Interpolate the solution from the next coarser multigrid level.
  void interpolate();

 public:
  macprojection_mg(const BoxArray& Grids,
                   const Geometry& Geom,
                   MultiFab* Phi,
                   MultiFab* Source,
                   MultiFab* Residual,
                   MultiFab* Sigma[], 
                   const Real* Dx); 
  ~macprojection_mg();
};
#endif
