#!/usr/bin/perl
#
# Variables
$version='2023';                            # Version of the code
$home=$ENV{'HOME'};                       # User home directory
$wdir=$ENV{'PWD'};                        # Current working directory
$prdir=$wdir;                             # Polyrate directory as current directory
$srcdir=$prdir.'/src';                    # Polyrate source code directory
$utildir=$prdir.'/util';                  # Polyrate util directory
$sprngdir=$prdir.'/sprng2.0';             # Spring 2.0 ramdom number generator directory

print "\nWelcome to POLYRATE! \n\n";      # Welcome to Polyrate 

&check_poly_path;                         # Check if Polyrate is already installed
&notice_for_user;                         # Note about the two different executables for polyrate (VRC and RP)
&makeclean;                               # Clean source directory using Makefile
&guess_setup;                             # Set compilers and create Makefile
&manual_setup;                            # Manual set up if necessary
if ($vrc_parallel) { &install_sprng; }    # Install random generator code for the VRC version 
&install_pr;                              # Install Polyrate

print "\n";

# Check if Polyrate is Installed

sub check_poly_path{
  $ow_ver=1;
  $ow_def=1;
  # Check Polyrate version
  if (-e "$home/.poly_ver"){                 
    open(my $fh, '<:encoding(UTF-8)', "$home/.poly_ver") or die "Cannot open file '$home/.poly_ver' $!"; # Open .poly_ver file
    my $currentversion = <$fh>;  # Current installed Polyrate version
    chomp $currentversion;
    &logprompt("POLYRATE $currentversion is already installed\n". 
            "in your system. Do you want to update your installation\n".
            "with this POLYRATE $version? ",$ow_ver);
  }  
  # Update path of the default version if needed it
  if (-e "$home/.poly_path"){
    &logprompt("\nDo you want this to be your\n".
               "new default version of POLYRATE?  ",$ow_def);
  }
}

# Function notice for users
# Notice there are two different Polyrate executables: Reaction-Path and Variable Reaction Coordinate
# Variational Transition State Theory

sub notice_for_user{
  print "\n                            Notice to users ";
  print "\n ************************************************************************";
  print "\n Starting from version 2008, POLYRATE has two kinds of executables: \n";
  print "\n 1. RP-VTST for reactions with potential energy barriers (serial code)"; 
  print "\n 2. VRC-VTST for barrierless bimolecular association reactions (MPI code) \n";
  print "\n RP-VTST and VRC-VTST need different executables and they should be ";
  print "\n compiled separately by running this script ";
  print "\n ************************************************************************\n";
}

# Function clean the source directory and executable directory

sub makeclean{
  print "\n Cleaning the src/ directory ... \n";
  chdir $srcdir;
  'rm -f *.o *.mod';  # Remove manually object files and module files
  `make clean`;       # Clean using Makefile
  chdir $prdir;
  chdir $srcdir;
  'rm -f *.exe';     # Remove executable 
  chdir $prdir;
}
                      
# Function find Fortran/C and MPI Fortran/C compilers 

