Skip to content

Commit

Permalink
Merge pull request #77 from j-c-cook/issue75_FluidProperties
Browse files Browse the repository at this point in the history
Properties module and fluid object
  • Loading branch information
MassimoCimmino authored Apr 10, 2021
2 parents a98cc24 + bb71e81 commit d48f310
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### New features

* [Issue 75](https://github.com/MassimoCimmino/pygfunction/issues/75) - New module `media` with properties of brine mixtures.
* [Issue 81](https://github.com/MassimoCimmino/pygfunction/issues/81) - Added functions to find a remove duplicate boreholes.

## Version 1.1.2 (2021-01-21)
Expand Down
10 changes: 10 additions & 0 deletions doc/source/media.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. media:
************
Media Module
************

.. automodule:: pygfunction.media
:members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions doc/source/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Modules
gfunction
heat_transfer
load_aggregation
media
networks
pipes
utilities
1 change: 1 addition & 0 deletions pygfunction/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from . import gfunction
from . import heat_transfer
from . import load_aggregation
from . import media
from . import networks
from . import pipes
from . import utilities
19 changes: 12 additions & 7 deletions pygfunction/examples/bore_field_thermal_resistance.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ def main():
# Fluid properties
# Total fluid mass flow rate per borehole (kg/s), from 0.01 kg/s to 1 kg/s
m_flow_boreholes = 10**np.arange(-2, 0.001, 0.05)
cp_f = 4000. # Fluid specific isobaric heat capacity (J/kg.K)
den_f = 1015. # Fluid density (kg/m3)
visc_f = 0.002 # Fluid dynamic viscosity (kg/m.s)
k_f = 0.5 # Fluid thermal conductivity (W/m.K)
# The fluid is propylene-glycol (20 %) at 20 degC
fluid = gt.media.Fluid('MPG', 20.)
cp_f = fluid.cp # Fluid specific isobaric heat capacity (J/kg.K)
den_f = fluid.rho # Fluid density (kg/m3)
visc_f = fluid.mu # Fluid dynamic viscosity (kg/m.s)
k_f = fluid.k # Fluid thermal conductivity (W/m.K)

# -------------------------------------------------------------------------
# Borehole field
Expand Down Expand Up @@ -96,11 +98,14 @@ def main():
SingleUTube = gt.pipes.SingleUTube(pos_pipes, rp_in, rp_out,
borehole, k_s, k_g, R_f + R_p)
UTubes.append(SingleUTube)
network = gt.networks.Network(
boreField[:nBoreholes],
UTubes[:nBoreholes],
bore_connectivity=bore_connectivity[:nBoreholes])

# Effective bore field thermal resistance
R_field = gt.pipes.field_thermal_resistance(
UTubes[:nBoreholes], bore_connectivity[:nBoreholes],
m_flow, cp_f)
R_field = gt.networks.network_thermal_resistance(
network, m_flow, cp_f)
# Add to result array
R[i,j] = R_field

Expand Down
10 changes: 6 additions & 4 deletions pygfunction/examples/equal_inlet_temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ def main():

# Fluid properties
m_flow = 0.25 # Total fluid mass flow rate per borehole (kg/s)
cp_f = 3977. # Fluid specific isobaric heat capacity (J/kg.K)
den_f = 1015. # Fluid density (kg/m3)
visc_f = 0.00203 # Fluid dynamic viscosity (kg/m.s)
k_f = 0.492 # Fluid thermal conductivity (W/m.K)
# The fluid is propylene-glycol (20 %) at 20 degC
fluid = gt.media.Fluid('MPG', 20.)
cp_f = fluid.cp # Fluid specific isobaric heat capacity (J/kg.K)
den_f = fluid.rho # Fluid density (kg/m3)
visc_f = fluid.mu # Fluid dynamic viscosity (kg/m.s)
k_f = fluid.k # Fluid thermal conductivity (W/m.K)

# Number of segments per borehole
nSegments = 12
Expand Down
10 changes: 6 additions & 4 deletions pygfunction/examples/fluid_temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ def main():

# Fluid properties
m_flow = 0.25 # Total fluid mass flow rate (kg/s)
cp_f = 3977. # Fluid specific isobaric heat capacity (J/kg.K)
den_f = 1015. # Fluid density (kg/m3)
visc_f = 0.00203 # Fluid dynamic viscosity (kg/m.s)
k_f = 0.492 # Fluid thermal conductivity (W/m.K)
# The fluid is propylene-glycol (20 %) at 20 degC
fluid = gt.media.Fluid('MPG', 20.)
cp_f = fluid.cp # Fluid specific isobaric heat capacity (J/kg.K)
den_f = fluid.rho # Fluid density (kg/m3)
visc_f = fluid.mu # Fluid dynamic viscosity (kg/m.s)
k_f = fluid.k # Fluid thermal conductivity (W/m.K)

# Number of segments per borehole
nSegments = 12
Expand Down
13 changes: 8 additions & 5 deletions pygfunction/examples/fluid_temperature_multiple_boreholes.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ def main():
# Fluid properties
m_flow_borehole = 0.25 # Total fluid mass flow rate per borehole (kg/s)
m_flow = m_flow_borehole*N_1*N_2 # Total fluid mass flow rate (kg/s)
cp_f = 3977. # Fluid specific heat capacity (J/kg.K)
den_f = 1015. # Fluid density (kg/m3)
visc_f = 0.00203 # Fluid dynamic viscosity (kg/m.s)
k_f = 0.492 # Fluid thermal conductivity (W/m.K)
# The fluid is propylene-glycol (20 %) at 20 degC
fluid = gt.media.Fluid('MPG', 20.)
cp_f = fluid.cp # Fluid specific isobaric heat capacity (J/kg.K)
den_f = fluid.rho # Fluid density (kg/m3)
visc_f = fluid.mu # Fluid dynamic viscosity (kg/m.s)
k_f = fluid.k # Fluid thermal conductivity (W/m.K)

# Number of segments per borehole
nSegments = 12
Expand Down Expand Up @@ -192,7 +194,8 @@ def main():
nz = 20
it = 8724
z = np.linspace(0., H, num=nz)
T_f = UTubes[0].get_temperature(z, T_f_in[it], T_b[it], m_flow, cp_f)
T_f = UTubes[0].get_temperature(
z, T_f_in[it], T_b[it], m_flow_borehole, cp_f)

plt.rc('figure')
fig = plt.figure()
Expand Down
10 changes: 6 additions & 4 deletions pygfunction/examples/mixed_inlet_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ def main():

# Fluid properties
m_flow = 0.25 # Total fluid mass flow rate in network (kg/s)
cp_f = 4000. # Fluid specific isobaric heat capacity (J/kg.K)
den_f = 1015. # Fluid density (kg/m3)
visc_f = 0.002 # Fluid dynamic viscosity (kg/m.s)
k_f = 0.5 # Fluid thermal conductivity (W/m.K)
# The fluid is propylene-glycol (20 %) at 20 degC
fluid = gt.media.Fluid('MPG', 20.)
cp_f = fluid.cp # Fluid specific isobaric heat capacity (J/kg.K)
den_f = fluid.rho # Fluid density (kg/m3)
visc_f = fluid.mu # Fluid dynamic viscosity (kg/m.s)
k_f = fluid.k # Fluid thermal conductivity (W/m.K)

# Number of segments per borehole
nSegments = 12
Expand Down
192 changes: 192 additions & 0 deletions pygfunction/media.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
from __future__ import absolute_import, division, print_function

from CoolProp.CoolProp import PropsSI
import warnings


class Fluid:
"""
An object for handling the fluid properties
Parameters
----------
mixer: str
The mixer for this application should be one of:
- 'Water' - Complete water solution
- 'MEG' - Ethylene glycol mixed with water
- 'MPG' - Propylene glycol mixed with water
- 'MEA' - Ethanol mixed with water
- 'MMA' - Methanol mixed with water
percent: float
Mass fraction of the mixing fluid added to water (in %).
Lower bound = 0. Upper bound is dependent on the mixture.
T: float, optional
The temperature of the fluid (in Celcius).
Default is 20 degC.
P: float, optional
The pressure of the fluid (in Pa).
Default is 101325 Pa.
Examples
----------
>>> import pygfunction as gt
>>> T = 20. # Temp at 20 C
>>> gage_P = 20 # PsiG
>>> atm_P = 14.69595
>>> P = (gage_P + atm_P) * 6894.75728 # Pressure in Pa
>>> # complete water solution
>>> mix = 'Water'
>>> percent = 0
>>> fluid = gt.media.Fluid(mix, percent, T=T, P=P)
>>> print(fluid)
>>> # 20 % propylene glycol mixed with water
>>> mix = 'MPG'
>>> percent = 20
>>> fluid = gt.media.Fluid(mix, percent, T=T, P=P)
>>> # 60% ethylene glycol mixed with water
>>> mix = 'MEG'
>>> percent = 60
>>> fluid = gt.media.Fluid(mix, percent, T=T, P=P)
>>> print(fluid)
>>> # 5% methanol mixed with water water
>>> mix = 'MMA'
>>> percent = 5
>>> fluid = gt.media.Fluid(mix, percent, T=T, P=P)
>>> print(fluid)
>>> # ethanol / water
>>> mix = 'MEA'
>>> percent = 10
>>> fluid = gt.media.Fluid(mix, percent, T=T, P=P)
>>> print(fluid)
"""
def __init__(self, mixer: str, percent: float,
T: float = 20., P: float = 101325.,):
if mixer == 'Water':
self.fluid_mix = mixer
elif mixer in ['MEG', 'MPG', 'MMA', 'MEA']: # Expected brines
self.fluid_mix = 'INCOMP::' + mixer + '-' + str(percent) + '%'
else:
warnings.warn('It is unknown whether or not cool props has the '
'mixing fluid requested, proceed with caution.')
# Initialize all fluid properties
# Temperature of the fluid (in Celsius)
self.T_C = T
# Temperature of the fluid (in Kelvin)
self.T_K = T + 273.15
# Pressure of the fluid (in Pa)
self.P = P
# Density (in kg/m3)
self.rho = self.density()
# Dynamic viscosity (in Pa.s, or N.s/m2)
self.mu = self.dynamic_viscosity()
# Kinematic viscosity (in m2/s)
self.nu = self.kinematic_viscosity()
# Specific isobaric heat capacity (J/kg.K)
self.cp = self.specific_heat_capacity()
# Volumetric heat capacity (in J/m3.K)
self.rhoCp = self.volumetric_heat_capacity()
# Thermal conductivity (in W/m.K)
self.k = self.thermal_conductivity()
# Prandlt number
self.Pr = self.Prandlt_number()

def __repr__(self):
return str(self.__class__) + '\n' + '\n'.join(
(str(item) + ' = ' + '{}'.format(
self.__dict__[item]) for item in sorted(self.__dict__)))

def append_to_dict(self, dnary):
if len(list(dnary.keys())) == 0:
for item in sorted(self.__dict__):
dnary[item] = []
for item in sorted(self.__dict__):
dnary[item].append('{:.5E}'.format(self.__dict__[item]))

def density(self):
"""
Returns the density of the fluid (in kg/m3).
Returns
-------
rho : float
Density (in kg/m3).
"""
return PropsSI('D', 'T', self.T_K, 'P', self.P, self.fluid_mix)

def dynamic_viscosity(self):
"""
Returns the dynamic viscosity of the fluid (in Pa.s, or N.s/m2).
Returns
-------
mu : float
Dynamic viscosity (in Pa.s, or N.s/m2).
"""
return PropsSI('V', 'T', self.T_K, 'P', self.P, self.fluid_mix)

def kinematic_viscosity(self):
"""
Returns the kinematic viscosity of the fluid (in m2/s).
Returns
-------
nu : float
Kinematic viscosity (in m2/s).
"""
return self.mu / self.rho

def specific_heat_capacity(self):
"""
Returns the specific isobaric heat capacity of the fluid (J/kg.K).
Returns
-------
cp : float
Specific isobaric heat capacity (J/kg.K).
"""
return PropsSI('C', 'T', self.T_K, 'P', self.P, self.fluid_mix)

def volumetric_heat_capacity(self):
"""
Returns the volumetric heat capacity of the fluid (J/m3.K).
Returns
-------
rhoCp : float
Volumetric heat capacity (in J/m3.K).
"""
return self.rho * self.cp

def thermal_conductivity(self):
"""
Returns the thermal conductivity of the fluid (in W/m.K).
Returns
-------
k : float
Thermal conductivity (in W/m.K).
"""
return PropsSI('L', 'T', self.T_K, 'P', self.P, self.fluid_mix)

def Prandlt_number(self):
"""
Returns the Prandtl of the fluid.
Returns
-------
Pr : float
Prandlt number.
"""
return PropsSI('PRANDTL', 'T', self.T_K, 'P', self.P, self.fluid_mix)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
numpy
scipy
matplotlib
CoolProp

0 comments on commit d48f310

Please sign in to comment.