Dymola does not provide such a feature in the gui. But with the ModelManagement
library its possible to obtain such information. The library is available with the standard Dymola license and pre-installed.
Below you find the function SO.printComponents()
which uses the ModelManagement library to obtain all components in a class which match the given criterias.
For your model the printed output is:
Components in Modelica.Fluid.Examples.HeatingSystem using Modelica.Fluid.System as outer:
tank<Modelica.Fluid.Vessels.BaseClasses.PartialLumpedVessel>.heatTransfer<Modelica.Fluid.Interfaces.PartialHeatTransfer>.system
tank<Modelica.Fluid.Interfaces.PartialLumpedVolume>.system
pump<Modelica.Fluid.Machines.BaseClasses.PartialPump>.heatTransfer<Modelica.Fluid.Interfaces.PartialHeatTransfer>.system
...
valve<Modelica.Fluid.Interfaces.PartialTwoPort>.system
...
You see all components in Modelica.Fluid.Examples.HeatingSystem
which contain an instance of Modelica.Fluid.System
with the prefix outer.
If a component inherited the system instance from a base class via extends
, the base class is given between angle brackets in the form <base-class>
.
The first component in the output for example means, that the tank
component is extending the PartialLumpedVessel
class, which contains a component heatTransfer
which extends the PartialHeatTransfer
which contains the system instance we are looking for.
Note that for multilevel inheritance only the final base class is given, not the full path to it. This is e.g. relevant for the valve, which inherits the system instance from PartialTwoPort
via PartialValve
and PartialTwoPortTransport
.
Background information
The ModelManagement library features some interesting functions in the package ModelManagement.Structure
which allow to obtain information about Modelica classes.
The functions are divided into two different types:
- ModelManagement.Structure.AST: For these functions, only Modelica code of the selected class is considered. Everything that is inherited is not considered.
- ModelManagement.Structure.Instantiated: All functions in this package operate on the translated model
At the first glance ModelManagement.Structure.Instantiated.UsedModels
seems a good starting point. But its documentation says:
Optionally disabled components, base-classes, and called functions are not included.
As the Fluid package makes heavy use of inheritance, we would easily miss a component when inheritance is not considered.
Fortunately the Testing library contains a function, which returns all inherited base classes Testing.Utilities.Class.getExtendedClasses
. In addition ModelManagement.Structure.AST.ComponentsInClassAttributes
allows us to retrieve all components of a given class (but not the inherited ones).
With those two functions, we can build a new function that:
- Retrieves all components of a class, including the ones inherited from base classes
- Checks if a component matches our search criteria (in your case it should be an outer instance of
Modelica.Fluid.System
)
- Recursively check sub-components of all components, as the usage of system could happen further down in the hierarchy
Here is the code. Additionally a small print function is included, which prints the found components nicely to the terminal.
package SO
function getComponentsUsingClass "Get all components in class c1 which use class c2 as local component"
import ModelManagement.Structure.AST;
import Testing.Utilities.Class.getExtendedClasses;
import Testing.Utilities.Vectors.catStrings;
input String c1 "Full path of class of which components are retrieved";
input String c2 "Full path of class which must be used in the components";
input Boolean isOuter=false "Return only components where c2 is used as an outer instance";
output String cmp[:] "All components in c1 using c2";
protected
String sub[:] "Sub-components";
Boolean baseClass "True if current class is a baseClass of c1 (c1 extends it)";
String prefix "Used to give base classe";
algorithm
cmp :=fill("", 0);
// loop over class c1 and all its base classes
for c in cat(1,{c1}, getExtendedClasses(c1)) loop
baseClass :=c <> c1;
prefix :=if baseClass then "<" + c + ">." else ".";
// loop over all components in the current class
for cmpa in AST.ComponentsInClassAttributes(c) loop
if cmpa.fullTypeName==c2 and cmpa.isOuter==isOuter then
cmp :=cat(1, cmp, {prefix+cmpa.name});
end if;
// if the current component is a Modelica class, obtain all sub-components using c2
// (Mon-Modelica classes would e.g. be the attributes min, max, stateSelect etc. of built in classes)
if cmpa.fullTypeName<>"" then
sub := getComponentsUsingClass(cmpa.fullTypeName, c2, isOuter);
sub :=catStrings(fill(prefix+cmpa.name, size(sub, 1)), sub);
cmp :=cat(1, cmp, sub);
end if;
end for;
end for;
end getComponentsUsingClass;
function printComponents
import Modelica.Utilities.Streams.print;
import DymolaModels.Utilities.Strings.stripLeft;
input String c1="Modelica.Fluid.Examples.HeatingSystem" "Full path of class of which components are retrieved";
input String c2="Modelica.Fluid.System" "Full path of class which must be used in the components";
input Boolean isOuter=true "Return only components where c2 is used as an outer instance";
algorithm
print("Components in " + c1 + " using " + c2 + (if isOuter then " as outer" else "") + ":");
for c in getComponentsUsingClass(c1, c2,isOuter) loop
print(" " + stripLeft(c, "."));
end for;
end printComponents;
annotation (uses(
Modelica(version="4.0.0"),
Testing(version="1.3.1"),
ModelManagement(version="1.2.0"),
DymolaModels(version="1.2")));
end SO;