Overview | Flags(Attributes) | API references | References |
DDS_PROCESSOR | DDS_VARIABLE |
As is shown in the examples bellow,setting DDS_FLAG_REQUIRED flag is the most important for the user. DDSL does everything,including computation order construction, to compute the variables of DDS_FLAG_REQUIRED flag. |
DDS_PROCESSOR p;
int e = DdsCreateProcessor(&p,10);
if(e!=0) printf("DdsCreateProcessor() returned an error\n");
DdsCreateProcessor(&p,10) allocates memories for DDS_PROCESSOR structure and sets it's pointer to p. The second argument 10 is the number of variables(explained later) the DdsProcessor() can keep which will be automatically extended if necessary. DdsCreateProcessor() returns 0 if DdsProcessor is normally allocated,or returns non-zero error code.
Note:DdsCreateProcessor() automatically allocates default variables,time and integration step,internally.
Upstream: In case like y = f(u,v,w). Variables u,v,and w are upstream variables of y.Variables must be registered to the processor(DDS_PROCESSOR) as:
Downstream: In case like x = f(y). Variable x is a downstream variable of 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 means that the value of y is to be 0.0 after computations. And the value of x1,which is not DDS_FLAG_SET this time,will be the value that make the value of y be 0.0. DDSL creates (non-linear) equation(s) and solves it automatically according to the user's specifications.
Note: Flags can be freely changed after 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]);
}
}
Note: All RHSVs of any variable are all pointers this time(ex:DdsAddVariableV(p, &dydt, "dy/dt", DDS_FLAG_REQUIRED, 0.0, CompDYDT, 4,&A,&B,&C,&y)).User flags | System flags | Block triangular decomposition |
DdsAddVariableV(p,&x2, "x2", DDS_FLAG_SET|DDS_FLAG_VOLATILE, 2.0, NULL,0);
or
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 |
User flag name (notation) | value |
---|---|
DDS_FLAG_REQUIRED (<R>) | 0x00000001 |
DDS_FLAG_SET (<S>) | 0x00000002 |
<S> is a constant specification. Any variable having this flag is never computed even RHSVs and the function to compute its value are defined. This specification may cause to divide one connected component into more than one. |
DDS_FLAG_TARGETED (<T>) | 0x00000004 |
The value of <T> variable becomes specified value by computation. The variable which can freely change it's value(<F>(detected by DDSL) variable which has no RHSVs and not <S>) must exist on the upstream of <T>. The value of <F> variable will be adjusted to make the value of <T> be the specified value. The (computed) value of <T> variable becomes the specified value by solving non-linear equation: y<T> = f(x<F>). Solvability conditions on non-linear equation systems(checked by DDSL):
Note: N-<T>s(N-<F>s) construct N-dimensional equation system in general(can be reduced if possible) if they are mutually connected. From downstream variables,<T> look like <S>. This specification may cause to divide one connected component into more than one. |
This looks to be 2-dimensional equation system because there are two <F>s and two <T>s. But,the independent 2 routes from each <F> to <T> can not be found that means the equation system can not be solved which is detected before actual computations(DDSL checks this condition). |
DDS_FLAG_DIVISIBLE (<D>) | 0x00000020 |
Any variable(say y) computed by itself like y = f(y) constructs a loop.
It is necessary to divide y ( y ==> y1 , y2 ) to compute value of the variables on the loop.
If y is divided into y1(=<F>) and y2(=<T>),then a new equation y2 = y1 - f(y1) y2==>0.0 will be added and be solved. y1 is <F> and y2 is <T>.also both y1 and y2 are <DD> at the same time. DDSL automatically detects loops and performs above procedures. Any variable on a loop can be divided. The user can specify this <D>(DDS_FLAG_DIVISIBLE) flag on any variable(by reason of easy estimation of initial value, etc.) to be divided. DDSL tries to divide <D> varable,but it is not alway divided. DDSL finds loops and tries to divide the variable which is located on more loops. The variable actually divided will have the system flag DDS_SFLAG_DIVIDED(<DD>). Note: <D> variable is not alway divided. Note: The y1 is the same as y,and newly created variable y2 has the name of y+'+'. |
DDS_FLAG_NON_DIVISIBLE (<N>) | 0x00000040 |
DDS_FLAG_INTEGRATED (<I>) | 0x00000008 |
The steady state,if exists,can be obtained to keep integration which is,althogh,time consuming. DDSL can algebraicaly compute the steady state as:See: DdsCompileGraph(p,DDS_STEADY_STATE)
- Change <I> variables to <F>.
- Change <DR> variables to <T> of value 0.0(steady state condition).
- Solve non-linear equation systems to find the value of <I>s that make all value of <DR>s be zero(steady state).
DDS_FLAG_VOLATILE (<V>) | 0x00000010 |
Newton method creates Jacobian matrix when it solves non-linear equation system (y=f(x) ==>0.0),y(x+dx) = y(x)+J*dx ==> 0.0 ,where J is a Jacobian matrix(=dy/dx), y,x,and dx are vectors,and x+dx is the next estimation. Computation of J or J-1 may be time-consuming if J is quite large. DDSL divides,if possible,J into a sequence of small-sized matrices as shown in the left image which is called as Block Triangular Decomposition. In the left image,instead of solving big J,smaller sized matrices (1),(2),and (3) are solved in this order by re-arranging columns and rows, DDSL adopts numerical differentiation,so that the user need not to prepaire any equations to compute the Jacobian-matrix(dy/dx). |
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 |
System flag name (notation) | value |
---|---|
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 |
Return value | Function name(arguments...) |
---|---|
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 or DDS_I_RUNGE_KUTTA can be specified only when the second argument of DdsCompileGraph() is the one of DDS_I_EULER or DDS_I_RUNGE_KUTTA(mutualy exchangeable).Note: To increment Time automaticaly,the value of Step must be defined beforehand.
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);
}
ErrHandler | DdsGetErrorHandler(DDS_PROCESSOR p) |
void | DdsSetErrorHandler(DDS_PROCESSOR p, ErrHandler handler) |
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) |