GPTUser elements :: 基本事項ユーザーエレメントの基本事項
GPT のユーザーエレメントの追加に関する基礎的なテクニックのメモです.
目次
はじめに
ユーザーは,GPT に機能 (エレメント) を追加することができます.元々のエレメントで計算ができないとき,ユーザーがプログラミング (C言語) を行い,ユーザーエレメントを追加します.
エレメントの追加方法
関数実行タイミング
ユーザーは,様々な関数を作成することができます.また,作成された関数の実行タイミングは,ユーザーが決められます.それは,(1) GPT の実行開始時,(2) 計算ステップ毎,(3) GPT の計算終了時です.ここでは,GPT のユーザーインターフェースを使い,新規にエレメント「UserElement」を作成する場合を例に説明します.
実行開始時
GPT のインターフェースを使うと,初期化関数「void UserElement_init(gptinit *init)」が自動的に作成されます.GPTの実行の初期段階で,この関数は 1 度,実行されます.様々な初期化処理に使うことができます.初期化関数には,エレメント名に「_init」が付きます.
この関数の引数は gptinit 型の構造体のポインターです.これは,GPTが作成する構造体「UserElement_info」です.gptinit の実態は不明ですが,構造体「UserElement_info」と考えれることができます(?).ユーザーが構造体を含めた変数を使う場合,この構造体に追加します.
計算ステップ毎
計算ステップ毎に実行される関数も,GPTが作成します.その関数は「void UserElement_sim(引数)」です.この関数のプロトタイプは,ファイル「UserElement.c」のヘッダー部に記述します.
この計算ステップ毎の関数は,初期化関数(UserElement_init)の中で登録します.それには,次の関数
void gptaddEBelement(gptinit *init, simfn simfn, exitfn exitfn, int type, void *info ) ;
を使います.具体的には「gptaddEBelement(init, UserElement_sim, gptfree, GPTELEM_LOCAL, info)」と記述されます.引数は変更可能ですが,これが一般的です.ただし,この登録作業をユーザーがする必要はありません.ユーザーエレメントを作成する GPT のインターフェースを使うと「UserElement.c」に書かれます.
メインサイクル中
gptaddmainfunction を使うと,メインサイクル内でユーザー関数を実行することができます.
void gptaddmainfunction(int position, void (*func)(void *info), void *info);
実行タイミングは,gptaddmainfunction の第一引数で指定します(表1).第二引数が関数名,第三引数は関数に渡す変数です.この関数を実行開始時に呼び出します.具体的には,実行開始時の処理関数内(UserElement_init)の中に,「gptaddmainfunction(GPTMAINFNC_TER, UserElement_ter, info)」を記述します.
gptaddmainfunction の第一引数
| 第一引数 |
モード |
説明 |
| GPTMAINFNC_STP |
カーネル |
コマンドライン,入力ファイルの解析,出力ファイルのオープン |
| GPTMAINFNC_INI |
ユーザー |
粒子を追加することができます.粒子のセットは変更可能です. |
| GPTMAINFNC_LST |
カーネル |
粒子のセットはマスターリストに変換されます. |
| GPTMAINFNC_DYN |
カーネル |
コンポーネントに関する全ての粒子のために,syncsets を使った動的なメモリ管理が開始されます. |
| GPTMAINFNC_PAR |
ユーザー |
完全な粒子のリストが有ります.粒子分布を変更する最後の機会です. |
| GPTMAINFNC_SIM |
カーネル |
メインシミュレーションが開始されます. |
| GPTMAINFNC_TER |
ユーザー |
終了ルーチンです. |
| GPTMAINFNC_EXT |
カーネル |
アウトプットファイルを閉じて,クリーンアップ実行します. |
計算終了時
計算終了時に実行する関数の指定には,
void gptaddmainfunction(GPTMAINFNC_TER, void (*func)(void *info), void *info) ;
を使います.
プログラミングテクニック
プログラミングのメモです.
- 計算ステップ毎に実行される関数 (…_sim) や終了関数 (…_ter) の実行時には,グローバル変数(?)「numpar」にマクロ粒子数が設定されています.その一方で初期化ルーチンの実行時には,この変数からマクロ粒子数を得ることができません.その場合には,以下のようにします.
void hogehoge_init(gptinit *init){
struct hogehoge_info *info;
gptparset *ppp;
int len;
info->name = gptgetargdouble(init,2);
ppp = gptgetparset(info->name) ;
gptgetparsetpars(ppp, &len);
- 粒子の情報は gptpar 型の構造体 (struct par) に書かれている.ユーザー関数の引数 (通常は *par) というポインターで与えられ,アクセスが可能である.この構造体の定義は,ユーザーファイル中の 「#include "elem.h"」のヘッダーの中から呼び出される「gps.h」に記述されている.これらのヘッダーファイルは,「C:\Program Files\General Particle Tracer\kernel」に保管されている.ヘッダーファイルに書かれているこの構造体の定義は以下のとおりである.
typedef struct par
{
double *Wr ;
int offWr ;
double *GBr ;
int offGBr ;
double m ;
double q ;
double n ;
double r2 ;
double tstart ;
double r[3] ;
double E[3] ;
double B[3] ;
double G ;
double WE[3] ;
double WB[3] ;
double WF[3];
struct axis *paxis ;
struct axis *newaxis ;
int kl, kc, kr ;
int el, er ;
int persistent ;
int alive ;
int tokill ;
int ID ;
struct gptparset *set ;
} gptpar ;
座標などは以下のとおりである.
- 粒子の座標(WCS)は \((x, ,y, z)\) =
(par->Wr[0], par->Wr[1], par->Wr[2])となる.運動量は \((\beta_x\gamma,\,\beta_y\gamma,\,\beta_z\gamma)\)=(par->GBr[0], par->GBr[1], par->GBr[2])である.
- 運動量は \((\beta_x\gamma,\,\beta_y\gamma,\,\beta_z\gamma)\)=
(par->GBr[0], par->GBr[1], par->GBr[2])である.
- ファイルのオープンは,以下のようににします.
if(fopen_s(&fp, info->file, "w")!=0){
printf("file open error!! at BeamEnergy_file\n");
return;
}
ページ作成情報
参考資料
- General Particle Tracer — Custom Elements —
更新履歴
|