#!/bin/bash
#SBATCH -N 1
#SBATCH --threads-per-core=1
#SBATCH --cpus-per-task=1
#SBATCH --mem=20G
#SBATCH -t 24:00:00
#SBATCH --output=%x-%j.o
#SBATCH --error=%x-%j.e
#SBATCH --signal=B:USR1@120
print_help() {
echo "
This tool runs all the necessary steps to get the g-values. It works with some
flags:
-b Use this flag to AVOID computation of frequencies.
-c <charge=0> charge of the system.
-d <directory='.'> directory containing at least model.xyz
-e Use this flag to AVOID computation of gvalues. Flags -f and -g are
unuseful when this flag is activated.
-f <hyperfine=''> indexes of atoms to be included in hyperfine corrections.
If the argument of this flag starts with g, the guess util
'eproducer iHFC_fromxyz' is used to find the H, O, and N atoms around the
indexes atoms with the indexes given in the arguments. If you use the
guess util, be sure to add the depth of the neighborhood with the letter
d. E.g. 'g4,5d3' finds the relevant atoms in the 3-depth-neigborhood of
the atoms 4 and 5.
-g <reference_mol=''> guess the location of the radical assuming an
abstraction process. Give the path of the file of the molecule before
the abstraction.
-m <multiplicity=2> multiplicity of the system.
-n <prior_name='model'> name of the input and output files. The script needs
at least a file called prior_name.xyz in the running directory (-d). Then,
it creates files called prior_name_opt., prior_name_epr., etc.
-o Use this flag to AVOID the optimization step. <prior_name>_opt.xyz must
exist, then.
-p <processors=16> number of processors used in the orca calculations.
-P Use this flag to ENABLE preemption. When the job is preempted (or hits
its time limit) it resubmits itself with the same allocation (processors,
nice value, job name and partition) using the -R restart option, so a
higher priority job can run first.
-r <reference_mol=''> guess the location of the radical assuming an
abstraction process. Give the path of the file of the molecule before
the abstraction.
-R Use this flag to RESTART the optimization. It uses the file
<prior_name>_opt.xyz as the input geometry for the optimization.
-s Use this flag to delete orca files like gbw...
-x <xc='B3LYP EPR-II'> functional and basis set for the g-value calculation.
The default is B3LYP EPR-II, which is a good choice for g-values.
-h prints this message.
-v verbose.
"
exit 0
}
bdes='true'
charge=0
directory='.'
mult=2
optimization='true'
epr='true'
processors=''
hyperfine=''
prior_name='model'
xc='B3LYP EPR-II'
restart='false'
preemption='false'
sweep='false'
while getopts 'bc:d:ef:m:n:op:Pr:Rsx:vh' flag;
do
case "${flag}" in
b) bdes='false' ;;
c) charge=${OPTARG} ;;
d) directory=${OPTARG} ;;
e) epr='false' ;;
f) hyperfine=${OPTARG} ;;
m) mult=${OPTARG} ;;
n) prior_name=${OPTARG} ;;
o) optimization='false' ;;
p) processors=${OPTARG} ;;
P) preemption='true' ;;
r) reference_mol=${OPTARG} ;;
R) restart='true' ;;
s) sweep='true' ;;
x) xc=${OPTARG} ;;
v) verbose='-v' ;;
h) print_help ;;
*) echo "for usage check: eproducer <function> -h" >&2 ; exit 1 ;;
esac
done
source "$(eproducer basics -path)" Gvals $verbose
load_modules
if [[ -z "$processors" ]]
then
if [[ -n "$SLURM_CPUS_ON_NODE" ]]
then
processors=$SLURM_CPUS_ON_NODE
else
processors=1
fi
fi
# ==== preemption =============================================================
# Resubmits the current job with the same allocation so a higher priority job
# can run first. Triggered by the trap set below when the job is preempted.
restart_job() {
verbose "Job preempted: resubmitting with the same allocation (-R restart)."
# there is no SLURM env var for the nice value, so query it from scontrol
local nice_val
nice_val=$(scontrol show job "$SLURM_JOB_ID" 2>/dev/null \
| grep -oP 'Nice=\K-?[0-9]+')
: "${nice_val:=0}"
if $bdes ; then bdes_flag='' ; else bdes_flag='-b'; fi
if $epr ; then epr_flag='' ; else epr_flag='-e' ; fi
if $optimization; then opt_flag='' ; else opt_flag='-o' ; fi
if $sweep ; then swe_flag='-s' ; else swe_flag='' ; fi
sbatch -n "$processors" \
--nice="$nice_val" \
-J "$SLURM_JOB_NAME" \
--partition="s.otter,c.otter" \
--qos=low \
"$(eproducer gval_workflow -path)" -c "$charge" \
-d "$directory" \
-f "$hyperfine" \
-m "$mult" \
-n "$prior_name" \
-p "$processors" \
-P \
-r "$reference_mol" \
-R \
-s "$sweep" \
-x "$xc" \
$bdes_flag $epr_flag $opt_flag $swe_flag $verbose
exit 0
}
if [[ "$preemption" == 'true' && -n "$SLURM_JOB_ID" ]]
then
qos_value=$(for i in $(scontrol show job "$SLURM_JOB_ID"); do echo $i; done | grep -i qos)
echo $qos_value | grep -q "QOS=low" || fail "when preemption, qos has to be set to qos=low"
# USR1 is delivered 120 s before the time limit / preemption thanks to the
# '#SBATCH --signal=B:USR1@120' directive above; SIGTERM is what SLURM sends
# after the configured GraceTime when preempting. Both trigger a resubmit.
trap restart_job SIGUSR1 SIGTERM
else
# The --signal directive is static and fires on every run. Without -P we must
# ignore USR1, otherwise its default action would kill the job 120 s early.
trap '' SIGUSR1
fi
# Runs orca in the background and waits for it, so a preemption signal is
# handled by the trap above promptly instead of being blocked by a foreground
# orca process.
run_orca() {
local inp=$1 out=$2
$orca "$inp" > "$out" &
wait $!
}
# starting information
verbose "JOB information"
echo " * Date:"
date
echo " * Command:"
echo "$0" "$@"
cd $directory
# ==== optimization ===========================================================
if $optimization
then
if $restart
then
xyz_ref_file=${prior_name}_opt.xyz
else
xyz_ref_file=${prior_name}.xyz
fi
verbose Optimization
cat << EOF > ${prior_name}_opt.inp
! B3LYP EPR-II OPT
%pal nprocs $processors end
%basis
NewGTO Cl "Def2-TZVP" end
NewGTO Br "Def2-TZVP" end
NewGTO S "Def2-TZVP" end
NewGTO P "Def2-TZVP" end
end
*XYZFile $charge $mult $xyz_ref_file
EOF
run_orca ${prior_name}_opt.inp ${prior_name}_opt.out
grep -q "ORCA TERMINATED NORMALLY" ${prior_name}_opt.out \
&& optimization='false' || fail "optimization failed, check ${prior_name}_opt.out"
else
[ -f ${prior_name}_opt.xyz ] || run_orca ${prior_name}_opt.inp \
${prior_name}_opt.out
fi
if grep -q "ORCA TERMINATED NORMALLY" ${prior_name}_opt.out && $sweep
then
rm ${xyz_file%.xyz}_opt.densities
rm ${xyz_file%.xyz}_opt.engrad
rm ${xyz_file%.xyz}_opt.gbw
rm ${xyz_file%.xyz}_opt.inp
rm ${xyz_file%.xyz}_opt.opt
rm ${xyz_file%.xyz}_opt_property.txt
rm ${xyz_file%.xyz}_opt_trj.xyz
rm ${xyz_file%.xyz}_opt.gori.xyz
fi
# ==== epr ====================================================================
if $epr
then
rad_loc=""
if [[ "$reference_mol" != "" ]]
then
location=$(eproducer rad_loc $reference_mol ${prior_name}_opt.xyz)
rad_loc="$location,"
fi
if [[ ${hyperfine: 0: 1} == 'g' ]]
then
nog=${hyperfine: 1} # remove g
radicals="$rad_loc${nog%d*}" # list of radicals
depth=${nog#*d} # depth
tmp_var=$(eproducer iHFC_fromxyz ${prior_name}_opt.xyz "[$radicals]" \
"$depth")
mapfile -t hyperfine < <(echo $tmp_var | grep -oP '\[\K[^\]]+')
fi
verbose g-values
cat <<EOF > ${prior_name}_epr.inp
! $xc AUTOAUX
%basis
NewGTO Cl "Def2-TZVP" end
NewGTO Br "Def2-TZVP" end
NewGTO S "Def2-TZVP" end
NewGTO P "Def2-TZVP" end
end
%pal nprocs $processors end
%maxcore 3000
*XYZFile $charge $mult ${prior_name}_opt.xyz
%EPRNMR
GTENSOR TRUE
ORI GIAO
END
EOF
# add necleous for hyperfine corrections
if [[ $hyperfine != '' ]]
then
verbose hyperfine
for sublist in "${hyperfine[@]}"
do
sed -i "/GTENSOR TRUE/a\ \ \ \ \ \ \ NUCLEI\ \ \ \ = \
$sublist {SHIFT, AISO, ADIP, AORB}" ${prior_name}_epr.inp
done
fi
run_orca ${prior_name}_epr.inp ${prior_name}_epr.out
fi
if grep -q "ORCA TERMINATED NORMALLY" ${prior_name}_epr.out && $sweep
then
eproducer add_gval2npz ${prior_name: :-4}.npz
rm ${xyz_file%.xyz}_epr.densities
rm ${xyz_file%.xyz}_epr.engrad
rm ${xyz_file%.xyz}_epr.gbw
rm ${xyz_file%.xyz}_epr.inp
rm ${xyz_file%.xyz}_epr.opt
rm ${xyz_file%.xyz}_epr_property.txt
rm ${xyz_file%.xyz}_epr_trj.xyz
rm ${xyz_file%.xyz}_epr.gori.xyz
fi
# ==== BDEs ===================================================================
if $bdes
then
verbose BDES
cat << EOF > ${prior_name}_freq.inp
! M062X def2-TZVP OPT FREQ
%maxcore 1200
%pal nprocs $processors end
*XYZFile $charge $mult ${prior_name}_opt.xyz
EOF
run_orca ${prior_name}_freq.inp ${prior_name}_freq.out
fi
finish