/*
** (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.
*/


#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: Un-buffered grid box
  Box domain;

//@ManDoc: Mesh spacing in x-direction
  Real _hx;

//@ManDoc: Mesh spacing in y-direction
  Real _hy;

//@ManDoc: Mesh spacing in z-direction
  Real _hz;

//@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;

 public:

//@ManDoc: Constructor
  mac_projector(const Box& Domain, Real * dx);

//@ManDoc: Destructor
  ~mac_projector();

//@ManDoc: Do the MAC projection
  void project(Real * uadv, 
               Real * vadv, 
               Real * wadv, 
               Real * rho,
               FArrayBox& divu_src);
};

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

//@Memo: Multigrid solver for MAC projection

//@ManDoc: Coefficient array on x-edges
  FArrayBox * sigmax;

//@ManDoc: Coefficient array on y-edges
  FArrayBox * sigmay;

//@ManDoc: Coefficient array on z-edges
  FArrayBox * sigmaz;

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

//@ManDoc: Scratch space for the conjugate gradient bottom solver
  FArrayBox *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 Box& Domain,
                   FArrayBox * Phi,
                   FArrayBox * Source,
                   FArrayBox * Residual,
                   FArrayBox * Sigmax, 
                   FArrayBox * Sigmay, 
                   FArrayBox * Sigmaz, 
                   Real Hx, 
                   Real Hy, 
                   Real Hz);
  ~macprojection_mg();
};
