2017-04-20 82 views
1

我想研究各種配置下兩種苯分子之間的範德華相互作用。要做到這一點,我已經寫了一個bash腳本來從包含那些2的位置的文件中旋轉兩個分子中的一個(現在只在x軸附近)。代碼似乎運行時沒有錯誤,但給出了完全錯誤的結果。我檢查過很多次,但沒有發現任何「數學」錯誤,所以也許我在某處出現了語法錯誤? 我是bash(和linux)的初學者,所以任何幫助將不勝感激:)! 下面是代碼:在bash腳本中編寫旋轉

#!/bin/bash 

echo "Angle of rotation (in rad:" 
read angle 
echo "File or path to file :" 
read fichier 
echo "Your file:" 
cat $fichier 
echo "Give the line numbers which contain the atoms you want to rotate :" 
read ligneDebut 
read ligneFin 

# creation of an associative array playing the role of the rotation matrix 
declare -A Rx 
Rx=([1,1]=1 [1,2]=0 [1,3]=0 [2,1]=0 [2,2]=`echo "c($angle)" | bc -l` [2,3]=`echo "-s($angle)" | bc -l` [3,1]=0 [3,2]=`echo "s($angle)" | bc -l` [3,3]=`echo "c($angle)" | bc -l`) 

#storage of the atomic positions in an array 
declare -A posAtomes 
for((i=$ligneDebut; i<=$ligneFin; i++)) do 
    for((j=1; j<4; j++)) do 
     posAtomes[$i,$j]=`awk -v ligne=$i -v colonne=$j '{if(NR==ligne) print $(colonne+1)}' $fichier` 
    done 
done 

#computation of the new positions after rotation 
declare -A newPos 
for((i=$ligneDebut; i<=$ligneFin; i++)) do 
    for((j=1; j<4; j++)) do 
     newPos[$i,$j]=`echo "${posAtomes[$i,1]} * ${Rx[$j,1]} + ${posAtomes[$i,2]} * ${Rx[$j,2]} + ${posAtomes[$i,3]} * ${Rx[$j,3]}" | bc -l` 
    done 
done 

#writing the new positions in the original file 
for ((i=$ligneDebut; i<=$ligneFin; i++)) do 
    for ((j=1;j<4;j++)) do 
     awk -v ligne=$i -v colonne=$j -v val=${newPos[$i,$j]} '{if(NR==ligne) {$(colonne+1)=val; print $0} else print $0}' $fichier > tmp && mv tmp $fichier 
    done 
done 

位置文件看起來像這樣(這裏只有一個分子):

C 0.00000000000000000E+00 1.39600002765655495E+00 12.25 
C 1.20899999141693093E+00 6.98000013828277699E-01 12.25 
C 1.20899999141693093E+00 -6.98000013828277699E-01 12.25 
C 0.00000000000000000E+00 -1.39600002765655495E+00 12.25 
C -1.20899999141693093E+00 -6.98000013828277699E-01 12.25 
C -1.20899999141693093E+00 6.98000013828277699E-01 12.25 
H 0.00000000000000000E+00 2.47900009155273393E+00 12.25 
H 2.14700007438659712E+00 1.24000000953674294E+00 12.25 
H 2.14700007438659712E+00 -1.24000000953674294E+00 12.25 
H 0.00000000000000000E+00 -2.47900009155273393E+00 12.25 
H -2.14700007438659712E+00 -1.24000000953674294E+00 12.25 
H -2.14700007438659712E+00 1.24000000953674294E+00 12.25 

如果你知道我做錯了什麼?在此先感謝!

+0

既然你說你是'bash'的初學者,我會藉此機會建議你爲這類任務使用另一種語言。 'bash'有很多優點,但是實現算術運算的難易並不是其中之一。如果你正在尋找每臺Linux機器上可用的通用語言,我認爲'python'會是一個不錯的選擇。更專業化的語言將包括Mathematica和Matlab/Octave。 – Aaron

回答

0

我可以提供一些基本的故障排除步驟,但我並不熟悉確切的計算。

0)要獲得更詳細的幫助,請嘗試發佈輸入的示例輸入(旋轉角度和行數),期望的結果以及您看到的結果。此外,添加您正試圖實施的公式可能會有幫助。

1)嘗試添加很多簡單的回聲語句來查看各個步驟的進度:調試語句。例如:

echo "Angle of rotation (in rad:" 
read angle 
echo "OK, operating with angle: "${angle} 

echo "File or path to file :" 
read fichier 
echo "OK, input file is: "${fichier} 

在我看來,這兩個步驟在您的程序中是正確的。但是,希望該方法能爲您提供進一步的調試步驟。在整個代碼中添加這些調試回顯語句以輸出中間值並驗證它們是否按預期工作。

快樂的黑客攻擊。另外,是否有一個特別的原因,你用bash實現這個?也許另一種語言,例如帶有內置矢量數學庫(Python,R,Matlab ...)的語言會更合適。

+0

使用'bash -x'調用腳本(或者在腳本中添加一個'set -x'命令)是一個更容易的方法,可以添加大量的'echo',儘管非常詳細的輸出可能會導致錯誤 – Aaron

+0

這只是告訴你哪條線正在運行,對嗎?我建議顯示每個步驟的輸出,例如變量的值。基本上是逐步調試。 ;-) – nshiff

+0

它顯示了哪個命令正在運行,這更接近分步,因爲它將分解多個步驟中的組合命令並顯示每個連續步驟處理前一個結果。我只注意到'read'不會很好地工作,但是對於標準變量情感,它將顯示變量的有效值而不是表達式,這與在該步驟之後添加額外的回聲具有相同的效果。 – Aaron

0

感謝您的回覆!我以爲我已經做了「把回聲放到處」的事情,但我沒有做好。我發現了這個錯誤:bc不能處理科學記數法(對於一個有點蹩腳的u_u的計算器),所以必須使用sed或awk將所有E + 01重新分配10^01。該死的我失去了這麼多時間!下次我會用Python haha​​