Skip to content

Commit

Permalink
Handle empty arrays better during unit checking (#10064)
Browse files Browse the repository at this point in the history
- Check for zero-dimensions instead of using `Expression.isEmptyArray`
  when checking if a unit expression is a non-empty array, since an
  array can be non-empty and still not contain any scalar elements (such
  as `{{}}`).
- Avoid having to evaluate `fill` calls when getting the unit string
  from an expression, all elements in the resulting array will be the
  same anyway so we can just take the fill argument directly instead.

Fixes #10057
  • Loading branch information
perost committed Jan 18, 2023
1 parent 303c807 commit d8c3652
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
8 changes: 7 additions & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFUnitCheck.mo
Expand Up @@ -1023,9 +1023,15 @@ algorithm
// A literal array. This happens for array variables, assume each variable
// has the same unit for now.
case Expression.ARRAY(literal = true)
guard Expression.isLiteral(unitExp) and not Expression.isEmptyArray(unitExp)
guard Expression.isLiteral(unitExp) and not Type.isEmptyArray(Expression.typeOf(unitExp))
then getUnitStringFromExp(Expression.arrayFirstScalar(unitExp));

// A fill call. Will generate an array where all elements are the same, so
// no need to evaluate it.
case Expression.CALL(Call.TYPED_CALL(arguments = exp :: _))
guard Call.isNamed(unitExp.call, "fill")
then getUnitStringFromExp(exp);

// A non-literal expression, evaluate it and try again if it could be evaluated.
case _
guard not Expression.isLiteral(unitExp)
Expand Down
1 change: 1 addition & 0 deletions testsuite/simulation/modelica/unitcheck/Makefile
Expand Up @@ -23,6 +23,7 @@ UnitCheck19.mos \
UnitCheck20.mos \
UnitCheck21.mos \
UnitCheck22.mos \
UnitCheck23.mos \
ticket3631.mos \


Expand Down
12 changes: 6 additions & 6 deletions testsuite/simulation/modelica/unitcheck/UnitCheck22.mos
@@ -1,34 +1,34 @@
// name: UnitCheck21
// name: UnitCheck22
// keywords: initialization
// status: correct
// cflags: -d=newInst --unitChecking -d=dumpUnits

loadString("
model UnitCheck21
model UnitCheck22
type Length = Real(unit = \"m\");
type Area = Real(unit = \"m2\");

Area A;
Length L;
equation
A = L^3;
end UnitCheck21;
end UnitCheck22;
"); getErrorString();

instantiateModel(UnitCheck21); getErrorString();
instantiateModel(UnitCheck22); getErrorString();

// Result:
// true
// ""
// (A, 1.0 * m^(2))
// (L, 1.0 * m^(1))
// ######## UnitCheck COMPLETED ########
// "class UnitCheck21
// "class UnitCheck22
// Real A(unit = \"m2\");
// Real L(unit = \"m\");
// equation
// A = L ^ 3.0;
// end UnitCheck21;
// end UnitCheck22;
// "
// "[<interactive>:9:5-9:12:writable] Warning: The following equation is INCONSISTENT due to specified unit information: A = L ^ 3.0
// Warning: The units of following sub-expressions need to be equal:
Expand Down
24 changes: 24 additions & 0 deletions testsuite/simulation/modelica/unitcheck/UnitCheck23.mos
@@ -0,0 +1,24 @@
// name: UnitCheck23
// keywords: initialization
// status: correct
// cflags: -d=newInst --unitChecking -d=dumpUnits

loadString("
model UnitCheck23
type MassFlowRate = Real(final unit = \"kg/s\");
MassFlowRate[1, 0] ports_mXi_flow;
end UnitCheck23;
"); getErrorString();

instantiateModel(UnitCheck23); getErrorString();

// Result:
// true
// ""
// (ports_mXi_flow, 1000.0 * s^(-1) * g^(1))
// ######## UnitCheck COMPLETED ########
// "class UnitCheck23
// end UnitCheck23;
// "
// ""
// endResult

0 comments on commit d8c3652

Please sign in to comment.