###############################################################################
# PFLOTRAN makefile
#
# Before building make sure that the environmental variables
#   PETSC_DIR and PETSC_ARCH are defined.
#
# To build PFLOTRAN from within the source directory, run, e.g.:
#   cd $PFLOTRAN_DIR/src/pflotran
#   make pflotran
# this will generate the executable and object files in the source directory.
# 
# To have the object/executable files placed in a separate directory,
# run make from the target directory and specify the makefile and 
# source directory locations to make, e.g.:
#  mkdir -p $PFLOTRAN_DIR/build/$PETSC_ARCH
#  cd $PFLOTRAN_DIR/build/$PETSC_ARCH
#  make -f $PFLOTRAN_DIR/src/pflotran/makefile SRC_DIR=$PFLOTRAN_DIR/src/pflotran pflotran
#
# Targets:
# pflotran -- the complete PFLOTRAN executable
# libpflotranchem.a -- PFLOTRAN reaction library
# pflotran_rxn -- PFLOTRAN batch reactor executable (wraps libpflotranchem.a)
# test -- run unit (utest) and regression (rtest) tests
# check -- verify that PFLOTRAN was built correctly and runs
# clean-tests -- remove the output generated by tests
# clean-pflotran -- remove .o, .mod, and other build files 
# echo-flags -- print the make and compiler flags to be used
#
###############################################################################

# PFLOTRAN source directory -- default to the current directory
SRC_DIR = ./

# make option to search for source files in $SRC_DIR
VPATH = $(SRC_DIR)

pflotran_src =
common_src   =
regression_test_dir = $(SRC_DIR)/../../regression_tests
unit_test_dir = $(SRC_DIR)/unittests

# Import variables/options/rules from PETSc.
include ${PETSC_DIR}/lib/petsc/conf/variables
include ${PETSC_DIR}/lib/petsc/conf/rules
# reseting PETSC_MAKE_STOP_ON_ERROR causes build to stop on error.
PETSC_MAKE_STOP_ON_ERROR=
# Those files also include 
# ${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/petscvariables
# and 
# ${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/petscrules
# so that PFLOTRAN will be built with the same options as 
# the petsc configured in $PETSC_DIR/$PETSC_ARCH

MYFLAGS = -I. 

###############################################################################
# Preprocessor flags for special PFLOTRAN features/hacks
###############################################################################

# if compiling pflotran_rxn or libpflotranchem.a, need to toggle 
# PFLOTRAN_RXN_FLAG 
ifneq (,$(filter libpflotranchem.a pflotran_rxn,$(MAKECMDGOALS)))
  PFLOTRAN_RXN_FLAG := 1
endif

ifdef ci
  gnu_code_coverage = 1
  gnu_runtime_checks = 1
  catch_warnings_as_errors = 1
endif

ifdef cw
  catch_warnings_as_errors = 1
endif

ifdef match_tough2
  MYFLAGS += ${FC_DEFINE_FLAG}MATCH_TOUGH2
endif

ifdef uo2
  MYFLAGS += ${FC_DEFINE_FLAG}COMPUTE_INTERNAL_MASS_FLUX
endif

ifdef fmdm
  MYFLAGS += ${FC_DEFINE_FLAG}FMDM_MODEL
endif

ifdef glenn
#  MYFLAGS += ${FC_DEFINE_FLAG}XINGYUAN_BC
#  MYFLAGS += ${FC_DEFINE_FLAG}BROADCAST_DATASET
endif

ifdef dbl
  MYFLAGS += ${FC_DEFINE_FLAG}DOUBLE_LAYER
endif

ifdef pcl
  MYFLAGS += ${FC_DEFINE_FLAG}PCL ${FC_DEFINE_FLAG}MUALEM_SPLINE
endif

ifdef condnr
  MYFLAGS += ${FC_DEFINE_FLAG}CONDNR
endif

ifdef remove_sat
  MYFLAGS += ${FC_DEFINE_FLAG}REMOVE_SATURATION
endif

ifdef no_vapor_diffusion
  MYFLAGS += ${FC_DEFINE_FLAG}NO_VAPOR_DIFFUSION
endif

ifdef debug_gen
  MYFLAGS += ${FC_DEFINE_FLAG}DEBUG_GENERAL
  ifeq ($(debug_gen),2)
    MYFLAGS += ${FC_DEFINE_FLAG}DEBUG_GENERAL_INFO
  endif
endif 

ifdef coll
  MYFLAGS += ${FC_DEFINE_FLAG}COLL
endif

ifdef have_hdf5
  MYFLAGS += -I$(HDF5_INCLUDE) -I$(HDF5_LIB) ${FC_DEFINE_FLAG}PETSC_HAVE_HDF5
endif

ifdef ugrid_debug
  MYFLAGS += ${FC_DEFINE_FLAG}UGRID_DEBUG
endif

ifdef amanzi_bgd
  MYFLAGS += ${FC_DEFINE_FLAG}AMANZI_BGD
