Nonlinear Equation Solver

Discussion about the use of Simantics System Dynamics
Post Reply
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Nonlinear Equation Solver

Post by armandocora » August 29th, 2014, 4:05 pm

Hi guys,

Is there a way of solving a nonlinear equation inside Simantics System Dynamics?

I know its possible to add a C language function to do this but I don't have admin rights on my machine to compile one.

Thanks
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Re: Nonlinear Equation Solver

Post by armandocora » August 29th, 2014, 5:44 pm

I found this library:

https://github.com/modelica/Modelica/bl ... nlinear.mo

Is there a way of using it in Simantics?

Thanks
Tuomas Miettinen
Site Admin
Posts: 31
Joined: March 11th, 2013, 3:14 pm

Re: Nonlinear Equation Solver

Post by Tuomas Miettinen » September 1st, 2014, 8:41 am

Hi,

There's currently no straightforward way of including a Modelica library to Simantics System Dynamics. I think there are two alternatives you can do with that library (or any other Modelica library):
1) You can add the functions in that library by hand to the tool. This basically means that you'd have to copy paste the Modelica code of the functions to the tool. Adding custom functions is explained in the user manual: https://www.simantics.org/end_user_wiki ... #Functions
2) Simantics System Dynamics converts its models to Modelica models, which are then solved. Thus you could take the Modelica code out of the tool and use that any way you like in any external Modelica environment. The Modelica code of the system dynamics model can be viewed by right-clicking the Configuration of the model and selecting Open With -> Modelica Code Viewer. If you need the included sources too, you'll need to simulate the model with OpenModelica (Window -> Preferences -> Solver -> OpenModelica) and look at the Console view where the path in which the Modelica sources etc. are is shown (if the model was simulated successfully).
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Re: Nonlinear Equation Solver

Post by armandocora » September 3rd, 2014, 12:19 am

Thanks

I tried copying and pasting this function:

Code: Select all

