#------------------------------------------------------------------------
# This Makefile is for building the MOZART4 model
#------------------------------------------------------------------------

# Set up special characters
null  :=
space := $(null) $(null)

#------------------------------------------------------------------------
# Determine platform 
#------------------------------------------------------------------------
UNAMES := $(shell uname -s)
UNAMEM := $(shell uname -m)
UNAMEN := $(shell uname -n)

#------------------------------------------------------------------------
# Check for site name; defaults to NCAR
#------------------------------------------------------------------------
ifeq ($(SITE),$(null))
  SITE := NCAR
endif

#------------------------------------------------------------------------
# Check for object directory
#------------------------------------------------------------------------
ifeq ($(OBJDIR),$(null))
  OBJDIR := OBJ
endif

#------------------------------------------------------------------------
# Check for name of Base file list; defaults to Base_Srclist_F
#------------------------------------------------------------------------
ifeq ($(SRCLIST),$(null))
  SRCLIST := $(OBJDIR)/Srclist
endif

#------------------------------------------------------------------------
# Set the code source paths
#------------------------------------------------------------------------
#dirs := $(CODEDIR)/Base $(CODEDIR)/pp $(CODEDIR)/chem/scalar $(CODEDIR)/chem
dirs := $(CODEDIR)/Base $(CODEDIR)/chem/scalar $(CODEDIR)/chem
ifneq ($(SRCDIRS),$(null))
  dirs := $(SRCDIRS) $(dirs)
endif

FFINCS := -I./

#------------------------------------------------------------------------
# Expand any tildes in directory names. Change spaces to colons.
#------------------------------------------------------------------------
DIRS    := $(foreach dir,$(dirs),$(dir)) 
vpath %.F90 $(DIRS)
vpath %.c $(CODEDIR)/Base

all: $(MODEL_EXEDIR)/$(EXENAME) 

#------------------------------------------------------------------------
# Get list of files, determine objects
#------------------------------------------------------------------------
SOURCES   := $(shell cat Srcfiles)
OBJS      := $(addsuffix .o, $(basename $(SOURCES)))

Depends: Srcfiles Filepath
	$(CODEDIR)/utils/mkDepends Filepath Srcfiles > $@

Srcfiles: Filepath
	$(CODEDIR)/utils/mkSrcfiles > $@

Filepath:
	$(CODEDIR)/utils/mkFilepath $(dirs) > $@

$(MODEL_EXEDIR)/$(EXENAME):	$(OBJS)
	$(FC) -o $@ $(OBJS) $(LDFLAGS)

.SUFFIXES:
.SUFFIXES: .F90 .c .o

.F90.o:
	$(FC) $(FFLAGS) $(DFLAGS) $(FFINCS) $<

.c.o:
	$(CC) $(CFLAGS) $<

#========================================================================
# Architecture-specific flags and rules
#========================================================================
#------------------------------------------------------------------------
# Linux
#------------------------------------------------------------------------
ifeq ($(OP_SYS),LINUX)

  DFLAGS := -DINTEL
  ifeq ($(MODEL_MODE),PURE_OMP)
    DFLAGS += -DUSE_OMP
  endif

  ifeq ($(MODEL_MODE),PURE_MPI)
    DFLAGS += -DUSE_MPI
  endif

  ifeq ($(MODEL_MODE),HYBRID)
    DFLAGS += -DUSE_OMP -DUSE_MPI
  endif

  ifeq ($(SITE),NCAR)
    DFLAGS  += -DNCAR
  endif

  ifeq ($(MODEL_MODE),HYBRID)
    FC      := $(MPI_DIR)/mpif90
    FOPTS   := -openmp
    LDFLAGS := -openmp
  endif
  ifeq ($(MODEL_MODE),PURE_MPI)
    FC      := $(MPI_DIR)/mpif90
  endif

#------------------------------------------------------------------------
# select compiler
#------------------------------------------------------------------------
  ifeq ($(COMPILER),Intel)
#------------------------------------------------------------------------
# Intel
#------------------------------------------------------------------------
    DFLAGS += -DIFORT

    ifeq ($(MODEL_MODE),PURE_OMP)
      FC      := ifort
      FOPTS   := -openmp
      LDFLAGS := -openmp
    endif
    ifeq ($(MODEL_MODE),SNG)
      FC      := ifort
    endif
    
    CC        := cc

    ifneq ($(DEBUG),ON)
      FOPTS    := $(FOPTS) -c -r8 -module $(OBJDIR) -O -ftz -fpconstant -fp-model precise
    else
      FOPTS    := $(FOPTS) -c -r8 -g -check all -traceback -module $(OBJDIR)
      LDFLAGS  := $(LDFLAGS) -check bounds -traceback -g
    endif
  endif

  ifeq ($(COMPILER),Lahey)
#------------------------------------------------------------------------
# Lahey
#------------------------------------------------------------------------
    ifeq ($(MODEL_MODE),HYBRID)
      LDFLAGS     := --openmp
      FOPTS       := --openmp
    endif
    ifeq ($(MODEL_MODE),PURE_OMP)
      FC      := lf95
      FOPTS   := --openmp
      LDFLAGS := --openmp
    endif
    ifeq ($(MODEL_MODE),SNG)
      FC      := lf95
    endif

    CC        := cc 

    ifneq ($(DEBUG),ON)
      FOPTS := $(FOPTS) --g --nap --nchk --npca --nsav --ntrace --dbl -c --wide --mod $(OBJDIR) -O
    else
      FOPTS    := $(FOPTS) --nap --chk --g --pca --nsav --trace --trap --dbl -c --wide --mod $(OBJDIR)
    endif
  endif

  ifeq ($(COMPILER),GNU)
