#ifndef ALLVARS 
#define ALLVARS


#define  MAXTOPNODES     200000
#define  MAX_REAL_NUMBER  1e37
#define  BITS_PER_DIMENSION 18
#define  PEANOCELLS (((peanokey)1)<<(3*BITS_PER_DIMENSION))


#define TOPNODEFACTOR  20.0
#define REDUC_FAC      0.98

#define NTAB 1000

#define TAG_N             10      /*!< Various tags used for labelling MPI messages */ 
#define TAG_HEADER        11
#define TAG_PDATA         12
#define TAG_SPHDATA       13
#define TAG_KEY           14
#define TAG_DMOM          15
#define TAG_NODELEN       16
#define TAG_HMAX          17
#define TAG_GRAV_A        18
#define TAG_GRAV_B        19
#define TAG_DIRECT_A      20
#define TAG_DIRECT_B      21
#define TAG_HYDRO_A       22 
#define TAG_HYDRO_B       23
#define TAG_NFORTHISTASK  24
#define TAG_PERIODIC_A    25
#define TAG_PERIODIC_B    26
#define TAG_PERIODIC_C    27
#define TAG_PERIODIC_D    28
#define TAG_NONPERIOD_A   29 
#define TAG_NONPERIOD_B   30
#define TAG_NONPERIOD_C   31
#define TAG_NONPERIOD_D   32
#define TAG_POTENTIAL_A   33
#define TAG_POTENTIAL_B   34
#define TAG_DENS_A        35
#define TAG_DENS_B        36
#define TAG_LOCALN        37



typedef  long long  peanokey;


#define FLOAT float

struct particle_data
{
  FLOAT Pos[3];			/*!< particle position at its current time */
  FLOAT Mass;			/*!< particle mass */
  FLOAT Vel[3];			/*!< particle velocity at its current time */
  FLOAT GravAccel[3];		/*!< particle acceleration due to gravity */
  FLOAT Potential;		/*!< gravitational potential */
  FLOAT OldAcc;			/*!< magnitude of old gravitational force. Used in relative opening criterion */
  int Type;		        /*!< flags particle type.  0=gas, 1=halo, 2=disk, 3=bulge, 4=stars, 5=bndry */
  int Ti_endstep;               /*!< marks start of current timestep of particle on integer timeline */ 
  int Ti_begstep;               /*!< marks end of current timestep of particle on integer timeline */
  FLOAT Density;
  FLOAT Observable;
  unsigned int ID;
};


struct sph_particle_data
{
  FLOAT Density;
  FLOAT Hsml; 
};


struct global_data_all_processes
{
  
  long long TotNumPart;
  long long TotN_gas;  
  
  int MaxPart;
  int MaxPartSph;
  double SofteningTable[6];
  double ForceSoftening[6];
  
  double PartAllocFactor;
  double TreeAllocFactor;
  
  double ErrTolTheta;
  
  int DesNumNgb;
  int MaxNumNgbDeviation;
  
  double MinGasHsmlFractional;
  double MinGasHsml;
  
  
  int BufferSize;	
  int BunchSizeForce;	
  int BunchSizeDensity;  
  int BunchSizeHydro;	 
  int BunchSizeDomain;     
  
  double G;
  double OmegaLambda;
  double Omega0;
  double Hubble;
  
  /* new parameters (yr) */
  int OutputInfo;
  int PeanoHilbertOrder;
  
  int ComovingIntegrationOn;
  int PeriodicBoundariesOn;
  
  int TypeOfOpeningCriterion;
  double ErrTolForceAcc;
  
};


struct topnode_exchange
{
  peanokey Startkey;
  int Count;
};

struct topnode_data
{
  int Daughter;                   /*!< index of first daughter cell (out of 8) of top-level node */
  int Pstart;                     /*!< for the present top-level node, this gives the index of the first node in the concatenated list of topnodes collected from all processors */
  int Blocks;                     /*!< for the present top-level node, this gives the number of corresponding nodes in the concatenated list of topnodes collected from all processors */
  int Leaf;                       /*!< if the node is a leaf, this gives its number when all leaves are traversed in Peano-Hilbert order */
  peanokey Size;                  /*!< number of Peano-Hilbert mesh-cells represented by top-level node */
  peanokey StartKey;              /*!< first Peano-Hilbert key in top-level node */
  long long Count;                /*!< counts the number of particles in this top-level node */
};


struct DomainNODE
{
  FLOAT s[3];                     /*!< center-of-mass coordinates */
  FLOAT vs[3];                    /*!< center-of-mass velocities */
  FLOAT mass;                     /*!< mass of node */
#ifdef UNEQUALSOFTENINGS
#ifndef ADAPTIVE_GRAVSOFT_FORGAS
  int   bitflags;                 /*!< this bit-field encodes the particle type with the largest softening among the particles of the nodes, and whether there are particles with different softening in the node */
#else
  FLOAT maxsoft;                  /*!< hold the maximum gravitational softening of particles in the 
                                       node if the ADAPTIVE_GRAVSOFT_FORGAS option is selected */
#endif
#endif
};



struct peano_hilbert_data
{
  peanokey key;
  int index;
};


struct NODE
{
  FLOAT len;			/*!< sidelength of treenode */
  FLOAT center[3];		/*!< geometrical center of node */
#ifdef ADAPTIVE_GRAVSOFT_FORGAS
  FLOAT maxsoft;                /*!< hold the maximum gravitational softening of particles in the 
                                     node if the ADAPTIVE_GRAVSOFT_FORGAS option is selected */
#endif
  union
  {
    int suns[8];		/*!< temporary pointers to daughter nodes */
    struct
    {
      FLOAT s[3];               /*!< center of mass of node */
      FLOAT mass;               /*!< mass of node */
      int bitflags;             /*!< a bit-field with various information on the node */
      int sibling;              /*!< this gives the next node in the walk in case the current node can be used */
      int nextnode;             /*!< this gives the next node in case the current node needs to be opened */
      int father;               /*!< this gives the parent node of each node (or -1 if we have the root node) */
    }
    d;
  }
  u;
};



struct extNODE 
{
  FLOAT hmax;	
  FLOAT vs[3];	
};
       

struct particle_IdProc 
{
  unsigned int ID;	
  unsigned int Proc;
};



struct gravdata_index
{
  int Task;
  int Index;
  int SortIndex;
};


struct gravdata_in
{
  union
  {
    FLOAT Pos[3];
    FLOAT Acc[3];
    FLOAT Potential;
  }
  u;
#ifdef UNEQUALSOFTENINGS
  int Type;
#ifdef ADAPTIVE_GRAVSOFT_FORGAS
  FLOAT Soft;
#endif
#endif
  union
  {
    FLOAT OldAcc;
    int Ninteractions;
  }
  w;
};

       
#endif
