Message Boards Message Boards

GROUPS:

[?]Make variables show up in Sensitivity Analysis? (WSMSimulateSensitivity)

Posted 3 years ago
4214 Views
|
8 Replies
|
2 Total Likes
|

I'm trying to use WSMSimulateSensitivity but when returning "SensitivityNames" I get a short list of variables that I don't really care about. How can I make sure that the variables I'm interested in show up?

I thought they might need to be defined as "output Real myVar" in the model, but that hasn't worked.

Thanks, Eric

8 Replies

It looks like only variables that have differential equations can be used for sensitivity analysis. I have a DAE model that I'm using right now and I want to look at one of the algebraic variables.

I tried tricking the system with something like:

output Modelica.SIunit.Velocity v_out;
initial equation
    v_out = 0;
equation
    der(v_out) = der(v);

Where v has it's own algebraic expression. But the model didn't like that; it runs fine without those lines. Can someone explain why?

Hi Eric!

The only variables that can be used for sensitivity analysis are those that the solver uses as states. You can influence how the solver selects states with the stateSelect attribute.

For example, in the following model:

model TestStates
  Real x(start = 1);
  parameter Real k=1;
  output Real y(stateSelect=StateSelect.always);
equation
  x*k=y;
  der(x)=1;
end TestStates;

y is forced to be used as a a state.

So the following code will bring up y's sensitivity to k:`

WSMPlot[WSMSimulateSensitivity[
  "TestStates", {0, 10}, {"k"}], {{"y", "k", 0.1}}]

The stateSelect attribute can take on the following values: StateSelect.never, StateSelect.avoid, StateSelect.default, StateSelect.prefer, StateSelect.always.

The difference between prefer and always is that in both cases the solver will prefer choosing the variable as a state, but if StateSelect.always is set, it will throw an error if it is unable to use the variable as a state. The same, but inverse is true for avoid and never.

Thank you Patrik. That's very helpful, but what other conditions does "StateSelect.always" put on variables? Simulation Center is failing to create the model when I add it.

The variable "v" (velocity) is used in an equation with a Moody Roughness function that's piecewise-continuous. Do I have to define the derivative of this function in order to make "v" a state variable?

Error:

Internal error: Internal error: DeriveMC.differentiateExpTime: error for expression CALL .MultiphaseProcessComponents.MoodyFriction
   |CREF pipelineSection1 [model .PipelineSection$pipelineSection1] .Re [Real] CREFTYPE:Real
   |BINARY  /  Real
   |   |CREF pipelineSection1 [model .PipelineSection$pipelineSection1] .epsilon [Real] CREFTYPE:Real
   |   |CREF pipelineSection1 [model .PipelineSection$pipelineSection1] .D [Real] CREFTYPE:Real

I don't get this error when not setting stateSelect=StateSelect.always

I see you described the difference between "prefer" and "always". However, both are returning the same error in Simulation Center

When I remove the MoodyFriction function from the equation and replace it with a constant, I'm still getting a warning when I declare "v" as a state variable.

[WARNING]: No unique solution for solving linear equation: -0.02 * pipelineSection1.medium.rho * pipelineSection1.v * pipelineSection1.L * $tmpBuf[4] + $tmpBuf[2] * der(pipelineSection2.flowPortb.mflow) = --0.02 * pipelineSection1.medium.rho * pipelineSection1.v * pipelineSection1.L * $tmpBuf[6]

I know these are custom models, but I'm hoping the message is generic enough to illustrate the problem.

I also simplified the model by removing the non-linearity.

dP = medium.rho * L * v * 0.01
(*instead of*)
dP = medium.rho * L * v^2 * 0.01

When I do that the errors go away, but it's not what I'm looking for which is...

dP = medium.rho * L * v^2 * MoodyFriction(Re, epsilon/D)
(*where*)
Re = v * D / medium.nue

Hi Eric,