function solveOneNonlinearEquation
"Solve f(u) = 0 in a very reliable and efficient way (f(u_min) and f(u_max) must have different signs)"
extends Modelica.Icons.Function;
import Modelica.Utilities.Streams.error;
input Modelica.Math.Nonlinear.Interfaces.partialScalarFunction f
"Function y = f(u); u is computed so that y=0";
input Real u_min "Lower bound of search interval";
input Real u_max "Upper bound of search interval";
input Real tolerance=100*Modelica.Constants.eps
"Relative tolerance of solution u";
output Real u "Value of independent variable u so that f(u) = 0";
protected
constant Real eps=Modelica.Constants.eps "machine epsilon";
Real a=u_min "Current best minimum interval value";
Real b=u_max "Current best maximum interval value";
Real c "Intermediate point a <= c <= b";
Real d;
Real e "b - a";
Real m;
Real s;
Real p;
Real q;
Real r;
Real tol;
Real fa "= f(a)";
Real fb "= f(b)";
Real fc;
Boolean found=false;
algorithm
// Check that f(u_min) and f(u_max) have different sign
fa := f(u_min);
fb := f(u_max);
fc := fb;
if fa > 0.0 and fb > 0.0 or fa < 0.0 and fb < 0.0 then
error(
"The arguments u_min and u_max provided in the function call\n"+
" solveOneNonlinearEquation(f,u_min,u_max)\n" +
"do not bracket the root of the single non-linear equation 0=f(u):\n" +
" u_min = " + String(u_min) + "\n" + " u_max = " + String(u_max)
+ "\n" + " fa = f(u_min) = " + String(fa) + "\n" +
" fb = f(u_max) = " + String(fb) + "\n" +
"fa and fb must have opposite sign which is not the case");
end if;
// Initialize variables
c := a;
fc := fa;
e := b - a;
d := e;
// Search loop
while not found loop
if abs(fc) < abs(fb) then
a := b;
b := c;
c := a;
fa := fb;
fb := fc;
fc := fa;
end if;
tol := 2*eps*abs(b) + tolerance;
m := (c - b)/2;
if abs(m) <= tol or fb == 0.0 then
// root found (interval is small enough)
found := true;
u := b;
else
// Determine if a bisection is needed
if abs(e) < tol or abs(fa) <= abs(fb) then
e := m;
d := e;
else
s := fb/fa;
if a == c then
// linear interpolation
p := 2*m*s;
q := 1 - s;
else
// inverse quadratic interpolation
q := fa/fc;
r := fb/fc;
p := s*(2*m*q*(q - r) - (b - a)*(r - 1));
q := (q - 1)*(r - 1)*(s - 1);
end if;
if p > 0 then
q := -q;
else
p := -p;
end if;
s := e;
e := d;
if 2*p < 3*m*q - abs(tol*q) and p < abs(0.5*s*q) then
// interpolation successful
d := p/q;
else
// use bi-section
e := m;
d := e;
end if;
end if;
// Best guess value is defined as "a"
a := b;
fa := fb;
b := b + (if abs(d) > tol then d else if m > 0 then tol else -tol);
fb := f(b);
if fb > 0 and fc > 0 or fb < 0 and fc < 0 then
// initialize variables
c := a;
fc := fa;
e := b - a;
d := e;
end if;
end if;
end while;
annotation (Documentation(info="<html>
<h4>Syntax</h4>
<blockquote><pre>
<b>solveOneNonlinearEquation</b>(function f(), u_min, u_max);
<b>solveOneNonlinearEquation</b>(function f(), u_min, u_max, tolerance=100*Modelica.Constants.eps);
</pre></blockquote>
<h4>Description</h4>
<p>
This function determines the solution of <b>one non-linear algebraic equation</b> \"y=f(u)\"
in <b>one unknown</b> \"u\" in a reliable way. It is one of the best numerical
algorithms for this purpose. As input, the nonlinear function f(u)
has to be given, as well as an interval u_min, u_max that
contains the solution, i.e., \"f(u_min)\" and \"f(u_max)\" must
have a different sign. The function computes a smaller interval
in which a sign change is present using the relative tolerance
\"tolerance\" that can be given as 4th input argument.
</p>
<p>
The interval reduction is performed using
inverse quadratic interpolation (interpolating with a quadratic polynomial
through the last 3 points and computing the zero). If this fails,
bisection is used, which always reduces the interval by a factor of 2.
The inverse quadratic interpolation method has superlinear convergence.
This is roughly the same convergence rate as a globally convergent Newton
method, but without the need to compute derivatives of the non-linear
function. The solver function is a direct mapping of the Algol 60 procedure
\"zero\" to Modelica, from:
</p>
<blockquote>
<dl>
<dt> Brent R.P.:</dt>
<dd> <b>Algorithms for Minimization without derivatives</b>.
Prentice Hall, 1973, pp. 58-59.<br>
Download: <a href=\"http://wwwmaths.anu.edu.au/~brent/pd/rpb011i.pdf\">http://wwwmaths.anu.edu.au/~brent/pd/rpb011i.pdf</a><br>
Errata and new print: <a href=\"http://wwwmaths.anu.edu.au/~brent/pub/pub011.html\">http://wwwmaths.anu.edu.au/~brent/pub/pub011.html</a>
</dd>
</dl>
</blockquote>
<h4>Example</h4>
<p>
See the examples in <a href=\"modelica://Modelica.Math.Nonlinear.Examples\">Modelica.Math.Nonlinear.Examples</a>.
</p>
</html>"));
end solveOneNonlinearEquation;
To solve this other function:

Code: Select all

 function fun1 "y = u^2 - 1"
extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
algorithm
y := u^2 - 1;
end fun1;
But it did not work. If it is not too much trouble can you post an example of how to use these functions in Simantics.

Thanks
Tuomas Miettinen
Site Admin
Posts: 31
Joined: March 11th, 2013, 3:14 pm

Re: Nonlinear Equation Solver

Post by Tuomas Miettinen » September 3rd, 2014, 1:26 pm

Hi,

I've looked at the problem, and that cannot be done in a straightforward manner in the current release (no support for functions as arguments nor usage of the whole standard Modelica library), but I'll tackle this issue and this will probably be available in the Thursday-Friday nightly.
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Re: Nonlinear Equation Solver

Post by armandocora » September 3rd, 2014, 7:43 pm

Thanks very much! I'll look for the latest nightly in a few days.
Tuomas Miettinen
Site Admin
Posts: 31
Joined: March 11th, 2013, 3:14 pm

Re: Nonlinear Equation Solver

Post by Tuomas Miettinen » September 4th, 2014, 3:04 pm

The trunk version now supports Modelica libraries, they can be enabled in the Model properties (in the selection view of the model Configuration) by checking the "Use Modelica libraries" checkbox.

The changes will be included onward from the next nightly (b673). Nightlies are found at:
http://www.simantics.org/download/sysdyn/nightly/trunk/

A word of warning about the nightlies: Currently the trunk is in a bit unstable state, so on some environments the application crashes or gets stuck quite often. This issue will be solved asap. Another thing is that there is no guarantee that models made with nightlies can be imported to newer versions of the tool.

Attached is a sample model in which the functions you gave are used. It compiles and simulates but doesn't make anything too smart.
Attachments
nonlinear example.zip
(5.7 KiB) Downloaded 27 times
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Re: Nonlinear Equation Solver

Post by armandocora » September 4th, 2014, 9:37 pm

Toumas thanks for the example. Is version b673 supposed to be in trunk archive? If not I'll just wait until it is released.
Tuomas Miettinen
Site Admin
Posts: 31
Joined: March 11th, 2013, 3:14 pm

Re: Nonlinear Equation Solver

Post by Tuomas Miettinen » September 5th, 2014, 7:54 am

Actually the b673 was skipped so the changes will be effective from b674 onwards. The build is now available.
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Re: Nonlinear Equation Solver

Post by armandocora » September 5th, 2014, 8:03 pm

Thanks. I was able to run it and solve fun1 from the example in the library. Now I'm trying to solve fun2:

Code: Select all

 function fun2 "y = 3*u - sin(w*u) - 1"
extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
input Real w "Angular velocity";
algorithm
y := 3*u - sin(w*u) - 1;
end fun2;
By typing something similar to this:

Code: Select all

solveOneNonlinearEquation(function fun2(w=3), -3, 2)
But it seems like simantics doesn't like that syntax. Attached is an example of what I'm trying to do.
I'll appreciate any help.
Attachments
nonlinear example2.zip
(6.75 KiB) Downloaded 25 times
Tuomas Miettinen
Site Admin
Posts: 31
Joined: March 11th, 2013, 3:14 pm

Re: Nonlinear Equation Solver

Post by Tuomas Miettinen » September 8th, 2014, 8:58 am

The syntax error you get is due to a bug in the Modelica parser of the tool. I've fixed that now and the change is active onward from the next nightly.

However, it seems that the model you sent simulates with OpenModelica even with the broken Modelica parser; certain syntax errors break the simulation and some don't, and it seems the parser can cope with this one.
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Re: Nonlinear Equation Solver

Post by armandocora » September 9th, 2014, 11:41 pm

I'm trying to solve the same example and it simulates but it doesn't return the correct answer. I'm using the latest nightly (b682).

Thanks
Tuomas Miettinen
Site Admin
Posts: 31
Joined: March 11th, 2013, 3:14 pm

Re: Nonlinear Equation Solver

Post by Tuomas Miettinen » September 10th, 2014, 8:19 am

First of all you should off course double check, but when you've done that, you could try the following:

The sequence of simulating a model is that the model is first converted to a Modelica model and then solved as such with either OpenModelica or the internal solver. Since the latest version of OpenModelica doesn't work correctly on command line without installing certain libraries, we still use quite an old version (1.9.0beta4) of OpenModelica by default.

First of all, you could try to install the latest installer or even the latest nightly of OpenModelica ( https://openmodelica.org/download/download-windows ) and use that instead. The OpenModelica used by the tool can be changed in Window -> Preferences -> Modelica. If I recall correctly, the missing libraries affects only game experiments. Nevertheless, the libraries OpenModelica doesn't find are libgfortran-3.dll and pthreadGC2.dll should you need them.

If that still gives you the wrong results, you could try to ask help at the OpenModelica forum ( https://openmodelica.org/forum ). Before doing that you could also try to simulate the Modelica model that the tool produces directly with OpenModelica. The directory of the Modelica model files are shown in the Console view after a successful simulation run. However, I don't think it is of any help.
armandocora
Posts: 8
Joined: August 29th, 2014, 4:01 pm

Re: Nonlinear Equation Solver

Post by armandocora » September 12th, 2014, 4:26 pm

Thanks. Right now I'm solving my equation using the excel solver as my priority is to finish the project. But as soon as I have time I'll try to figure out what's happening with Simantics and report my findings.
Post Reply