#-------------------------------------------------------------------
# makefile for use with GNU make, to make vine.  
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# This module is a component of VINE, copyright by the authors,    #
# as listed below. Please see the COPYING and LICENSE files        #
# in the parent directory for additional information.              #
# This notification is present as an attempt to follow the         #
# recommendations for licensing published on the FSF page.         # 
#-------------------------------------------------------------------


# Here is a list of the possible flags for the making of VINE. Most of 
# the flags are for simply enabling or disabling a feature, i.e. the flag
# is either set to 1 or 0, respectively. For those flags which have additional
# choices, these are explained below with the description of the flag.
#
#   MACHINE   : Select the architecture for which vine will be compiled.
#               Possible choices are as follows. Note that for intel/amd
#               chips, the definition parses to <compiler><chip>:
#
#               PGFAMD64     AMD64 CPUs, use of Portland Group Compiler
#               PATHAMD64    AMD64 CPUs, use of Pathscale Compiler
#               LAHEYAMD     AMD   CPUs, use of Lahey 32bit compiler
#               INTLPGF      Intel CPUs, use of Portland Group Compiler
#               INTLX86      Intel 32bit CPUs, use of Intel Fortran Compiler
#               INTLITAN     Intel Itanium CPUs, use of Intel Fortran Compiler
#               INTLC2DUO    Intel Core 2 Duo, use of Intel Fortran Compiler
#               INTLAMD64    AMD   64bit CPUs, use of Intel Fortran Compiler
#               IBM4         IBM power4 CPUs, like in IBM p690
#               IBM5L        IBM power5 CPUs, like in IBM p570, Linux
#               IBM5A        IBM power5 CPUs, like in IBM p570, AIX
#               G95          Use the g95 compiler 
#               GFORT        Use the gfortan/gcc compiler 
#               G5_P         PowerPC chips in Apple G5 with xlf compiler
#               G5_I         Intel chips in Apple G5 (not currently implemented)
#               SGI          SGI/MIPS R1x000 CPUs, like in SGI Origin
#               SUN          Sun Ultrasparc, like in Sunblade
#               HITACHI      Hitachi SR-8000 CPUs
#
#   MODE      : This flag selects the compiler flags used. Set to FAST for 
#               production runs or DEBUG for debugging. 
#   PARALLEL  : Compile code for running in parallel using OpenMP
#   NDIM      : Number of dimensions. set to value 2 or 3
#   INTEG     : Use the Runge-Kutta integrator (set to RK) or the leapfrog
#               integrator (set to LF). If you write another integrator, 
#               give it a flag.
#   SELFFORCE : Include routines to do self force calculations. 
#               Currently, this means gravity, but you could put
#               something else in instead.
#               Because of some ridiculous LANL copyright nonsense, the forcedirect.F
#               module is distributed as an addon in a different directory
#               Read the file INCLUDE/makefile.dirsum for instructions how to
#               access it.
#   GRAPE     : Allow use of Grape hardware. Set to 
#                    0    for no GRAPE 
#                    3    for GRAPE-3
#                    5    for GRAPE-5
#                    565  for GRAPE-6A using grape5 emulation calls in libg65 (doesn't work)
#                    6    for GRAPE-6
#                    65   for GRAPE-6A using reduced communication libg65 (doesn't work)
#                    66   for GRAPE-6A    
#               Add FAKE to each option above, to use the fakegrape
#               module instead of a real grape. In other words, do
#                    66FAKE to get fakegrape G6A
#               Because of some ridiculous LANL copyright nonsense, the fakegrape
#               module is distributed as an addon in a different directory
#               Read the file INCLUDE/makefile.fakegrape for instructions how to
#               access it.
#
#   SPH       : Use sph subroutines
#   KERNEL    : Which kernel to use for SPH calculations.
#                    currently implement either W4 or W4ALT
#               Because of some ridiculous LANL copyright nonsense, the W4ALT
#               kernel is distributed as an addon module in a different directory
#               Read the file INCLUDE/makefile.altkern for instructions how to
#               access it.
#   PM        : Include point mass subroutines 
#   COSMO     : Use cosmology subroutines
#   PERIODIC  : Use periodic boundary conditions 
#   IOFMT     : Kind of IO to use:
#                       FTNSTD uses only fortran standard io
#                       FXDR uses the xdr library for dump portability
#                       HDF5 add someday 
#   FFTW      : Use the FFTW library for the Fourier transforms of the 
#               periodic boundary conditions (Ewald method)
#   RECIPES   : Include Numerical Recipes routines. Required for some
#               modules to compile, but not included in vine due to
#               copyright restrictions. You can get them yourself easily 
#               enough however.

