Skip to content

Commit

Permalink
All isoline generators now use the new functions
Browse files Browse the repository at this point in the history
  • Loading branch information
fwitte committed Jul 21, 2024
1 parent 2577996 commit f73e48f
Showing 1 changed file with 118 additions and 76 deletions.
194 changes: 118 additions & 76 deletions src/fluprodia/fluid_property_diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,11 @@ def from_json(cls, path):
def _setup_functions_and_inputs(self):
"""Setup lookup tables for isoline functions and CoolProp inputs."""
self.single_isoline_functions = {
'p': self._single_isobaric,
'v': self._single_isochoric,
'T': self._single_isothermal,
'h': self._single_isenthalpic,
's': self._single_isentropic
'p': self._single_isoline,
'v': self._single_isoline,
'T': self._single_isoline,
'h': self._single_isoline,
's': self._single_isoline
}
self.CoolProp_inputs = {
'p': CP.iP,
Expand Down Expand Up @@ -460,8 +460,8 @@ def _get_state_result_by_name(self, property_name):
def _update_state(self, input_dict):
output_dict = {}
for property_name, value in input_dict.items():
if property_name == "d":
output_dict["d"] = 1 / value
if property_name == "v":
output_dict["v"] = 1 / value
else:
output_dict[property_name] = value

Expand Down Expand Up @@ -596,10 +596,6 @@ def _isobaric(self):
"""Calculate an isoline of constant pressure."""
isolines = self.pressure['isolines']

iterator = 1 / np.append(
np.geomspace(self.v_min, self.v_intermediate, 100, endpoint=False),
np.geomspace(self.v_intermediate, self.v_max, 100))

for p in isolines.round(8):
if p <= self.p_crit:
T_sat = CP.CoolProp.PropsSI("T", "P", p, "Q", 0, self.fluid)
Expand All @@ -620,14 +616,24 @@ def _isochoric(self):
"""Calculate an isoline of constant specific volume."""
isolines = self.volume['isolines']

iterator = np.append(
np.geomspace(self.p_trip, self.p_crit * 0.8, 100, endpoint=False),
np.geomspace(self.p_crit * 0.8, self.p_max, 100)
)

for v in isolines.round(8):
self.volume[v] = self._single_isochoric(
iterator, np.ones(len(iterator)) * 1 / v)
if v > self.v_crit * 1.2 and v < 1e-3 / CP.CoolProp.PropsSI("D", "P", self.p_trip, "Q", 1, self.fluid):
p_end = CP.CoolProp.PropsSI("P", "D|twophase", 1 / v, "Q", 0.2, self.fluid)
T_sat = CP.CoolProp.PropsSI("T", "D|twophase", 1 / v, "Q", 1, self.fluid)
iterators = [
('p', np.geomspace(self.p_trip, p_end, 80)),
('Q', np.geomspace(0.2, 1, 21)),
('T', np.linspace(T_sat, self.T_max, 99))
]
else:
iterators = [
('p', np.append(
np.geomspace(self.p_trip, self.p_crit * 0.8, 100, endpoint=False),
np.geomspace(self.p_crit * 0.8, self.p_max, 100)
))
]

self.volume[v] = self._single_isoline(iterators, "v", v)

def _isothermal(self):
"""Calculate an isoline of constant temperature."""
Expand Down Expand Up @@ -802,92 +808,107 @@ def calc_individual_isoline(
)

starting_point_value = self.convert_to_SI(
starting_point_value, starting_point_property)
starting_point_value, starting_point_property
)
ending_point_value = self.convert_to_SI(
ending_point_value, ending_point_property)
ending_point_value, ending_point_property
)

isoline_vector = np.linspace(isoline_value, isoline_value_end, 100)

if isoline_property == 'v':
isoline_value = 1 / isoline_value
isoline_value_end = 1 / isoline_value_end
isoline_property = 'D'
if starting_point_property == 'v':
starting_point_value = 1 / starting_point_value
starting_point_property = 'D'
if ending_point_property == 'v':
ending_point_value = 1 / ending_point_value
ending_point_property = 'D'

if isoline_property == 'D':

if starting_point_property == 'p':
pressure_start = starting_point_value
else:
pressure_start = CP.CoolProp.PropsSI(
'P', starting_point_property.upper(),
starting_point_value, 'D', isoline_value, self.fluid
)
self._update_state({
starting_point_property: starting_point_value,
isoline_property: isoline_value
})
pressure_start = self.state.p()

if ending_point_property == 'p':
pressure_end = ending_point_value
else:
pressure_end = CP.CoolProp.PropsSI(
'P', ending_point_property.upper(),
ending_point_value, 'D', isoline_value_end, self.fluid
)
self._update_state({
ending_point_property: ending_point_value,
isoline_property: isoline_value_end
})
pressure_end = self.state.p()

