package OneNonLinearEquation "Determine solution of a non-linear algebraic equation in one unknown without derivatives in a reliable and efficient way"
extends Modelica.Icons.Package;
replaceable partial function f_nonlinear
"Nonlinear algebraic equation in one unknown: y = f_nonlinear(x,p,X)"
extends Modelica.Icons.Function;
input Real x "Independent variable of function";
input Real p_=0.0 "Disregarded variables (here always used for pressure)";
input Real T_= 0 "Disregarded variables (here always used for temperature)";
input Real d_= 0 "Disregarded variables (here always used for density)";
input Real[:] X_=fill(0, 0)
"Disregarded variables (her always used for composition)";
output Real y "= f_nonlinear(x)";
// annotation(derivative(zeroDerivative=y)); // this must hold for all replaced functions
end f_nonlinear;
replaceable function solve
"Solve f_nonlinear(x_zero)=y_zero; f_nonlinear(x_min) - y_zero and f_nonlinear(x_max)-y_zero must have different sign"
import Modelica.Utilities.Streams.error;
extends Modelica.Icons.Function;
input Real y_zero
"Determine x_zero, such that f_nonlinear(x_zero) = y_zero";
input Real x_min "Minimum value of x";
input Real x_max "Maximum value of x";
input Real pressure=0.0
"Disregarded variables (here always used for pressure)";
input Real temperature= 0 "Disregarded variables (here always used for temperature)";
input Real density= 0 "Disregarded variables (here always used for density)";
input Real[:] X=fill(0, 0)
"Disregarded variables (here always used for composition)";
input Real x_tol=100*Modelica.Constants.eps
"Relative tolerance of the result";
output Real x_zero "f_nonlinear(x_zero) = y_zero";
protected
constant Real eps=Modelica.Constants.eps "Machine epsilon";
constant Real x_eps=1e-10
"Slight modification of x_min, x_max, since x_min, x_max are usually exactly at the borders T_min/h_min and then small numeric noise may make the interval invalid";
Real x_min2=x_min - x_eps;
Real x_max2=x_max + x_eps;
Real a=x_min2 "Current best minimum interval value";
Real b=x_max2 "Current best maximum interval value";
"Calculates a stoichiometry matrix with pivoting so that lambdaout =(I|lambda_var) with permutation matrix Pout for reordering species elements of lambda_ordered = lambdaout*Pout"
"Calculates a stoichiometry matrix with pivoting so that nuout =(I|nu_var) with permutation matrix Pout for reordering species elements of nu_ordered = nuout*Pout"
"Calculates a stoichiometry matrix with pivoting so that nuout =(I|nu_var) with permutation matrix Pout for reordering species elements of nu_ordered = nuout*Pout"