Skip to content

Commit

Permalink
-Assertions are checked in DAElow.lower if they are always false. In …
Browse files Browse the repository at this point in the history
…that case error message is given and lowering fails. (to test this instantiate a CombiTable component and run checkModel, without giving any table data).

-Assertions only output if accepting a step (see acceptedStep variable).
-Fixed minor typos in comments.

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@2798 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Peter Aronsson committed May 23, 2007
1 parent 7b12d72 commit 6c21a39
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 19 deletions.
34 changes: 28 additions & 6 deletions Compiler/DAELow.mo
Expand Up @@ -4487,7 +4487,7 @@ algorithm
{"if-equations","rewrite equations using if-expressions"});
then
fail();

/* assert in equation section is converted to ALGORITHM */
case (DAE.DAE(elementLst = (DAE.ASSERT(cond,msg) :: xs)),states,whenclauses)
local
Expand All @@ -4496,12 +4496,13 @@ algorithm
Exp.Exp cond,msg;

equation
(v,kv,extVars,e,re,ie,ae,al,whenclauses_1,extObjCls) = lower2(DAE.DAE(xs), states, whenclauses) "Print.print_error_buf \"#Warning, Asserts are not supported/checked for.\\n\" &" ;
checkAssertCondition(cond,msg);
(v,kv,extVars,e,re,ie,ae,al,whenclauses_1,extObjCls) = lower2(DAE.DAE(xs), states, whenclauses);
then
(v,kv,extVars,e,re,ie,ae,Algorithm.ALGORITHM({Algorithm.ASSERT(cond,msg)})::al,whenclauses_1,extObjCls);

/* terminate in equation section is converted to ALGORITHM */
case (DAE.DAE(elementLst = (DAE.ASSERT(cond,msg) :: xs)),states,whenclauses)
case (DAE.DAE(elementLst = (DAE.TERMINATE(msg) :: xs)),states,whenclauses)
local
Variables v;
list<Equation> e;
Expand All @@ -4510,16 +4511,19 @@ algorithm
equation
(v,kv,extVars,e,re,ie,ae,al,whenclauses_1,extObjCls) = lower2(DAE.DAE(xs), states, whenclauses) ;
then
(v,kv,extVars,e,re,ie,ae,Algorithm.ALGORITHM({Algorithm.ASSERT(cond,msg)})::al,whenclauses_1,extObjCls);
case (DAE.DAE(elementLst = (_ :: xs)),states,whenclauses)
(v,kv,extVars,e,re,ie,ae,Algorithm.ALGORITHM({Algorithm.TERMINATE(msg)})::al,whenclauses_1,extObjCls);

case (DAE.DAE(elementLst = (DAE.INITIALALGORITHM(_) :: xs)),states,whenclauses)
local
Variables v;
list<Equation> e;
equation
Error.addMessage(Error.UNSUPPORTED_LANGUAGE_FEATURE,
{"initial algorithm","rewrite initial algorithms to initial equations"});
(v,kv,extVars,e,re,ie,ae,al,whenclauses_1,extObjCls) = lower2(DAE.DAE(xs), states, whenclauses);
then
(v,kv,extVars,e,re,ie,ae,al,whenclauses_1,extObjCls);

case (_,_,_)
equation
print("-lower2 failed\n");
Expand All @@ -4528,6 +4532,24 @@ algorithm
end matchcontinue;
end lower2;

protected function checkAssertCondition "Succeds if condition of assert is not constant false"
input Exp.Exp cond;
input Exp.Exp message;
algorithm
_ := matchcontinue(cond,message)
case(cond,message) equation
false = Exp.isConstFalse(cond);
then ();
case(cond,message)
local String messageStr;
equation
true = Exp.isConstFalse(cond);
messageStr = Exp.printExpStr(message);
Error.addMessage(Error.ASSERT_CONSTANT_FALSE_ERROR,{messageStr});
then fail();
end matchcontinue;
end checkAssertCondition;

protected function lowerTupleEquation "Lowers a tuple equation, e.g. (a,b) = foo(x,y)
by transforming it to an algorithm (TUPLE_ASSIGN), e.g. (a,b) := foo(x,y);