MACHINE   = INTLC2DUO
MODE      = FAST
PARALLEL  = 0
NDIM      = 3
INTEG     = LF
SELFFORCE = 1
GRAPE     = 0
SPH       = 0
KERNEL    = W4
PM        = 0
COSMO     = 0
PERIODIC  = 0
FFTW      = 0            #an override sets FFTW=1 if PERIODIC=1
IOFMT     = FTNSTD
RECIPES   = 0

EXEC  = vine

########################################################################
#
# First strip trailing whitespaces from the definitions above because
# those might mess up the comparisons below.
#
########################################################################

MACHINE   := $(strip $(MACHINE))
MODE      := $(strip $(MODE))
PARALLEL  := $(strip $(PARALLEL))
NDIM      := $(strip $(NDIM))
INTEG     := $(strip $(INTEG))
SELFFORCE := $(strip $(SELFFORCE))
GRAPE     := $(strip $(GRAPE))
SPH       := $(strip $(SPH))
KERNEL    := $(strip $(KERNEL))
PM        := $(strip $(PM))
COSMO     := $(strip $(COSMO))
PERIODIC  := $(strip $(PERIODIC))
FFTW      := $(strip $(FFTW))
IOFMT     := $(strip $(IOFMT))
########################################################################
#
# Now the flags set above are translated into the appropriate choice of
# preprocessor flags, source files and libraries to link.
#
#######################################################################

# Dimensions of the code

ifeq ($(NDIM),3)
   NDIMCPP = -DNDIM=3
endif

ifeq ($(NDIM),2)
   NDIMCPP= -DNDIM=2
endif

#######################################################################

# Choice of integrator

ifeq ($(INTEG),RK)
   INTEGCPP = -DRK
   INTEGSRCS = rk12.F
endif

ifeq ($(INTEG),LF)
   INTEGCPP = -DLF
   INTEGSRCS = leapfrog.F
endif

#######################################################################

# Include self forces (e.g. gravity) code

ifeq ($(SELFFORCE),1)

   SELFFORCECPP = -DSELFFORCE
   SELFFORCESRC = forcelaw.F

# GRAPE hardware (assumes real hardware is available 
#  unless make.fakegrape is included. It sets FAKE=1)

   FAKE = 0

   ifeq ($(GRAPE),3)
      GRAPECPP    = -DGRAPE=3 
      GRAPESRC    = grape3.F
      LIBGRAPE    = -lnsl -lgrape3a 
      LDGRAPEPATH = 
   endif

   ifeq ($(GRAPE),5)
      GRAPECPP = -DGRAPE=5
      GRAPESRC = grape5.F 
      ifeq ($(PARALLEL),0)
         LIBGRAPE    = -lg5a -lphibdma
         LDGRAPEPATH = 
      else
         LIBGRAPE    = -lg5ap -lphibdmap
         LDGRAPEPATH = 
      endif
   endif

   ifeq ($(GRAPE),565)
      GRAPECPP    = -DGRAPE=565 -D__LANGUAGE_FORTRAN__
      GRAPESRC    = grape5.F 
      LIBGRAPE    = -lg65
      LDGRAPEPATH = -L/usr/local/g6a
      LDGRAPEPATH = -L.
   endif

   ifeq ($(GRAPE),6)
      GRAPECPP    = -DGRAPE=6 
      GRAPESRC    = grape6.F 
      LIBGRAPE    = -lg6lx
      LDGRAPEPATH = 
   endif

   ifeq ($(GRAPE),65)
      GRAPECPP    = -DGRAPE=65 
      GRAPESRC    = grape6.F 
      LIBGRAPE    = -lg65
      LDGRAPEPATH = -L/usr/local/g6a
   endif

   ifeq ($(GRAPE),66)
      GRAPECPP    = -DGRAPE=66 
      GRAPESRC    = grape6.F 
      LIBGRAPE    = -lg6a
      LDGRAPEPATH = -L/usr/local/g6a
   endif

   include INCLUDE/make.fakegrape
   FAKE := $(strip $(FAKE))

   include INCLUDE/make.dirsum

   SELFFORCECPP += $(GRAPECPP) $(DIRSUMCPP)
   SELFFORCESRC += $(GRAPESRC) $(DIRSUMSRC)