Does this error occur at the beginning of the simulation? That could indicate that it is an initialization problem, where it fails to find a consistent set of initial values due to the non-linearity. The solver will prefer to use the specified initial values of states over other variables, so now with a new set of states, the initial conditions could be badly formed. You can force the solver to use a certain initial condition, even if the variable is not a state using the fixed=true keyword:

model TestStates
  Real x(start = 1);
  parameter Real k = 1;
  output Real y(start = 0,stateSelect = StateSelect.always);
equation
  x * k = y;
  der(x) = 1;
end TestStates;

Will initialize y to 0.

model TestStates
  Real x(start = 1,fixed=true);
  parameter Real k = 1;
  output Real y(start = 0,stateSelect = StateSelect.always);
equation
  x * k = y;
  der(x) = 1;
end TestStates;

Will initialize y to k*x.

To see how states were selected and initialized before and after you force v to become a state, you can go to Tools > Options > Simulation Center > Debug Output and select "Normal" and mark "Initialization" from Simulation Center.

Patrik,

I tried a few things, but am still struggling. I appreciate the help I've gotten so far.

I've stripped the model down to something extremely simple (not accurate equations). I'm still getting the "No unique solution for solving linear equation..." error. Setting start and fixed on dp and V_flow (via a modification) hasn't worked and results in an Overdetermined initial equation warning.

model PipelineSection
  extends Modelica.Thermal.FluidHeatFlow.Interfaces.Partials.TwoPort(V_flow(stateSelect=StateSelect.prefer));
equation
  dp = V_flow^2 * 0.01
  Q_flow = 0.0;

And I connect it with some standard components (see attached file).

And since you asked for the initialization debug output:

[INIT]: Initialized states to :
[INIT]:  pipelineSection.T = 288.15
[INIT]:  der(pipelineSection.T) = -0
[INIT]:  pipelineSection1.T = 288.15
[INIT]:  der(pipelineSection1.T) = -0
[INIT]:  pipelineSection2.T = 288.15
[INIT]:  der(pipelineSection2.T) = 0
[INIT]:  volumeFlow.T = 293.15
[INIT]:  der(volumeFlow.T) = -0
[INIT]:  $dummy = 0
[INIT]:  der($dummy) = 0
[GENERAL]: Checking events at initialization at time = 0.
[GENERAL]: Starting numerical solver at time 0
[INIT]: Initialization took 0.000432s.
Attachments:

Hi Eric,

Try using the CVODES solver, it seems to avoid the "No unique solution for solving linear equation..." error. However, that alone wont simply solve your state selection problem.

In the two port component, the derivative of T occurs in the following equation:

flowPort_a.H_flow + flowPort_b.H_flow + Q_flow = m * medium.cv * der(T);

So if any state beside T is to be chosen using stateSelect=always, it needs to be able to use that to solve der(T). V_flow is not such a variable, possibly due to the presence of the special "semiLinear" function in the component. I was however able to trick it to add an additional state, beside T by using your original approach:

Change

V_flow = flowPort_a.m_flow / medium.rho;

To

der(V_flow) = der(flowPort_a.m_flow) / medium.rho;

in the TwoPort component. In your model, you will only be able to set 2 out of 3 pipes to use V_flow as a state, since the third variable can be directly calculated from the other 2. With 3 states, the solution would be over determined. You can for example have:

PipelineSection pipelineSection(T_a.fixed = false, T_b.fixed = false, T0fixed = true, V_flow(stateSelect = StateSelect.always));
PipelineSection pipelineSection1(T_a.fixed = false, T_b.fixed = false, T0fixed = true, V_flow(stateSelect = StateSelect.always));
PipelineSection pipelineSection2(T_a.fixed = false, T_b.fixed = false, T0fixed = true);

Try the attached model and see if it works for your purposes.

This could be considered a pretty dirty fix, so there could be a better way. I would have to think about it a bit more.

Attachments:
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract