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

//
// $Id: SyncRegister.H,v 1.17 2000/10/02 20:50:16 lijewski Exp $
//

#include <PArray.H>
#include <BoxArray.H>
#include <FArrayBox.H>
#include <MultiFab.H>
#include <Geometry.H>
#include <BndryRegister.H>
#include <BCRec.H>

class SyncRegister
    :
    public BndryRegister
{
public:
    SyncRegister ();

    SyncRegister (const BoxArray& fine_boxes,
                  const IntVect&  ref_ratio,
                  int             fine_lev);

    ~SyncRegister ();

    void define (const BoxArray& fine_boxes,
                 const IntVect&  ref_ratio,
                 int             fine_lev);
    //
    // Access functions.
    //
    IntVect refRatio () const { return ratio; }

    int fineLevel () const { return fine_level; }

    int crseLevel () const { return fine_level-1; }

    const BoxArray& coarsenedBoxes () const { return grids; }

    void CrseInit (MultiFab*    Sync_resid_crse,
                   const Geometry&    crse_geom,
                   Real               mult);

    void FineAdd  (MultiFab*    Sync_resid_crse,
                   const Geometry&    fine_geom,
                   const Geometry&    crse_geom,
                   const BCRec*       phys_bc,
                   Real               mult);

    void CompAdd  (MultiFab*    Sync_resid_crse,
                   const Geometry&    fine_geom,
                   const Geometry&    crse_geom,
                   const BCRec*       phys_bc,
                   const BoxArray&    Pgrids,
                   Real               mult);

    void InitRHS (MultiFab&       rhs,
                  const Geometry& geom,
                  const BCRec*    phys_bc);
    //
    // Compute sum of values (overlap values only counted once).
    // WARNING: this is a diagnostic and is not efficient.
    //
    Real sum ();

protected:
    //
    // Helper member functions.
    //
    void incrementPeriodic (const Geometry& geom,
                            const Box&      domain,
                            const MultiFab& mf);

    void copyPeriodic (const Geometry& geom,
                       const Box&      domain,
                       MultiFab&       rhs) const;

    void multByBndryMask (MultiFab& rhs) const;
    //
    // The data.
    //
    FabSet  bndry_mask[2*BL_SPACEDIM];
    IntVect ratio;
    int     fine_level;
};

#endif /*_SYNCREGISTER_H_*/