endif

#######################################################################

# Include hydro (SPH)

ifeq ($(SPH),1)
   SPHCPP = -DSPH
   SPHSRC = sph.F eostate.F energy.F 
   ifeq ($(KERNEL),W4)
      SPHCPP   += -DW4KERN
      KERNELSRC = W4kern.F
   endif
   include INCLUDE/make.altkern

   SPHSRC += $(KERNELSRC)
endif

#######################################################################

# Include point masses

ifeq ($(PM),1)

   PMCPP   = -DPM
   PMCALC  = pm.F pmcalcs.F

   PMSRCS := $(PMCALC)
endif

#######################################################################

# Periodic boundary conditions

ifeq ($(PERIODIC),1)
   PERIODICCPP = -DPERIODIC
   PERIODICSRC = ewald.F
   FFTW = 1
   FFTW := $(strip $(FFTW))
endif

#######################################################################

# Use of FFTW library

ifeq ($(FFTW),1)
    FFTWCPP = -DFFTW
    ifeq ($(PARALLEL),0)
      LIBFFTW = -lfftw3
   else
      LIBFFTW = -lfftw3_threads -lfftw3
   endif
endif

#######################################################################

# Cosmological expansion

ifeq ($(COSMO),1)
   COSMOCPP = -DCOSMO
   COSMOSRC = cosmo.F 
endif

#######################################################################

# Kind of IO format to include. (Can always do fortran io)

ifeq ($(IOFMT),FTNSTD)
   IOCPP   = 
   LIBIO   = 
   LIOPATH = 
endif
ifeq ($(IOFMT),FXDR)
   IOCPP   = -DXDR
   LIBIO   = -lfxdr
   LIOPATH = -L$(HOME)/local/$(ARCH)/lib
endif

#######################################################################

# Include Numerical Recipes routines 
# (not included in VINE due to copyright--create your own copy as needed)

ifeq ($(RECIPES),1)
   RECIPESCPP = -DRECIPES 
   RECIPESSRC = recipes.f90
endif


######################################################################
#
# Now assemble the preprocessor flags for compiling VINE according to
# the variables set above.
#
######################################################################

PREPROCFLAGS= $(NDIMCPP) $(INTEGCPP) $(PERIODICCPP) $(FFTWCPP) \
              $(SELFFORCECPP) $(IOCPP) $(COSMOCPP) $(SPHCPP) $(PMCPP) \
              $(RECIPESCPP)


# Note: we don't use the CPPFLAGS make variable, because we
# want to prefer the fortran preprocessor if one exists


#######################################################################
#
# Choose the compiler and compilation flags for the given machine type
# and run mode (fast = production, debug = debugging)
#
# Add your own compiler here, in the same format if you run on
# different machines that we have listed.
#
#######################################################################

########################
# Power like chips     #
########################

ifeq ($(MACHINE),G5_P)
   include INCLUDE/makefile.g5
endif

ifeq ($(MACHINE),IBM4)
   include INCLUDE/makefile.pwr4
endif

ifeq ($(MACHINE),IBM5L)
   include INCLUDE/makefile.pwr5
endif

########################
# SGI/Mips chips       #
########################

ifeq ($(MACHINE),SGI)
   include INCLUDE/makefile.sgi
endif


########################
# Sun/Sparc chips      #
########################

ifeq ($(MACHINE),SUN)
   include INCLUDE/makefile.sun
endif


########################
# x86 chips            #
########################

ifeq ($(MACHINE),INTLX86)
   include INCLUDE/makefile.x86intl
endif


########################
# x86_64/EMT64 chips   #
########################

