2
votes

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.

1
seems to me that you are mixing variables with parameters. Parameters are constrant throughout a whole simulation. So arrays should be declared as variables, i.e. remove final parameterAtiyah Elsheikh
The last error is because parameters only have initial equations and should not be solved for in regular equations. Final is used for things that don't change - variables, parameters, or constants. I recommend using constants for array dimensions. Users can also change variables and constants in the GUI and if you give them a Dialog annotation you can control where they show up.sjoelund.se
@AtiyahElsheikh Thank you. Removing final parameter when declaring arrays solved a bunch of my problems. However, when I try to remove final parameter from final parameter Real dx = length/3(which is constant throughout the whole simulation) I get the error Dimensions must be parameter or constant expression (in N). in Real fp_array[T,N];. Do you know how to counter this?Jonas
@sjoelund.se After removing final parameter the last error disappeared, as you mentioned. I have also declared another boundary condition (which I left out in my original post) which is H_array[j+1,1]=1; under //Left boundary condition in equation. The same error (Internal error pipe.H_array[3,1] = 1.0 has size size 1 but 0 variables ()) now appears here. Do you know how to solve this as well? Thank you for your reply!Jonas
@Jonas d_x is a parameter, so you can declare it as a parameter.Atiyah Elsheikh

1 Answers

3
votes

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?