Skip to content

Commit

Permalink
Add positiveMax definition to Base Modelica (#12429)
Browse files Browse the repository at this point in the history
  • Loading branch information
perost committed May 15, 2024
1 parent 87ce925 commit d9f2966
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 21 deletions.
68 changes: 67 additions & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFBuiltinFuncs.mo
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import Absyn.{Path, TypeSpec};
import SCode;
import SCode.{Mod, Comment};
import DAE;
import Builtin = NFBuiltin;
import NFBinding;
import Pointer;
import NFPrefixes.Visibility;
Expand Down Expand Up @@ -476,5 +475,72 @@ constant InstNode CLOCK_NODE = InstNode.CLASS_NODE("Clock",
constant ComponentRef CLOCK_CREF =
ComponentRef.CREF(CLOCK_NODE, {}, Type.INTEGER(), Origin.CREF, ComponentRef.EMPTY());

constant SCode.Element BASE_MODELICA_POSITIVE_MAX_SIMPLE = SCode.Element.CLASS(
"$OMC$PositiveMax",
SCode.defaultPrefixes,
SCode.Encapsulated.ENCAPSULATED(),
SCode.Partial.NOT_PARTIAL(),
SCode.Restriction.R_FUNCTION(SCode.FunctionRestriction.FR_NORMAL_FUNCTION(Absyn.FunctionPurity.NO_PURITY())),
SCode.ClassDef.PARTS(
{
// input Real flowValue;
SCode.Element.COMPONENT(
"flowValue",
SCode.defaultPrefixes,
SCode.defaultInputAttr,
Absyn.TPATH(Absyn.IDENT("Real"), NONE()),
SCode.Mod.NOMOD(),
SCode.noComment,
NONE(),
AbsynUtil.dummyInfo
),
// input Real eps;
SCode.Element.COMPONENT(
"eps",
SCode.defaultPrefixes,
SCode.defaultInputAttr,
Absyn.TPATH(Absyn.IDENT("Real"), NONE()),
SCode.Mod.NOMOD(),
SCode.noComment,
NONE(),
AbsynUtil.dummyInfo
),
// output Real positiveMax;
SCode.Element.COMPONENT(
"positiveMax",
SCode.defaultPrefixes,
SCode.defaultOutputAttr,
Absyn.TPATH(Absyn.IDENT("Real"), NONE()),
SCode.Mod.NOMOD(),
SCode.noComment,
NONE(),
AbsynUtil.dummyInfo
)
},
{}, {},
// algorithm
{
SCode.AlgorithmSection.ALGORITHM({
// positiveMax := max(flowValue, eps);
SCode.Statement.ALG_ASSIGN(
Absyn.Exp.CREF(Absyn.ComponentRef.CREF_IDENT("positiveMax", {})),
Absyn.Exp.CALL(Absyn.ComponentRef.CREF_IDENT("max", {}),
Absyn.FunctionArgs.FUNCTIONARGS({
Absyn.Exp.CREF(Absyn.ComponentRef.CREF_IDENT("flowValue", {})),
Absyn.Exp.CREF(Absyn.ComponentRef.CREF_IDENT("eps", {}))
}, {}),
{}
),
SCode.noComment,
AbsynUtil.dummyInfo
)
})
},
{}, {}, {}, NONE()
),
SCode.noComment,
AbsynUtil.dummyInfo
);

annotation(__OpenModelica_Interface="frontend");
end NFBuiltinFuncs;
33 changes: 22 additions & 11 deletions OMCompiler/Compiler/NFFrontEnd/NFConnectEquations.mo
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ protected
Expression stream_exp, flow_exp;
algorithm
(stream_exp, flow_exp) := streamFlowExp(element);
exp := Expression.BINARY(makePositiveMaxCall(flow_exp, element, flowThreshold, variables),
exp := Expression.BINARY(makePositiveMaxCall(flow_exp, stream_exp, element, flowThreshold, variables),
Operator.makeMul(Type.REAL()), makeInStreamCall(stream_exp));
end sumOutside1;

Expand All @@ -616,7 +616,7 @@ protected
algorithm
(stream_exp, flow_exp) := streamFlowExp(element);
flow_exp := Expression.UNARY(Operator.makeUMinus(Type.REAL()), flow_exp);
exp := Expression.BINARY(makePositiveMaxCall(flow_exp, element, flowThreshold, variables),
exp := Expression.BINARY(makePositiveMaxCall(flow_exp, stream_exp, element, flowThreshold, variables),
Operator.makeMul(Type.REAL()), stream_exp);
end sumInside1;

Expand All @@ -629,10 +629,10 @@ function sumOutside2
input UnorderedMap<ComponentRef, Variable> variables;
output Expression exp;
protected
Expression flow_exp;
Expression flow_exp, stream_exp;
algorithm
flow_exp := flowExp(element);
exp := makePositiveMaxCall(flow_exp, element, flowThreshold, variables);
(stream_exp, flow_exp) := streamFlowExp(element);
exp := makePositiveMaxCall(flow_exp, stream_exp, element, flowThreshold, variables);
end sumOutside2;

function sumInside2
Expand All @@ -644,11 +644,11 @@ function sumInside2
input UnorderedMap<ComponentRef, Variable> variables;
output Expression exp;
protected
Expression flow_exp;
Expression flow_exp, stream_exp;
algorithm
flow_exp := flowExp(element);
(stream_exp, flow_exp) := streamFlowExp(element);
flow_exp := Expression.UNARY(Operator.makeUMinus(Type.REAL()), flow_exp);
exp := makePositiveMaxCall(flow_exp, element, flowThreshold, variables);
exp := makePositiveMaxCall(flow_exp, stream_exp, element, flowThreshold, variables);
end sumInside2;

function makeInStreamCall
Expand All @@ -664,15 +664,17 @@ end makeInStreamCall;
function makePositiveMaxCall
"Generates a max(flow_exp, eps) call."
input Expression flowExp;
input Expression streamExp;
input Connector element;
input Expression flowThreshold;
input UnorderedMap<ComponentRef, Variable> variables;
output Expression positiveMaxCall;
protected
//InstNode flow_node;
ComponentRef flow_name;
Option<Expression> nominal_oexp;
Expression nominal_exp, flow_threshold;
InstNode fn_node;
Function fn;
algorithm
flow_name := associatedFlowCref(Connector.name(element));
nominal_oexp := lookupVarAttr(flow_name, "nominal", variables);
Expand All @@ -684,8 +686,17 @@ algorithm
flow_threshold := flowThreshold;
end if;

positiveMaxCall := Expression.CALL(Call.makeTypedCall(NFBuiltinFuncs.POSITIVE_MAX_REAL,
{flowExp, flow_threshold}, Connector.variability(element), Purity.PURE));
if Flags.getConfigBool(Flags.BASE_MODELICA) then
fn_node := Class.lookupElement("$OMC$PositiveMax",
InstNode.getClass(InstNode.topScope(ComponentRef.node(flow_name))));
fn_node := Function.instFunctionNode(fn_node, NFInstContext.NO_CONTEXT, AbsynUtil.dummyInfo);
{fn} := Function.typeNodeCache(fn_node);
positiveMaxCall := Expression.CALL(Call.makeTypedCall(fn,
{flowExp, flow_threshold}, Connector.variability(element), Purity.PURE));
else
positiveMaxCall := Expression.CALL(Call.makeTypedCall(NFBuiltinFuncs.POSITIVE_MAX_REAL,
{flowExp, flow_threshold}, Connector.variability(element), Purity.PURE));
end if;

setGlobalRoot(Global.isInStream, SOME(true));
end makePositiveMaxCall;
Expand Down
7 changes: 1 addition & 6 deletions OMCompiler/Compiler/NFFrontEnd/NFFunction.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1984,12 +1984,7 @@ uniontype Function

function isDefaultRecordConstructor
input Function fn;
output Boolean isConstructor;
algorithm
isConstructor := match Class.restriction(InstNode.getClass(fn.node))
case Restriction.RECORD_CONSTRUCTOR() then true;
else false;
end match;
output Boolean isConstructor = Restriction.isRecordConstructor(InstNode.restriction(fn.node));
end isDefaultRecordConstructor;

function isNonDefaultRecordConstructor
Expand Down
11 changes: 9 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFInst.mo
Original file line number Diff line number Diff line change
Expand Up @@ -426,18 +426,25 @@ function makeTopNode
input list<SCode.Element> annotationClasses;
output InstNode topNode;
protected
list<SCode.Element> top_classes;
SCode.Element cls_elem, ann_package;
Class cls, ann_cls;
ClassTree elems;
InstNodeType node_ty;
InstNode ann_node;
UnorderedMap<String, InstNode> generated_inners;
algorithm
top_classes := topClasses;

if Flags.getConfigBool(Flags.BASE_MODELICA) then
top_classes := NFBuiltinFuncs.BASE_MODELICA_POSITIVE_MAX_SIMPLE :: top_classes;
end if;

// Create a fake SCode.Element for the top scope, so we don't have to make the
// definition in InstNode an Option only because of this node.
cls_elem := SCode.CLASS("<top>", SCode.defaultPrefixes, SCode.NOT_ENCAPSULATED(),
SCode.NOT_PARTIAL(), SCode.R_PACKAGE(),
SCode.PARTS(topClasses, {}, {}, {}, {}, {}, {}, NONE()),
SCode.PARTS(top_classes, {}, {}, {}, {}, {}, {}, NONE()),
SCode.COMMENT(NONE(), NONE()), AbsynUtil.dummyInfo);

// Make an InstNode for the top scope, to use as the parent of the top level elements.
Expand Down Expand Up @@ -469,7 +476,7 @@ algorithm
topNode := InstNode.setNodeType(node_ty, topNode);

// Create a new class from the elements, and update the inst node with it.
cls := Class.fromSCode(topClasses, false, topNode, NFClass.DEFAULT_PREFIXES);
cls := Class.fromSCode(top_classes, false, topNode, NFClass.DEFAULT_PREFIXES);
// The class needs to be expanded to allow lookup in it. The top scope will
// only contain classes, so we can do this instead of the whole expandClass.
cls := Class.initExpandedClass(cls);
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFInstNode.mo
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ uniontype InstNode
algorithm
topScope := match node
case CLASS_NODE(nodeType = InstNodeType.TOP_SCOPE()) then node;
else topScope(parentScope(node));
else topScope(parent(node));
end match;
end topScope;

Expand Down
78 changes: 78 additions & 0 deletions testsuite/openmodelica/basemodelica/InStreamNominalThreshold.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// name: InStreamNominalThreshold
// keywords:
// status: correct
// cflags: -d=newInst -f
//
//

connector S
Real r;
flow Real f;
stream Real s;
end S;

model A
S s1(f(nominal = 1e-3));
S s2(f(nominal = 2000));
S s3;
Real instream_s1;
Real instream_s2;
Real instream_s3;
equation
connect(s1, s2);
connect(s2, s3);
instream_s1 = inStream(s1.s);
instream_s2 = inStream(s2.s);
end A;

model InStreamNominalThreshold
A a;
Real instream_a_s1;
Real instream_a_s2;
equation
instream_a_s1 = inStream(a.s1.s);
instream_a_s2 = inStream(a.s2.s);
end InStreamNominalThreshold;

// Result:
// package 'InStreamNominalThreshold'
// function '$OMC$PositiveMax'
// input Real 'flowValue';
// input Real 'eps';
// output Real 'positiveMax';
// algorithm
// 'positiveMax' := max('flowValue', 'eps');
// end '$OMC$PositiveMax';
//
// model 'InStreamNominalThreshold'
// Real 'a.s1.r';
// Real 'a.s1.f'(nominal = 0.001);
// Real 'a.s1.s';
// Real 'a.s2.r';
// Real 'a.s2.f'(nominal = 2000.0);
// Real 'a.s2.s';
// Real 'a.s3.r';
// Real 'a.s3.f';
// Real 'a.s3.s';
// Real 'a.instream_s1';
// Real 'a.instream_s2';
// Real 'a.instream_s3';
// Real 'instream_a_s1';
// Real 'instream_a_s2';
// equation
// 'a.s2.r' = 'a.s3.r';
// 'a.s2.r' = 'a.s1.r';
// -('a.s2.f' + 'a.s3.f' + 'a.s1.f') = 0.0;
// 'a.s1.s' = ('$OMC$PositiveMax'('a.s3.f', 1e-7) * 'a.s3.s' + '$OMC$PositiveMax'('a.s2.f', 1.9999999999999998e-4) * 'a.s2.s') / ('$OMC$PositiveMax'('a.s3.f', 1e-7) + '$OMC$PositiveMax'('a.s2.f', 1.9999999999999998e-4));
// 'a.s3.s' = ('$OMC$PositiveMax'('a.s1.f', 1e-10) * 'a.s1.s' + '$OMC$PositiveMax'('a.s2.f', 1.9999999999999998e-4) * 'a.s2.s') / ('$OMC$PositiveMax'('a.s1.f', 1e-10) + '$OMC$PositiveMax'('a.s2.f', 1.9999999999999998e-4));
// 'a.s2.s' = ('$OMC$PositiveMax'('a.s1.f', 1e-10) * 'a.s1.s' + '$OMC$PositiveMax'('a.s3.f', 1e-7) * 'a.s3.s') / ('$OMC$PositiveMax'('a.s1.f', 1e-10) + '$OMC$PositiveMax'('a.s3.f', 1e-7));
// 'a.s1.f' = 0.0;
// 'a.s2.f' = 0.0;
// 'a.s3.f' = 0.0;
// 'a.instream_s1' = 'a.s1.s';
// 'a.instream_s2' = 'a.s2.s';
// 'instream_a_s1' = 'a.s1.s';
// 'instream_a_s2' = 'a.s2.s';
// end 'InStreamNominalThreshold';
// end 'InStreamNominalThreshold';
// endResult
1 change: 1 addition & 0 deletions testsuite/openmodelica/basemodelica/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ TESTFILES = \
Comments.mo \
DoublePendulum.mos \
Expression1.mo \
InStreamNominalThreshold.mo \
Record1.mo \
SD.mo \
SimpleCoolingCycle.mo \
Expand Down

0 comments on commit d9f2966

Please sign in to comment.