iterator = np.geomspace(pressure_start, pressure_end, 100)
iterator = [("p", np.geomspace(pressure_start, pressure_end, 100))]

elif isoline_property == 'T':
if starting_point_property == 's':
entropy_start = starting_point_value
else:
entropy_start = CP.CoolProp.PropsSI(
'S', starting_point_property.upper(),
starting_point_value, isoline_property.upper(),
isoline_value, self.fluid
)
self._update_state({
starting_point_property: starting_point_value,
isoline_property: isoline_value
})
entropy_start = self.state.smass()

if ending_point_property == 's':
entropy_end = ending_point_value
else:
entropy_end = CP.CoolProp.PropsSI(
'S', ending_point_property.upper(),
ending_point_value, isoline_property.upper(),
isoline_value_end, self.fluid
)
self._update_state({
ending_point_property: ending_point_value,
isoline_property: isoline_value_end
})
entropy_end = self.state.smass()

iterator = np.linspace(entropy_start, entropy_end, 100)
iterator = [("s", np.linspace(entropy_start, entropy_end, 100))]

else:
if starting_point_property == 'D':
density_start = starting_point_value
if starting_point_property == 'v':
density_start = 1 / starting_point_value
else:
density_start = CP.CoolProp.PropsSI(
'D', starting_point_property.upper(),
starting_point_value, isoline_property.upper(),
isoline_value, self.fluid
"D",
starting_point_property.upper(),
starting_point_value,
isoline_property.upper(),
isoline_value,
self.fluid
)

if ending_point_property == 'D':
density_end = ending_point_value
# self._update_state({
# starting_point_property: starting_point_value,
# isoline_property: isoline_value_end
# })
# density_start = self.state.rhomass()

if ending_point_property == 'v':
density_end = 1 / ending_point_value
else:
density_end = CP.CoolProp.PropsSI(
'D', ending_point_property.upper(),
ending_point_value, isoline_property.upper(),
isoline_value_end, self.fluid
"D",
ending_point_property.upper(),
ending_point_value,
isoline_property.upper(),
isoline_value,
self.fluid
)
# this produces a different result, no idea why
# self._update_state({
# ending_point_property: ending_point_value,
# isoline_property: isoline_value_end
# })
# density_end = self.state.rhomass()

if isoline_property == 'p':
density_range = np.geomspace(density_start, density_end, 100)
density_change = np.append(
0, np.diff(density_range)[::-1]
/ (density_range[0] - density_range[-1])
)
isoline_vector = (
isoline_value + density_change.cumsum()
* ( isoline_value - isoline_value_end)
)

iterator = np.geomspace(density_start, density_end, 100)

if isoline_property == 'p':
density_change = np.append(
0, np.diff(iterator)[::-1] / (iterator[0] - iterator[-1]))
isoline_vector = isoline_value + density_change.cumsum() * (
isoline_value - isoline_value_end)
else:
isoline_vector = np.linspace(isoline_value, isoline_value_end, 100)
iterator = [("v", 1 / np.geomspace(density_start, density_end, 100))]

datapoints = f(iterator, isoline_vector)
datapoints = f(iterator, isoline_property, isoline_vector)

for key in datapoints.keys():
datapoints[key] = self.convert_from_SI(datapoints[key], key)
Expand Down Expand Up @@ -1011,20 +1032,41 @@ def _single_isoline(self, iterators, isoline_property, isoline_value):
datapoints = {'h': [], 'T': [], 'v': [], 's': [], 'p': [], 'Q': []}

num_points = sum([len(_[1]) for _ in iterators])
datapoints[isoline_property] = np.ones(num_points) * isoline_value
if isinstance(isoline_value, float):
datapoints[isoline_property] = np.ones(num_points) * isoline_value
else:
if len(isoline_value) != num_points:
msg = (
"If you pass an array of isoline values instead of a "
"single value, the array length must match the length of "
"all iterators."
)
raise ValueError(msg)
datapoints[isoline_property] = isoline_value

for iterator_property, iterator_values in iterators:
# this is necessary because when changing the iterator
# CoolProp sometimes cannot find values
self.state.unspecify_phase()

datapoints[iterator_property] += iterator_values.tolist()

for value in iterator_values:
result_properties = (
set(datapoints.keys())
- {iterator_property, isoline_property}
)
for isoline_value, value in zip(datapoints[isoline_property], iterator_values):
try:
self._update_state({isoline_property: isoline_value, iterator_property: value})
self._update_state({
isoline_property: isoline_value,
iterator_property: value
})
success = True
except ValueError as e:
success = False

result = np.nan
for result_property in set(datapoints.keys()) - {iterator_property, isoline_property}:
for result_property in result_properties:
if success:
result = self._get_state_result_by_name(result_property)

Expand Down

0 comments on commit f73e48f

Please sign in to comment.