/*
** (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_
//
// $Id: MacProj.H,v 1.25 2003/02/06 19:07:22 almgren Exp $
//
#include <BC_TYPES.H>
#include <BCRec.H>
#include <Amr.H>
#include <AmrLevel.H>
#include <FluxRegister.H>
#include "Godunov.H"

class MacProj
{
public:
    
    MacProj (Amr*   parent,
             int    _finest_level,
             BCRec* _phys_bc, 
             int    _radius_grow );
    
    virtual ~MacProj ();
    void read_params ();
    
    void install_level (int           level, 
                        AmrLevel*     level_data,
                        MultiFab&     volume,
                        MultiFab*     area,
                        PArray<Real>* _radius );
    
    void setup (int level);
    void cleanup (int level);
    //
    // The level advance mac projection.
    //
    void mac_project (int             level,
                      MultiFab*       u_mac,
                      MultiFab&       S,
                      Real            dt,
                      Real            prev_time,
                      const MultiFab& divu,
                      int             have_divu);

    void test_umac_periodic (int level, MultiFab* u_mac);
    //
    // The sync solve.
    //
    void mac_sync_solve (int       level,
                         Real      dt, 
                         MultiFab* rho_half,
                         IntVect&  fine_ratio);
    //
    // Computing the sync tendency.
    //
    void mac_sync_compute (int                   level,
                           MultiFab*             u_mac, 
                           MultiFab*             Vsync,
                           MultiFab*             Ssync,
                           MultiFab*             rho_half, 
                           FluxRegister*         adv_flux_reg,
                           Array<AdvectionForm>& advectionType,
                           Real                  prev_time,
                           Real                  prev_pres_time,
                           Real                  dt,
                           int                   NUM_STATE,
                           Real                  be_cn_theta,
                           bool                  modify_reflux_normal_vel,
                           int		         do_mom_diff,
                           const Array<int>&     increment_sync = Array<int>());

    void mac_sync_compute (int                   level,
                           MultiFab*             Sync,
                           int                   comp,
                           int                   s_ind,
                           const MultiFab*       const* sync_edges,
			   int                   eComp,
                           MultiFab*             rho_half,
                           FluxRegister*         adv_flux_reg,
                           Array<AdvectionForm>& advectionType,
                           bool		         modify_reflux_normal_vel,
                           Real                  dt);
protected:
    //
    // Test the divergence constraint.
    //
    void check_div_cond (int      level,
                         MultiFab U_edge[]) const;
    //
    // Boundary conditions.
    //
    void BuildPhiBC (int level);

    void set_outflow_bcs (int level,
                          MultiFab* mac_phi,
                          const MultiFab* u_mac, 
                          const MultiFab& S,
                          const  MultiFab& divu);
    //
    // Pointers to amr,amrlevel.
    //
    Amr*             parent;
    PArray<AmrLevel> LevelData;
    //
    // Boundary condition objects.
    //
    BCRec*                phys_bc;
    Array< Array<BCRec> > phi_bcs;
    //
    // MAC sync correction and solution.
    //
    PArray<MultiFab>     mac_phi_crse;
    PArray<FluxRegister> mac_reg;
    //
    // Volume and area fractions.
    //
    PArray<MultiFab> volume;
    Array<MultiFab*> area;
    //
    // Radius data.
    //
    int                    radius_grow;
    PArray< PArray<Real> > radius;
    //
    // Parameters.
    //
    int        finest_level;
    int        finest_level_allocated;

    static int  verbose;
    static bool  use_cg_solve;
    static int  do_outflow_bcs;
    static Real mac_tol;
    static Real mac_abs_tol;
    static Real mac_sync_tol;
    static int  check_umac_periodicity;

#if 1
// this code should go away when Marc makes this option
// part of the multigrid code--rbp, 2/13/97
    static int fix_mac_sync_rhs;
#endif
};

#endif
