|
本帖最后由 从头开始搞计算 于 2024-12-10 22:01 编辑
这个程序有问题,导出的没有元素及匹配个数,写了个从头到尾的提交脚本。MS的文件传到服务器按这个脚本直接提交计算完就能得到可以直接用VESTA处理的CHGCAR文件。
#!/bin/bash
#SBATCH -n 48
#SBATCH -N 1
# 打印任务信息
echo "Starting job $SLURM_JOB_ID at " `date`
echo "SLURM_SUBMIT_DIR is $SLURM_SUBMIT_DIR"
echo "Running on nodes: $SLURM_NODELIST"
# 遍历当前目录下所有 .param 文件
for file in *.param; do
# 检查文件是否已经包含 'write_formatted_density = true'
if ! grep -q "write_formatted_density = true" "$file"; then
# 将配置追加到文件末尾
echo "write_formatted_density = true" >> "$file"
echo "已更新文件: $file"
else
echo "文件已包含配置: $file"
fi
done
# 执行任务
# 这里演示如何提交CASTEP任务。可以将RunCASTEP.sh替换为RunDFTB.sh, RunDMol3.sh, RunMesoDyn.sh 等 来运行对应的程序。
module load MaterialsStudio
export LD_PRELOAD=/opt/pub/softwares/MaterialsStudio2020/BIOVIA/strtok_proxy.so
RunCASTEP.sh -np 48 PP-Li2S6-diff #NAME_CHANGE
RunCASTEP.sh -np 48 PP-Li2S6-diff_Subset1 #Prefix_name
RunCASTEP.sh -np 48 PP-Li2S6-diff_Subset2
gfortran den2vasp.f90 -o den2vasp
# 函数1:替换文件的特定行
replace_lines() {
local file_name="$1"
# 定义文件名
local input_file="${file_name}.cell"
local output_file="CHGCAR_${file_name}.vasp"
local temp_file="${output_file}.tmp"
# 提取第2-4行的内容
local replacement
replacement=$(sed -n '2,4p' "$input_file")
# 使用awk替换目标文件的第3-5行
awk -v repl="$replacement" '
BEGIN {
split(repl, lines, "\n") # 将替换内容按换行符分割
}
NR >= 3 && NR <= 5 { # 替换目标文件的第3-5行
print lines[NR-2]
next
}
{ print } # 保留其他行
' "$output_file" > "$temp_file"
# 替换原文件
mv "$temp_file" "$output_file"
echo "完成替换:$input_file 的第2-4行已替换到 $output_file 的第3-5行"
}
# 函数2:统计元素及个数
count_words_in_array() {
# 初始化标志
in_block=false
# 声明关联数组用于统计单词出现次数
declare -A word_count
# 用于记录单词的出现顺序
order=()
# 读取文件并统计单词
while IFS= read -r line; do
# 检查是否遇到%BLOCK POSITIONS_FRAC
if [[ "$line" == "%BLOCK POSITIONS_FRAC" ]]; then
in_block=true
continue
fi
# 检查是否遇到%ENDBLOCK POSITIONS_FRAC
if [[ "$line" == "%ENDBLOCK POSITIONS_FRAC" ]]; then
in_block=false
continue
fi
# 如果在%BLOCK POSITIONS_FRAC和%ENDBLOCK POSITIONS_FRAC之间,提取第一个单词并统计
if $in_block; then
first_word=$(echo "$line" | awk '{print $1}')
# 如果该单词第一次出现,记录它的顺序
if [[ -z "${word_count["$first_word"]}" ]]; then
order+=("$first_word")
fi
# 更新该单词的计数
((word_count["$first_word"]++))
fi
done < "$1"
# 输出按顺序排列的单词
for word in "${order[@]}"; do
echo -n "$word "
done
echo
# 输出每个单词的计数,按照单词的顺序
for word in "${order[@]}"; do
echo -n "${word_count[$word]} "
done
echo
}
# 函数3:添加元素及个数
insert_count_to_file() {
local file_name="$1"
# 获取统计结果
output=$(count_words_in_array "$file_name.cell")
# 分割统计结果为第一行和第二行
first_line=$(echo "$output" | head -n 1)
second_line=$(echo "$output" | tail -n 1)
# 使用sed命令替换第6行并插入第二行到第7行
sed -e "6s/.*/$first_line/" -e "7i\\
$second_line" "CHGCAR_$file_name.vasp" > temp_file && mv temp_file "CHGCAR_$file_name.vasp"
}
# 遍历当前目录下所有 .param 文件
for param_file in *.param; do
# 如果 CHGCAR 文件存在,则删除
if [ -f "CHGCAR" ]; then
rm CHGCAR
fi
# 检查文件名中是否包含 _Subset1 或 _Subset2
if [[ "$param_file" != *"Subset1"* && "$param_file" != *"Subset2"* ]]; then
# 如果文件名不包含 _Subset1 和 _Subset2,直接执行
file_name=$(basename "$param_file" .param)
echo "$file_name"
./den2vasp "$file_name"
mv CHGCAR CHGCAR_$file_name.vasp
replace_lines "$file_name" #替换坐标
insert_count_to_file "$file_name" #添加元素及个数
elif [[ "$param_file" == *"Subset1"* ]]; then
# 如果文件名包含 _Subset1,执行并重命名
file_name=$(basename "$param_file" .param)
echo "$file_name"
./den2vasp "$file_name"
mv CHGCAR CHGCAR_$file_name.vasp
replace_lines "$file_name" #替换坐标
insert_count_to_file "$file_name" #添加元素及个数
elif [[ "$param_file" == *"Subset2"* ]]; then
# 如果文件名包含 _Subset2,执行并重命名
file_name=$(basename "$param_file" .param)
echo "$file_name"
./den2vasp "$file_name"
mv CHGCAR CHGCAR_$file_name.vasp
replace_lines "$file_name" #替换坐标
insert_count_to_file "$file_name" #添加元素及个数
fi
done
# 任务结束
echo "Job $SLURM_JOB_ID done at " `date` |
评分 Rate
-
查看全部评分 View all ratings
|