Functions
in Class Base.Container.Reactor [Go to Top]
|
/*
Base_Container_Reactor.c
* - DLL routines for class <Component>Base.Container.Reactor
* DATE: Monday, September 10, 2001 TIME: 03:57:13 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include
<stdio.h>
#include "SGdll.h"
|
#include
"../Mixer_1_0/Mixer_1_0.h" |
#ifdef
__cplusplus
extern "C"
{
#endif
SG_EXPORT
SG_SIM_FUNC SG_xInitSize_Base_Container_Reactor;
SG_EXPORT SG_SIM_FUNC SG_xInit_Base_Container_Reactor;
SG_EXPORT SG_SIM_FUNC SG_xPreEval_Base_Container_Reactor;
SG_EXPORT SG_SIM_FUNC SG_xEval_Base_Container_Reactor;
SG_EXPORT SG_SIM_FUNC SG_xPostEval_Base_Container_Reactor;
#ifdef
__cplusplus
}
#endif
/*
Macros for attribute indices in class version [1.0.alpha.7] */
#define SG_NDX_FCONCENTRATION 0 /* fConcentration - Concentration */
#define SG_NDX_RREACTOR 1 /* rReactor - Reactor Table */
#define SG_NDX_RCONSTANT 2 /* rConstant - Constant Matrix */
#define SG_NDX_IPARTINDEX 3 /* iPartIndex - Part Index (1-Based) */ |
/* Manually entered indices for
simControl, link, and reference objects access */
#define SG_NDX_OBJ_REACTORTABLE 0 /* reactor table,
always the first */
#define SG_NDX_OBJ_CONSTMATRIX 1 /* constant
matrix, always the second */ |
/*
============================================================
* SG_xInitSize - Resize for Init
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInitSize_Base_Container_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */ |
INT *piNumReactors = &simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0]; |
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */ |
/* register the reactor
part for solver to resize matrices and tables */
if (*piNumReactors < 0)
*piNumReactors = 1;
else
*piNumReactors += 1; |
return SG_R_OK;
}
/*
============================================================
* SG_xInit - Initialization
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInit_Base_Container_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */ |
INT iPartNdx;
const INT ciPartSN = (INT)self->nCmpnNo; |
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */ |
/* set user type for future identification - to prevent class name
comparison
* during component class run-time type checking
*/
MIX_SET_USER_TYPE(self, MIX_USER_TYPE_REACTOR);
/* check to see if there are two reference objects */
if (*piRefObjs != 2)
{
strcpy(cMessage, "Need a Reactor Table and
a Constant Matrix.");
/* important - reset the number of reactors in
the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0]
= 0;
return SG_R_STOP;
}
/* register the reactor in the reactor table and find the 1-based index.
* registerReactor() is implemented in Table_Reactor.c
and is called via
* the function prototype defined in Mixer_1_0.h
*/
iPartNdx = registerReactor(refObjs[SG_NDX_OBJ_REACTORTABLE],
ciPartSN);
if (iPartNdx < 1)
{
strcpy(cMessage, "Cannot register this
part in the reactor table.");
/* important - reset the number of reactors
in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0]
= 0;
return SG_R_STOP;
}
else
{ /* record the 1-based index for bi-directional
reference */
self->zValues[SG_NDX_IPARTINDEX].iData[0]
= iPartNdx;
} |
return SG_R_OK;
}
/*
============================================================
* SG_xPreEval - Pre-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPreEval_Base_Container_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */ |
INT i;
const FLOAT cfConcentration = self->zValues[SG_NDX_FCONCENTRATION].fData[0]; |
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */ |
/* Deposit Reactor
Concentration to all the output links */
for (i = 0; i < *piLnkObjs; i++)
{
if (lnkObjs[i]->zValues[SG_NDX_LINK_ILINKINFO].iData[0]
== SG_LINK_OUT)
lnkObjs[i]->zValues[SG_NDX_LINK_FCONCENTRATION].fData[0]
=
cfConcentration;
} |
return SG_R_OK;
}
/*
============================================================
* SG_xEval - Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xEval_Base_Container_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */ |
INT i;
INT iType;
BOOL bInput;
SG_OBJ* pConstMatrix;
SG_OBJ* pReactorTable;
FLOAT fFlowRate;
FLOAT fConcentration; |
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */ |
/* start loading the constant matrix and RHS vector,
* using the law of conservation
*/
if (*piRefObjs < 2)
{
strcpy(cMessage, "Constant Matrix and
Reactor Table objects are required.");
/* important - reset the number of reactors
in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0]
= 0;
return SG_R_STOP;
}
pReactorTable = refObjs[SG_NDX_OBJ_REACTORTABLE];
pConstMatrix = refObjs[SG_NDX_OBJ_CONSTMATRIX];
for (i = 0; i < *piLnkObjs; i++)
{ /* going through all the links and adjacent
objects */
bInput = (lnkObjs[i]->zValues[SG_NDX_LINK_ILINKINFO].iData[0]
==
SG_LINK_IN);
if (bInput)
{ /* input */
iType =
MIX_GET_USER_TYPE(adjObjs[i]);
switch (iType)
{
case
MIX_USER_TYPE_REACTOR:
loadMatrixConstant(pConstMatrix,
self->zValues[SG_NDX_IPARTINDEX].iData[0],
adjObjs[i]->zValues[SG_NDX_IPARTINDEX].iData[0],
lnkObjs[i]->zValues[SG_NDX_LINK_FFLOWRATE].fData[0],
bInput );
break;
case MIX_USER_TYPE_SOURCE:
fFlowRate = lnkObjs[i]->zValues[SG_NDX_LINK_FFLOWRATE].fData[0];
fConcentration =
lnkObjs[i]->zValues[SG_NDX_LINK_FCONCENTRATION].fData[0];
if (fFlowRate
< 0.f || fConcentration < 0.f)
{
strcpy(cMessage, "Source to the reactor has not been
initialized.");
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return SG_R_STOP;
}
loadTableConstant(pReactorTable,
self->zValues[SG_NDX_IPARTINDEX].iData[0],
fConcentration * fFlowRate,
bInput );
break;
case MIX_USER_TYPE_SINK:
/* do
nothing */
default:
break;
}
}
else
{ /* output */
iType =
MIX_GET_USER_TYPE(adjObjs[i]);
switch (iType)
{
case MIX_USER_TYPE_REACTOR:
case MIX_USER_TYPE_SINK:
/* load constant to the main diagnal cell */
/* same behavior for both reactor and sink in the output */
loadMatrixConstant(pConstMatrix,
self->zValues[SG_NDX_IPARTINDEX].iData[0],
self->zValues[SG_NDX_IPARTINDEX].iData[0],
lnkObjs[i]->zValues[SG_NDX_LINK_FFLOWRATE].fData[0],
bInput );
break;
case MIX_USER_TYPE_SOURCE:
/* do nothing */
default:
break;
}
}
} |
return SG_R_OK;
}
/*
============================================================
* SG_xPostEval - Post-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPostEval_Base_Container_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */ |
INT i;
const INT ciPartNdx = self->zValues[SG_NDX_IPARTINDEX].iData[0];
FLOAT fConcentration;
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* check the existence of reactor table */
if (*piRefObjs < 2)
{
strcpy(cMessage,
"ERROR: Constant Matrix and Reactor Table objects are
required." );
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return SG_R_STOP;
}
/* fetch the solution from the reactor
table */
/* notice that ciPartNdx is 1-based */
fConcentration = (FLOAT)(refObjs[SG_NDX_OBJ_REACTORTABLE]->
zValues[SG_NDX_TBL_DSOLUTION].dData[ciPartNdx - 1] );
self->zValues[SG_NDX_FCONCENTRATION].fData[0] =
fConcentration;
/* deposit Reactor Concentration to all the
output links */
for (i = 0; i < *piLnkObjs; i++)
{
if (lnkObjs[i]->zValues[SG_NDX_LINK_ILINKINFO].iData[0] ==
SG_LINK_OUT)
lnkObjs[i]->zValues[SG_NDX_LINK_FCONCENTRATION].fData[0] =
fConcentration;
}
|
return SG_R_OK;
}
|
Functions
in Class Base.Container.Sink [Go to Top]
|
/* Base_Container_Sink.c
* - DLL routines for class <Component>Base.Container.Sink
* DATE: Monday, September 10, 2001 TIME: 03:57:13 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include <stdio.h>
#include "SGdll.h"
|
#include "../Mixer_1_0/Mixer_1_0.h"
|
#ifdef
__cplusplus
extern "C"
{
#endif
SG_EXPORT SG_SIM_FUNC
SG_xInit_Base_Container_Sink;
SG_EXPORT SG_SIM_FUNC SG_xPostEval_Base_Container_Sink;
#ifdef __cplusplus
}
#endif
/* Macros for attribute indices in class
version [1.0.alpha.7] */
#define SG_NDX_FCONCENTRATION 0 /* fConcentration - Concentration */
/*
============================================================
* SG_xInit - Initialization
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInit_Base_Container_Sink(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* set user type for future identification - to prevent class name comparison
* during component class run-time type checking
*/
MIX_SET_USER_TYPE(self, MIX_USER_TYPE_SINK);
|
return SG_R_OK;
}
/*
============================================================
* SG_xPostEval - Post-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPostEval_Base_Container_Sink(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* fetch concentration from input link - one big requirement here is that
* this routine in all sinks shall be executed AFTER all the PostEval
* routines in the reactors have been executed. Use the name order
* or other execution sequence control in the simControl object.
*/
if (*piLnkObjs > 0)
{
self->zValues[SG_NDX_FCONCENTRATION].fData[0] =
lnkObjs[0]->zValues[SG_NDX_LINK_FCONCENTRATION].fData[0];
}
|
return SG_R_OK;
}
|
Functions
in Class Base.Source [Go to Top]
|
/* Base_Source.c
* - DLL routines for class <Component>Base.Source
* DATE: Monday, September 10, 2001 TIME: 03:57:13 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include <stdio.h>
#include "SGdll.h"
|
#include "../Mixer_1_0/Mixer_1_0.h"
|
#ifdef __cplusplus
extern "C"
{
#endif
SG_EXPORT SG_SIM_FUNC SG_xInit_Base_Source;
SG_EXPORT SG_SIM_FUNC SG_xPreEval_Base_Source;
#ifdef __cplusplus
}
#endif
/* Macros for attribute indices in class
version [1.0.alpha.3] */
#define SG_NDX_FCONCENTRATION 0 /* fConcentration - Initial Concentration */
/*
============================================================
* SG_xInit - Initialization
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInit_Base_Source(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* set user type for future identification - to prevent class name comparison
* during component class run-time type checking
*/
MIX_SET_USER_TYPE(self, MIX_USER_TYPE_SOURCE);
|
return SG_R_OK;
}
/*
============================================================
* SG_xPreEval - Pre-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPreEval_Base_Source(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
const FLOAT cfConcentration = self->zValues[SG_NDX_FCONCENTRATION].fData[0];
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* Deposit Source Concentration to the output link - should be only one */
if (*piLnkObjs > 0)
lnkObjs[0]->zValues[SG_NDX_LINK_FCONCENTRATION].fData[0] =
cfConcentration;
|
return SG_R_OK;
}
|
Functions
in Class Base.Source.Variable [Go to Top]
|
/* Base_Source_Variable.c
* - DLL routines for class <Component>Base.Source.Variable
* DATE: Monday, September 10, 2001 TIME: 03:57:13 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include <stdio.h>
#include "SGdll.h"
|
#include <math.h>
#include "../Mixer_1_0/Mixer_1_0.h"
|
#ifdef
__cplusplus
extern "C"
{
#endif
SG_EXPORT SG_SIM_FUNC
SG_xInit_Base_Source_Variable;
SG_EXPORT SG_SIM_FUNC SG_xPreEval_Base_Source_Variable;
#ifdef __cplusplus
}
#endif
/* Macros for attribute indices in class
version [1.0.alpha.4] */
#define SG_NDX_FCONCENTRATION 0 /* fConcentration - Initial Concentration */
#define SG_NDX_FSTEADY 1 /* fSteady - Steady State Concentration */
#define SG_NDX_FCURRENT 2 /* fCurrent - Current Concentration */
/*
============================================================
* SG_xInit - Initialization
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInit_Base_Source_Variable(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
extern SG_SIM_FUNC SG_xInit_Base_Source;
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* call base class initialization function */
return SG_xInit_Base_Source(self, simCtrl, chgChild,
refObjs, piRefObjs,
adjObjs,
piAdjObjs, lnkObjs, piLnkObjs,
cMessage,
iMsgLen, cCommand, iCmdLen, pOutFile );
|
}
/*
============================================================
* SG_xPreEval - Pre-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPreEval_Base_Source_Variable(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
const FLOAT cfCurTime = simCtrl->zValues[SG_NDX_CTRL_FCURTIME].fData[0];
const FLOAT cfInit = self->zValues[SG_NDX_FCONCENTRATION].fData[0];
const FLOAT cfSteady = self->zValues[SG_NDX_FSTEADY].fData[0];
FLOAT *fConcentration = &self->zValues[SG_NDX_FCURRENT].fData[0];
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* use simple (exponential) lag for the first-order step response */
/* the time constant is hard coded with 1 minute (not shown in terms) */
*fConcentration = (cfSteady - cfInit) * (1.f - (FLOAT)exp((DOUBLE)-cfCurTime)) +
cfInit;
/* Deposit Source Concentration to the output link - should be only one */
if (*piLnkObjs > 0)
lnkObjs[0]->zValues[SG_NDX_LINK_FCONCENTRATION].fData[0] =
*fConcentration;
|
return SG_R_OK;
}
|
Functions
in Class Collection.Solver [Go to Top]
|
/* Collection_Solver.c
* - DLL routines for class <Reference>Collection.Solver
* DATE: Monday, September 10, 2001 TIME: 03:57:13 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include <stdio.h>
#include "SGdll.h"
|
#include "../Mixer_1_0/Mixer_1_0.h"
/* Define MIX_WITH_MATLAB in the
compilation option to activate MATLAB solution.
* If MIX_WITH_MATLAB is defined, it requires the MATLAB Engine from
Mathworks.
* The MATLAB Engine include and library files will be needed to build the
DLL.
*/
#ifdef MIX_WITH_MATLAB
#include "matrix.h" /* mx routines header file */
#include "engine.h" /* matlab engine header file */
static Engine *pMatlabEng = (Engine*)NULL; /* MATLAB Engine */
static mxArray *pMatlabC; /* constant matrix */
static mxArray *pMatlabI; /* inverse matrix */
static mxArray *pMatlabR; /* RHS vector */
static mxArray *pMatlabS; /* solution vector */
static void matlabCleanUp(void);
#endif
|
#ifdef
__cplusplus
extern "C"
{
#endif
SG_EXPORT SG_SIM_FUNC
SG_xBgnRun_Collection_Solver;
SG_EXPORT SG_SIM_FUNC SG_xEval_Collection_Solver;
SG_EXPORT SG_SIM_FUNC SG_xPostEval_Collection_Solver;
SG_EXPORT SG_SIM_FUNC SG_xEndRun_Collection_Solver;
#ifdef __cplusplus
}
#endif
/* Macros for attribute indices in class
version [1.0.alpha.7] */
#define SG_NDX_RREACTOR 0 /* rReactor - Reactor Table */
#define SG_NDX_RCONSTANT 1 /* rConstant - Constant Matrix */
#define SG_NDX_RINVERSE 2 /* rInverse - Inverse Matrix */
#define SG_NDX_RSCRATCH 3 /* rScratch - Scratch Matrix for Temporaries */
|
/* Get linear index from row and column
(column-major order) */
#define MIX_INDEX(R, C, N) ((C) * (N) + (R))
/* Solution methods */
#define MIX_SOLVE_GAUSS
0
#define MIX_SOLVE_LUDECOMP 1
#define MIX_SOLVE_MATLAB
2
static BOOL
solveLinearEquationsGauss(DOUBLE[], DOUBLE[], DOUBLE[],
DOUBLE[], DOUBLE[], const INT );
static BOOL solveLinearEquationsLUD(DOUBLE[], DOUBLE[], DOUBLE[],
DOUBLE[],
DOUBLE[], DOUBLE[],
DOUBLE[], const INT );
static BOOL solveLinearEquationsMatlab(DOUBLE[], DOUBLE[], DOUBLE[],
DOUBLE[], const INT );
static BOOL decompose(DOUBLE[], const INT);
static BOOL substitute(DOUBLE[], DOUBLE[], DOUBLE[], const INT);
static BOOL inverse(DOUBLE[], DOUBLE[], DOUBLE[], DOUBLE[], DOUBLE[], const INT);
|
/*
============================================================
* SG_xBgnRun - Begin Run
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xBgnRun_Collection_Solver(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
INT iNumVars = simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0];
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
if (simCtrl->zValues[SG_NDX_CTRL_ISOLVER].iData[0] ==
MIX_SOLVE_MATLAB)
{
#ifdef MIX_WITH_MATLAB
/* The following statement may not be thread safe */
/* open connection to the local Matlab Engine */
if (!(pMatlabEng = engOpen("\0")))
{
strcpy(cMessage, "Cannot open MATLAB Engine.");
return
SG_R_STOP;
}
/* create all matrices for MATLAB Engine */
if (!(pMatlabC =
mxCreateDoubleMatrix(iNumVars, iNumVars, mxREAL)) ||
!(pMatlabR =
mxCreateDoubleMatrix(iNumVars, 1, mxREAL)) ||
!(pMatlabS =
mxCreateDoubleMatrix(iNumVars, 1, mxREAL)) ||
!(pMatlabI =
mxCreateDoubleMatrix(iNumVars, iNumVars, mxREAL)) )
{
engClose(pMatlabEng);
strcpy(cMessage, "Cannot create MATLAB matrices.");
return
SG_R_STOP;
}
#else
/* call MATLAB option is set, but no MATLAB access code */
strcpy(cMessage, "This version does not have MATLAB support.");
return SG_R_STOP;
#endif
}
|
return SG_R_OK;
}
/*
============================================================
* SG_xEval - Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xEval_Collection_Solver(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
DOUBLE *pdConstantMatrix;
DOUBLE *pdInverseMatrix;
DOUBLE *pdScratchMatrix;
DOUBLE *pdConstantRHS;
DOUBLE *pdSolutionVector;
DOUBLE *pdScratchVector1;
DOUBLE *pdScratchVector2;
const INT ciNumReactors = simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0];
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* Here we start to solve the simultaneous equations because all the
* parts' evaluation routines have been called to load the constant
* matrix and reactor table (RHS constants).
*/
if (*piRefObjs < 4)
{
strcpy(cMessage,
"Either Constant, Inverse, Scratch Matrix or Reactor Table is
missing." );
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return SG_R_STOP;
}
/* The matrices are in column major order */
pdConstantMatrix = refObjs[SG_NDX_RCONSTANT]->zValues[SG_NDX_MTX_DELEMENT].dData;
pdInverseMatrix = refObjs[SG_NDX_RINVERSE]->zValues[SG_NDX_MTX_DELEMENT].dData;
pdScratchMatrix = refObjs[SG_NDX_RSCRATCH]->zValues[SG_NDX_MTX_DELEMENT].dData;
pdConstantRHS = refObjs[SG_NDX_RREACTOR]->zValues[SG_NDX_TBL_DCONSTANT].dData;
pdSolutionVector = refObjs[SG_NDX_RREACTOR]->zValues[SG_NDX_TBL_DSOLUTION].dData;
pdScratchVector1 = refObjs[SG_NDX_RREACTOR]->zValues[SG_NDX_TBL_DSCRATCH1].dData;
pdScratchVector2 = refObjs[SG_NDX_RREACTOR]->zValues[SG_NDX_TBL_DSCRATCH2].dData;
/* call the solver routine - the routine is
destructive and that is why
* we pass in the scratch matrix and vector instead
*/
switch (simCtrl->zValues[SG_NDX_CTRL_ISOLVER].iData[0])
{
case MIX_SOLVE_GAUSS:
if (!solveLinearEquationsGauss(pdConstantMatrix,
pdConstantRHS,
pdSolutionVector, pdScratchMatrix,
pdScratchVector1, ciNumReactors ))
{
strcpy(cMessage, "No solution can be found using Gauss Elimination.");
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return
SG_R_STOP;
}
break;
case MIX_SOLVE_LUDECOMP:
if (!solveLinearEquationsLUD(pdConstantMatrix,
pdConstantRHS,
pdSolutionVector, pdInverseMatrix,
pdScratchMatrix, pdScratchVector1,
pdScratchVector2, ciNumReactors ))
{
strcpy(cMessage, "No solution can be found using LU Decomposition");
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return
SG_R_STOP;
}
break;
case MIX_SOLVE_MATLAB:
if (!solveLinearEquationsMatlab(pdConstantMatrix,
pdConstantRHS,
pdSolutionVector, pdInverseMatrix,
ciNumReactors ))
{
strcpy(cMessage, "Cannot locate/use the MATLAB Engine to solve it.");
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return
SG_R_STOP;
}
break;
default:
strcpy(cMessage, "Unknown solver type. Check the SimControl
object.");
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return SG_R_STOP;
break;
}
|
return SG_R_OK;
}
/*
============================================================
* SG_xPostEval - Post-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPostEval_Collection_Solver(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* Advance system clock - access with care in other reference objects */
simCtrl->zValues[SG_NDX_CTRL_FCURTIME].fData[0] +=
simCtrl->zValues[SG_NDX_CTRL_FTIMEINC].fData[0];
|
return SG_R_OK;
}
/*
============================================================
* SG_xEndRun - End Run
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xEndRun_Collection_Solver(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* Solver's duty to reset the reactor counter for the next run */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
/* Reset the current time to 0 if it is
preferred */
/* simCtrl->zValues[SG_NDX_CTRL_FCURTIME].fData[0] = 0.f; */
#ifdef MIX_WITH_MATLAB
if (simCtrl->zValues[SG_NDX_CTRL_ISOLVER].iData[0] ==
MIX_SOLVE_MATLAB)
{
if (pMatlabEng)
matlabCleanUp();
}
#endif
|
return SG_R_OK;
}
|
/*
============================================================
* solveLinearEquationsGauss - solve the linear simultaneous
* equations using Naive Gauss Elimination
* ------------------------------------------------------------
* There is no inverse matrix calculated when using this method.
* ------------------------------------------------------------
*/
BOOL solveLinearEquationsGauss(DOUBLE dConstantMatrix[], DOUBLE dConstantRHS[],
DOUBLE dSolutionVector[], DOUBLE
dScratchMatrix[],
DOUBLE dScratchVector[], const INT ciNumVars )
{
const INT ciDoubleLength = sizeof(DOUBLE) * ciNumVars;
INT i, j, k, n;
DOUBLE dFactor;
DOUBLE dDivisor;
DOUBLE dSum;
/* remember the constant matrix and RHS
constant vector */
memcpy(dScratchMatrix, dConstantMatrix, ciDoubleLength *
ciNumVars);
memcpy(dScratchVector, dConstantRHS, ciDoubleLength);
for (k = 0; k < ciNumVars - 1; k++)
{
for (i = k + 1; i < ciNumVars; i++)
{
dDivisor =
dScratchMatrix[MIX_INDEX(k, k, ciNumVars)];
if (dDivisor == 0.)
return FALSE;
dFactor =
dScratchMatrix[MIX_INDEX(i, k, ciNumVars)] / dDivisor;
for (j = k + 1; j < ciNumVars; j++)
dScratchMatrix[MIX_INDEX(i, j, ciNumVars)] -=
dFactor * dScratchMatrix[MIX_INDEX(k, j, ciNumVars)];
dScratchVector[i] -= dFactor * dScratchVector[k];
}
}
n = ciNumVars - 1;
dDivisor = dScratchMatrix[MIX_INDEX(n, n, ciNumVars)];
if (dDivisor == 0.)
return FALSE;
dSolutionVector[n] = dScratchVector[n] / dDivisor;
for (i = n - 1; i >= 0; i--)
{
dSum = 0.;
for (j = i + 1; j < ciNumVars; j++)
{
dSum +=
dScratchMatrix[MIX_INDEX(i, j, ciNumVars)] *
dSolutionVector[j];
}
dDivisor = dScratchMatrix[MIX_INDEX(i,
i, ciNumVars)];
if (dDivisor == 0.)
return FALSE;
dSolutionVector[i] = (dScratchVector[i] -
dSum) / dDivisor;
}
return TRUE;
}
/*
============================================================
* solveLinearEquationsLUD - solve the linear simultaneous
* equations using LU Decomposition
* ------------------------------------------------------------
*/
BOOL solveLinearEquationsLUD(DOUBLE dConstantMatrix[], DOUBLE dConstantRHS[],
DOUBLE dSolutionVector[], DOUBLE
dInverseMatrix[],
DOUBLE dScratchMatrix[], DOUBLE dScratchVector1[],
DOUBLE dScratchVector2[], const INT ciNumVars )
{
const INT ciDoubleLength = sizeof(DOUBLE) * ciNumVars;
/* remember the constant matrix and RHS
constant vector */
memcpy(dScratchMatrix, dConstantMatrix, ciDoubleLength *
ciNumVars);
if (!decompose(dScratchMatrix, ciNumVars))
return FALSE;
/* remember the LU matrix in dScratchMatrix
for inverse matrix calculation */
memcpy(dInverseMatrix, dScratchMatrix, ciDoubleLength *
ciNumVars);
/* copy the RHS vector for inverse matrix
calculation */
memcpy(dScratchVector1, dConstantRHS, ciDoubleLength);
if (!substitute(dScratchMatrix, dScratchVector1,
dSolutionVector, ciNumVars))
return FALSE;
/* Inverse matrix should contain the LU
decomposed result */
memcpy(dScratchMatrix, dInverseMatrix, ciDoubleLength *
ciNumVars);
return inverse(dScratchMatrix, dInverseMatrix, dConstantRHS, dScratchVector1,
dScratchVector2, ciNumVars );
}
/*
------------------------------------------------------------
*/
BOOL decompose(DOUBLE dConstantMatrix[], const INT ciNumVars)
{
INT i, j, k;
DOUBLE dFactor, dDivisor;
for (k = 0; k < ciNumVars - 1; k++)
{
for (i = k + 1; i < ciNumVars; i++)
{
dDivisor =
dConstantMatrix[MIX_INDEX(k, k, ciNumVars)];
if (dDivisor == 0.)
return FALSE;
dFactor =
dConstantMatrix[MIX_INDEX(i, k, ciNumVars)] / dDivisor;
dConstantMatrix[MIX_INDEX(i, k, ciNumVars)] = dFactor;
for (j = k + 1; j <
ciNumVars; j++)
dConstantMatrix[MIX_INDEX(i, j, ciNumVars)] -=
dFactor * dConstantMatrix[MIX_INDEX(k, j, ciNumVars)];
}
}
return TRUE;
}
/*
------------------------------------------------------------
*/
BOOL substitute(DOUBLE dMatrixLU[], DOUBLE dVectorRHS[],
DOUBLE dVectorSolution[], const INT ciNumVars )
{
INT i, j, n;
DOUBLE dSum, dDivisor;
/* forward substitution */
for (i = 1; i < ciNumVars; i++)
{
dSum = dVectorRHS[i];
for (j = 0; j < i; j++)
dSum -=
dMatrixLU[MIX_INDEX(i, j, ciNumVars)] * dVectorRHS[j];
dVectorRHS[i] = dSum;
}
/* backward substitution */
n = ciNumVars - 1;
dDivisor = dMatrixLU[MIX_INDEX(n, n, ciNumVars)];
if (dDivisor == 0.)
return FALSE;
dVectorSolution[n] = dVectorRHS[n] / dDivisor;
for (i = n - 1; i >= 0; i--)
{
dSum = 0.;
for (j = i + 1; j < ciNumVars; j++)
dSum +=
dMatrixLU[MIX_INDEX(i, j, ciNumVars)] * dVectorSolution[j];
dDivisor = dMatrixLU[MIX_INDEX(i, i,
ciNumVars)];
if (dDivisor == 0.)
return FALSE;
dVectorSolution[i] = (dVectorRHS[i] -
dSum) / dDivisor;
}
return TRUE;
}
/*
------------------------------------------------------------
*/
BOOL inverse(DOUBLE dMatrixLU[], DOUBLE dMatrixInverse[], DOUBLE dVectorRHS[],
DOUBLE dVectorScratch1[], DOUBLE dVectorScratch2[],
const INT ciNumVars )
{
/* calling decompose() is not necessary because the input is LU result */
INT i, j;
memcpy(dVectorScratch1, dVectorRHS, sizeof(DOUBLE) * ciNumVars);
for (i = 0; i < ciNumVars; i++)
{
for (j = 0; j < ciNumVars; j++)
dVectorScratch1[j] =
(i == j) ? 1. : 0.;
/* use dVectorScratch2 to receive solution
vector X */
if (!substitute(dMatrixLU, dVectorScratch1, dVectorScratch2,
ciNumVars))
return FALSE;
for (j = 0; j < ciNumVars; j++)
dMatrixInverse[MIX_INDEX(j, i, ciNumVars)] = dVectorScratch2[j];
}
return TRUE;
}
/*
============================================================
* solveLinearEquationsMatlab - solve the linear simultaneous
* equations using the MATLAB Engine
* ------------------------------------------------------------
*/
BOOL solveLinearEquationsMatlab(DOUBLE dConstantMatrix[], DOUBLE dConstantRHS[],
DOUBLE dSolutionVector[], DOUBLE
dInverseMatrix[],
const INT ciNumVars )
{
#ifdef MIX_WITH_MATLAB
const INT ciDoubleLength = sizeof(DOUBLE) * ciNumVars;
/* prepare input matrices */
memcpy((void*)mxGetPr(pMatlabC), (void*)dConstantMatrix,
ciDoubleLength * ciNumVars );
memcpy((void*)mxGetPr(pMatlabR), (void*)dConstantRHS,
ciDoubleLength);
memset((void*)mxGetPr(pMatlabS), 0, ciDoubleLength);
memset((void*)mxGetPr(pMatlabI), 0, ciDoubleLength *
ciNumVars);
if (engPutVariable(pMatlabEng, "C", pMatlabC) ||
engPutVariable(pMatlabEng,
"R", pMatlabR) ||
engPutVariable(pMatlabEng,
"S", pMatlabS) ||
engPutVariable(pMatlabEng,
"I", pMatlabI) )
{
matlabCleanUp();
return FALSE;
}
/* now execute MATLAB commands - both must
be executed */
if (engEvalString(pMatlabEng, "S = C \\ R;") ||
engEvalString(pMatlabEng, "I =
inv(C);") )
{
matlabCleanUp();
return FALSE;
}
/* now fetch the solutions */
if (!(pMatlabS = engGetVariable(pMatlabEng, "S")))
{
matlabCleanUp();
return FALSE;
}
memcpy((void*)dSolutionVector, (void*)mxGetPr(pMatlabS),
ciDoubleLength);
if (!(pMatlabI = engGetVariable(pMatlabEng,
"I")))
{
matlabCleanUp();
return FALSE;
}
memcpy((void*)dInverseMatrix, (void*)mxGetPr(pMatlabI),
ciDoubleLength * ciNumVars );
return TRUE;
#else
/* call MATLAB option is set, but no MATLAB access code */
return FALSE;
#endif
}
/*
============================================================
* matlabCleanUp - subroutine to clean up MATLAB access
* ------------------------------------------------------------
*/
#ifdef MIX_WITH_MATLAB
void matlabCleanUp()
{
mxDestroyArray(pMatlabC);
mxDestroyArray(pMatlabR);
mxDestroyArray(pMatlabS);
mxDestroyArray(pMatlabI);
engClose(pMatlabEng);
}
#endif
|
Functions
in Class Matrix.Calculation [Go to Top]
|
/* Matrix_Calculation.c
* - DLL routines for class <Reference>Matrix.Calculation
* DATE: Monday, September 10, 2001 TIME: 03:57:13 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include <stdio.h>
#include "SGdll.h"
|
#include "../Mixer_1_0/Mixer_1_0.h"
|
#ifdef
__cplusplus
extern "C"
{
#endif
SG_EXPORT SG_SIM_FUNC
SG_xInitSize_Matrix_Calculation;
SG_EXPORT SG_SIM_FUNC SG_xPreEval_Matrix_Calculation;
#ifdef __cplusplus
}
#endif
/* Macros for attribute indices in class
version [1.0.alpha.5] */
#define SG_NDX_ICOLS 0 /* iCols - Number of Columns */
#define SG_NDX_IROWS 1 /* iRows - Number of Rows */
#define SG_NDX_ISHEETS 2 /* iSheets - Number of Sheets */
#define SG_NDX_DELEMENT 3 /* dElement - Elements in Matrix */
/*
============================================================
* SG_xInitSize - Resize for Init
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInitSize_Matrix_Calculation(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
const INT ciNumReactors = simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0];
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* resize constant matrix according to the number of reactors registered */
if (ciNumReactors < 1)
{
strcpy(cMessage, "At least one reactor part is required.");
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return SG_R_STOP;
}
self->zValues[SG_NDX_ICOLS].iData[0] = ciNumReactors;
self->zValues[SG_NDX_IROWS].iData[0] = ciNumReactors;
self->zValues[SG_NDX_ISHEETS].iData[0] = 1; /* always */
|
return SG_R_OK;
}
/*
============================================================
* SG_xPreEval - Pre-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPreEval_Matrix_Calculation(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
INT iSize = self->zValues[SG_NDX_DELEMENT].iSize;
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* initialize the matrix to 0 to prepare for loading constants */
memset(self->zValues[SG_NDX_DELEMENT].dData, 0,
sizeof(DOUBLE) * iSize);
|
return SG_R_OK;
}
|
/*
============================================================
* loadMatrixConstant - load a simultaneous equation constant into
* the constant matrix
* ------------------------------------------------------------
* ARGUMENT:
* self - the Matrix.Constant object to load constants to
* ciPartNdx- the registered 1-based index of the reactor (row)
* ciLoadNdx- the 1-based index of the reactor associated (column)
* cfValue- the constant value to be loaded
* cbInput- TRUE, if input to the part; FALSE, if output
*
* RETURN:
* 1-based index of the reactor (row); 0 when failed.
*
* NOTES:
* The convention for loading equation constants (LHS) is that
* the input values are negative and output values are positive.
* The matrix is stored in column major order.
* ------------------------------------------------------------
*/
INT loadMatrixConstant(SG_OBJ *const self, const INT ciPartNdx,
const INT ciLoadNdx, const FLOAT cfValue,
const BOOL cbInput )
{
const INT ciRow = ciPartNdx - 1; /* now 0-based */
const INT ciCol = ciLoadNdx - 1; /* now 0-based */
const INT ciSize = self->zValues[SG_NDX_IROWS].iData[0];
INT iNdx; /* to store linearized index */
/* should be a square matrix */
if (ciRow < 0 || ciCol < 0 || ciRow >= ciSize || ciCol >=
ciSize)
return 0; /* out of bound error */
/* calculate linear index */
iNdx = ciSize * ciCol + ciRow;
if (cbInput)
self->zValues[SG_NDX_DELEMENT].dData[iNdx] -=
(DOUBLE)cfValue;
else
self->zValues[SG_NDX_DELEMENT].dData[iNdx] +=
(DOUBLE)cfValue;
return ciPartNdx;
}
|
Functions
in Class Table.Reactor [Go to Top]
|
/* Table_Reactor.c
* - DLL routines for class <Reference>Table.Reactor
* DATE: Monday, September 10, 2001 TIME: 03:57:13 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include <stdio.h>
#include "SGdll.h"
|
#include "../Mixer_1_0/Mixer_1_0.h"
|
#ifdef
__cplusplus
extern "C"
{
#endif
SG_EXPORT SG_SIM_FUNC
SG_xInitSize_Table_Reactor;
SG_EXPORT SG_SIM_FUNC SG_xInit_Table_Reactor;
SG_EXPORT SG_SIM_FUNC SG_xPreEval_Table_Reactor;
#ifdef __cplusplus
}
#endif
/* Macros for attribute indices in class
version [1.0.alpha.9] */
#define SG_NDX_ISIZE 0 /* iSize - Table Size */
#define SG_NDX_ISHEETS 1 /* iSheets - Number of Sheets */
#define SG_NDX_IPARTSN 2 /* iPartSN - Part Internal Serial Number */
#define SG_NDX_DCONSTANT 3 /* dConstant - Constants in Mass Balance Eqns */
#define SG_NDX_DSOLUTION 4 /* dSolution - Solutions in Mass Balance Eqns */
#define SG_NDX_DSCRATCH1 5 /* dScratch1 - Vector Buffer 1 for Temporaries */
#define SG_NDX_DSCRATCH2 6 /* dScratch2 - Vector Buffer 2 for Temporaries */
/*
============================================================
* SG_xInitSize - Resize for Init
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInitSize_Table_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
const INT ciNumReactors = simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0];
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
if (ciNumReactors < 1)
{
strcpy(cMessage, "ERROR: At least one reactor part is required.");
/* important - reset the number of reactors in the simControl object */
simCtrl->zValues[SG_NDX_CTRL_INUMREACTORS].iData[0] = 0;
return SG_R_STOP;
}
self->zValues[SG_NDX_ISIZE].iData[0] = ciNumReactors;
self->zValues[SG_NDX_ISHEETS].iData[0] = 1; /* always */
|
return SG_R_OK;
}
/*
============================================================
* SG_xInit - Initialization
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xInit_Table_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
INT iSize = sizeof(INT) * self->zValues[SG_NDX_IPARTSN].iSize;
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* zero out the reactor parts registration */
/* all the other vectors need to be initialized in each Pre-Eval cycle */
memset(self->zValues[SG_NDX_IPARTSN].iData, 0, iSize);
|
return SG_R_OK;
}
/*
============================================================
* SG_xPreEval - Pre-Evaluation
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xPreEval_Table_Reactor(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const
chgChild,
SG_OBJ *const refObjs[], const INT *const
piRefObjs,
SG_OBJ *const adjObjs[], const INT *const
piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const
piLnkObjs,
TCHAR *const cMessage, const INT
iMsgLen,
TCHAR *const cCommand, const INT
iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
|
INT iDoubleSize = sizeof(DOUBLE) * self->zValues[SG_NDX_DCONSTANT].iSize;
|
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
|
/* reset constant and solution vectors to prepare for loading */
memset(self->zValues[SG_NDX_DCONSTANT].dData, 0,
iDoubleSize);
memset(self->zValues[SG_NDX_DSOLUTION].dData, 0,
iDoubleSize);
memset(self->zValues[SG_NDX_DSCRATCH1].dData, 0,
iDoubleSize);
memset(self->zValues[SG_NDX_DSCRATCH2].dData, 0,
iDoubleSize);
|
return SG_R_OK;
}
|
/*
============================================================
* registerReactor - register reactor to the table
* ------------------------------------------------------------
* ARGUMENT:
* self - the Table.Reactor object to provide registration
* ciPartSN- the unique serial number of the reactor
*
* RETURN:
* 1-based index of the reactor; 0 when failed.
* ------------------------------------------------------------
*/
INT registerReactor(SG_OBJ *const self, const INT ciPartSN)
{
INT i;
const INT ciSize = self->zValues[SG_NDX_IPARTSN].iSize;
INT *piPartSN = self->zValues[SG_NDX_IPARTSN].iData;
for (i = 0; i < ciSize; i++)
{
if (*piPartSN < 1)
{ /* it is not occupied, register it in the table */
*piPartSN =
ciPartSN;
return i + 1; /* return 1-based index */
}
else if (*piPartSN == ciPartSN)
{ /* it has been registered before */
return i + 1; /* return 1-based index */
}
piPartSN++; /* move the pointer to the next element */
}
return 0; /* failed */
}
/*
============================================================
* loadTableConstant - load a constant into the RHS vector
* ------------------------------------------------------------
* ARGUMENT:
* self - the Table.Reactor object to load RHS constants to
* ciPartNdx- the registered 1-based index of the reactor
* cfValue- the constant value to be loaded
* cbInput- TRUE, if input to the part; FALSE, if output
*
* RETURN:
* 1-based index of the reactor; 0 when failed.
*
* NOTES:
* The convention for loading RHS constants is that the input
* values are positive and output values are negative.
* ------------------------------------------------------------
*/
INT loadTableConstant(SG_OBJ *const self, const INT ciPartNdx,
const FLOAT cfValue, const BOOL cbInput )
{
const INT ciNdx = ciPartNdx - 1; /* now 0-based */
const INT ciSize = self->zValues[SG_NDX_DCONSTANT].iSize;
if (ciNdx < 0 || ciNdx >= ciSize)
return 0; /* out of bound error */
/* See NOTES above for the sign of the
value */
if (cbInput)
self->zValues[SG_NDX_DCONSTANT].dData[ciNdx] +=
(DOUBLE)cfValue;
else
self->zValues[SG_NDX_DCONSTANT].dData[ciNdx] -=
(DOUBLE)cfValue;
return ciPartNdx;
}
|
Contents
in Mixer_1_0.h [Go to Top]
|
/* Mixer_1_0.h - manually created header file for macros and
* function prototype, called from various classes
*/
#include <memory.h>
#include <string.h>
typedef INT BOOL;
#define FALSE 0
#define TRUE (!FALSE)
#define SG_NDX_CTRL_ISOLVER
9 /* from class simControl.Mixer */
#define SG_NDX_CTRL_FTIMEINC 10
#define SG_NDX_CTRL_FCURTIME 11
#define SG_NDX_CTRL_INUMREACTORS 12
#define SG_NDX_MTX_DELEMENT
3 /* from class Matrix.Calculation */
#define SG_NDX_TBL_IPARTSN
2 /* from class Table.Reactor */
#define SG_NDX_TBL_DCONSTANT 3
#define SG_NDX_TBL_DSOLUTION 4
#define SG_NDX_TBL_DSCRATCH1 5
#define SG_NDX_TBL_DSCRATCH2 6
#define SG_NDX_LINK_ILINKINFO
0 /* from class Link.Pipe */
#define SG_NDX_LINK_FFLOWRATE 1
#define SG_NDX_LINK_FCONCENTRATION 2
#define MIX_USER_TYPE_UNKNOWN
0 /* for class type info in iUserData */
#define MIX_USER_TYPE_REACTOR 1
#define MIX_USER_TYPE_SOURCE 2
#define MIX_USER_TYPE_SINK 3
#define MIX_SET_USER_TYPE(X, T) ((X)->iUserData = (T))
#define MIX_GET_USER_TYPE(X) ((X)->iUserData)
extern INT registerReactor(SG_OBJ *const,
const INT);
extern INT loadTableConstant(SG_OBJ *const, const INT, const FLOAT, const BOOL);
extern INT loadMatrixConstant(SG_OBJ *const, const INT, const INT,
const FLOAT, const BOOL );
|