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

//
// $Id: BndryRegister.H,v 1.10 2001/08/01 21:50:47 lijewski Exp $
//

#include <BoxArray.H>
#include <FabSet.H>

class Orientation;

//@Man:
/*@Memo:
        A BndryRegister organizes FabSets bounding each grid in a BoxArray.
        A FabSet is maintained for each boundary orientation, as well as
        the BoxArray domain of definition.
*/        
/*@Doc:
        A BndryRegister object contains a list of FabSets bounding the grids
        in a BoxArray.  The FabSet FABs are at the same refinement level
        as the grids they bound, and are accessed and modified via a variety
        of member functions.

        Non-default instantiation allocates a set of FABs, grown into and
        out of the bounding surfaces of each box in the BoxArray.  The width of
        the layer (in/out), as well as the "extent" of a bounding FABs (the
        number of nodes beyond the box boundaries, parallel to the grid
        surface) are determined by constructor argument.  All boxes and
        FABs in this context are assumed to be cell-centered.

        A small number of linear mathematical operations are provided for
        BndryRegisters, as well as overloaded [] operators for access based
        on grid boundary orientation.  The BoxArray domain of definition is
        accessible, but not resettable,
*/

class BndryRegister
{

public:
    //
    //@ManDoc: The default constructor.
    //
    BndryRegister ();
    //
    //@ManDoc: The constructor, given number of cells in/out, extent and number of components (assumes cell-centered boxes, and allocates cell-centered FABs)
    //
    BndryRegister (const BoxArray& grids,
                   int             in_rad,
                   int             out_rad,
                   int             extent_rad,
                   int             ncomp);
    //
    //@ManDoc: The copy constructor.
    //
    BndryRegister (const BndryRegister& src);
    //
    //@ManDoc: The copy assignment operator.
    //
    BndryRegister& operator= (const BndryRegister& src);
    //
    //@ManDoc: The destructor.
    //
    virtual ~BndryRegister();
    //
    //@ManDoc: Get box domain (as an array of boxes).
    //
    const BoxArray& boxes () const;
    //
    //@ManDoc: Return the number of grids in this domain.
    //
    int size () const;
    //
    //@ManDoc: Return const set of FABs bounding the domain grid boxes on a given orientation
    //
    const FabSet& operator[] (const Orientation& face) const;
    //
    //@ManDoc: Return set of FABs bounding the domain grid boxes on a given orientation
    //
    FabSet& operator[] (const Orientation& face);
    //
    //@ManDoc: Set all boundary FABs to given value.
    //
    void setVal (Real v);
    //
    //@ManDoc: Fill the boundary FABs on intersection with given MultiFab.
    //
    BndryRegister& copyFrom (const MultiFab& src,
                             int             nghost,
                             int             src_comp,
                             int             dest_comp,
                             int             num_comp);
    //
    //@ManDoc: Increment the boundary FABs on intersect with given MultiFab.
    //
    BndryRegister& plusFrom (const MultiFab& src,
                             int             nghost,
                             int             src_comp,
                             int             dest_comp,
                             int             num_comp);
    //
    //@ManDoc: Linear combination: this := a*mfa + b*mfb on intersection of MultiFabs with the boundary FABs
    //
    BndryRegister& linComb (Real            a,
                            const MultiFab& mfa,
                            int             a_comp,
                            Real            b,
                            const MultiFab& mfb,
                            int             b_comp,
                            int             dest_comp,
                            int             num_comp,
                            int             n_ghost = 0);
    //
    //@ManDoc: Set box domain, if not set previously.
    //
    void setBoxes (const BoxArray& grids);
    //
    //@ManDoc: Build FABs along given face.
    //
    void define (const Orientation& face,
                 const IndexType&   typ,
                 int                in_rad,
                 int                out_rad,
                 int                extent_rad,
                 int                ncomp);
protected:
    //
    // Used by the copy constructor and assignment operator.
    //
    void init (const BndryRegister& src);
    //
    // The data.
    //
    FabSet    bndry[2*BL_SPACEDIM];
    BoxArray  grids;
};

#endif /*_BNDRYREGISTER_H_*/