ifeq ($(MACHINE),INTLPGF)
   include INCLUDE/makefile.x86pgf
endif

ifeq ($(MACHINE),G95)
   include INCLUDE/makefile.g95
endif

ifeq ($(MACHINE),GFORT)
   include INCLUDE/makefile.gfort
endif

ifeq ($(MACHINE),INTLAMD64)
   include INCLUDE/makefile.amdintl
endif

ifeq ($(MACHINE),PATHAMD64)
   include INCLUDE/makefile.amdpath
endif

ifeq ($(MACHINE),PGFAMD64)
   include INCLUDE/makefile.amdpgf
endif

ifeq ($(MACHINE),LAHEYAMD)
   include INCLUDE/makefile.amdlahey
endif

########################
# Itanic chips         #
########################

ifeq ($(MACHINE),INTLITAN)
   include INCLUDE/makefile.itan
endif

########################
# Core 2 Duo chips     #
########################

ifeq ($(MACHINE),INTLC2DUO)
   include INCLUDE/makefile.c2duointl
endif

########################
# Hitachi              #
########################

ifeq ($(MACHINE),HITACHI)
   include INCLUDE/makefile.hit
endif




######################################################################
#
# Now assemble the libary flags for linking VINE according to
# the variables set above.
#
# Note that /usr/local/lib may not be the correct local library
# directory on some systems. For example, SGI has []/lib, []/lib32
# and []/lib64 for various compilation options. Other systems
# are similar.
#
######################################################################

LIBES= $(LIBGRAPE) $(LIBFFTW) $(LIBIO) $(LIBNATIVE) -lm
LDPATH = -L/usr/local/lib $(LIOPATH) $(LDPATHNAT) $(LDGRAPEPATH)

######################################################################
#
# Now assemble the list of source files for building VINE according to
# the variables set above.
# Some of these modules (source files) are required for operation of 
# the code, those are explicitly specified here. Others are swappable 
# one for another or are removable entirely. They are specified through
# variables which contain the approriate choice according to the make 
# flags set above. The stubs.F file contains templates for routines 
# that are missing so that the code will still compile if some of the 
# *SRCS variables are empty.
#
# SRCS and SRCSF refer to free and fixed form fortran files respectively
#
######################################################################

SRCC = $(G6CSRC)

SRCS= perform.f90 

SRCSF= dimens.F constants.F stubs.F miscvars.F clmpvars.F \
         partvars.F integvars.F sphvars.F indivtsvars.F treevars.F \
         $(INTEGSRCS) $(SPHSRC) $(PMSRCS) $(PERIODICSRC) $(COSMOSRC) \
         $(SELFFORCESRC) $(PLATSRC) \
         derivcalc.F errorcrit.F indivts.F io.F analyze.F \
         driver.F tree.F treemake.F treesort.F vineutils.F

SRCS  += $(RECIPESSRC)


INITSRCS = perform.f90 initvine.f90

INITSRCSF = dimens.F constants.F stubs.F miscvars.F clmpvars.F \
            partvars.F integvars.F sphvars.F indivtsvars.F treevars.F \
            smoothadjust.F io.F \
            $(SPHSRC) $(PMSRCS) $(PERIODICSRC) $(COSMOSRC) $(SELFFORCESRC) \
            $(PLATSRC) \
            tree.F treemake.F treesort.F vineutils.F

#-------------------------------------------------------------------
# How to make objects from .F (fixed form) and .f90 (free form) files

.F.o:
	$(FCF) $(FFLAGS) -c $<

%.o: %.f90
	$(FC90) $(F90FLAGS) -c $<


.c.o: 
	cc -O2 -c $<

# dependencies

OBJ  = $(SRCS:.f90=.o)
OBJF = $(SRCSF:.F=.o)

INITOBJ  = $(INITSRCS:.f90=.o)
INITOBJF = $(INITSRCSF:.F=.o)
#-------------------------------------------------------------------
#Make rules for making executables and object files.

$(EXEC): $(OBJ) $(OBJF) 
	$(FCF) $(FFLAGS) $(OBJ) $(OBJF) $(LDPATH) $(LIBES) -o $(EXEC)