endif

ifdef th_bc_hack
  MYFLAGS += ${FC_DEFINE_FLAG}THDIRICHLET_TEMP_BC_HACK
endif

ifdef debug
  MYFLAGS += ${FC_DEFINE_FLAG}DEBUG
endif

ifdef use_matseqaij_fix
  MYFLAGS += ${FC_DEFINE_FLAG}USE_MATSEQAIJ_FIX
endif

ifdef debug_geomech_regression
  MYFLAGS += ${FC_DEFINE_FLAG}GEOMECHANICS_REGRESSION_DEBUG
endif

ifdef geomech_debug
  MYFLAGS += ${FC_DEFINE_FLAG}GEOMECH_DEBUG
endif

UPDATE_PROVENANCE=0
ifdef provenance
  UPDATE_PROVENANCE=1
endif

ifdef well_debug
  MYFLAGS += ${FC_DEFINE_FLAG}WELL_DEBUG
endif

ifdef towg_debug
  MYFLAGS += ${FC_DEFINE_FLAG}TOWG_DEBUG
endif

ifdef ug_mpi_scatter_glb
  MYFLAGS += ${FC_DEFINE_FLAG}MPI_SCATTER_GLOBAL
endif

ifdef ug_mpi_scatter_ghost
  MYFLAGS += ${FC_DEFINE_FLAG}MPI_SCATTER_GHOST_ONLY
endif

ifdef have_hdf5
LIBS +=  -L${HDF5_LIB} -lhdf5_fortran -lhdf5 -lz 
endif

# Set this accordingly on your platform
# SCORPIO_DIR=${HOME}/soft/scorpio
ifdef scorpio
  LIBS += -L${SCORPIO_DIR}/lib -lscorpio
  MYFLAGS += ${FC_DEFINE_FLAG}SCORPIO
  MYFLAGS += ${FC_DEFINE_FLAG}SCORPIO_WRITE
  MYFLAGS += -I${SCORPIO_DIR}/include
endif

ifdef gnu_code_coverage
  MYFLAGS += -fprofile-arcs -ftest-coverage
  LIBS += -lgcov
endif

ifdef gnu_runtime_checks
  MYFLAGS += -fcheck=all
endif

ifdef catch_warnings_as_errors
  MYFLAGS += -Werror=all -Wno-unused-dummy-argument 
endif

ifdef no_warnings
  MYFLAGS += -w
endif

###############################################################################
# Assign additional compiler/preprocessor flags
###############################################################################

# These flags are supplemental to the PETSc flags
CFLAGS   =
FFLAGS   = 
CPPFLAGS = ${MYFLAGS}
FPPFLAGS = ${MYFLAGS}

# In ${PETSC_DIR}/lib/petsc/conf/variables, 
# FPPFLAGS is appended to FCPPFLAGS.
# FCPPFLAGS is then used when compiling .F90 files.
# Similarly, CPPFLAGS is appended to CCPPFLAGS
#
# PETSc (${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/petscrules) defines
# the default rule for compiling .F90 files:
#.F.o .F90.o .F95.o: 
#	${FC} -c ${FC_FLAGS} ${FFLAGS} ${FCPPFLAGS} -o $@ $<
#
# FC_FLAGS is defined in ${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/petscvariables

# List of files to remove when running "make clean-pflotran"
CLEANFILES       = pflotran pflotran_rxn libpflotranchem.a make.log $(SRC_DIR)/pflotran_provenance.F90

###############################################################################
# Lists all files that PFLOTRAN (and other targets) depends on 
#
# '# Begin Source Block' and '# End Source Block' are keywords that bound the
# .o files.  The python script PFLOTRAN_DIR/src/python/pflotran_dependencies.py
# creates a list of source files associated with all .o files and parses them
# to create the list of dependencies included below.
#
###############################################################################

# Begin object file block

# please see pflotran_object_files.txt for a list of the object files. this 
# approach of including the object files allows us to re-use the list in other
# makefiles (e.g. clm-pflotran/makefile).
include $(SRC_DIR)/pflotran_object_files.txt

# End object file block

###############################################################################
# Targets
###############################################################################

# Concatentate dependency groups 
pflotran_base_obj = $(util_obj) $(eos_obj) $(mode_aux_obj) $(mode_obj) \
	$(shared_mode_aux_obj) $(chem_obj) $(geomech_obj) $(geophysics_obj) \
	$(grid_obj) $(relations_obj) $(properties_obj) $(dataset_obj) \
	$(srcsink_obj) $(io_obj) $(misc_obj) $(solver_obj) \
	$(deriv_obj) $(mode_process_model_obj)

pflotran_obj = $(pflotran_base_obj) ${pflotran_src}pflotran.o

pflotran_rxn_obj = ${pflotran_src}pflotran_rxn.o

# PFLOTRAN executable
pflotran : $(pflotran_obj)
	${FLINKER} -o pflotran $(pflotran_obj) ${PETSC_LIB} ${LIBS} 