Expand Down
3 changes: 3 additions & 0 deletions Compiler/Error.mo
Expand Up @@ -192,6 +192,7 @@ public constant ErrorID BREAK_OUT_OF_LOOP= 94;
public constant ErrorID DIFFERENT_VARIABLES_SOLVED_IN_ELSEWHEN= 95;
public constant ErrorID GENERIC_TRANSLATION_ERROR = 96;
public constant ErrorID MODIFIER_DECLARATION_TYPE_MISMATCH_ERROR=97;
public constant ErrorID ASSERT_CONSTANT_FALSE_ERROR=98;
public constant ErrorID UNBOUND_PARAMETER_WARNING=500;
public constant ErrorID BUILTIN_FUNCTION_SUM_HAS_SCALAR_PARAMETER=501;
public constant ErrorID BUILTIN_FUNCTION_PRODUCT_HAS_SCALAR_PARAMETER=502;
Expand Down Expand Up @@ -391,6 +392,8 @@ protected constant list<tuple<Integer, MessageType, Severity, String>> errorTabl
"Notification, differentiated equation %s to %s for index reduction"),
(DIFFERENT_VARIABLES_SOLVED_IN_ELSEWHEN,SYMBOLIC(),ERROR(),
"Error, The same variables must me solved in elsewhen clause as in the when clause"),
(ASSERT_CONSTANT_FALSE_ERROR,SYMBOLIC(),ERROR(),
"Error, assert with constant condition during translation: %s"),
(SETTING_FIXED_ATTRIBUTE,TRANSLATION(),WARNING(),
"Warning, no variable has fixed=false but model contains initial equations. Setting fixed=false to the following variables: %s"),
(GENERIC_TRANSLATION_ERROR,TRANSLATION(),ERROR(),
Expand Down
26 changes: 26 additions & 0 deletions Compiler/Exp.mo
Expand Up @@ -4207,6 +4207,32 @@ algorithm
end matchcontinue;
end typeofOp;

public function isConstFalse "
Return true if expression is false
"
input Exp inExp;
output Boolean outBoolean;
algorithm
outBoolean:=
matchcontinue (inExp)
case BCONST(false) then true;
case (_) then false;
end matchcontinue;
end isConstFalse;

public function isConstTrue "
Return true if expression is true
"
input Exp inExp;
output Boolean outBoolean;
algorithm
outBoolean:=
matchcontinue (inExp)
case BCONST(true) then true;
case (_) then false;
end matchcontinue;
end isConstTrue;

protected function isConstOne "function: isConstOne
Return true if expression is 1
Expand Down
4 changes: 2 additions & 2 deletions Compiler/SimCodegen.mo
Expand Up @@ -2494,9 +2494,9 @@ protected function generateArrayDefine "function: generateArrayDefine
Generates a define for an array variable.
For an array s, each scalar value is given a define, e.g.
#define s{1,3} y{17}, etc. But to also be able to treat the whole array
#define s[1,3] y[17], etc. But to also be able to treat the whole array
as a value this function generates a define to point to the first element
of the array, e.g. #deine s &y{15}.
of the array, e.g. #define s &y[15].
"
input Exp.ComponentRef inComponentRef;
Expand Down
1 change: 1 addition & 0 deletions c_runtime/simulation_init.cpp
Expand Up @@ -218,6 +218,7 @@ int initialize(const std::string*method)
cout << getName(&globalData->states[i]) << "(fixed=" << (globalData->initFixed[i]?"true":"false") << ")"
<< endl;
}
cout << "number of non-fixed variables: " << nz << endl;
}

// No initial values to calculate.
Expand Down
4 changes: 4 additions & 0 deletions c_runtime/simulation_runtime.cpp
Expand Up @@ -62,6 +62,10 @@ long numpoints; // the number of points requested by init file

int sim_verbose; // Flag for logging

int acceptedStep=0; /* Flag for knowning when step is accepted and when solver searches for solution.
If solver is only searching for a solution, asserts, etc. should not be triggered, causing faulty error messages to be printed
*/

int modelErrorCode=0; // set by model calculations. Can be transferred to num. solver.

const std::string *init_method; // method for initialization.
Expand Down
4 changes: 2 additions & 2 deletions c_runtime/simulation_runtime.h
Expand Up @@ -59,7 +59,7 @@ double old(double*);
double old2(double*);

extern int sim_verbose; // control debug output during simulation.

extern int acceptedStep; // !=0 when accepted step is calculated, 0 otherwise.
extern int modelTermination; //// Becomes non-zero when user terminates simulation.

/* Flags for controlling logging to stdout */
Expand Down Expand Up @@ -245,7 +245,7 @@ int initial_residual();

double newTime(double t, double step,double stop);

#define MODELICA_ASSERT(cond,msg) do { if (!(cond)) { modelTermination=1; \
#define MODELICA_ASSERT(cond,msg) do { if (!(cond)&& acceptedStep) { modelTermination=1; \
throw TerminateSimulationException(string(msg)); } } while(0)

#define MODELICA_TERMINATE(msg) do { modelTermination=1; \
Expand Down
27 changes: 23 additions & 4 deletions c_runtime/solver_dasrt.cpp
Expand Up @@ -77,6 +77,15 @@ int dummyJacobianDASSL(double *t, double *y, double *yprime, double *pd, long *c
return 1000.0*uround*fabs(tout);
}
}
/* Returns the index of the first root that is active*/
int activeEvent(int nRoots, long *jroot)
{
int i;
for (i=0; i < nRoots; i++) {
if (jroot[i]) return i;
}
return -1;
}