sub guess_setup{
  print "\n";

  $proc=`uname -p`;    # processor
  $os=  `uname`;       # operative system

  chomp $proc;
  chomp $os;

  print "... processor is $proc\n";
  print "... OS is $os\n";

  $vrc_parallel=0;      # RP or VRC-VTST, RP by default
  &logprompt1("\nIs this run used to install RP-VTST or VRC-VTST version? \n",$vrc_parallel);

  if($vrc_parallel) {   # VRC-VTST
    $parallel=1
   }

# Fortran Compilers: Intel/OneAPI - NVIDIA-NVHPC/PGI - LLVM - GCC 

  $gnu=0;      # GCC Fortran Compilers (gfortran)
  $intel=0;    # Intel/OneAPI Fortran Compilers (ifort)
  $pgi=0;      # Portland Group/NVIVIA NVIDIA-NVHPC/PGI Compilers (pgf90 pgf95 pgfortran nvfortran)
  $llvm=0;     # LLVM Fortran Compilers (flang)

# MPI compilers OpenMPI Intel Mvapich2 Mvapich

  $openmpi=0;  # OpenMPI
  $mvapich2=0; # Mvapich2
  $mpich=0;    # Mpich

# Only Linux OS - 64 bit machines are supported

#  if (($os eq 'Linux')and($proc eq 'x86_64')){

# Fortran Compiler

    $fc = find('gfortran','GNU Fortran Compiler - gfortran'); if($fc){$gnu=1};
    if(!$fc){$fc=find('ifort','Intel Fortran Compiler - ifort'); if($fc){$intel=1} };
    if(!$fc){$fc=find('pgf90','Portland Group/NVIDIA Fortran Compiler - pgfortran'); if($fc){$pgi=1} };
    if(!$fc){$fc=find('flang','LLVM Compiler - flang'); if($fc){$llvm=1} };

# MPI Fortran Compiler

    $mpi_f90=find('mpif90','MPI Fortran compiler - mpif90');

# C Compiler

    $cc = find('gcc','GNU C Compiler - gcc');
    if(!$cc){$cc=find('icc','Intel C compiler - icc');};
    if(!$cc){$cc=find('pgcc','PGI/NVIDIA C compiler - pgcc');};
    if(!$cc){$cc=find('clang','LLVM C Compiler- clang');};

# MPI C Compiler 

    $mpi_cc = find('mpicc','MPI C compiler');

# Fortran and C compilers found -  guess ok 

   if (($fc)and($cc)) {$guess_ok=1};

# Compiler paths

   chomp $fc;
   chomp $mpi_f90;
   chomp $cc;
   chomp $mpi_cc;

# Fortran compiler flags

   $f90_compiler=$fc." -O ";
   $mpi_compiler=$mpi_f90." -O ";  

#  MPI parallel Reaction-Path Polyrate version
#   if ($mpi_f90 && !$vrc_parallel){ $parallel=1;}

#  }else{die 'This OS/Machine is not supported'}
}
                                                                              
# Check if compiler options are ok  

sub manual_setup{
  print "\n";
  &logprompt(" Do the options chosen above look OK?",$guess_ok);
  if (not $guess_ok){die 'Restart script or configure manually (modify the ./src/Makefile)'}
}
     
# Function install Polyrate                                                                           

sub install_pr{
  $successful=1;
  print "... installing\n";

  if($ow_def){`echo $prdir > $home/.poly_path`};     # Update Polyrate path file if necessary
  if($ow_ver){`echo $version > $home/.poly_ver`};    # Update Polyrate version file if necessary 

  # Fortran compiler flags 

  if ($gnu){$f90_compiler=$f90_compiler."-fno-automatic -fdefault-integer-8 -DUse_I8"};
  if ($intel){$f90_compiler=$f90_compiler."-save -DUse_I8"};
  if ($pgi){$f90_compiler=$f90_compiler."-i8 -r8 -Mbackslash -DUse_I8"};
  if ($llvm){$f90_compiler=$f90_compiler."  "};

  &create_makefile; # Create Makefile

  if ($successful){
    print "\n---- POLYRATE INSTALLATION COMPLETE ----\n\nHave a nice day! :)\n";
  }
}

# Function read answer yes or no                
sub logprompt{
  my $logicalt;
  if ($_[1] == 0) {$logicalt='no'}
  else {$logicalt='yes'}
  print $_[0]," [ $logicalt ]: ";
  my $ans=<STDIN>;
  $ans;
  if ($ans =~ /n|N/){$_[1]=0}
  if ($ans =~ /y|Y/){$_[1]=1}
}

# Function read RP or VRC
sub logprompt1{
  my $logicalt;
  if ($_[1] == 0){$logicalt='rp'}
  else {$logicalt='vrc'}
  print $_[0]," [ Choose 'RP' or 'VRC' ]: ";
  my $ans=<STDIN>;
  chomp $ans;
  if ($ans =~ /r|R/){$_[1]=0}
  if ($ans =~ /v|V/){$_[1]=1}
}

