Skip to content

Commit

Permalink
Use old frontend for PDEModelica (#9396)
Browse files Browse the repository at this point in the history
- Automatically switch to the old frontend and notify the user of the
  switch when PDEModelica is used.
  • Loading branch information
perost committed Sep 21, 2022
1 parent 819dd55 commit efca9a9
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 116 deletions.
108 changes: 46 additions & 62 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Expand Up @@ -85,7 +85,6 @@ import Expression;
import ExpressionDump;
import FBuiltin;
import FGraph;
import FGraphDump;
import Figaro;
import FindZeroCrossings;
import FInst;
Expand Down Expand Up @@ -3272,91 +3271,76 @@ algorithm
end runFrontEndLoadProgram;
protected function runFrontEndWork
input FCore.Cache inCache;
input FCore.Graph inEnv;
input output FCore.Cache cache;
input output FCore.Graph env;
input Absyn.Path className;
input Boolean relaxedFrontEnd "Do not check for illegal simulation models, so we allow instantation of packages, etc";
input Boolean dumpFlat;
output FCore.Cache cache;
output FCore.Graph env;
output DAE.DAElist dae;
output String flatString = "";
output DAE.DAElist dae;
output String flatString = "";
protected
Integer numError = Error.getNumErrorMessages();
Absyn.Restriction restriction;
Absyn.Program p = SymbolTable.getAbsyn();
algorithm
(cache,env,dae) := matchcontinue (inCache,inEnv,className)
local
Absyn.Class absynClass;
String str,re;
SCode.Program scodeP;
DAE.FunctionTree funcs;
NFFlatModel flat_model;
NFFlatten.FunctionTree nf_funcs;
Boolean graph_inst, nf_inst, nf_inst_actual;
SCode.Program scodeP;
DAE.FunctionTree funcs;
NFFlatModel flat_model;
NFFlatten.FunctionTree nf_funcs;
algorithm
graph_inst := Flags.isSet(Flags.GRAPH_INST);
nf_inst := Flags.isSet(Flags.SCODE_INST);
nf_inst_actual := nf_inst;
// PDEModelica is not yet supported by the new frontend, switch to the old one
// if `-g=PDEModelica` is set.
if nf_inst and Flags.getConfigEnum(Flags.GRAMMAR) == Flags.PDEMODELICA then
nf_inst := false;
FlagsUtil.set(Flags.SCODE_INST, false);
Error.addMessage(Error.NF_PDE_NOT_IMPLEMENTED, {});
end if;
case (_, _, _)
(cache,env,dae) := matchcontinue (graph_inst, nf_inst)
case (false, true)
algorithm
false := Flags.isSet(Flags.GRAPH_INST);
true := Flags.isSet(Flags.SCODE_INST);
(flat_model, nf_funcs, flatString) := runFrontEndWorkNF(className, dumpFlat);
(dae, funcs) := NFConvertDAE.convert(flat_model, nf_funcs);
cache := FCore.emptyCache();
FCore.setCachedFunctionTree(cache, funcs);
env := FGraph.new("graph", FCore.dummyTopModel);
then (cache, env, dae);
case (cache,env,_)
equation
true = Flags.isSet(Flags.GRAPH_INST);
false = Flags.isSet(Flags.SCODE_INST);
then
(cache, env, dae);
case (true, false)
algorithm
System.realtimeTick(ClockIndexes.RT_CLOCK_FINST);
dae = FInst.instPath(className, SymbolTable.getSCode());
then (cache,env,dae);
case (cache,env,_)
equation
false = Flags.isSet(Flags.GRAPH_INST);
false = Flags.isSet(Flags.SCODE_INST);
//System.stopTimer();
//print("\nExists+Dependency: " + realString(System.getTimerIntervalTime()));
//System.startTimer();
//print("\nAbsyn->SCode");
scodeP = SymbolTable.getSCode();
dae := FInst.instPath(className, SymbolTable.getSCode());
then
(cache,env,dae);
case (false, false)
algorithm
scodeP := SymbolTable.getSCode();
ExecStat.execStat("FrontEnd - Absyn->SCode");
//System.stopTimer();
//print("\nAbsyn->SCode: " + realString(System.getTimerIntervalTime()));
//System.startTimer();
//print("\nInst.instantiateClass");
(cache,env,_,dae) = Inst.instantiateClass(cache,InnerOuter.emptyInstHierarchy,scodeP,className,true,relaxedFrontEnd);
dae = DAEUtil.mergeAlgorithmSections(dae);
//FGraphDump.dumpGraph(env, "F:\\dev\\" + AbsynUtil.pathString(className) + ".graph.graphml");
//System.stopTimer();
//print("\nInst.instantiateClass: " + realString(System.getTimerIntervalTime()));
(cache,env,_,dae) := Inst.instantiateClass(cache,InnerOuter.emptyInstHierarchy,scodeP,className,true,relaxedFrontEnd);
dae := DAEUtil.mergeAlgorithmSections(dae);
// adrpo: do not add it to the instantiated classes, it just consumes memory for nothing.
DAEUtil.getFunctionList(FCore.getFunctionTree(cache),failOnError=true); // Make sure that the functions are valid before returning success
then (cache,env,dae);
else
equation
str = AbsynUtil.pathString(className);
true = Error.getNumErrorMessages() == numError;
str = "Instantiation of " + str + " failed with no error message.";
Error.addMessage(Error.INTERNAL_ERROR, {str});
then fail();
case (_, _)
guard Error.getNumErrorMessages() == numError
algorithm
Error.addMessage(Error.INTERNAL_ERROR,
{"Instantiation of " + AbsynUtil.pathString(className) + " failed with no error message."});
FlagsUtil.set(Flags.SCODE_INST, nf_inst_actual);
then
fail();
end matchcontinue;
// Switch back to the new frontend in case we changed it at the beginning of the function.
FlagsUtil.set(Flags.SCODE_INST, nf_inst_actual);
end runFrontEndWork;
public function runFrontEndWorkNF
Expand Down
2 changes: 2 additions & 0 deletions OMCompiler/Compiler/Util/Error.mo
Expand Up @@ -877,6 +877,8 @@ public constant ErrorTypes.Message INVALID_SPECIALIZATION_FOR_BINDING_EQUATION =
Gettext.gettext("Component ‘%s‘ may not have a binding equation due to class specialization ‘%s‘."));
public constant ErrorTypes.Message INVALID_SPECIALIZATION_IN_ASSIGNMENT = ErrorTypes.MESSAGE(401, ErrorTypes.TRANSLATION(), ErrorTypes.ERROR(),
Gettext.gettext("Component ‘%s‘ may not be assigned to due to class specialization ‘%s‘."));
public constant ErrorTypes.Message NF_PDE_NOT_IMPLEMENTED = ErrorTypes.MESSAGE(402, ErrorTypes.TRANSLATION(), ErrorTypes.NOTIFICATION(),
Gettext.gettext("PDEModelica is not yet supported by the new front-end, using the old front-end instead."));

