| 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
      __cplusplusextern "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
__cplusplusextern "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 __cplusplusextern "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
__cplusplusextern "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
__cplusplusextern "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_MATLABif (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
__cplusplusextern "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
__cplusplusextern "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 );
 |