# PFLOTRAN as a library
libpflotran.a : $(pflotran_obj)
	$(AR) $(ARFLAGS) $@ $(pflotran_obj)

libpflotranchem.a : $(chem_obj) $(shared_mode_aux_obj) $(util_obj)
	$(AR) $(ARFLAGS) $@ $(chem_obj) $(shared_mode_aux_obj) $(util_obj)

# GNU 11.3 reports link errors when libpflotranchem.a is used instead of the
# object files lists below.... This is a workaround.
pflotran_rxn : libpflotranchem.a $(pflotran_rxn_obj)
	${FLINKER} -o $@ $(pflotran_rxn_obj) $(chem_obj) $(shared_mode_aux_obj) \
	$(util_obj) ${PETSC_LIB} ${LIBS} 

# PFLOTRAN derivative test
pflotran_derivative : $(pflotran_base_obj) pflotran_derivative.o
	${FLINKER} -o pflotran_derivative $(pflotran_base_obj) pflotran_derivative.o ${PETSC_LIB} ${LIBS} 

$(SRC_DIR)/pflotran_provenance.F90 : FORCE
ifeq ($(UPDATE_PROVENANCE),1)
	@-rm pflotran_provenance.o pflotran_provenance_module.mod $(SRC_DIR)/pflotran_provenance.F90; \
	$(PYTHON) $(SRC_DIR)/pflotran-provenance.py \
		--pflotran-fflags "${FC_FLAGS} ${FFLAGS} ${FCPPFLAGS}" \
		--petsc-config "${CONFIGURE_OPTIONS}";
else
	@if test ! -f $(SRC_DIR)/pflotran_provenance.F90; then cp $(SRC_DIR)/pflotran_no_provenance.F90 $(SRC_DIR)/pflotran_provenance.F90; fi;
endif

###############################################################################
# Dependencies
# Dependencies stemming from "use" statements.
# These ensure that the module files are built in the correct order.
# The source file (i.e. file.F90) is intentionally omitted; 
# it is picked up by the default/implicit build rule (defined by PETSc)
###############################################################################
ifndef fast
  include $(SRC_DIR)/pflotran_dependencies.txt
endif
###############################################################################
# End Dependencies
###############################################################################


###############################################################################
# Other targets (clean, testing, etc)
###############################################################################

# developer level regression testing
test : utest rtest

utest : pflotran
	@if [ -d $(unit_test_dir) ]; then \
		$(MAKE) --directory=$(unit_test_dir) EXE_DIR=${PWD} test; \
	fi

rtest : pflotran
	@if [ -d $(regression_test_dir) ]; then \
		$(MAKE) --directory=$(regression_test_dir) PFLOTRAN=${PWD}/pflotran test; \
	fi

clean-tests : FORCE
	@if [ -d $(unit_test_dir) ]; then \
		$(MAKE) --directory=$(unit_test_dir) EXE_DIR=${PWD} $(MAKECMDGOALS); \
	fi
	@if [ -d $(regression_test_dir) ]; then \
		$(MAKE) --directory=$(regression_test_dir) PFLOTRAN=${PWD}/pflotran $(MAKECMDGOALS); \
	fi

# user level tests to verify pflotran is built correctly
check : FORCE
	@if [ -d $(regression_test_dir) ]; then \
		$(MAKE) --directory=$(regression_test_dir) PFLOTRAN=${PWD}/pflotran $(MAKECMDGOALS); \
	fi

clean-pflotran :
	-rm -f $(CLEANFILES) *.o *.mod *.a *.gcov *.gcda *.gcno;

# Flags
echo-flags :
	@echo ; \
	echo "PFLOTRAN source"; \
	echo "SRC_DIR = $(SRC_DIR)"; \
	echo ; \
	echo "PETSc environment"; \
	echo "PETSC_DIR = $(PETSC_DIR)"; \
	echo "PETSC_ARCH = $(PETSC_ARCH)"; \
	echo ; \
	echo "Flags defined in this makefile"; \
	echo "CFLAGS = $(CFLAGS)"; \
	echo "FFLAGS = $(FFLAGS)"; \
	echo ; \
	echo "MYFLAGS = $(MYFLAGS)"; \
	echo "CPPFLAGS = $(CPPFLAGS)"; \
	echo "FPPFLAGS = $(FPPFLAGS)"; \
	echo ; \
	echo "Flags invoked when compiling fortran source"; \
	echo "FC_FLAGS = $(FC_FLAGS)"; \
	echo "FFLAGS = $(FFLAGS)"; \
	echo "FCPPFLAGS =  $(FCPPFLAGS)"; \
	echo ; \
	echo "Included Libraries" ;\
	echo "LIBS = $(LIBS)"; \
	echo ; \
	echo "PETSC_LIB = $(PETSC_LIB)"; \
	echo ; \


# null rule to force things to happen
FORCE :