/* The main function for the dassl solver*/
int dassl_main(int argc, char**argv,double &start, double &stop, double &step, long &outputSteps,
Expand Down Expand Up @@ -188,13 +197,15 @@ int dassl_main(int argc, char**argv,double &start, double &stop, double &step,
if(functionODE()) {
throw TerminateSimulationException(globalData->timeValue,string("Error calculating initial derivatives\n"));
}
// Calculate initial output values
// Calculate initial output values
acceptedStep = 1;
if(functionDAE_output()|| functionDAE_output2()) {
throw TerminateSimulationException(globalData->timeValue,
string("Error calculating initial derivatives\n"));

acceptedStep = 0;
}


tout = globalData->timeValue+calcTinyStep(globalData->timeValue); // take tiny step.
//saveall();

Expand Down Expand Up @@ -227,7 +238,9 @@ int dassl_main(int argc, char**argv,double &start, double &stop, double &step,
functionDAE_res(&globalData->timeValue,globalData->states,globalData->statesDerivatives,
dummy_delta,0,0,0); // Since residual function calculates
// alg vars too.
acceptedStep=1;
functionDAE_output();
acceptedStep=0;

tout = newTime(tout,step,stop);
while(globalData->timeValue<stop && idid>0) {
Expand All @@ -236,7 +249,7 @@ int dassl_main(int argc, char**argv,double &start, double &stop, double &step,
while (idid == 4) {
if (sim_verbose) {
cout << std::setprecision(20) <<
"found event at time " << globalData->timeValue << endl;
"Found event " << activeEvent(globalData->nZeroCrossing,jroot) << " at time " << globalData->timeValue << endl;
}
if (emit()) {printf("Too many points\n");
idid = -99; break;}
Expand Down Expand Up @@ -298,7 +311,9 @@ int dassl_main(int argc, char**argv,double &start, double &stop, double &step,
globalData->statesDerivatives,
dummy_delta,0,0,0); // Since residual function calculates
// alg vars too.
acceptedStep = 1;
functionDAE_output();
acceptedStep = 0;

info[0] = 1;

Expand All @@ -323,10 +338,14 @@ int dassl_main(int argc, char**argv,double &start, double &stop, double &step,
function_zeroCrossing, &globalData->nZeroCrossing, jroot);
functionDAE_res(&globalData->timeValue,globalData->states,globalData->statesDerivatives,dummy_delta,0,0,0); // Since residual function calculates
// alg vars too.
functionDAE_output(); // discrete variables are seperated so that the can be emited before and after the event.
acceptedStep=1;
functionDAE_output(); // discrete variables are seperated so that the can be emited before and after the event.
acceptedStep=0;
} // end while

acceptedStep=1;
functionDAE_output2(); // calculate discrete varibles separately, see above
acceptedStep=0;

if (sim_verbose) { cout << "Simulation stopped at time " << globalData->timeValue << endl; }

Expand Down
22 changes: 17 additions & 5 deletions c_runtime/tables.cpp
Expand Up @@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace std;

#include "tables.h"
#include "simulation_runtime.h"

vector<InterpolationTable*> interpolationTables;

Expand Down Expand Up @@ -95,7 +96,10 @@ double omcTableTimeIpo(int tableID,int icol,double timeIn)
if ((int)interpolationTables.size() != 0 && tableID >= 0 && tableID < (int)interpolationTables.size()) {
return interpolationTables[tableID]->Interpolate(timeIn,icol-1);
} else { // error, unvalid tableID
cerr << "in omcTableTimeIpo, tableID " << tableID << " is not a valid table ID." << endl;
if (acceptedStep) {
cerr << "in omcTableTimeIpo, tableID " << tableID << " is not a valid table ID." << endl;
cerr << " There are currently " << interpolationTables.size() << " tables allocated" << endl;
}
return 0.0;
}
}
Expand All @@ -107,7 +111,10 @@ double omcTableTimeTmax(int tableID)
InterpolationTable* table = interpolationTables[tableID];
return table->MaxTime();
} else { // error, unvalid tableID
cerr << "in omcTableTimeTmax, tableID " << tableID << " is not a valid table ID." << endl;
if (acceptedStep) {
cerr << "in omcTableTimeTmax, tableID " << tableID << " is not a valid table ID." << endl;
cerr << " There are currently " << interpolationTables.size() << " tables allocated" << endl;
}
return 0.0;
}
}
Expand All @@ -119,7 +126,10 @@ double omcTableTimeTmin(int tableID)
InterpolationTable* table = interpolationTables[tableID];
return table->MinTime();
} else { // error, unvalid tableID
cerr << "in omcTableTimeTmin, tableID " << tableID << " is not a valid table ID." << endl;
if (acceptedStep) {
cerr << "in omcTableTimeTmin, tableID " << tableID << " is not a valid table ID." << endl;
cerr << " There are currently " << interpolationTables.size() << " tables allocated" << endl;
}
return 0.0;
}
}
Expand Down Expand Up @@ -238,8 +248,10 @@ double InterpolationTable::getElt(int row, int col)
{
// Remove this check once running. it's internal checking only.
if (row < 0 || row > nRows_ || col < 0 || col > nCols_) {
cerr << "Error, indexing out of data with data[" << row << ", " << col << "]" << endl;
cerr << "nRows = " << nRows_ << " nCols = " << nCols_ << endl;
if(acceptedStep) {
cerr << "Error, indexing out of data with data[" << row << ", " << col << "]" << endl;
cerr << "nRows = " << nRows_ << " nCols = " << nCols_ << endl;
}
return 0.0;
}
int index = 0;
Expand Down

0 comments on commit 6c21a39

Please sign in to comment.