public constant ErrorTypes.Message INITIALIZATION_NOT_FULLY_SPECIFIED = ErrorTypes.MESSAGE(496, ErrorTypes.TRANSLATION(), ErrorTypes.WARNING(),
Gettext.gettext("The initial conditions are not fully specified. %s."));
Expand Down
112 changes: 58 additions & 54 deletions testsuite/flattening/modelica/others/PDEModelicaTest.mos
@@ -1,69 +1,73 @@
// name: PDEModelica general test
// keywords: PDEModelica field, indomain, pder, extrapolateField, domain
// status: correct
// cflags: -d=-newInst
// cflags: -d=newInst
//
// Test main features of PDEModelica
//
// This uses the new frontend on purpose even though it doesn't yet support
// PDEModelica, to test that it automatically switches to the old frontend.
//
//setCompilerFlags("--grammar=PDEModelica"); getErrorString();
setCommandLineOptions("--grammar=PDEModelica"); getErrorString();
loadFile("PDEModelicaTest.mo"); getErrorString();
instantiateModel(PDEModelicaTest); getErrorString();

// Result:
//true
//""
//true
//""
//"function DomainLineSegment1D \"Automatically generated record constructor for DomainLineSegment1D\"
// input Real x0(unit = \"m\") = 0.0;
// input Real L(unit = \"m\") = 1.0;
// input Real dx = 0.1111111111111111 * L;
// input Real[10] x(unit = \"m\") = {x0, x0 + dx, x0 + 2.0 * dx, x0 + 3.0 * dx, x0 + 4.0 * dx, x0 + 5.0 * dx, x0 + 6.0 * dx, x0 + 7.0 * dx, x0 + 8.0 * dx, x0 + 9.0 * dx};
// input DomainLineSegment1D.Region left = DomainLineSegment1D.Region();
// input DomainLineSegment1D.Region right = DomainLineSegment1D.Region();
// input DomainLineSegment1D.Region interior = DomainLineSegment1D.Region();
// protected Integer N(unit = \"\") = 10;
// output DomainLineSegment1D res;
//end DomainLineSegment1D;
// true
// ""
// true
// ""
// "function DomainLineSegment1D \"Automatically generated record constructor for DomainLineSegment1D\"
// input Real x0(unit = \"m\") = 0.0;
// input Real L(unit = \"m\") = 1.0;
// input Real dx = 0.1111111111111111 * L;
// input Real[10] x(unit = \"m\") = {x0, x0 + dx, x0 + 2.0 * dx, x0 + 3.0 * dx, x0 + 4.0 * dx, x0 + 5.0 * dx, x0 + 6.0 * dx, x0 + 7.0 * dx, x0 + 8.0 * dx, x0 + 9.0 * dx};
// input DomainLineSegment1D.Region left = DomainLineSegment1D.Region();
// input DomainLineSegment1D.Region right = DomainLineSegment1D.Region();
// input DomainLineSegment1D.Region interior = DomainLineSegment1D.Region();
// protected Integer N(unit = \"\") = 10;
// output DomainLineSegment1D res;
// end DomainLineSegment1D;
//
//function DomainLineSegment1D.Region \"Automatically generated record constructor for DomainLineSegment1D.Region\"
// output Region res;
//end DomainLineSegment1D.Region;
// function DomainLineSegment1D.Region \"Automatically generated record constructor for DomainLineSegment1D.Region\"
// output Region res;
// end DomainLineSegment1D.Region;
//
//class PDEModelicaTest
// constant Real pde2.pi = 3.14159;
// parameter Real pde2.omega.x0(unit = \"m\") = 0.0 \"x value at left boundary\";
// parameter Real pde2.omega.L(unit = \"m\") = 2.0 \"length of the domain\";
// constant Integer pde2.omega.N = 5 \"number of grid nodes\";
// parameter Real pde2.omega.dx = 0.25 * pde2.omega.L \"grid space step\";
// parameter Real pde2.omega.x[1](unit = \"m\") = pde2.omega.x0 \"space coordinate\";
// parameter Real pde2.omega.x[2](unit = \"m\") = pde2.omega.x0 + pde2.omega.dx \"space coordinate\";
// parameter Real pde2.omega.x[3](unit = \"m\") = pde2.omega.x0 + 2.0 * pde2.omega.dx \"space coordinate\";
// parameter Real pde2.omega.x[4](unit = \"m\") = pde2.omega.x0 + 3.0 * pde2.omega.dx \"space coordinate\";
// parameter Real pde2.omega.x[5](unit = \"m\") = pde2.omega.x0 + 4.0 * pde2.omega.dx \"space coordinate\";
// Real pde2.u[1];
// Real pde2.u[2];
// Real pde2.u[3];
// Real pde2.u[4];
// Real pde2.u[5];
// Real pde2.u$ghostL;
// Real pde2.u$ghostR;
//initial equation
// pde2.u[1] = sin(6.28318 * pde2.omega.x[1]);
// pde2.u[2] = sin(6.28318 * pde2.omega.x[2]);
// pde2.u[3] = sin(6.28318 * pde2.omega.x[3]);
// pde2.u[4] = sin(6.28318 * pde2.omega.x[4]);
// pde2.u[5] = sin(6.28318 * pde2.omega.x[5]);
//equation
// pde2.u$ghostL = 0.0;
// der(pde2.u[1]) + 0.5 * (pde2.u[2] - pde2.u$ghostL) / pde2.omega.dx + (2.0 * pde2.u[1] + (-pde2.u[2]) - pde2.u$ghostL) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[2]) + 0.5 * (pde2.u[3] - pde2.u[1]) / pde2.omega.dx + (2.0 * pde2.u[2] + (-pde2.u[3]) - pde2.u[1]) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[3]) + 0.5 * (pde2.u[4] - pde2.u[2]) / pde2.omega.dx + (2.0 * pde2.u[3] + (-pde2.u[4]) - pde2.u[2]) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[4]) + 0.5 * (pde2.u[5] - pde2.u[3]) / pde2.omega.dx + (2.0 * pde2.u[4] + (-pde2.u[5]) - pde2.u[3]) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[5]) + 0.5 * (pde2.u$ghostR - pde2.u[4]) / pde2.omega.dx + (2.0 * pde2.u[5] + (-pde2.u$ghostR) - pde2.u[4]) / pde2.omega.dx ^ 2.0 = 0.0;
// pde2.u$ghostR = 2.0 * pde2.u[5] - pde2.u[4];
//end PDEModelicaTest;
//"
//""
// class PDEModelicaTest
// constant Real pde2.pi = 3.14159;
// parameter Real pde2.omega.x0(unit = \"m\") = 0.0 \"x value at left boundary\";
// parameter Real pde2.omega.L(unit = \"m\") = 2.0 \"length of the domain\";
// constant Integer pde2.omega.N = 5 \"number of grid nodes\";
// parameter Real pde2.omega.dx = 0.25 * pde2.omega.L \"grid space step\";
// parameter Real pde2.omega.x[1](unit = \"m\") = pde2.omega.x0 \"space coordinate\";
// parameter Real pde2.omega.x[2](unit = \"m\") = pde2.omega.x0 + pde2.omega.dx \"space coordinate\";
// parameter Real pde2.omega.x[3](unit = \"m\") = pde2.omega.x0 + 2.0 * pde2.omega.dx \"space coordinate\";
// parameter Real pde2.omega.x[4](unit = \"m\") = pde2.omega.x0 + 3.0 * pde2.omega.dx \"space coordinate\";
// parameter Real pde2.omega.x[5](unit = \"m\") = pde2.omega.x0 + 4.0 * pde2.omega.dx \"space coordinate\";
// Real pde2.u[1];
// Real pde2.u[2];
// Real pde2.u[3];
// Real pde2.u[4];
// Real pde2.u[5];
// Real pde2.u$ghostL;
// Real pde2.u$ghostR;
// initial equation
// pde2.u[1] = sin(6.28318 * pde2.omega.x[1]);
// pde2.u[2] = sin(6.28318 * pde2.omega.x[2]);
// pde2.u[3] = sin(6.28318 * pde2.omega.x[3]);
// pde2.u[4] = sin(6.28318 * pde2.omega.x[4]);
// pde2.u[5] = sin(6.28318 * pde2.omega.x[5]);
// equation
// pde2.u$ghostL = 0.0;
// der(pde2.u[1]) + 0.5 * (pde2.u[2] - pde2.u$ghostL) / pde2.omega.dx + (2.0 * pde2.u[1] + (-pde2.u[2]) - pde2.u$ghostL) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[2]) + 0.5 * (pde2.u[3] - pde2.u[1]) / pde2.omega.dx + (2.0 * pde2.u[2] + (-pde2.u[3]) - pde2.u[1]) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[3]) + 0.5 * (pde2.u[4] - pde2.u[2]) / pde2.omega.dx + (2.0 * pde2.u[3] + (-pde2.u[4]) - pde2.u[2]) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[4]) + 0.5 * (pde2.u[5] - pde2.u[3]) / pde2.omega.dx + (2.0 * pde2.u[4] + (-pde2.u[5]) - pde2.u[3]) / pde2.omega.dx ^ 2.0 = 0.0;
// der(pde2.u[5]) + 0.5 * (pde2.u$ghostR - pde2.u[4]) / pde2.omega.dx + (2.0 * pde2.u[5] + (-pde2.u$ghostR) - pde2.u[4]) / pde2.omega.dx ^ 2.0 = 0.0;
// pde2.u$ghostR = 2.0 * pde2.u[5] - pde2.u[4];
// end PDEModelicaTest;
// "
// "Notification: PDEModelica is not yet supported by the new front-end, using the old front-end instead.
// "
// endResult

0 comments on commit efca9a9

Please sign in to comment.