initvine:  $(INITOBJF) $(INITOBJ)
	$(FCF) $(FFLAGS) $(INITOBJ) $(INITOBJF) $(LDPATH) $(LIBES) -o initvine
#	mv initvine $(HOME)/local/$(ARCH)/bin/

writeout:
	echo OBJC         $(OBJC)
	echo SPHSRC       $(SPHSRC)
	echo PMSRCS       $(PMSRCS)
	echo PERIODICSRC  $(PERIODICSRC)
	echo COSMOSRC     $(COSMOSRC)
	echo SELFFORCESRC $(SELFFORCESRC)
	echo DIRSUMSRC    $(DIRSUMSRC)
	echo PLATSRC      $(PLATSRC)

writeoutobj:
	echo OBJC         $(OBJC)
	echo SPHOBJ       $(SPHOBJ)
	echo PMOBJ        $(PMOBJS)
	echo PERIODICOBJ  $(PERIODICOBJ)
	echo COSMOSRC     $(COSMOOBJ)
	echo SELFFORCEOBJ $(SELFFORCEOBJ)
	echo DIRSUMOBJ    $(DIRSUMOBJ)
	echo PLATOBJ      $(PLATOBJ)


.PHONY: clean
clean :
	/bin/rm $(EXEC) *.o *.mod *.MOD


######################################################################
#
# It is an annoying fact of f90 compilers that .mod files that are
# produced have no standard naming format. Some use capital letters
# (MODULE.mod) and some use small letters (module.mod). In order to
# avoid this issue we make some .o files dependent on other .o files
# if they `use' a module. (NB: use is a stronger form of `include'
# which requires compiler interaction at the compile step, in order to
# do various kinds of type checking etc for subroutine/function calls
# (among other things).
# In contrast, object files are only needed at the link step)
#
# It is another annoying fact of f90 compilers and their interaction
# with make that modules often lead to unnecessary compilation cascades.
# So far no one has told the make people, or at least not loudly enough
# to get them to do anything about it.
#
######################################################################

PERIODICOBJ  = $(PERIODICSRC:.F=.o)
SELFFORCEOBJ = $(SELFFORCESRC:.F=.o)
DIRSUMOBJ    = $(DIRSUMSRC:.F=.o)
GRAPEOBJ     = $(GRAPESRC:.F=.o)
INTEGOBJ     = $(INTEGSRCS:.F=.o)
SPHOBJ       = $(SPHSRC:.F=.o)
KERNELOBJ    = $(KERNELSRC:.F=.o)
COSMOOBJ     = $(COSMOSRC:.F=.o)
PMCALCOBJ    = $(PMCALC:.F=.o)
PMOBJ        = $(PMSRCS:.F=.o)
RECIPESOBJ   = $(RECIPESSRC:.f90=.o)


analyze.o    : dimens.o constants.o partvars.o stubs.o
analyze.o    : indivtsvars.o miscvars.o derivcalc.o indivts.o 
analyze.o    : perform.o $(INTEGOBJ)
clmpvars.o   : dimens.o
constants.o  :
cosmo.o      : dimens.o constants.o miscvars.o
derivcalc.o  : dimens.o constants.o perform.o stubs.o miscvars.o 
derivcalc.o  : indivtsvars.o integvars.o clmpvars.o partvars.o
derivcalc.o  : $(PMCALCOBJ) $(INTEGOBJ) $(SPHOBJ) $(PERIODICOBJ) 
derivcalc.o  : tree.o treemake.o
dimens.o     :
driver.o     : dimens.o constants.o perform.o stubs.o partvars.o 
driver.o     : clmpvars.o analyze.o derivcalc.o
driver.o     : indivts.o indivtsvars.o io.o miscvars.o 
driver.o     : $(INTEGOBJ) integvars.o errorcrit.o
driver.o     : vineutils.o treemake.o $(PERIODICOBJ) $(SELFFORCEOBJ)
driver.o     : $(PMCALCOBJ) $(COSMOOBJ) $(SPHOBJ) 
energy.o     : dimens.o constants.o miscvars.o sphvars.o perform.o 
eostate.o    : dimens.o constants.o miscvars.o sphvars.o perform.o 
errorcrit.o  : dimens.o constants.o stubs.o perform.o miscvars.o
errorcrit.o  : partvars.o integvars.o $(INTEGOBJ) $(COSMOOBJ) $(SPHOBJ) 
ewald.o      : dimens.o constants.o indivtsvars.o miscvars.o INCLUDE/fftw3.f 
ewald.o      :  perform.o $(RECIPESOBJ)
forcelaw.o   : dimens.o constants.o treevars.o perform.o
forcelaw.o   :   stubs.o $(GRAPEOBJ) $(DIRSUMOBJ) $(PERIODICOBJ) INCLUDE/hwinfo
forcedirect.o: dimens.o treevars.o constants.o INCLUDE/hwinfo
	if test ! -e forcedirect.F; then                           \
	   ln -s ../../addon1/forcedirect.F forcedirect.F;         \
	fi
	$(FCF) $(FFLAGS) -c forcedirect.F
