Message Boards Message Boards


Avoid results with unexpected units with FindRoot and ThermodynamicData?

Posted 5 years ago
1 Reply
1 Total Likes

The ThermodynamicData functions allow the user to lookup values by specifying a temperature and pressure, I wanted to write some routines where, for example, pressure and enthalpy could be specified. Using FindRoot is the chosen method. The idea is that given an pressure and enthalpy of interest, use FindRoot to find the corresponding temperature. Then any required property could be found using the given pressure and the temperature determined by FindRoot.

Somehow, FindRoot is returning an unexpected result. (Perhaps user error.) Test code is below. For the test, an enthalpy is determined at a given pressure and temperature, then FindRoot is asked to find the temperature, given the pressure and enthalpy.

p0 = Quantity[3500, "psi"];
t0 = Quantity[1000, "DegreesFahrenheit"];
h0 = ThermodynamicData["Water",   "Enthalpy", {"Pressure" -> p0, "Temperature" -> t0}]

tmin = Quantity[900, "DegreesFahrenheit"];
tmax = Quantity[1100, "DegreesFahrenheit"];
FindRoot[ h0 == ThermodynamicData["Water", "Enthalpy", {"Pressure" -> p0, "Temperature" -> tx}], {tx, tmin , tmax}]
(* result: {tx -> Quantity[611.111, ("Kelvins")^2]}*)

There appear to be two problems with the result from FindRoot:

  1. the result has units of temperature squared. It should have units of temperature
  2. the result does not correspond to 1000 Fahrenheit.

Any help would be appreciated.


There appears to be a bug in the way FindRoot handles units. I would report this.

This works:

In[1]:= FindRoot[Quantity[6, "ft"] == x, {x, Quantity[4, "in"]}]

Out[1]= {x -> Quantity[1.8288, "Meters"]}

but this does not:

In[6]:= FindRoot[
 Quantity[6, "ft"] == x, {x, Quantity[4, "in"], Quantity[400, "in"]}]

Out[6]= {x -> Quantity[10.16, ("Meters")^2]}

I generally avoid using units in expression handling as the results I've observed have been unpredictable. Your problem can be solved by doing this:

In[2]:= func[x_Real] := 
  ThermodynamicData["Water",  "Enthalpy", {"Pressure" -> p0, 
    "Temperature" -> Quantity[x, "DegreesFahrenheit"]}]]

In[11]:= FindRoot[QuantityMagnitude[h0] == func[tx], {tx, 900., 1100.}]

Out[11]= {tx -> 1000.}

Note that the x_Real pattern is necessary because I found that FindRoot calls the expression with symbols and numbers (I guess that it tries to first solve things analytically). If you do not protect the function by only letting it get called with Real numbers, you get the correct answer with warning messages like this:

ThermodynamicData::quant: tx is not a real number.


Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract