概要 | フラグ(属性) | 関数一覧 | 参考 |
DDS_PROCESSOR | DDS_VARIABLE |
重要なのは計算して欲しい変数にDDS_FLAG_REQUIREDフラグを設定することです(後述)。DDSLはDDS_FLAG_REQUIREDフラグの付いた変数を計算するため、計算順序の決定等、すべてを自動的に処理して計算を実行します(以下の例参照)。 |
DDS_PROCESSOR p;
int e = DdsCreateProcessor(&p,10);
if(e!=0) printf("DdsCreateProcessor() returned an error\n");
DdsCreateProcessor(&p,10) は DDS_PROCESSOR に必要なメモリーを確保して、そのアドレスを p にセットします。第二引数 10 は p が管理できる変数の個数を指定します。これは後に必要なら自動的に拡大されます。
DdsCreateProcessor() は正常終了すれば 0 を、エラーの場合はゼロ以外を返します(具体的な戻り値は ddsl.h を参照)。
※:DdsCreateProcessor() は自動的に二つの組み込み変数(動的シミュレーション用の時間と積分時間刻み) time と step を用意します。
上流: y = f(u,v,w)、この場合 u,v,w は y の上流。全ての変数はプロセッサー(DDS_PROCESSOR)に、以下の様に、登録する必要があります。
下流: x = f(y)、 x は y の下流に位置します。
|
|
DdsAddVariableV(p,&x1, "x1", DDS_FLAG_REQUIRED, 1.0, NULL,0);
DdsAddVariableV(p,&y, "y", DDS_FLAG_TARGETED, 0.0, CompY,2,x1,x2);
/* ==> Value: y=0.000000 x1=0.693148 x2=2.000000 */
DDS_FLAG_TARGETED は y の値を計算の結果(従属変数)として 0.0 にしたいという意味になります。
そのために x1 が独立変数として(DDS_FLAG_SET のフラグは外されています)、 y を 0.0 にするために計算されることになります。 指定に応じて、 DDSL は自動的に非線形方程式(通常は連立)を組み立てて y の値を計算します。
※: DdsAddVariableV() の後でもフラグは自由に変更できます。
|
|
pVs = DdsGetVariables(&nv, p);
for (i = 0; i < nv; ++i) {
pVr = DdsGetRhsvs(&nr, pVs[i]);
for (j = 0; j < nr; ++j) {
pVr[j] = *((DDS_VARIABLE*)pVr[j]);
}
}
※: この時の RHSV はポインター DdsAddVariableV(p, &dydt, "dy/dt", DDS_FLAG_REQUIRED, 0.0, CompDYDT, 4,&A,&B,&C,&y)).ユーザーフラグ | システムフラグ | ブロック三角分解 |
DdsAddVariableV(p,&x2, "x2", DDS_FLAG_SET|DDS_FLAG_VOLATILE, 2.0, NULL,0);
または
DdsSetUserFlag(x2,DDS_FLAG_SET|DDS_FLAG_VOLATILE);
DDS_FLAG_REQUIRED | DDS_FLAG_SET | DDS_FLAG_TARGETED | DDS_FLAG_INTEGRATED |
DDS_FLAG_VOLATILE | DDS_FLAG_DIVISIBLE | DDS_FLAG_NON_DIVISIBLE |
ユーザーフラグ(記法) | 値 |
---|---|
DDS_FLAG_REQUIRED (<R>) | 0x00000001 |
DDS_FLAG_SET (<S>) | 0x00000002 |
<S> は定数指定です。 <S> が指定されると、例え値を計算する関数や右辺変数が定義されていても全ては無視され、値が計算されることはなくなります。 この指定がされると(右辺変数が定義されていた場合、無視されることにより)連結成分が分割される場合があります。 |
DDS_FLAG_TARGETED (<T>) | 0x00000004 |
<T> は計算結果として指定した値になることを強制する指定です。 従って、<T>(従属変数)を指定した値にするため、自由に値を変更できる独立変数(<F>、DDSLが検出)が上流に存在することが必要になります。 <F>変数は値を自由に変更できるので右辺変数(RHSV)を持たず、<S>でもありません。 <T> 変数を指定した値にするためには方程式(一般に非線形連立)を解く必要があります。 連立方程式の解の存在条件(DDSLがチェックします): y<T> = f(x<F>)
※: 一般に N 個の <T> (N個の <F>) は N 次元の連立方程式(可能なら小さくできます。)になります。 ※: 下流の変数から見れば <T> は <S> に見えます。 ※: この指定の結果、連結成分が分割されることがあります。 |
上図は、2個の <F> と2個の <T> が接続しているので、2次元の連立方程式に見えます。 しかし、途中で一本のルートになっていて2個の「独立した」ルートがないので、計算するまでもなく解は存在しません(計算前にDDSLがチェックします)。 |
DDS_FLAG_DIVISIBLE (<D>) | 0x00000020 |
<D>は分割候補指定です。 左辺変数 (y とします) が直接・間接的に右辺変数となること( y = f(y) )はループとなります。 この場合、y を次の様に分割( y ==> y1 , y2 )してループ上の変数を計算する必要があります。 y1 は <F>) になり、y2 は <T>) となり、以下の様に処理されます。 y2 = y1 - f(y1) y2==>0.0 y1 は <F>、 y2 は <T> であると同時に両者とも <DD> となります。 DDSL は自動的にループを検出して上記の処理を実行します。 どのループ上の変数も分割の対象になり得ます。 従って、ユーザは初期値の与えやすさなどを考慮して、分割の候補を <D>(DDS_FLAG_DIVISIBLE) フラグで指定することが出来ます。 DDSL は <D> フラグ変数を優先して分割します。しかし、複数のループに関係する変数があれば、そちらが優先されるので常に <D> 変数が分割されるとは限りません。 実際に分割された変数にはシステムフラグ DDS_SFLAG_DIVIDED(<DD>) が付与されます。 ※: <D> が常に分割されるとは限りません。 ※: y1 は元の y と同じです。新規に作成される変数 y2 は名前として yの名前+'+' となります。 |
DDS_FLAG_NON_DIVISIBLE (<N>) | 0x00000040 |
DDS_FLAG_INTEGRATED (<I>) | 0x00000008 |
もし、存在するなら、積分を続ければ定常状態にいつかは達するはずです。しかし、多分、計算はかなりの量になります。 DDSL は以下の様に定常状態を代数的に直接計算することが出来ます。参照: DdsCompileGraph(p,DDS_STEADY_STATE)
- <I> を <F> 変数に変更する
- 時間微分変数 <DR> を値 0.0 (時間変化無し==>つまり定常状態)の <T> に変更する。
- 上記方程式(非線形連立)を解くことで、 時間微分変数 <DR> をゼロにする <I> 変数を直接計算します。
DDS_FLAG_VOLATILE (<V>) | 0x00000010 |
非線形連立方程式(y=f(x) ==>0.0)を Newton 法で解く場合は Jacobian 行列(一次微分行列)を計算する必要があります。y(x+dx) = y(x)+J*dx ==> 0.0 ,ここで J は Jacobian 行列(=dy/dx), y,x,そして dx はベクトル,さらに x+dx は繰り返し計算の次の近似値。 J や J-1 の計算は時に大規模になり得ます。 DDSL は、可能なら、J をより小さいサイズの連続した行列に分解(ブロック三角分解)します。 左図では 大きな J を計算せず (1)、(2)、そして (3) の順に(行と列を入れ換えることで)計算することが出来ます。 ※:DDSL は数値微分機能を実装しているので Jacobian 行列用の計算式を用意する必要はありません。 |
DDS_SFLAG_ALIVE | DDS_SFLAG_FREE | DDS_SFLAG_DIVIDED | DDS_SFLAG_DERIVATIVE |
DDS_SFLAG_ERROR | DDS_COMPUTED_ONCE | DDS_COMPUTED_EVERY_TIME | DDS_COMPUTED_ANY_TIME |
システムフラグ (記法) | 値 |
---|---|
DDS_SFLAG_ALIVE (<AL>) | 0x00001000 |
DDS_SFLAG_FREE (<F>) | 0x00002000 |
DDS_SFLAG_DIVIDED (<DD>) | 0x00004000 |
DDS_SFLAG_DERIVATIVE (<DR>) | 0x00008000 |
DDS_SFLAG_ERROR (<ER>) | 0x00010000 |
DDS_COMPUTED_ONCE (<1T>) | 0x00020000 |
DDS_COMPUTED_EVERY_TIME (<ET>) | 0x00040000 |
DDS_COMPUTED_ANY_TIME (<AT>) | 0x00080000 |
戻り値 | 関数名(引数...) |
---|---|
int | DdsCreateProcessor(DDS_PROCESSOR* p, int nv) |
void | DdsDeleteProcessor(DDS_PROCESSOR* p) |
int | DdsAddVariableV(DDS_PROCESSOR p,DDS_VARIABLE *pv,const char *name,unsigned int f,double val, ComputeVal func,int nr,...) |
int | DdsAddVariableA(DDS_PROCESSOR p, DDS_VARIABLE* pv, const char* name, unsigned int f, double val, ComputeVal func, int nr, DDS_VARIABLE* rhsvs) |
int | DdsCompileGraph(DDS_PROCESSOR p,int method) |
int | DdsComputeStatic(DDS_PROCESSOR p) |
int | DdsComputeDynamic(DDS_PROCESSOR p,int method) |
DDS_I_EULER または DDS_I_RUNGE_KUTTA は、 DdsCompileGraph() にどちらかを指定した場合のみ可能です( DDS_I_EULER と DDS_I_RUNGE_KUTTA は相互に交換可能です)。※: 時間(t) は自動的に 時間刻み (予め設定されている必要があります)分更新されます。
ErrHandler | DdsGetErrorHandler(DDS_PROCESSOR p) |
void | DdsSetErrorHandler(DDS_PROCESSOR p, ErrHandler handler) |
DDS_VARIABLE | DdsTime(DDS_PROCESSOR p) |
DDS_VARIABLE | DdsStep(DDS_PROCESSOR p) |
unsigned int | DdsGetUserFlag(DDS_VARIABLE v) |
unsigned int | DdsSetUserFlag(DDS_VARIABLE v,unsigned int f) |
unsigned int | DdsGetSystemFlag(DDS_VARIABLE v) |
unsigned int | DdsSetUserFlagOn(DDS_VARIABLE v, unsigned int f) |
unsigned int | DdsSetUserFlagOff(DDS_VARIABLE v, unsigned int f) |
DDS_VARIABLE* | DdsGetVariables(int* nv, DDS_PROCESSOR p) |
void* | DdsGetVariableUserPTR(DDS_VARIABLE v) |
void | DdsSetVariableUserPTR(DDS_VARIABLE v, void* val) |
const char* | DdsGetVariableName(DDS_VARIABLE v) |
double | DdsGetValue(DDS_VARIABLE v) |
double | DdsSetValue(DDS_VARIABLE v,double val) |
DDS_VARIABLE* | DdsGetRhsvs(int* nr, DDS_VARIABLE v) |
int | DdsSetRHSV(DDS_VARIABLE v, int i, DDS_VARIABLE rv) |
DDS_VARIABLE | DdsGetRHSV(DDS_VARIABLE v, int i) |
DDS_VARIABLE | DdsGetVariableSequence(DDS_PROCESSOR p, unsigned int seq) |
DDS_VARIABLE v = DdsGetVariableSequence(p,DDS_COMPUTED_ONCE);
/* The order of variables computed at DDS_COMPUTED_ONCE */
while(v != NULL) {
printf(" Name=%s\n",DdsGetVariableName(v));
v = DdsGetVariableNext(v);
}
double | DdsGetEPS(DDS_PROCESSOR p) |
double | DdsSetEPS(DDS_PROCESSOR p, double eps) |
int | DdsGetMaxIterations(DDS_PROCESSOR p) |
int | DdsSetMaxIterations(DDS_PROCESSOR p, int max) |
void* | DdsGetProcessorUserPTR(DDS_PROCESSOR p) |
void | DdsSetProcessorUserPTR(DDS_PROCESSOR p,void* val) |
int | DdsCheckVariable(DDS_PROCESSOR p, DDS_VARIABLE hv) |
void | DdsDbgPrintF(FILE* f, const char* title, DDS_PROCESSOR p) |
DDS_VARIABLE | DdsGetVariableNext(DDS_VARIABLE v) |
int | DdsGetVariableIndex(DDS_VARIABLE v) |
int | DdsGetVariableScore(DDS_VARIABLE v) |
int | DdsSieveVariable(DDS_PROCESSOR p) |
int | DdsDivideLoop(DDS_PROCESSOR p) |
int | DdsCheckRouteFT(DDS_PROCESSOR p) |
int | DdsBuildSequence(DDS_PROCESSOR p) |