/*
** (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 _FLUXREGISTER_H_
#define _FLUXREGISTER_H_
//
// $Id: FluxRegister.H,v 1.13 2002/11/14 07:08:32 marc Exp $
//
#include <BndryRegister.H>

class Geometry;

//
//@Man:
//@Memo: Flux Register.
/*@Doc:

  Stores and manipulates fluxes at coarse-fine interfaces.
*/

class FluxRegister
    :
    public BndryRegister
{
public:
    //
    //@ManDoc: The default constructor.
    //
    FluxRegister();

    /*@ManDoc: The constructor.
               Note that this takes the fine BoxArray.
    */
    FluxRegister (const BoxArray& fine_boxes, 
                  const IntVect&  ref_ratio,
                  int             fine_lev,
                  int             nvar);
    //
    //@ManDoc: The destructor.
    //
    virtual ~FluxRegister ();

    //
    //@ManDoc: An enum that says whether to add or copy src data to members.
    //
    enum FrOp {COPY = 0, ADD = 1};

    /*@ManDoc: Initialize after using default constructor.
               Note that this takes the fine BoxArray.
    */
    virtual void define (const BoxArray& fine_boxes, 
                         const IntVect&  ref_ratio,
                         int             fine_lev,
                         int             nvar);
    //
    //@ManDoc: Returns the refinement ratio.
    //
    const IntVect& refRatio () const;
    //
    //@ManDoc: Returns the level number of the fine level.
    //
    int fineLevel () const;
    //
    //@ManDoc: Returns the level number of the coarse level (fineLevel()-1).
    //
    int crseLevel () const;
    //
    //@ManDoc: The number of components.
    //
    int nComp () const;
    //
    //@ManDoc: The coarsened boxes.
    //
    const BoxArray& coarsenedBoxes () const;
    //
    //@ManDoc: Returns the sum of the registers.
    //
    Real SumReg (int comp) const;
    //
    //@ManDoc: Copy from flux register to FAB `flx'.
    //
    void copyTo (FArrayBox& flx,
                 int        dir,
                 int        src_comp,
                 int        dest_comp,
                 int        num_comp);
    //
    //@ManDoc: flx = flx + mult*register.
    //
    void addTo (FArrayBox& flx,
                int        dir,
                Real       mult,
                int        src_comp,
                int        dest_comp,
                int        num_comp);
    //
    //@ManDoc: mf = fm + mult*register.
    //
    void addTo (MultiFab& mf,
                int       dir,
                Real      mult,
                int       src_comp,
                int       dest_comp,
                int       num_comp);
    //
    //@ManDoc: Initialize flux correction with coarse data.
    //
    void CrseInit (const MultiFab& mflx,
                   const MultiFab& area,
                   int             dir,
                   int             srccomp,
                   int             destcomp,
                   int             numcomp,
                   Real            mult = -1.0,
                   FrOp            op = FluxRegister::COPY);
    //
    //@ManDoc: Initialize flux correction with coarse data. 
    //
    void CrseInit (const FArrayBox& flux,
                   const Box&       subbox,
                   int              dir,
                   int              srccomp,
                   int              destcomp,
                   int              numcomp,
                   Real             mult = -1.0,
                   FrOp             op = FluxRegister::COPY);
    //
    // This isn't documented  --  it's a parallel feature :-(
    //
    // It MUST be called after all CrseInit()s outside of
    // any implicit or explicit parallel loop.
    //
    void CrseInitFinish (FrOp op = FluxRegister::COPY);
    //
    //@ManDoc: Increment flux correction with fine data.
    //
    void FineAdd (const MultiFab& mflx,
                  int             dir, 
                  int             srccomp,
                  int             destcomp,
                  int             numcomp,
                  Real            mult);
    //
    //@ManDoc: Increment flux correction with fine data.
    //
    void FineAdd (const MultiFab& mflx,
                  const MultiFab& area,
                  int             dir, 
                  int             srccomp,
                  int             destcomp,
                  int             numcomp,
                  Real            mult);
    //
    //@ManDoc: Increment flux correction with fine data.
    //
    void FineAdd (const FArrayBox& flux,
                  int              dir,
                  int              boxno,
                  int              srccomp,
                  int              destcomp,
                  int              numcomp,
                  Real             mult);
    //
    //@ManDoc: Increment flux correction with fine data.
    //
    void FineAdd (const FArrayBox& flux,
                  const FArrayBox& area,
                  int              dir,
                  int              boxno,
                  int              srccomp,
                  int              destcomp,
                  int              numcomp,
                  Real             mult);
    //
    //@ManDoc: Apply flux correction.  Note that this takes the coarse Geometry.
    //
    void Reflux (MultiFab&       mf,
                 const MultiFab& volume,
                 Real            scale,
                 int             srccomp,
                 int             destcomp,
                 int             numcomp,
                 const Geometry& crse_geom);
    //
    //@ManDoc: Constant volume version of Reflux().  Note that this takes the coarse Geometry.
    //
    void Reflux (MultiFab&       mf,
                 Real            scale,
                 int             srccomp,
                 int             destcomp,
                 int             numcomp,
                 const Geometry& crse_geom);

protected:
    //
    // Refinement ratio
    //
    IntVect ratio;
    //
    // Current level + 1.
    //
    int fine_level;
    //
    // Number of state components.
    //
    int ncomp;
    //
    // Helper member function.
    //
    void increment (const FArrayBox& fab, int dir);
};

#endif /*_FLUXREGISTER_H_*/