# Function find program
sub find{
  my $program=$_[0];
  $found = `which $program`;
  if ($found =~ /no $program/){
    $found = 0;
  }
  if ($found){
    print "....found $_[1] :",$found;
    return $found;
  }
  else {
    print "....did not find $_[1] \n";
    return 0;
  }
}

# Function create Makefile
sub create_makefile{
  open (MAKEFILE, ">src/Makefile");
  print ".... creating Makefile \n";
  if ($parallel){ # Parallel
    print MAKEFILE "F90C    = $mpi_compiler\n";
    print MAKEFILE "F77C    = $f90_compiler\n";
    print MAKEFILE "CC      = $mpi_cc\n";
    print MAKEFILE "MPIF90C = $mpi_compiler\n";
    print MAKEFILE "MPIF77C = $mpi_compiler\n";
    print MAKEFILE "MPICC = $mpi_cc\n";
  }
  else {          # Serial
  print MAKEFILE "F90C    = $f90_compiler\n";
  print MAKEFILE "F77C    = $f90_compiler\n";
  print MAKEFILE "CC      = $cc\n";
  }
  print MAKEFILE "VERSION =$version\n";
  print MAKEFILE "VPATH = ../poten    \n";
  print MAKEFILE '# executables that can be built from this makefile

DUMSEXE   = ../exe/polyrate$(VERSION).dum.serial.exe

CH5SEXE   = ../exe/polyrate$(VERSION).ch5.serial.exe  
CLHBRSEXE = ../exe/polyrate$(VERSION).clhbr.serial.exe
CH4OSEXE  = ../exe/polyrate$(VERSION).ch4o.serial.exe 
CMCSEXE   = ../exe/polyrate$(VERSION).cmc.serial.exe  
CWMCSEXE  = ../exe/polyrate$(VERSION).cwmc.serial.exe 
NH3SEXE   = ../exe/polyrate$(VERSION).nh3.serial.exe  
H2NISEXE  = ../exe/polyrate$(VERSION).h2ni.serial.exe 
H3SEXE    = ../exe/polyrate$(VERSION).h3.serial.exe   
HNISEXE   = ../exe/polyrate$(VERSION).hni.serial.exe  
OH3SEXE   = ../exe/polyrate$(VERSION).oh3.serial.exe 
OHCLSEXE  = ../exe/polyrate$(VERSION).ohcl.serial.exe
HO2SEXE   = ../exe/polyrate$(VERSION).ho2.serial.exe';

if ($parallel) {
print MAKEFILE '
CH5PEXE = ../exe/polyrate$(VERSION).ch5.mpi.exe
CH3PEXE = ../exe/polyrate$(VERSION).ch3.mpi.exe
';}
print MAKEFILE '
#User may add new executables here';
  print MAKEFILE "\n\n";

  print MAKEFILE '%.o: %.F',"\n";
  print MAKEFILE chr(9);        # print a tab
  if($parallel){
  print MAKEFILE '$(MPIF90C) -c $<',"\n";
  }
  else {
  print MAKEFILE '$(F90C) -c $<',"\n"; 
  }
  print MAKEFILE '%.o: %.f90',"\n";
  print MAKEFILE chr(9);        # print a tab
  print MAKEFILE '$(F90C) -c $<',"\n"; 
  print MAKEFILE '%.o: %.c',"\n";
  print MAKEFILE chr(9);        # print a tab
  print MAKEFILE '$(CC) -c $<',"\n";
  print MAKEFILE "\n\n";

  if ($vrc_parallel) {  # Parallel
  print MAKEFILE 'OBJ = aamod.o tumme_mod.o acespoly.o alloc.o dattim.o givtst.o intbsv3.o poly40.o \
polyrr.o headr.o interface.o polysz.o ef.o \
hooks.o ivtstm.o polyag.o rtpjac.o \
energetics.o intbsv1.o main_vrcmpi.o \
polyhl.o fromblas.o intbsv2.o poly31.o polymq.o util.o torsion.o fromlapack.o',"\n\n";

  print MAKEFILE 'vrctst_mpi.o : sprng_f.h vrctst_mpi.F',"\n";
  print MAKEFILE chr(9);
  print MAKEFILE '$(MPIF90C) -c vrctst_mpi.F',"\n\n";
#
# The path for linking SPRNG library. Users should modify it to the correct one in their machines.
#
  print MAKEFILE 'SPRNGLIB = -L../sprng2.0/lib -lsprng -lm',"\n\n"
  }
  else {                # Serial
  print MAKEFILE 'OBJ = aamod.o tumme_mod.o acespoly.o alloc.o dattim.o givtst.o intbsv3.o poly40.o \
polyrr.o headr.o interface.o polysz.o ef.o hooks.o ivtstm.o polyag.o rtpjac.o \
energetics.o intbsv1.o main.o polyhl.o fromblas.o intbsv2.o poly31.o \
polymq.o util.o torsion.o fromlapack.o',"\n\n";
  }

  print MAKEFILE 'poly_mpi.o: poly_mpi.F',"\n";
  print MAKEFILE chr(9),'$(MPIF90C) -c poly_mpi.F',"\n";
  print MAKEFILE 'ch3.o: ../poten/ch3.f90',"\n";
  print MAKEFILE chr(9),'$(MPIF90C) -c ../poten/ch3.f90',"\n";
  print MAKEFILE 'ch4o.o: ../poten/ch4o_module.f90 ../poten/ch4o.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/ch4o_module.f90 ../poten/ch4o.f90',"\n";
  print MAKEFILE 'ch5.o: ../poten/ch5_module.f90 ../poten/ch5.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/ch5_module.f90 ../poten/ch5.f90',"\n";
  print MAKEFILE 'chain3.o: ../poten/chain3.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/chain3.f90',"\n";
  print MAKEFILE 'chain4.o: ../poten/chain4.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/chain4.f90',"\n";
  print MAKEFILE 'clhbr.o: ../poten/clhbr.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/clhbr.f90',"\n";
  print MAKEFILE 'cmc.o: ../poten/cmc.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/cmc.f90',"\n";
  print MAKEFILE 'coord3.o: ../poten/coord3.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/coord3.f90',"\n";
  print MAKEFILE 'coord4.o: ../poten/coord4.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/coord4.f90',"\n";
  print MAKEFILE 'cwmc.o: ../poten/cwmc_module.f90 ../poten/cwmc.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/cwmc_module.f90 ../poten/cwmc.f90',"\n";
  print MAKEFILE 'dumpot.o: ../poten/dumpot.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/dumpot.f90',"\n";
  print MAKEFILE 'h2ni.o: ../poten/h2ni_module.f90 ../poten/h2ni.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/h2ni_module.f90 ../poten/h2ni.f90',"\n";
  print MAKEFILE 'h3.o: ../poten/h3.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/h3.f90',"\n";
  print MAKEFILE 'hni.o: ../poten/hni.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/hni.f90',"\n";
  print MAKEFILE 'ho2.o: ../poten/ho2.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/ho2.f90',"\n";
  print MAKEFILE 'nh3.o: ../poten/nh3_module.f90 ../poten/nh3.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/nh3_module.f90 ../poten/nh3.f90',"\n";
  print MAKEFILE 'oh3.o: ../poten/oh3.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/oh3.f90',"\n";
  print MAKEFILE 'ohcl.o: ../poten/ohcl.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/ohcl.f90',"\n";
  print MAKEFILE 'setup3.o: ../poten/setup3.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/setup3.f90',"\n";
  print MAKEFILE 'setup4.o: ../poten/setup4.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/setup4.f90',"\n";
  print MAKEFILE 'surf3.o: ../poten/surf3.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/surf3.f90',"\n";
  print MAKEFILE 'surf4.o: ../poten/surf4.f90',"\n";
  print MAKEFILE chr(9),'$(F90C) -c ../poten/surf4.f90',"\n";
  print MAKEFILE '#User may add line here to compile potential file.  Start second line with a tab',"\n";
  print MAKEFILE "\n\n";
  
  print MAKEFILE '#User may add lines here to make the executable.  Example:',"\n";
  print MAKEFILE '#SURFACE:',"\n";
  print MAKEFILE '#',chr(9),'make $(SURFACEEXE)',"\n";
  print MAKEFILE '#$(SURFACEEXE):$(OBJ) dummy_mpi.o surface.o',"\n";
  print MAKEFILE '#',chr(9),'$(F90C) -o $(SURFACEEXE) $(OBJ) dummy_mpi.o surface.o',"\n","\n";

  print MAKEFILE 'DUMS:',"\n",chr(9);
  print MAKEFILE 'make -s $(DUMSEXE)',"\n";
  print MAKEFILE '$(DUMSEXE):$(OBJ) dummy_mpi.o dumpot.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(DUMSEXE) $(OBJ) dummy_mpi.o dumpot.o',"\n","\n";

  print MAKEFILE 'CH4OS:',"\n",chr(9);
  print MAKEFILE 'make -s $(CH4OSEXE)',"\n";
  print MAKEFILE '$(CH4OSEXE):$(OBJ) dummy_mpi.o ch4o.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(CH4OSEXE) $(OBJ) dummy_mpi.o ch4o.o ch4o_module.o',"\n","\n";

  print MAKEFILE 'CH5S:',"\n",chr(9);
  print MAKEFILE 'make -s $(CH5SEXE)',"\n";
  print MAKEFILE '$(CH5SEXE):$(OBJ) dummy_mpi.o ch5.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(CH5SEXE) $(OBJ) dummy_mpi.o ch5.o ch5_module.o',"\n","\n";

  print MAKEFILE 'CLHBRS:',"\n",chr(9);
  print MAKEFILE 'make -s $(CLHBRSEXE)',"\n";
  print MAKEFILE '$(CLHBRSEXE):$(OBJ) dummy_mpi.o clhbr.o setup3.o surf3.o coord3.o chain3.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(CLHBRSEXE) $(OBJ) dummy_mpi.o clhbr.o setup3.o surf3.o coord3.o chain3.o',"\n","\n";

  print MAKEFILE 'CMCS:',"\n",chr(9);
  print MAKEFILE 'make -s $(CMCSEXE)',"\n";
  print MAKEFILE '$(CMCSEXE):$(OBJ) dummy_mpi.o cmc.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(CMCSEXE) $(OBJ) dummy_mpi.o cmc.o',"\n","\n";

  print MAKEFILE 'CWMCS:',"\n",chr(9);
  print MAKEFILE 'make -s $(CWMCSEXE)',"\n";
  print MAKEFILE '$(CWMCSEXE):$(OBJ) dummy_mpi.o cwmc_module.o cwmc.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(CWMCSEXE) $(OBJ) dummy_mpi.o cwmc_module.o cwmc.o',"\n","\n";

  print MAKEFILE 'H2NIS:',"\n",chr(9);
  print MAKEFILE 'make -s $(H2NISEXE)',"\n";
  print MAKEFILE '$(H2NISEXE):$(OBJ) dummy_mpi.o h2ni_module.o h2ni.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(H2NISEXE) $(OBJ) dummy_mpi.o h2ni_module.o h2ni.o',"\n","\n";

  print MAKEFILE 'H3S:',"\n",chr(9);
  print MAKEFILE 'make -s $(H3SEXE)',"\n";
  print MAKEFILE '$(H3SEXE):$(OBJ) dummy_mpi.o h3.o setup3.o surf3.o coord3.o chain3.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(H3SEXE) $(OBJ) dummy_mpi.o h3.o setup3.o surf3.o coord3.o chain3.o',"\n","\n";

  print MAKEFILE 'HNIS:',"\n",chr(9);
  print MAKEFILE 'make -s $(HNISEXE)',"\n";
  print MAKEFILE '$(HNISEXE):$(OBJ) dummy_mpi.o hni.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(HNISEXE) $(OBJ) dummy_mpi.o hni.o',"\n","\n";

  print MAKEFILE 'HO2S:',"\n",chr(9);
  print MAKEFILE 'make -s $(HO2SEXE)',"\n";
  print MAKEFILE '$(HO2SEXE):$(OBJ) dummy_mpi.o ho2.o setup3.o surf3.o coord3.o chain3.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(HO2SEXE) $(OBJ) dummy_mpi.o ho2.o setup3.o surf3.o coord3.o chain3.o',"\n","\n";

  print MAKEFILE 'NH3S:',"\n",chr(9);
  print MAKEFILE 'make -s $(NH3SEXE)',"\n";
  print MAKEFILE '$(NH3SEXE):$(OBJ) dummy_mpi.o nh3_module.o nh3.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(NH3SEXE) $(OBJ) dummy_mpi.o nh3_module.o nh3.o',"\n","\n";

  print MAKEFILE 'OH3S:',"\n",chr(9);
  print MAKEFILE 'make -s $(OH3SEXE)',"\n";
  print MAKEFILE '$(OH3SEXE):$(OBJ) dummy_mpi.o oh3.o setup4.o surf4.o coord4.o chain4.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(OH3SEXE) $(OBJ) dummy_mpi.o oh3.o setup4.o surf4.o coord4.o chain4.o',"\n","\n";

  print MAKEFILE 'OHCLS:',"\n",chr(9);
  print MAKEFILE 'make -s $(OHCLSEXE)',"\n";
  print MAKEFILE '$(OHCLSEXE):$(OBJ) dummy_mpi.o ohcl.o setup3.o surf3.o coord3.o chain3.o',"\n",chr(9);
  print MAKEFILE '$(F90C) -o $(OHCLSEXE) $(OBJ) dummy_mpi.o ohcl.o setup3.o surf3.o coord3.o chain3.o',"\n";
  print MAKEFILE "\n";

# VRC Polyrate version only - CH3 + CH3 association test
  if($parallel){
   print MAKEFILE 'CH3:',"\n",chr(9);
   print MAKEFILE 'make -s $(CH3PEXE)',"\n";
   print MAKEFILE '$(CH3PEXE):$(OBJ) dummy_mpi.o vrctst_mpi.o ch3.o',"\n",chr(9);
   print MAKEFILE '$(MPIF90C) -o $(CH3PEXE) $(OBJ) dummy_mpi.o vrctst_mpi.o ch3.o $(SPRNGLIB)',"\n";
   print MAKEFILE "\n";
  }
# Parallel version of RP Polyrate
# if ($parallel && !$vrc_parallel){
#  print MAKEFILE 'CH5P:',"\n",chr(9);
#  print MAKEFILE 'make -s $(CH5PEXE)',"\n";
#  print MAKEFILE '$(CH5PEXE):$(OBJ) poly_mpi.o ch5.o',"\n",chr(9);
#  print MAKEFILE '$(MPIF90C) -o $(CH5PEXE) $(OBJ) poly_mpi.o ch5.o',"\n"; 
#   print MAKEFILE "\n";}
#
  print MAKEFILE "\n";
  print MAKEFILE "clean:","\n",chr(9),"rm -f *.o *.mod","\n";
  close MAKEFILE;
  print ".... done with Makefile \n";
}


# Function install SPRNG2.0 random number generator 
sub install_sprng {
  print "\n Installing SPRNG2.0 library ... \n";
  chdir $sprngdir;
  $ccline = 'CC = '.$mpi_cc;
  replace ($ccline);
  `make realclean`;
  `make`;
  if (-e "$sprngdir/lib/libsprng.a") {
  print "SPRNG 2.0 installation complete \n\n";
  } else {die "Failed to install SPRNG2.0 library";}
  chdir $prdir;
}


# Function replace line in SPRNG2.0 Makefile
sub replace {
  $replace = $_[0];

  local @lines;
  local $data_file;
  $data_file= './SRC/make.GENERIC';
  open DATA, "$data_file" or die "Cannot open $data_file $!";
  my @array_of_data = <DATA>;
  close (DATA);
  $key='CC =';
  @array_search = grep{/$key/}@array_of_data;
  chomp  @array_search;
  $search = @array_search[0];
  
  open(NAME,"<$data_file");
  while(<NAME>){
  $_ =~ s/$search/$replace/g;
  push @lines, $_;}
  close(NAME);open(NAME,">$data_file");
  foreach $line (@lines){print NAME $line}
}
