# SPDX-FileCopyrightText: 2025 Deutsches Elektronen-Synchrotron DESY
# SPDX-License-Identifier: AGPL-3.0-only

# The makefile compiles (type make) and makes an executable called XCASCADE.x

EXEPATH = .

EXE = $(EXEPATH)/xcascade3d.x
LD = ld

# choose the compiles among gfortran, ifort
ifeq ($(c),gf)
	F90 = gfortran
	# Flags for quick compilation if you compile it as "make c=gf"
	F90FLAGS = -ffree-line-length-0 -fopenmp
else ifeq ($(c),gfd)
	F90 = gfortran
	# Flags for debugging if you compile it as "make c=gfd"
	F90FLAGS = -ffree-line-length-0 -fopenmp
	F90FLAGS += -Waliasing -Wampersand -Wsurprising -Wintrinsics-std -Wintrinsic-shadow -Wline-truncation
	F90FLAGS += -Wuninitialized -O -Wextra -Wno-unused-variable
	F90FLAGS += -fbounds-check -g -fbacktrace -ffpe-trap=zero,overflow,underflow
	#90FLAGS += -static -static-libgfortran 
	#~ F90FLAGS +=  -Wno-unused-dummy-argument -pedantic -std=f2008 -Wtabs
	# F90FLAGS += -fdefault-real-8   # dangerous!
else ifeq ($(c),gfo)
	F90 = gfortran
	# Flags for maximum performance if you compile it as "make c=gfo"
	F90FLAGS = -ffree-line-length-0 -fopenmp -O3 -ffast-math -fexpensive-optimizations
	 #F90FLAGS += -static -static-libgfortran 
	# F90FLAGS += -ftree-vectorize
else
	# choosing ifort; you can change the next line to F90 = ifx if you use ifx compiler
	F90 = ifort
	
	ifneq (${OMP},) # OMP=no means no omp
		F90FLAGS = -qmkl
	else  # there is omp by default
		F90FLAGS = -qopenmp -D OMP_inside
		F90FLAGS += -qmkl=parallel
		# use heap instead of stack for array larger than 100
		F90FLAGS += -heap-arrays 10
	endif
	
	ifeq ($(db),y)
		# flags for debugging	
		F90FLAGS += -debug all -check all -fpe0 -O0 -g -fp-model precise -traceback -gen-interfaces -warn interfaces -fpp
		#F90FLAGS += -g -fbounds-check
	else
		# Flags for maximum performance
		F90FLAGS += -O5 -fpp -ipo -march=native
		#F90FLAGS +=  -ffast-math
		#ulimit -s unlimited
	endif
endif

# list the files necessary for the compilation in the order of their dependencies
OBJS = DefaultParameters.o Constants.o Objects.o Read_input.o Monte_Carlo.o Write_output.o 3D-Cascading_code.o
# Find the libraries if necessary, depending on the compiler
default:
	@echo " "
ifeq ($(c),gf)
	@echo "Compiling XCASCADE3D with gfortran"
else ifeq ($(c),gfd)
	@echo "Debugging XCASCADE3D with gfortran"
else ifeq ($(c),gfo)
	@echo "Compiling XCASCADE with gfortran"
else ifeq ($(db),y)
	@echo "Debugging XCASCADE with ifort"
else
	@echo "Compiling XCASCADE3D with ifort"
endif

# autoclean before the compilation
	rm -f *.o
	rm -f *.mod
	$(MAKE) $(EXE)
# autoclean after the compilation
	rm *.o
	rm *.mod
	
# compile and load
$(EXE):	$(OBJS)
	$(F90) $(F90FLAGS) $(LDFLAGS)  -o $(EXE)  $(OBJS)
	
.SUFFIXES: .f90 .o .mod
.f90.o:
	$(F90) $(F90FLAGS) -c $*.f90

clean:
	rm -f *.o
	rm -f *.mod
	rm -f xcascade3d.x
	rm -f *__*

# cleaning and removing all results - be careful!
cleanall:
	rm -f *.o
	rm -f *.mod
	rm -f *__*
	rm -f xcascade3d.x
	rm -f *.dat
	rm -f  OUTPUTs/*.dat
	rm -f xcascade3d/*.dat
	rm -f *.eps
	rm -f *.png
	rm -f *.out
	rm -f plots/*png
	rm -f plots/*eps
