Jonas
Jonas

Reputation: 99

How to avoid a overdetermined system in Modelica?

I am currently creating a pipe based on Modelica.Fluid.Pipes.StaticPipe in OpenModelica. The model I am creating is quite similar, but I'm trying to implement the method of characteristics instead.

When I check the model it counts 38 equations and 10 variables, and the system is therefore overdetermined. As far as I know I need every equation that I have coded, and I therefore think that variables and constants are declared wrong.

This is how I generally declare variables and constants:

  1. When defining things I want the user to change (in the GUI in OpenModelica) I use parameter, e.g parameter SIunits.Length length=1;.
  2. When defining things I don't want the user to change I use final parameter, e.g final parameter SIunits.Area crossArea=Modelica.Constants.pi*diameter*diameter/4;.
  3. When declaring things I need to use in equation I only use the correct type, e.g Real f "Darcy-Weisbach friction factor";. I typically have seperate functions which are stored in these variables later in equation.
  4. When declaring arrays which are used in equation I use final parameter, e.g final parameter Real f_array[j_length,i_length];
  5. In equation, when storing variables in arrays I do this: f_array[j,i] = Functions.Friction(v=v,D=diameter,rho=rho, mu=mu, eps=roughness);.

Below is a simplified snippet of my code. I've left out a number of declarations in order to make it easier to read.

    model pipe_MSL
       outer Modelica.Fluid.System system;
       extends Modelica.Fluid.Interfaces.PartialTwoPort;

       // Geometry
       parameter SI.Length length=1 "Length";
       final parameter SI.Area crossArea=Modelica.Constants.pi*diameter*diameter/4;

       // Initialization
       final parameter Medium.AbsolutePressure p_a_start=system.p_start;

       // Method of Characteristics declarations
       Real f "Darcy-Weisbach friction factor";
       Real B "Impedance from MOC";
       Real R "Resistance from MOC";
       final parameter Real dx = length/3
       final parameter Integer N = integer(length/dx)
       final parameter Real dt = dx/a "Time step";
       Real v "Water velocity";

       // Local array storage declarations.
       final parameter Real B_array[T,N];
    
    initial equation
       //Initial condition
       B_array[1,:] = {Functions.B_Impedance(a=a, A=crossArea, g=system.g)*k for k in 1:N};

    equation
       for j in 1:T loop
          //Left boundary condition
          Cm_array[j+1,1] = OpenWPL.Functions.C_minus(Hb=H_array[j,2], B=Bm_array[j,1], Qb=Q_array[j,2]);

          for i in 1:(N-1) loop
             B_array[j,i] = Functions.B_Impedance(a=a, A=crossArea, g=system.g) + R_array[j,i]*abs(Q_array[j,i-1]);;
          end for; 
       end for;
    end pipe_MSL;

My questions are:

  1. Am I using parameter / final parameter / Real and other declarations correctly? I've read the guide from Michael Tiller on variables over and over, but I cannot figure out if I use them correctly.
  2. Any specific tips on how to make the system not overdetermined?
  3. When simulating (even though the system is overdetermined) I get the error Internal error Cm_array[2,1] = OpenWPL.Functions.C_minus(H_array[1,2], Bm_array[1,1], Q_array[1,2]) has size size 1 but 0 variables (). Any idea how to solve this?

I can post the full version of my code if it is needed. Thanks in advance.

Upvotes: 2

Views: 862

Answers (1)

Hans Olsson
Hans Olsson

Reputation: 12527

You are not using parameter correctly and there is one more error:

  • You can have initial equations for parameters with fixed=false, but it doesn't seem like B_array is a parameter since there's a normal equation for it. So remove parameter in front of B_array.
  • And the initial equation for B_array will not work (see below); erase it to get started
  • Alternatively you have to write B_array(each fixed=false) and ensure that there initial equations for all elements of B_array not just one row.
  • You have variables that aren't used (at the moment) - just remove their declarations: f, B, R, v (unless there are equations that you haven't given).

Initial equations are only intended to fix states (and sometimes parameters); and the idea is that variables must satisfy the normal equations and the initial equations. Thus having an initial equation that looks like the normal equation doesn't work.

Added: If the goal is to write your own time-discretized system of equations that doesn't use Modelica for differential equations I see two possibilities:

  • Turn it into a traditional algorithm in a function so that you have parameter Real B_array[T,N]=myDiscretization(...); and everything inside the function myDiscretization
  • Or just have everything as equations; Real B_array[T,N] in the main model.

A tool should be able to see that the equations are parametric and only solve them once.

In both cases you have to be really careful about indices:

  • Above it is i in 1:(N-1) but using Q_array[j,i-1].
  • The initial conditions are for B_array[1,:], but there are normal equations for B_array[1,:] as well

So should the initial equations be for B_array[:,1] and the loop for i in 2:N instead, since that ensures that all elements have an equation? Or is it subtler?

Upvotes: 3

Related Questions