# How to use inner and outer correctly?

Posted 2 years ago
3822 Views
|
5 Replies
|
3 Total Likes
|

A support case with the identification [CASE:4275098] was created.

While I noted some implementation problems regarding inner and outer in another context which have been acknowledged, I would like to get very general advice on how to reliably (= correctly?) make use of inner and outer declarations in Wolfram System Modeler.

I would like to provide three simple examples for a clarifying discussion.

## Outer Declaration inside a subcomponent

The following example works fine: The inner variables x, y, z[3] are passed on towards the submodel using corresponding outer declarations and accordingly subX, subY, and subZ show correct values if we simulate MainModel.

package TestingInnerOuter_1
model MainModel
inner parameter Integer x = 1;
inner parameter Real y = 2;
inner Real z[3];
Submodel submodel;
equation
z = ones(3);
end MainModel;

block Submodel
outer parameter Integer x;
outer parameter Real y;
outer Real[3] z;
output Real subX, subY;
output Real[3] subZ;
equation
subX = x;
subY = y;
subZ = z;
end Submodel;

end TestingInnerOuter_1;


## Simultaneous inner outer declaration inside a subcomponent

Now we simply add inner as a prefix to the outer declarations making them simultaneous inner outer declarations.

package TestingInnerOuter_2
model MainModel
inner parameter Integer x = 1;
inner parameter Real y = 2;
inner Real z[3];
Submodel submodel;
equation
z = ones(3);
end MainModel;

block Submodel
inner outer parameter Integer x;
inner outer parameter Real y;
inner outer Real[3] z;
output Real subX, subY;
output Real[3] subZ;
equation
subX = x;
subY = y;
subZ = z;
end Submodel;

end TestingInnerOuter_2;


And now the MainModel will not run but give errors from compilation:

From this message we already get a "hunch" about what is going amiss. And indeed the following modified version of Submodel will work in the second example:

block Submodel
inner outer parameter Integer x;
inner outer parameter Real y;
output Real subX, subY;
equation
subX = x;
subY = y;
end Submodel;


While the MainModel will now simulate, we note that the values for x and y are not passed on, instead we see that each has been given the default value of zero.

## Simultaneous inner outer declaration inside a subcomponent with modifications

So, given the error message for z we finally look at a version where the submodel will modify the values for x and y.

package TestingInnerOuter_3
model MainModel
inner parameter Integer x = 1;
inner parameter Real y = 2;
inner Real z[3];
Submodel submodel;
equation
z = ones(3);
end MainModel;

block Submodel
inner outer parameter Integer x = -1;
inner outer parameter Real y = -2;
output Real subX, subY;
equation
subX = x;
subY = y;
end Submodel;

end TestingInnerOuter_3;


Interestingly, this works out for the parameters and subX and subY show the correct values (e.g. 1 and 2). But, what surprises me, is that 'submodl.x' and 'submodel.y' are reported to be -1 and -2 in the ModelCenter.

So to wrap it up, the following questions arise for me:

1. Why will an inner outer declaration not work out for continuous variables? What can be done?
2. Why are submodel.x and submodel.y not reported with the values according to the lookup to the inner values in a higher scope (e.g. the MainModel values)?

## Update 1 (Warnings upon validation for inner outer )

I am a bit confused about the compiler messages I get for the following simple declaration of a parameter as inner outer:

model InnerOuter "Test of inner outer model"
inner outer parameter Real myParameter = 1;
end InnerOuter;


Validating this model gives:

Those warnings do not really make sense, do they?

1. There is an inner declaration since the outer declaration is simultaneously an inner one.
2. The parameter myParameter has explicitly been given a start value of 1 which is not recognized somehow.

So another question is: What about those warnings - they do not seem correct. What is going on?

## Update 2 (Internal error upon using inner outer in a subcomponent)

I am getting an internal error message validating a component that has a subcomponent with a parameter that is declared as inner outer. A minimal example for this is the following code:

package InnerOuterTest

block HasInnerOuterParameter

inner outer parameter Real k = 1;

end HasInnerOuterParameter;

block UsesComponentWithInnerOuterParameter

HasInnerOuterParameter c;

end UsesComponentWithInnerOuterParameter;

end InnerOuterTest;


Validation of the block UsesComponentWithInnerOuterParameter will give the following error message:

What is the reason for this message? How then should we have a parameter in a subcomponent that is simultaneously inner outer?

(Note: I tested the code given here (package InnerOuterTest) in OpenModelica and there it will validate without any errors)

5 Replies
Sort By:
Posted 1 year ago
 Hi Guido,thanks for your update, this sounds like a known bug in the product where we fail to add the automatic inner declaration to a inner outer declaration.I have added you to the list of reporter so that we can contact you when it is fixed.As you pointed out, a workaround is to add by hand the missing inner declaration at the top level of your model.Quentin
Posted 1 year ago
 Malte,that remark pertains to my experience from the library I am building where Simulation Center indeed does surprise me with building a simulation despite the internal error being reported upon validation (I have a block-based class there, that I can test without problems in Simulation Center but not via SystemModelSimulate which is my preferred way of testing using VerficationTest to build a battery of unit tests).I will try to come up with a "minimal example" for this behavior shortly and accordingly update this post.GuidoUPDATEOk, while I cannot quickly come up with a minimal example, I have checked now and I must make my statement more precise.I have a "converter" (block) that models an n-th order exponential (information-) delay called SmoothN. Validating this component will give the internal error (i.e. hd Check failed). The error will not be given if the inner outer declaration for a parameter in some subcomponent of that class is changed to a mere outer declaration.I have instantiated this component in a model that has a corresponding inner declaration in the outside scope and then everything will work fine in Simulation Center. But I have no chance to run the model using SystemModelSimulate: apparantly the missing inner declaration in the outer scope prevents the model to run.I can provide the library with the full example if you want by Mail.
Posted 1 year ago
 The internal error shown is also preventing SystemModelSimulate[ ] from running a model that contains a simultaneous inner outer declaration (WSM will simulate a model despite an internal error message). Which example are you referring to here? The InnerOuterTest.UsesComponentWithInnerOuterParameter in your Update 2 doesn't build for me in Simulation Center either (which is expected when there is an internal error).
 The internal error shown is also preventing SystemModelSimulate[ ] from running a model that contains a simultaneous inner outer declaration (WSM will simulate a model despite an internal error message). Good to know, that it will be addressed as a Bug.As far as I understand it now, the behavior for TestingInnerOuter_3 makes sense: Inside the local scope of Submodel the outer definition is used which references the inner declaration of an enclosing scope (e.g. the positive values declared in the MainModel). Any outer declaration in the scopes below Submodel (e.g. "Sub-Submodels") will then use the inner declaration which has been modified or rather been given a declaration equation (so then the negative values will apply). To make this clearer: package TestInnerOuter block Submodel inner outer parameter Integer x = -1; output Integer y; Subsubmodel ssm; equation y = x; end Submodel; block Subsubmodel outer parameter Integer x; output Integer y; equation y = x; end Subsubmodel; model MainModel inner parameter Integer x = 1; Submodel sm; end MainModel; end TestInnerOuter; Running the model reveals, that sm.y = 1 (e.g. it uses the global inner declaration for x via the outer part of the inner outer declaration inside of sm).The declaration equation inside of Submodel sm changes the inner declaration for sm.x which is then referenced by the outer declaration in the nested Subsubmodel ssm.Accordingly ssm.y = -1.It is rather tricky business and my intended use case was a different one, as I had though that the declaration equation for an inner outer variable would be overridden by the enclosing inner declaration. But, as shown, that is not the case: A declaration equation for a simultaneous inner outer variable will override enclosing inner definitions and will serve as a modified inner declaration referenced by corresponding outer declarations in nested (inside) scopes. Regards.Guido