#------------------------------------------------------------------------
# GNU
#------------------------------------------------------------------------
    ifeq ($(MODEL_MODE),HYBRID)
      LDFLAGS     := -fopenmp
      FOPTS       := -fopenmp
    endif
    ifeq ($(MODEL_MODE),PURE_OMP)
      FC      := gfortran
      FOPTS   := -fopenmp
      LDFLAGS := -fopenmp
    endif
    ifeq ($(MODEL_MODE),SNG)
      FC      := gfortran
    endif

    CC        := gcc 

    ifneq ($(DEBUG),ON)
      FOPTS := $(FOPTS) -c -O -fdefault-double-8 -fdefault-real-8 -fno-range-check
    else
      FOPTS := $(FOPTS) -g -c -O -fdefault-double-8 -fdefault-real-8 -fno-range-check
    endif
  endif

  ifeq ($(COMPILER),PGI)
#------------------------------------------------------------------------
# Portland
#------------------------------------------------------------------------
    ifeq ($(MODEL_MODE),HYBRID)
      LDFLAGS     := -mp
      FOPTS       := -mp
    endif
    ifeq ($(MODEL_MODE),PURE_OMP)
      FC          := pgf90
      LDFLAGS     := -mp
      FOPTS       := -mp
    endif
    ifeq ($(MODEL_MODE),SNG)
      FC          := pgf90
    endif

    CC          := pgcc 

    ifneq ($(DEBUG),ON)
      FOPTS       := $(FOPTS) -g -O0 -r8 -c -Mr8intrinsics -Mextend -module $(OBJDIR) -Mnosave -Ktrap=divz,ovf
    else
      FOPTS       := $(FOPTS) -O2 -r8 -c -Mr8intrinsics -Mextend -module $(OBJDIR) -Mnosave -Ktrap=divz,ovf
    endif
  endif

  FFLAGS      := $(FOPTS)
  CFLAGS      := -c -DINTEL

endif

ifeq ($(UNAMES),AIX)
#------------------------------------------------------------------------
# AIX
#------------------------------------------------------------------------
#------------------------------------------------------------------------
# Set compilers
#------------------------------------------------------------------------
  ifeq ($(MODEL_MODE),PURE_OMP)
    FC          := xlf95_r 
    CC          := cc_r
  endif
  ifeq ($(MODEL_MODE),PURE_MPI)
    FC          := mpxlf95_r
    CC          := mpcc_r
  endif
  ifeq ($(MODEL_MODE),SINGLE_CPU)
    FC          := xlf95
    CC          := cc
  endif
  ifeq ($(MODEL_MODE),HYBRID)
    FC          := mpxlf95_r 
    CC          := mpcc_r
  endif

  ifneq ($(DEBUG),ON)
    COMFLAGS    := -q64 -qarch=auto -qtune=auto -qrealsize=8 -qzerosize -O3 -qstrict -qdpc=e -g
  else
    COMFLAGS    := -q64 -qarch=auto -qtune=auto -qrealsize=8 -qzerosize -O3 -qstrict -qdpc=e -g \
                   -qinitauto=FF911299 -qflttrap=ov:zero:inv:en -qsigtrap=xl__trcedump
  endif

  FFLAGS      := -c $(COMFLAGS) -qfree=f90 -qsuffix=f=f90:cpp=F90 -NS16384 -qmoddir=$(OBJDIR) -I$(OBJDIR)
  ifeq ($(findstring be,$(UNAMEN)),be)
    FFINCS    += -I/usr/lpp/ppe.poe/include/thread64
  endif

  ifneq ($(SITE),ECMWF)
    CFLAGS      := -q64 -c -O2 -DIBM
  else
    CFLAGS      := -q64 -c -O2 -DIBM -DIBM_UND
  endif

  ifneq ($(DEBUG),ON)
    ifneq ($(SITE),ECMWF)
      LDFLAGS     := $(COMFLAGS) -bloadmap:loadmap -lmass -lmassv
    else
      LDFLAGS     := $(COMFLAGS) -bloadmap:loadmap -lessl -lmass -lmassv
    endif
  else
    LDFLAGS     := $(COMFLAGS) -bloadmap:loadmap
  endif

  ifneq ($(SITE),ECMWF)
    DFLAGS     := -WF,-DIBM
  else
    DFLAGS     := -WF,-DIBM -WF,-DIBM_UND
  endif

  ifeq ($(SITE),NCAR)
    DFLAGS  += -WF,-DNCAR
  endif

  LDFLAGS += -bdatapsize:64K -bstackpsize:64K -btextpsize:64K

  ifeq ($(MODEL_MODE),PURE_OMP)
    DFLAGS  += -WF,-DUSE_OMP
    FFLAGS  := -qsmp=omp $(FFLAGS)
    LDFLAGS := -qsmp $(LDFLAGS)
  endif
  ifeq ($(MODEL_MODE),PURE_MPI)
    DFLAGS += -WF,-DUSE_MPI
  endif
  ifeq ($(MODEL_MODE),HYBRID)
    DFLAGS  += -WF,-DUSE_MPI -WF,-DUSE_OMP
    FFLAGS  := -qsmp=omp $(FFLAGS)
    LDFLAGS := -qsmp $(LDFLAGS)
  endif

endif

LDFLAGS     += -L$(NCD_DIR)/lib $(AR_LIBS)
FFINCS      += -I$(NCD_DIR)/include

#------------------------------------------------------------------------
# Default rules
#------------------------------------------------------------------------

RM := rm

cleanobj:
	$(RM) -f $(OBJDIR)/*

cleanall:
	$(RM) -f $(OBJDIR)/* $(MODEL_EXEDIR)/$(EXENAME)

show-list:
	# src_list1 is: '$(src_list1)'
	# OBJ       is: '$(OBJS)'

debug:
	echo "VPATH: $(VPATH)"

include Depends
