Message Boards Message Boards

Avoid time-consuming warnings in FindRoot with thermodynamic properties

Posted 10 months ago

I think some databases for thermodynamic properties come with built-in inverse functions. I did not find such an inverse function for my problem, and so, I resorted to using FindRoot.

When doing a simple calculation, say, to get the new temperature after a change in energy or enthalpy, I encounter this of error (or warning) message. It may be a just a warning, because it still provides an answer, and it seems accurate enough. My concern is that these things usually use time.

From the text of the message 9see below), it seems that FindRoot and ThermodynamicData "are not understanding" each other very well. It seems to me that FindRoot wants to explore the function using a variable with no specified value, whereas ThermodynamicData wants to see a number. Can this be done in a different way to avoid this glitch?

My example:

In[51]:= FindRoot[
 QuantityMagnitude[
   ThermodynamicData["Water", 
    "Enthalpy", {"Pressure" -> Quantity[1.5*^7, "Pascals"], 
     "Temperature" -> Quantity[t, "Kelvins"]}]] == 1.4*^6, {t, 550.0, 
  610.0}]

During evaluation of In[51]:= ThermodynamicData::quant: t is not a real number.

Out[51]= {t -> 584.113}
POSTED BY: Otto Linsuain
4 Replies

Maybe try:

  f = FunctionInterpolation[QuantityMagnitude[
     ThermodynamicData["Water", 
      "Enthalpy", {"Pressure" -> Quantity[1.5*^7, "Pascals"], 
       "Temperature" -> Quantity[t, "Kelvins"]}]], {t,230,1000}]//Quiet

 FindRoot[f[t]== 1.4*^6, {t, 550.0, 610.0}]
 (*{t->584.113} *)
POSTED BY: Mariusz Iwaniuk
Posted 10 months ago

Wow! Thanks! That is amazing. I had tried that before (a while back) and it had not work. It must have been an older version. I think these days I still have 12.0 in one of my computers, but it did work in 13.2. I see that now both Pressure and Temperature appear in the list of properties. That suggests more things can be inverted.

There will still be cases where FindRoot or something similar is necessary, and I have run into those. These are basically cases where the function to invert is not just the enthalpy but a combination of enthalpy and temperature. Something like:

a * H(Press, Temp) + b * Temp = c

Where a, b, c, and Press are known. This happens when the enthalpy rise is not exactly known, because it depends on the unknown temperature (like when there is an amount of heat exchanged that depends on the unknown temperature through a heat exchange coefficient, as in Newton's Law of Cooling).

So, I think technically you did answer my question the way I presented the example, and I appreciate that a lot, since it simplifies many things, but there is still that odd miscommunication between FindRoot and ThermodynamicData that I would like to be able to address.

Thanks and best regards, Otto Linsuain.

POSTED BY: Otto Linsuain
Posted 10 months ago

To avoid the error message "ThermodynamicData::quant: t is not a real number", we could use Quiet@FindRoot[...]

For a case like this: H(Temp) + b * Temp = c, we could define a function to calculate the enthalpy that only accepts numbers and thus avoid the first evaluation H[t] with t as a symbol, wich generates the error. For example:

H[Temp_Real] := 
 QuantityMagnitude[
  ThermodynamicData["Water", 
   "Enthalpy", {"Pressure" -> Quantity[P, "Pascals"], 
    "Temperature" -> Quantity[Temp, "Kelvins"]}]]

other form is

H[Temp_/;NumberQ@Temp]:=QuantityMagnitude[
      ThermodynamicData["Water", 
       "Enthalpy", {"Pressure" -> Quantity[P, "Pascals"], 
        "Temperature" -> Quantity[Temp, "Kelvins"]}]]

Pressure could also be included and tested in the H function.

As an example with the data you give

In[1]:=Clear[H, c]; 
H[Temp_Real] := 
 QuantityMagnitude[
  ThermodynamicData["Water", 
   "Enthalpy", {"Pressure" -> Quantity[1.5*^7, "Pascals"], 
    "Temperature" -> Quantity[Temp, "Kelvins"]}]];
c = H[584.113] + .1*584.113;
FindRoot[H[t] + .1*t == c, {t, 500.0, 610.0}] Out[1]:={t->584.113}
POSTED BY: Legibus Motus
Posted 10 months ago

For this problem you could use pressure and enthalpy as input and ask for temperature:

QuantityMagnitude[
 ThermodynamicData["Water", "Temperature",  {"Pressure" -> Quantity[1.5*^7, "Pascals"], 
   "Enthalpy" -> Quantity[1.4*^6, "Joules"/"Kilograms"]}]]

I think this works since version 12.2

POSTED BY: Legibus Motus
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract