#Makefile of the RMC_POT++ v2023.1 program for Linux
#
#You do not need to edit the altern.h file for switching the option switches. 
#Use command line options for make to switch ON the option switches located in the altern.h file.
#The switching off the options in the altern.h is done automtically by this Makefile, and only those
#option will be on, for which a command line option will be passed to the make, see their description below, or type make help!
#See the description of the option switches in the code or on the RMC website.
#The name of the executable will contain indicators of the used option switches
#to avoid confusion. The file names will always begin with 'rmc' and end with '.exe'.
#The command line options for make, and the indicators in the executable name are the following:
#AENET=0	_aen	for _AENET
#AGC=0		_agc    for _ADVANCED_GEOM_CONST
#EDIFF=0        _ediff  for _READ_EDIFF reading electron diffraction data as well, only important for fixed format data reading
#LOC=0		_loc    for _LOCAL_INV
#LOC=ns		_locns  for _LOC_INV and _LOCAL_INV_NS
#MULQ=0		_mq	for _MUL_SCAT_VECTOR
#NOPER=0	_nop	for _NO_PERIODIC
#RGR=0		-rgrX	for _R_SWITCH_GR_MIN_1
#VIBRAMP=0	_vamp	for _VIBR_AMP
#NEI=0          _nei	for _NEI
#NEI=e          _neie	for _NEI and _NEIE
#OH=0		_oh	for _OLD_HEADER
#AVM=0		_avm	for _AV_MOVE
#AT=0 		_atlas	for _ATLAS
#I32=0		_i32    for _USE_INT32
#TEST=0		_t	for _TEST_MODE
#TESTDUR=0	_tdur	for _TEST_MODE and WRITE_TH_DURATION=1 writes thread duration
#CHI=0		_chi	for _WRITE_CHI2_DETAIL
#ARCH=X		this adds the X to the end of the file name before extension
#INT=0		_i	compile with intel icc
#MAC=0		_mac	for _CODE_WARRIOR_MAC

#For example compiling the code for advanced geometrical constraint _ADVANCED_GEOM_CONST
#using version name v2023.1
#     make AGC=0 ARCH=_v2.5
#This will result in executable named rmcp_agc_v2023.1.exe
  
#The program name and its parts. WARNING! DO NOT add spaces before or after the values, otherwise
#the program name will not be consecutive, and the linking will fail!
PROGRAM =rmcp# program base name
LOC_EXT =_loc#indicator in the programme name, that _LOCAL_INV option is used
AT_EXT =_atlas# indicator in the program name, that ATLAS is used  
TEST_EXT =_t# indicator in the program name, that it was compiled for test mode
TESTDUR_EXT =_tdur# indicator in the program name, that it was compiled for test mode and writes timing values
OLDOUT_EXT =_oo# indicator in the program name, that it was compiled with old format output option
OH_EXT =_oh# indicator in the program name, that it was compiled with old header option
MULQ_EXT =_mq# indicator in the program name, that it was compiled with _MUL_SCAT_VECTOR 
RGR_EXT =_rgr# indicator in the program name, that it was compiled with _R_SWITCH_GR_MIN_1 ON, X is the power of r, only given, if X>1 
NEI_EXT =_nei# indicator in the program name, that it was compiled with _NEI ON 
AVM_EXT = _avm# indicator in the program name, that it was compiled with _AV MOVE ON
AGC_EXT = _agc# indicator in the program name, that it was compiled with _ADVANCED_GEOM_CONST 
MAC_EXT =_mac# indicator in the program name, that it was compiled with _CODE_WARRIOR_MAC ON 
I32_EXT =_i32# indicator in the program name, that it was compiled with _USE_INT32 ON 
CHI_EXT =_chi# indicator in the program name, that it was compiled with _WRITE_CHI2_DETAIL ON 
NOP_EXT =_nop# indicator in the program name, that it was compiled with _NO_PERIODIC option ON
EDIFF_EXT =_ediff# indicator in the program name, that it was compiled with _READ_EDIFF option ON
VIBR_EXT =_vamp# indicator in the program name, that it was compiled with _VIBR_AMP option ON 
AENET_EXT =_ann# indicator in the program name, that it was compiled with the _AENET option ON 
ARCH_EXT =# indicator in the program name, for example version number
EXT =.exe# file extension
EXENAME:=$(PROGRAM)
MY_BIN_DIR:=/rmc/gereben/bin

#if architecture indicator ARCH was specified in the command line set its value
ifeq ("$(origin ARCH)","command line")
	ARCH_EXT:=$(ARCH)
#set the bin directory for the user
#	ifeq ($(ARCH) , 64)
#		MY_BIN_DIR:=/home/gereben/bin
#	endif
#	ifeq ($(ARCH) , 8p64)
#		MY_BIN_DIR:=/home/gereben/bin
#	endif
#	ifeq ($(ARCH) , 03)
#		MY_BIN_DIR:=/home/gereben/bin
#	endif
endif

#default compiler is g++
#since the version 2.0 the new gcc gave warnings regarding optimazition problems in Topology::GetParams, which could not be amended, so to avoid them lower
#optimazition in used for that routine 
OBJDIR:= Linuxobj
CC:= g++ -Wall -O4 -std=c++14 -lpthread -g
CC2:= g++ -Wall -O2 -std=c++14 -lpthread -g
LD:= g++ -Wall -O4 -std=c++14 -pthread -g
#these are for debugging with VSCODE
#CC:= g++ -Wall  -std=c++14 -lpthread -g
#CC2:= g++ -Wall -std=c++14 -lpthread -g
#LD:= g++ -Wall -std=c++14 -pthread -g


#object files
OBJS := $(addprefix $(OBJDIR)/, altern.o AvCoordConst.o BondValenceSumConst.o CalcData.o CalcPart.o ChiSquared.o CommonNeighConst.o\
CoordNumbConst.o CosDistrConst.o data.o DataMat.o ExptsData.o FNC_POT.o global.o History.o HistoSet.o\
makemove.o makemovecus.o Move.o NeighbourList.o PPCFSet.o RMC_POT.o\
RunParams.o SimpleCfg.o SecondNeighConst.o Threads.o  utilities.o Topology.o)
OBJ_AENET :=  $(addprefix $(OBJDIR)/, Aenet.o)

#include files
INCS := altern.h classes1.h classes2.h data.h global.h\
Move.h NeighbourList.h Threads.h units.h utilities.h Topology.h
INC_AT= rmcblas.h
INC_AENET = Aenet.h

#This will be the objects and includes together
DEPENDENCY :=

LIBS :=
#blas library for ATLAS, change the path, if necessary
LIB_AT = -L$ /usr/local/atlas/lib -lcblas -latlas
#LIB_AT = -L$ /rmc/gereben/ATLASsrc-3.6/ATLAS/lib/Linux_HAMMER64SSE2_2 -lcblas -latlas
#library for aenet, change path if necessary
LIB_AENET = libaenet.a liblbfgsb.a -lgfortran -lblas

#containing the compiler option to pass (the combination of option switches to switch ON 
#in the altern.h file).
#It can only switch ON options, which are otherwise switched OFF in the file, cannot turn off switches
# which are switched ON in the file!
SWITCH :=-D_GNU_LINUX

ifdef AENET
	SWITCH := $(SWITCH) -D_AENET
	EXENAME :=$(EXENAME)$(AENET_EXT)
	INCS += $(INC_AENET)
	OBJS += $(OBJ_AENET)
	LIBS += $(LIB_AENET)
endif

ifdef AGC
	SWITCH := $(SWITCH) -D_ADVANCED_GEOM_CONST
	EXENAME :=$(EXENAME)$(AGC_EXT)
endif 

ifdef EDIFF
	SWITCH := $(SWITCH) -D_READ_EDIFF
	EXENAME :=$(EXENAME)$(EDIFF_EXT)
endif

ifdef LOC
	SWITCH := $(SWITCH) -D_LOCAL_INV
	EXENAME :=$(EXENAME)$(LOC_EXT)
	ifeq ($(LOC),ns)
		SWITCH := $(SWITCH) -D_LOCAL_INV_NS
		EXENAME :=$(EXENAME)ns
	endif
endif

ifdef MULQ
	SWITCH := $(SWITCH) -D_MUL_SCAT_VECTOR
	EXENAME :=$(EXENAME)$(MULQ_EXT)
endif

ifdef NOPER
	SWITCH := $(SWITCH) -D_NO_PERIODIC
	EXENAME :=$(EXENAME)$(NOP_EXT)
endif

ifdef RGR
	SWITCH := $(SWITCH) -D_R_SWITCH_GR_MIN_1 
	EXENAME :=$(EXENAME)$(RGR_EXT)
endif

ifdef VIBRAMP
	SWITCH := $(SWITCH) -D_VIBR_AMP
	EXENAME :=$(EXENAME)$(VIBR_EXT)
endif 


ifdef AVM
	SWITCH := $(SWITCH) -D_AV_MOVE
	EXENAME :=$(EXENAME)$(AVM_EXT)
endif

ifdef NEI
	SWITCH := $(SWITCH) -D_NEI
	EXENAME :=$(EXENAME)$(NEI_EXT)
	ifeq ($(NEI),e)
		SWITCH := $(SWITCH) -D_NEIE
		EXENAME :=$(EXENAME)e
	endif
endif

ifdef AT
	SWITCH := $(SWITCH) -D_ATLAS
	INCS += $(INC_AT)
	LIBS += $(LIB_AT)
	EXENAME :=$(EXENAME)$(AT_EXT)
endif

ifdef I32
	SWITCH := $(SWITCH) -D_USE_INT64
	EXENAME :=$(EXENAME)$(I32_EXT)
endif

ifdef OH
	SWITCH := $(SWITCH) -D_OLD_HEADER
	EXENAME :=$(EXENAME)$(OH_EXT)
endif

ifdef MAC
	SWITCH := $(SWITCH) -D_CODE_WARRIOR_MAC
	EXENAME :=$(EXENAME)$(MAC_EXT)
endif

ifdef CHI
	SWITCH := $(SWITCH) -D_WRITE_CHI2_DETAIL
	EXENAME :=$(EXENAME)$(CHI_EXT)
endif
 
ifdef TEST
	SWITCH := $(SWITCH) -D_TEST_MODE 
	EXENAME :=$(EXENAME)$(TEST_EXT)
else
	ifdef TESTDUR
		SWITCH := $(SWITCH) -D_TEST_MODE -DWRITE_TH_DURATION=1
		EXENAME :=$(EXENAME)$(TESTDUR_EXT)
	endif
endif

#Intel C++ compiler should be used, if INT=0 is specified as command line argument
ifeq ("$(origin INT)","command line")
	CC:=icpc -O3
	CC2:=icpc -O3
	LD:=icpc -Wall -O3
	EXENAME :=$(EXENAME)_i
endif

EXENAME:=$(EXENAME)$(ARCH_EXT)$(EXT) #adding the file extension
DEPENDENCY := $(OBJS) $(INCS)

#compile and link
$(EXENAME): $(DEPENDENCY)
	$(LD) $(SWITCH) -o $(EXENAME) $(OBJS) $(LIBS)

#install as root !!!
install: $(EXENAME)
	#install -m 755 $(EXENAME) /usr/local/bin
	install $(EXENAME) $(MY_BIN_DIR)

#delete all compiled and installed files
clean:
	rm -f $(OBJS)
	rm -f ${OBJ_AENET}

cleanexe:
	rm -f $(EXENAME)
#	rm -f /usr/local/bin/$(EXENAME)

.PHONY: clean cleanexe install help

#rule for compilation (warning all)
$(OBJDIR)/%.o: %.cpp
	@mkdir -p $(OBJDIR)
	$(CC) $(SWITCH) -c -o $@ $<
	
$(OBJDIR)/Topology.o: Topology.cpp
	$(CC2) $(SWITCH) -c -o $@ $<	

.SUFFIXES: .cpp .o

help:
	@echo USAGE of the Makefile for RMC_POT version 2023.1 
	@echo The switching off the options in the altern.h is done automtically by this Makefile, and only those
	@echo option will be on, for which a command line options will be passed to the make, see their description below!
	@echo See the description of the option switches in the code or on the RMC website.
	@echo The name of the executable will contain indicators of the used option switches
	@echo to avoid confusion. The file names will always begin with 'rmcp' and end with '.exe'.
	@echo 
	@echo The command line options for make, and the indicators in the executable name are the following:
	@echo 		*** Functionality related ***
	@echo AENET=0		_aen	for _AENET,                 handling ANN potential	
	@echo AGC=0		_agc    for _ADVANCED_GEOM_CONST,   advanced geometrical constraints
	@echo EDIFF=0           _ediff  for _READ_EDIFF,            reading electron diffraction data as well
	@echo LOC=0		_loc	for _LOCAL_INV,             local invariance calculation
	@echo LOC=ns		_locns  for _LOCAL_INV_NS,          local invariance calculation, local histogram not saved
	@echo MULQ=0		_mq	for _MUL_SCAT_VECTOR,       fit X*Y(X) for neutron (X=Q, Y=S), X-ray (X=Q, Y=F) and electron diffr. (X=g, Y=F)
	@echo NOPER=0		_nop	for _NO_PERIODIC,           not to use periodic boundary conditions, spherical sample
	@echo RGR=0		_rgr	for _R_SWITCH_GR_MIN_1,     fit r^N*[g(r)-1] instead of g(r)
	@echo VIBRAMP=0		_vamp	for _VIBR_AMP,              vibrational amplitude calculation
	@echo 		*** Output related ***
	@echo NEI=0             _nei	for _NEI,                   saving the neighbourlist into the *.nei file
	@echo NEI=e             _neie	for _NEI and _NEIE          saving the neighbourlist and the squared distances into the *.nei file
	@echo OH=0		_oh	for _OLD_HEADER             use old *.h header
	@echo AVM=0		_avm    for _AV_MOVE                the move in each direction separately accumulated for every atom and displayed 
	@echo 		*** Computation related ***
	@echo AT=0 		_atlas	for _ATLAS                  use ATLAS library
	@echo I32=0		_i32    for _USE_INT32              use 32-bit integers for long
	@echo 		*** Developer section ***
	@echo TEST=0		_t	for _TEST_MODE              test mode
	@echo TESTDUR=0		_tdur	for _TEST_MODE with timing  test mode with timing values
	@echo CHI=0		_chi  	for _WRITE_CHI2_DETAIL      write the chi2 values to *.chi for every rejected move
	@echo 		*** Platform related
	@echo INT=0		_i	compile with Intel icc      
	@echo MAC=0		_mac	for _CODE_WARRIOR_MAC	
	@echo 		*** General ***
	@echo ARCH=X	        _X                                  this adds the X to the end of the file name before extension (version indicator)
	@echo
	@echo For example compiling the code version 2023.1 for advancd geometrical constraints with 64 bit integers for long int,
	@echo 	make AGC=0 ARCH=_v2023.1 
	@echo This will result in executable named rmcp_agc_v2023.1.exe
	
