next up previous contents
: 同梱BeanShellスクリプトの利用方法 : BeanShellスクリプトの例 : PHASEekcal計算を行うスクリプトのサンプル   目次


セルを一様に拡大しながらSCF計算を行うスクリプトのサンプル

セルを一様に変化させながらSCFを計算するスクリプトのサンプルが, PHASE-Viewerサンプルの ``scripting''プロジェクトの下にある``uniform-expansion''サブプロジェクトにあります. このサンプルについて詳解します.

6.5.1節と同様スクリプト設定画面上では``commands.bsh''を利用する設定となっています. 実際の計算を行うのは, ``uniform_exp.bsh''です. このスクリプトのソースは,
.chase/scripts/jobcontrol/phase/uniform_exp.bshです.

まず入力から説明します. 入力部は, 下記のようになっています.

control{
    from    = 0.95
    to      = 1.05
    incre   = 0.01
}
``from''で最初の体積を, ``to''で最後の体積を指定します. また, ``incre''で体積をどれくらい増やすかを指定します.

スクリプトの残りの部分を見てみましょう.

1:   nfinp = getFileName("F_INP","__TARGETDIR____FS__");
2:   nfinpfp = "__TARGETDIR____FS__"+nfinp;
3:   nfinporg = "__TARGETDIR____FS__"+nfinp+"_orig";
4:   nfene = "__TARGETDIR____FS__"+getFileName("F_ENF","__TARGETDIR____FS__");
5:   to = 0.95;
6:   from = 1.05;
7:   incre = 0.01;
8:   logger = getLogger("uniform_exp");
9:   init() {
10:      cp(nfinpfp,nfinporg);
11:    
12:      inputInterface = getInputInterfaceFromBSH("__TARGETDIR____FS____uniform_exp.bsh");
13:      inputInterface.selectBlock("control");
14:      nfinp = inputInterface.getPrimitiveEntry("inpfile").getValue();
15:      to = Double.parseDouble(inputInterface.getPrimitiveEntry("to").getValue());
16:      from = Double.parseDouble(inputInterface.getPrimitiveEntry("from").getValue());
17:      incre = Double.parseDouble(inputInterface.getPrimitiveEntry("incre").getValue());
18:     
19:      /*
20:      'condition' must be 'initial'
21:      */
22:      input = getInputInterface(nfinporg); 
23:      input.selectBlock("control");
24:      input.replaceEntry(new InputInterfacePrimitiveEntry("condition","initial",""));
25:      input.selectRoot();
26:      input.saveTo(new File(nfinporg));
27:  }
28: 
29:  boolean boolvec = true;
30:  loop() {    
31:      total = to - from;
32:      nsteps = (int) (total/incre);
33:      logger.info("nsteps: "+nsteps);
34:      if ( nsteps == 0 ) {
35:          return;
36:      }
37:     
38:      try{
39:          PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(nfene+"_all")));
40:          writer.println("#V/V0 L/L0 energy");
41:          for ( int i=0 ; i<nsteps ; i++ ) {
42:              inputInterface = getInputInterface(nfinporg);
43:              cellvec = getCellVec(inputInterface);    
44:              if ( cellvec == null ) {
45:                  logger.error("invalid cellvec!");
46:                  return;
47:              }        
48:              boolvec = true;
49:              if ( cellvec.length == 2 ) {
50:                  boolvec = false;
51:              }
52:              
53:              scale = Math.pow(from + i*incre,1.0/3.0);
54:              if ( boolvec ) {
55:                  for ( int i=0 ; i<3 ; i++ ) {
56:                      for ( int j=0 ; j<3 ; j++ ) {
57:                          cellvec[i][j] = scale * cellvec[i][j];
58:                      }
59:                      logger.info("cellvec: "+cellvec[i][0]+" "+cellvec[i][1]+" "+cellvec[i][2]);
60:                  }
61:              } else {
62:                  for ( int i=0 ; i<3 ; i++ ) {
63:                      cellvec[0][i] = cellvec[0][i] * scale;
64:                  }
65:                  logger.info("lattice const.: "+cellvec[0][i]+" "+cellvec[0][i]+" "+cellvec[0][i]);
66:              }
67:              setCellVec(cellvec,inputInterface);
68:              inputInterface.saveTo(new File(nfinpfp));
69:              execute("__PHASE__");
70:              
71:              BufferedReader reader = new BufferedReader(new FileReader(nfene));
72:              String foo = "";
73:              String bar = "";
74:              while( (foo = reader.readLine()) != null ) {
75:                  bar = foo;
76:              }
77:              String [] line = bar.split("\s+");
78:              String energy = "";
79:              if ( line != null && line.length >= 4 ) {
80:                  energy = line[3];
81:              } 
82:              reader.close();
83:              cp(nfene,nfene+"-"+String.valueOf(from+i*incre));
84:              
85:              logger.info("energy for step "+i+": "+energy);
86:              logger.info(System.getProperty("line.separator"));
87:              writer.println(String.valueOf(from+i*incre)+"  "
                               +String.valueOf(scale)+" "+energy);
88:          }
89:          writer.close();
90:      } catch(e){
91:          logger.error("error",e);
92:      }
93:     
94:      cp(nfinporg,nfinpfp);
95:      rm(nfinporg);
96:     
97:  }
98: 
99:  init();
100: loop();

少し長いスクリプトなので, ポイントのみ解説します.

99行目, 100行目
スクリプトが実行されると, まずこれらの行で呼んでいる``init()''メソッドと``loop()''メソッドが実行されます.
init()メソッド
初期化を行います. 入力ファイル操作用クラスのインスタンス化やスクリプト入力の読み込みなどを行っています.
loop()メソッド
実際の計算を行うメソッドです.
38-39行目:
各体積での計算のエネルギーを一つのファイルに書き込むため, PrintWriterクラスをインスタンス化しています. また, そのためループ全体をtryブロックに入れています.
43行目:
commands.bshで定義されている, ``getCellVec''メソッドによってセルベクトルを取得しています.
53-67行目:
セルをスケールしています. また, 最後にやはりcommands.bshで定義されている``setCellVec''メソッドで新しいセルをセットしています.
68-69行目:
計算で実際に利用する入力をディスクに保存し, PHASEを実行しています.
71-83行目:
各体積で得られたエネルギーの値を, 別ファイルに書き込んでいます.

注意点として, ¥の扱いがあります. 通常Javaでは¥は特別な記号なので¥を記述する場合エスケープして¥¥と書く必要があります. ところが, PHASE-Viewerはスクリプトを投げる前に¥を¥¥で置き換えるのでこのような書き方ではなく, 単に¥としてください. たとえば, 77行目でそのような書き方がされています.



jkoga 平成22年4月27日