Help - Search - Members - Calendar
Full Version: Différential Equation and when while if statements
Modelica Forum > Modelica > Modelica
Jawhar
Hello

I am beginning with Modelica and i have a problem. I hope that you can help me.

I want to resolve a differential equation (first order for the moment) during an interval of time.

I want to create two models: the first model resolves an equation when a condition is true.. if the condition is false the first model had to stop resolving (simulating) the différential equation.and the second model is activated..

An example:

model state1
Real x(start = 0.2);
connector1 dout1;
equation
der(x) = 2 * x; //equation i want to resolve it..
when x > 0.8 then// the condition to stop resolving the Diff equation.. here i can create an event but i can't stop the resolution of the equation

dout1.s = x; // put the x variable in the connector to use it with another module..
dout1.state = true;
end when;
end state1;


connector connector1
Real s;
Boolean state;
end connector1;
.
.
.
some aother code of the second model...

As you have seen i had used when.. but the model continue resolving the Equation and i can detect when x is superior than 0.8.. I had tried to use while condition in algorithm.. but the simulation crashes..

To resume: I want to resolve a differential equation until a condition occurs..after this condition i want stop the resolution but not the simulation (because others modules will continue to do something..).

Would you please excuse my bad english.. unsure.gif
Thank you! rolleyes.gif
wagner
Hello Jawhar,

I think what you want is not possible in standard Modelica. You can't stop resolving a differential equation. What might help is changing the derivative to zero. A short example:

CODE

model ChangingDerivative
  Real x( start=0.2);
  
  Boolean resolve( start=true);
equation
  
  if (resolve) then
    der(x)=2*x;
  else
    der(x)=0;
  end if;
  
  when (x>0.8) then
    resolve=false;
  end when;
  
end ChangingDerivative;


What might help you is the Modelica tool Mosilab (http://www.mosilab.de). It is especially designed to handle structure variant systems. With this tool it should be possible to remove the differential equation from the system you are simulating during runtime. Unfortunately the website is in German and not in English. The tool is not available yet, but is announced for beginning of this year.

Regards

Florian
Jawhar
Thank you a lot wagner..

I have done this for the moment. I have another question:

Let take the example below:

Let's consider that the variable x is is recovered from a connector.

CODE


model state2
  Real x; // NO INITIALIZATION
  connector1 din2;

equation
  x = din2.s; // Read the initial value from the connector din2..
  if (din2.state and x>=2) then
  der(x)= 0.3 * x; // Can't resolve the equation.. a problem of initialization i think.
  
  else
  x = din2.s;
  end if;
  
  
end state2;



How can i initialize the value of x with an internal variable of the whole model? I can't do like this in the declaration part : Real x(start = din2.s); It's wrong.. I have tried the block initial equation..but it does'nt work too. Have you any idea please?
wagner
Hello Jawhar,

I don't get the point what you really want to do with your model but to solve your initialisation problem I post the following example:


CODE

package ModelInitialisationPackage
  model Model1
    Real x; // NO INITIALIZATION
    Connector1 din2;
    
  equation
    if (initial()) then
      x = din2.s; // Read the initial value from the connector din2..
    end if;
    
    /*if (din2.state and x>=2) then
    der(x)= 0.3 * x;
  else
    //x = din2.s; you can't do this, since x is a state variable which can't jump
    //you can use reinit to reset a state variable to a certain value
  end if;*/
    
    if (din2.state and x>=2) then
      der(x)=0.3*x;
    else
      der(x)=0;
    end if;
    
    when
        (not
            (din2.state and x>=2)) then
      reinit(x,din2.s);
    end when;
    
  end Model1;

  connector Connector1
    Boolean state;
    Real s;
  end Connector1;

  model Model2
    parameter Real x0=5;
    Connector1 connector1;
    
    Boolean changeState(start=false);
  equation
    connector1.s=x0;
    
    when
        (time>0.5) then
      changeState=true;
    end when;
    
    if (changeState) then
      connector1.state=false;
    else
      connector1.state=true;
    end if;
  end Model2;

  model GlobalModel
    Model1 model1;
    Model2 model2;
    
  equation
    connect(model1.din2,model2.connector1);
  end GlobalModel;
end ModelInitialisationPackage;



It consists of Model1 (which is inspired by your posted model) a connector of type Connector1, with the variables state and s, and s second model Model2 which provides the initial value for Model1 and switches the value of state of the Connector1. The model Globalmodel connects the models together to get a runable model.

To initialise the state variable x in Model1 I make use of the initial() function which is true in the initial step of simulation and false in all other steps. It can be seen as

CODE

when(time>0) then
..
end when;


In general you have to be careful with resetting state variables. You can't get rid of derivatives by simply replacing them by ordinary equations (what you have done in your model). The value of the state variable has to be steady and differentiable.

The easiest way if you want to change a value of a state variable is to use reinit(variablename, newvalue). But this is only possible at points of time, not for an interval. Take a look at the code in Model1.

Regards

Florian
Jawhar
Thank you Florian for your great help.

I have to use the function initial() ok.. but there is a little problem.

CODE

if (initial()) then
      x = din2.s; // I haven't the good value of din2.s because i want to read din2.s also when din2.state is true..
    end if;


i think that doing this is wrong:

CODE

if (initial() [b]and din2.state[/b]) then // I think that is illogical and wrong.
      x = din2.s;
end if;


my problem is near to be resolved :-)

Thank you also for your great hints and ideas..

Best Regards,

Jawhar.
wagner
Hello Jawhar,

the point is, in which way do you want to initialize x if in the initial step din2.state is false? I would propose to take a meaningful standard value, and when state gets true to reinitialize x.

CODE

if (initial()) then
if (din2.state) then
   reinit(x,din2.s);
else
   reinit(x,0);
end if;
end if;

when(not(initial()) and din2.state) then
  reinit(x,din2.s);
end when;


Regards

Florian
Jawhar
QUOTE(wagner @ Feb 6 2007, 04:23 PM) *

Hello Jawhar,

the point is, in which way do you want to initialize x if in the initial step din2.state is false? I would propose to take a meaningful standard value, and when state gets true to reinitialize x.

CODE

if (initial()) then
if (din2.state) then
   reinit(x,din2.s);
else
   reinit(x,0);
end if;
end if;

when(not(initial()) and din2.state) then
  reinit(x,din2.s);
end when;


Regards

Florian


I don't know if in the initial step din2.state is false or true. My global model is autonomous. It's working now with this solution.

The problem is resolved. Thank you a lot Florian..
Hope that these posts help someone :-)

Best regards,

Jawhar.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2012 Invision Power Services, Inc.