Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properties module and fluid object #77

Merged
merged 13 commits into from
Apr 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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