/*
** (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 _OUTFLOWBC_H_
#define _OUTFLOWBC_H_

//
// $Id: OutFlowBC.H,v 1.6 2003/02/21 22:49:10 car Exp $
//

#include "FArrayBox.H"
#include "Geometry.H"
#include "Orientation.H"
#include "BCRec.H"

enum OutFlow_Solver_Type
{
    BC_BACK, // back substitution
    BC_MG    // multigrid
};

//
// The baseclass for MacOutFlowBC and ProjOutFlowBC.
//

class OutFlowBC
{
public:

    OutFlowBC ();

    virtual ~OutFlowBC ();

    virtual void computeBC (FArrayBox         velMF[][2*BL_SPACEDIM],
                            FArrayBox         divuMF[2*BL_SPACEDIM],
                            FArrayBox         rhoMF[2*BL_SPACEDIM],
                            FArrayBox         phiMF[2*BL_SPACEDIM],
                            const Geometry&    geom,
                            Orientation*       outFaces,
                            int                numOutFlowFaces,
                            Real               gravity = 0.0) = 0;

    static Box SemiGrow (const Box& baseBox,
                         int        nGrow,
                         int        direction);

    static Box SemiCoarsen (const Box& baseBox,
                            int        ref_factor,
                            int        direction);

    static void GetOutFlowFaces (bool&        haveOutFlow,
                                 Orientation* outFaces,
                                 BCRec*       _phys_bc,
                                 int&         numOutFlowFaces);

    static bool HasOutFlowBC (BCRec* _phys_bc);

protected:
};

//
// The baseclass for MacOutFlowBC_MG and ProjOutFlowBC_MG
//

class OutFlowBC_MG 
{
public:

    OutFlowBC_MG (const Box& Domain,
                  FArrayBox* Phi,
                  FArrayBox* Rhs,
                  FArrayBox* Resid,
                  FArrayBox* Beta,
                  Real*      H,
                  int*       IsPeriodic,
                  bool       is_scalar);

    virtual ~OutFlowBC_MG ();

    void solve (Real tol,
                Real abs_tol,
                int  i1,
                int  i2,
                int  maxIters,
                int  verbose);

    Real vcycle (int i1, int i2);

    const Box& theDomain () const { return domain; }

    FArrayBox* theRhs () { return rhs; }

    FArrayBox* thePhi () { return phi; }

protected:

    virtual void Restrict ()       = 0;
    virtual void interpolate ()    = 0;
    virtual Real residual ()       = 0;
    virtual void step (int nSteps) = 0;
    virtual void gsrb (int nSteps) = 0;
    //
    // The per-object data
    //
    Box           domain;
    FArrayBox*    phi;
    FArrayBox*    rhs;
    FArrayBox*    resid;
    FArrayBox*    cgwork;
    FArrayBox*    beta;
    Real          h[BL_SPACEDIM];
    int           isPeriodic[BL_SPACEDIM];
    OutFlowBC_MG* next;
    bool          beta_is_scalar;
};

#endif /*_OUTFLOWBC_H_*/