grape3.o     : dimens.o constants.o treevars.o indivtsvars.o perform.o miscvars.o
grape5.o     : dimens.o constants.o treevars.o indivtsvars.o perform.o
grape6.o     : dimens.o constants.o treevars.o indivtsvars.o perform.o
indivts.o    : dimens.o constants.o indivtsvars.o miscvars.o perform.o
indivtsvars.o: dimens.o
integvars.o  : dimens.o
io.o         : dimens.o constants.o partvars.o miscvars.o indivtsvars.o
io.o         :  perform.o vineutils.o clmpvars.o stubs.o $(COSMOOBJ)
io.o         :  INCLUDE/hwinfo
miscvars.o   : dimens.o
leapfrog.o   : dimens.o constants.o integvars.o partvars.o miscvars.o
leapfrog.o   :  perform.o stubs.o $(COSMOOBJ)
partvars.o   : dimens.o
perform.o    :
pm.o         : dimens.o constants.o partvars.o miscvars.o
pm.o         :   integvars.o indivtsvars.o 
pmcalcs.o    : dimens.o constants.o miscvars.o perform.o
recipes.o    : constants.o
rk12.o       : dimens.o constants.o integvars.o partvars.o miscvars.o 
rk12.o       :  perform.o
sph.o        : dimens.o constants.o miscvars.o sphvars.o perform.o 
sph.o        :   tree.o $(KERNELOBJ)
sphvars.o    : dimens.o
stubs.o      : dimens.o makefile
tree.o       : dimens.o constants.o treevars.o treefuncs 
tree.o       :   perform.o stubs.o $(SELFFORCEOBJ)
treemake.o   : dimens.o constants.o treevars.o treesort.o treefuncs 
treemake.o   :   $(SELFFORCEOBJ) perform.o
treesort.o   : dimens.o constants.o
treevars.o   : dimens.o
vineutils.o  : dimens.o partvars.o indivtsvars.o integvars.o sphvars.o
vineutils.o  :   treevars.o miscvars.o clmpvars.o tree.o treemake.o 
vineutils.o  :   perform.o stubs.o $(GRAPEOBJ)
W4kern.o     : dimens.o constants.o
W4kernalt.o  : dimens.o constants.o
	if test ! -e W4kernalt.F; then                         \
	   ln -s ../../addon2/W4kernalt.F W4kernalt.F;         \
	fi
	$(FCF) $(FFLAGS) -c W4kernalt.F


ifeq ($(FAKE),1)

wait.o       :
fakegrape.o  : treevars.o wait.o 
	if test ! -e fakegrape.F; then                         \
	   ln -s ../../addon1/fakegrape.F fakegrape.F;         \
	fi
	$(FCF) $(FFLAGS) -c fakegrape.F

grape3.o     : fakegrape.o
grape5.o     : fakegrape.o
grape6.o     : fakegrape.o

endif


initvine.o     : dimens.o partvars.o indivtsvars.o clmpvars.o miscvars.o
initvine.o     : sphvars.o constants.o treemake.o tree.o io.o
smoothadjust.o : dimens.o partvars.o indivtsvars.o clmpvars.o miscvars.o
smoothadjust.o : constants.o $(SPHOBJ) treemake.o sphvars.o tree.o

