Skip to content

Commit

Permalink
Change relations macro to function (#7513)
Browse files Browse the repository at this point in the history
Functions are documented and can be debugged.

  - New function relation replacing macro RELATION
  - New function relationhysteresis replacing macro RELATIONHYSTERESIS
  • Loading branch information
AnHeuermann committed Jun 4, 2021
1 parent 578ab40 commit 49710ab
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 48 deletions.
20 changes: 10 additions & 10 deletions OMCompiler/Compiler/Template/CodegenCFunctions.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5878,19 +5878,19 @@ case rel as RELATION(__) then
end match
else
let isReal = if isRealType(typeof(rel.exp1)) then (if isRealType(typeof(rel.exp2)) then 'true' else '') else ''
let hysteresisfunction = if isReal then 'RELATIONHYSTERESIS' else 'RELATION'
let hysteresisfunction = if isReal then 'relationhysteresis' else 'relation'
match rel.operator
case LESS(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%>, Less);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%>, Less<% if isReal then ', LessZC' else ''%>);<%\n%>'
res
case LESSEQ(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%>, LessEq);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%>, LessEq<% if isReal then ', LessEqZC' else ''%>);<%\n%>'
res
case GREATER(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%>, Greater);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%>, Greater<% if isReal then ', GreaterZC' else ''%>);<%\n%>'
res
case GREATEREQ(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%>, GreaterEq);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%>, GreaterEq<% if isReal then ', GreaterEqZC' else ''%>);<%\n%>'
res
end match
case SOME((exp,i,j)) then
Expand All @@ -5915,19 +5915,19 @@ case rel as RELATION(__) then
end match
else
let isReal = if isRealType(typeof(rel.exp1)) then (if isRealType(typeof(rel.exp2)) then 'true' else '') else ''
let hysteresisfunction = if isReal then 'RELATIONHYSTERESIS' else 'RELATION'
let hysteresisfunction = if isReal then 'relationhysteresis' else 'relation'
match rel.operator
case LESS(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, Less);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, Less<% if isReal then ', LessZC' else ''%>);<%\n%>'
res
case LESSEQ(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, LessEq);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, LessEq<% if isReal then ', LessEqZC' else ''%>);<%\n%>'
res
case GREATER(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, Greater);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, Greater<% if isReal then ', GreaterZC' else ''%>);<%\n%>'
res
case GREATEREQ(__) then
let &preExp += '<%hysteresisfunction%>(<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, GreaterEq);<%\n%>'
let &preExp += '<%hysteresisfunction%>(data, &<%res%>, <%e1%>, <%e2%>, <%rel.index%> + (<%iterator%> - <%i%>)/<%j%>, GreaterEq<% if isReal then ', GreaterEqZC' else ''%>);<%\n%>'
res
end match
end match
Expand Down
104 changes: 66 additions & 38 deletions OMCompiler/SimulationRuntime/c/simulation/solver/model_help.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,44 +36,6 @@ extern "C" {

#include "../../simulation_data.h"

/* lochel: I guess this is used for discrete relations */
#define RELATION(res,exp1,exp2,index,op_w) \
{ \
if(data->simulationInfo->initial) \
{ \
res = ((op_w)((exp1),(exp2))); \
data->simulationInfo->relations[index] = res; \
} \
else if(data->simulationInfo->discreteCall == 0 || data->simulationInfo->solveContinuous) \
{ \
res = data->simulationInfo->relationsPre[index]; \
} \
else \
{ \
res = ((op_w)((exp1),(exp2))); \
data->simulationInfo->relations[index] = res; \
} \
}

/* lochel: I guess this is used for continuous relations */
#define RELATIONHYSTERESIS(res,exp1,exp2,index,op_w) \
{ \
if(data->simulationInfo->initial) \
{ \
res = ((op_w)((exp1),(exp2))); \
data->simulationInfo->relations[index] = res; \
} \
else if(data->simulationInfo->discreteCall == 0 || data->simulationInfo->solveContinuous) \
{ \
res = data->simulationInfo->relationsPre[index]; \
} \
else \
{ \
res = ((op_w##ZC)((exp1),(exp2),data->simulationInfo->storedRelations[index])); \
data->simulationInfo->relations[index] = res; \
} \
}

extern int maxEventIterations;
extern double linearSparseSolverMaxDensity;
extern int linearSparseSolverMinSize;
Expand Down Expand Up @@ -177,6 +139,72 @@ modelica_boolean LessEqZC(double a, double b, modelica_boolean);
modelica_boolean GreaterZC(double a, double b, modelica_boolean);
modelica_boolean GreaterEqZC(double a, double b, modelica_boolean);


/**
* @brief Relation function for compare functions.
*
* Used for cases where exp1 or exp2 are discrete.
*
* Two cases:
* 1. During initialization or discrete calls or not continuous mode: Use op_w(exp1,exp2) and update relations[index] and return result in res.
* 2. Else (Not discrete call or in continuous mode) : Only return pre-value of relation in res
*
* @param[in] data Pointer to data struct
* @param[out] res Gets overwritten with result of relation.
* @param[in] exp1 First value (left side of relation).
* @param[in] exp2 Second value (right side of relation).
* @param[in] index Index of relation in data->simulationInfo->relations.
* @param[in] op_w Comparison function, e.g. Less.
*/
static inline void relation(DATA* data, modelica_boolean* res, double exp1, double exp2, int index, modelica_boolean(*op_w)(double, double))
{
if(data->simulationInfo->initial || !(data->simulationInfo->discreteCall == 0 || data->simulationInfo->solveContinuous) )
{
*res = op_w(exp1,exp2);
data->simulationInfo->relations[index] = *res;
}
else
{
*res = data->simulationInfo->relationsPre[index];
}
}

/**
* @brief Relation hysteresis function for compare functions.
*
* Used for cases where exp1 and exp2 are continuous.
*
* Three cases:
* 1. During initialization: Use op_w(exp1,exp2) and update relations[index] and return result in res.
* 2. No descrete call or in continuous case: Only return pre-value of relation in res
* 3. Else (events, zero-crossing): Use op_w_zc(exp1,exp2,...) to update relations[index] and return result in res.
*
* @param[in] data Pointer to data struct
* @param[out] res Gets overwritten with result of relation.
* @param[in] exp1 First value (left side of relation).
* @param[in] exp2 Second value (right side of relation).
* @param[in] index Index of relation in data->simulationInfo->relations.
* @param[in] op_w Comparison function, e.g. Less.
* @param[in] op_w_zc Matching comparison function of op_w for zero-crossing, e.g. LessZC.
*/
static inline void relationhysteresis(DATA* data, modelica_boolean* res, double exp1, double exp2, int index, modelica_boolean(*op_w)(double, double), modelica_boolean(*op_w_zc)(double, double, modelica_boolean))
{
if(data->simulationInfo->initial)
{
*res = op_w(exp1,exp2);
data->simulationInfo->relations[index] = *res;
}
else if(data->simulationInfo->discreteCall == 0 || data->simulationInfo->solveContinuous)
{
*res = data->simulationInfo->relationsPre[index];
}
else
{
*res = op_w_zc(exp1, exp2, data->simulationInfo->storedRelations[index]);
data->simulationInfo->relations[index] = *res;
}
}

extern int measure_time_flag;

void setContext(DATA* data, double* currentTime, int currentContext);
Expand Down

0 comments on commit 49710ab

Please sign in to comment.