[iapws] 13/16: new upstream 1.2

Alastair McKinstry mckinstry at moszumanska.debian.org
Thu Apr 20 10:51:09 UTC 2017


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to branch debian/master
in repository iapws.

commit b34da5371eae7b16dbacf4b8f4303df9e845bfaa
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Thu Apr 20 11:45:40 2017 +0100

    new upstream 1.2
---
 PKG-INFO                   |  349 ++---
 README.rst                 |  343 +----
 iapws.egg-info/PKG-INFO    |  349 ++---
 iapws.egg-info/SOURCES.txt |    3 +
 iapws/__init__.py          |   12 +-
 iapws/_iapws.py            | 1460 +++++++++++++++++---
 iapws/_utils.py            |  216 +++
 iapws/ammonia.py           |  891 +++++++++++++
 iapws/humidAir.py          |  983 ++++++++++++++
 iapws/iapws08.py           |  634 +++++++--
 iapws/iapws95.py           | 2155 ++++++++++++++++++++----------
 iapws/iapws97.py           | 3163 +++++++++++++++++++++++++++++++++-----------
 setup.cfg                  |    1 -
 13 files changed, 7942 insertions(+), 2617 deletions(-)

diff --git a/PKG-INFO b/PKG-INFO
index f189454..d8d6fbe 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,23 +1,49 @@
 Metadata-Version: 1.1
 Name: iapws
-Version: 1.1.3
+Version: 1.2
 Summary: Python implementation of standards from The InternationalAssociation for the Properties of Water and Steam
 Home-page: https://github.com/jjgomera/iapws
 Author: jjgomera
 Author-email: jjgomera at gmail.com
 License: gpl v3
-Download-URL: https://github.com/jjgomera/iapws/tarball/v1.1.3
-Description: iapws
+Download-URL: https://github.com/jjgomera/iapws/tarball/v1.2
+Description: .. image:: https://api.travis-ci.org/jjgomera/iapws.svg?branch=master
+            :target: https://travis-ci.org/jjgomera/iapws
+            :alt: Build Status
+        
+        .. image:: https://ci.appveyor.com/api/projects/status/a128sh8e50cjsiya?svg=true
+            :target: https://ci.appveyor.com/project/jjgomera/iapws
+            :alt: Windows Build Status
+        
+        .. image:: https://coveralls.io/repos/github/jjgomera/iapws/badge.svg?branch=master
+            :target: https://coveralls.io/github/jjgomera/iapws?branch=master
+            :alt: coveralls.io analysis
+        
+        .. image:: https://codecov.io/gh/jjgomera/iapws/branch/master/graph/badge.svg
+            :target: https://codecov.io/gh/jjgomera/iapws
+            :alt: codecov.io analysis
+        
+        .. image:: https://landscape.io/github/jjgomera/iapws/master/landscape.svg?style=flat
+           :target: https://landscape.io/github/jjgomera/iapws/master
+           :alt: Code Health
+        
+        .. image:: http://readthedocs.org/projects/iapws/badge/?version=latest
+            :target: http://iapws.readthedocs.io/en/latest/?badge=latest
+            :alt: Documentation Status
+        
+        iapws
         =====
         
-        Python implementation of standard from IAPWS (http://www.iapws.org/release.html). The available standard are::
+        Python implementation of standard from IAPWS (http://www.iapws.org/release.html). The module implements the full set of standards, including::
         
             IAPWS-IF97
             IAPWS-95
             IAPWS-06 for Ice
             IAPWS-08 for seawater
             IAPWS-05 for Heavy water
+            ...
             
+        
         dependences
         --------------------
         
@@ -28,92 +54,30 @@ Description: iapws
         install
         --------------------
         
-        In debian you can find in official repositories in testing and sid. In stable you can install using pip::
+        In debian you can find in official repositories in jessie, testing and sid. In ubuntu it's in official repositories from ubuntu saucy (13.10). In other system you can install using pip::
         
         	pip install iapws
+         
+        or directly cloning the github repository::
         
-        In ubuntu it's in official repositories from ubuntu saucy (13.10)
-        
-        In other SO you can download from its webpage in `pypi <http://pypi.python.org/pypi/iapws>`_ and unzipped in python folder dist-packages. This is the recommended options to have the latest version.
-        
-        
-        TODO
-        --------------------
+            git clone https://github.com/jjgomera/iapws.git
         
-        Improve convergence in two phase region for IAPWS95 and D2O class
+        and adding the folder to a python path. This is the recommended option to have the latest version.
         
         
-        IAPWS-IF97
+        documentation
         --------------------
+         
+        To see the full documentation of package, see `readthedocs <http://iapws.readthedocs.io/>`__
         
-        Class to model a state for liquid water or steam with the Industrial Formulation IAPWS-IF97
+        .. inclusion-marker-do-not-remove
         
-        Incoming properties:
+        For a rapid usage demostration, see this examples 
         
-        * T, Temperature, K
-        * P, Pressure, MPa
-        * h, Specific enthalpy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * x, Quality, [-]
-            
-        Definitions options:
-        
-        * T, P (Not valid for two-phases region)
-        * P, h
-        * P, s
-        * h, s
-        * T, x (Only for two-phases region)
-        * P, x (Only for two-phases region)
-            
-        Properties:
-        
-        * P, Pressure, MPa
-        * T, Temperature, K
-        * g, Specific Gibbs free energy, kJ/kg
-        * a, Specific Helmholtz free energy, kJ/kg
-        * v, Specific volume, m³/kg
-        * rho, Density, kg/m³
-        * x, quality, [-]
-        * h, Specific enthalpy, kJ/kg
-        * u, Specific internal energy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * cp, Specific isobaric heat capacity, kJ/kg·K
-        * cv, Specific isochoric heat capacity, kJ/kg·K
-        * Z, Compression factor. [-]
-        * gamma, Isoentropic exponent, [-]
-        * alfav, Isobaric cubic expansion coefficient, 1/K
-        * kt, Isothermal compressibility, 1/MPa
-        * alfap, Relative pressure coefficient, 1/K
-        * betap, Isothermal stress coefficient, kg/m³
-        * joule, Joule-Thomson coefficient, K/MPa
-        * deltat, Isothermal throttling coefficient, kJ/kg·MPa
-        * region, Region
-        
-        * v0, Ideal specific volume, m³/kg
-        * u0, Ideal specific internal energy, kJ/kg
-        * h0, Ideal specific enthalpy, kJ/kg
-        * s0, Ideal specific entropy, kJ/kg·K
-        * a0, Ideal specific Helmholtz free energy, kJ/kg
-        * g0, Ideal specific Gibbs free energy, kJ/kg
-        * cp0, Ideal specific isobaric heat capacity, kJ/kg·K
-        * cv0, Ideal specific isochoric heat capacity, kJ/kg·K
-        * w0, Ideal speed of sound, m/s
-        * gamma0, Ideal isoentropic exponent [-]
-            
-        * w, Speed of sound, m/s
-        * mu, Dynamic viscosity, Pa·s
-        * nu, Kinematic viscosity, m²/s
-        * k, Thermal conductivity, W/m·K
-        * alfa, Thermal diffusivity, m²/s
-        * sigma, Surface tension, N/m
-        * epsilon, Dielectric constant, [-]
-        * n, Refractive index, [-]
-        * Prandt, Prandtl number, [-]
-        * Tr, Reduced temperature, [-]
-        * Pr, Reduced pressure, [-]
         
+        IAPWS-IF97
         
-        Usage::
+        .. code:: python
         
         	from iapws import IAPWS97
         	sat_steam=IAPWS97(P=1,x=1)                #saturated steam with known P
@@ -121,221 +85,60 @@ Description: iapws
         	steam=IAPWS97(P=2.5, T=500)               #steam with known P and T
         	print(sat_steam.h, sat_liquid.h, steam.h) #calculated enthalpies
             
-            
-            
+        
         IAPWS-95
-        --------------------------------
-        
-        Class to model a state for liquid water or steam with the general and scientific formulation IAPWS-95
-        
-        Incoming properties:
-        
-        * T, Temperature, K
-        * P, Pressure, MPa
-        * rho, Density, kg/m3
-        * v, Specific volume, m3/kg
-        * h, Specific enthalpy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * x, Quality, [-]
-        * l, Optional parameter to light wavelength for Refractive index, mm
-        
-        rho and v are equivalent, only one can be defined
-        Definitions options:
-        
-        * T, P (Not valid for two-phases region)
-        * T, rho
-        * T, h
-        * T, s
-        * T, u
-        * P, rho
-        * P, h
-        * P, s
-        * P, u
-        * rho, h
-        * rho, s
-        * rho, u
-        * h, s
-        * h, u
-        * s, u
-        * T, x (Only for two-phases region)
-        * P, x (Only for two-phases region) Very slow
-        
-        Properties:
-        
-        * P,  Pressure, MPa
-        * Pr, Reduced pressure, [-]
-        * T, Temperature, K
-        * Tr, Reduced temperature, [-]
-        * x, Quality, [-]
-        * v, Specific volume, m³/kg
-        * rho, Density, kg/m³
-        * h, Specific enthalpy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * u, Specific internal energy, kJ/kg
-        * g, Specific Gibbs free energy, kJ/kg
-        * a, Specific Helmholtz free energy, kJ/kg
-        * cp, Specific isobaric heat capacity, kJ/kg·K
-        * cv, Specific isochoric heat capacity, kJ/kg·K
-        * cp_cv, Heat capacity ratio, [-]
-        * w, Speed of sound, m/s
-        * Z, Compression factor, [-]
-        * fi, Fugacity coefficient, [-]
-        * f, Fugacity, MPa
-        * gamma, Isoentropic exponent, [-]
-        
-        * alfav, Thermal expansion coefficient (Volume expansivity), 1/K
-        * kappa, Isothermal compressibility, 1/MPa
-        * alfap, Relative pressure coefficient, 1/K
-        * betap, Isothermal stress coefficient, kg/m³
-        * betas, Isoentropic temperature-pressure coefficient, [-]
-        * joule, Joule-Thomson coefficient, K/MPa
-        * Gruneisen, Gruneisen parameter, [-]
-        * virialB, Second virial coefficient, m³/kg
-        * virialC, Third virial coefficient, m⁶/kg²
-        * dpdT_rho, Derivatives, dp/dT at constant rho, MPa/K
-        * dpdrho_T, Derivatives, dp/drho at constant T, MPa·m³/kg
-        * drhodT_P, Derivatives, drho/dT at constant P, kg/m³·K
-        * drhodP_T, Derivatives, drho/dP at constant T, kg/m³·MPa
-        * dhdT_rho, Derivatives, dh/dT at constant rho, kJ/kg·K
-        * dhdP_T, Isothermal throttling coefficient, kJ/kg·MPa
-        * dhdT_P, Derivatives, dh/dT at constant P, kJ/kg·K
-        * dhdrho_T, Derivatives, dh/drho at constant T, kJ·m³/kg²
-        * dhdrho_P, Derivatives, dh/drho at constant P, kJ·m³/kg²
-        * dhdP_rho, Derivatives, dh/dP at constant rho, kJ/kg·MPa
-        * kt, Isothermal Expansion Coefficient, [-]
-        * ks, Adiabatic Compressibility, 1/MPa
-        * Ks, Adiabatic bulk modulus, MPa
-        * Kt, Isothermal bulk modulus, MPa
-        
-        * Hvap, Vaporization heat, kJ/kg
-        * Z_rho, (Z-1) over the density, m³/kg
-        * IntP,  Internal pressure, MPa
-        * invT, Negative reciprocal temperature, 1/K
-        * hInput, Specific heat input, kJ/kg
-        
-        * mu, Dynamic viscosity, Pa·s
-        * nu, Kinematic viscosity, m²/s
-        * k, Thermal conductivity, W/m·K
-        * sigma, Surface tension, N/m
-        * alfa, Thermal diffusivity, m²/s
-        * Pramdt, Prandtl number, [-]
-        * epsilon, Dielectric constant, [-]
-        * n, Refractive index, [-]
-        
-        * v0, Ideal gas Specific volume, m³/kg
-        * rho0, Ideal gas Density, kg/m³
-        * h0, Ideal gas Specific enthalpy, kJ/kg
-        * u0, Ideal gas Specific internal energy, kJ/kg
-        * s0, Ideal gas Specific entropy, kJ/kg·K
-        * a0, Ideal gas Specific Helmholtz free energy, kJ/kg
-        * g0, Ideal gas Specific Gibbs free energy, kJ/kg
-        * cp0, Ideal gas Specific isobaric heat capacity, kJ/kg·K
-        * cv0, Ideal gas Specific isochoric heat capacity, kJ/kg·K
-        * cp0_cv, Ideal gas Heat capacity ratio, [-]
-        * gamma0, Ideal gas Isoentropic exponent, [-]
-        
-        
-        Usage::
+        
+        .. code:: python
         
         	from iapws import IAPWS95
         	sat_steam=IAPWS95(P=1,x=1)                #saturated steam with known P
         	sat_liquid=IAPWS95(T=370, x=0)            #saturated liquid with known T
         	steam=IAPWS95(P=2.5, T=500)               #steam with known P and T
         	print(sat_steam.h, sat_liquid.h, steam.h) #calculated enthalpies
+            
+        
+        IAPWS-05 for Heavy water
+        
+        .. code:: python
+        
+        	from iapws import D2O
+        	sat_liquid=D2O(T=370, x=0)            #saturated liquid with known T
+        	print(sat_liquid.h)                   #calculated enthalpy
         
         
-            
         IAPWS-06 for Ice Ih
-        --------------------------------------------
-        
-        There is too implemented a function to calculate properties of ice Ih from 2009 revision, in this case only let temperature and pressure as input for calculate properties, the function return a dict with properties available:
-        
-        * P, Pressure, MPa
-        * T, Temperature, K
-        * v, Specific volume, m³/kg
-        * rho, Density, kg/m³
-        * g, Specific Gibbs free energy, kJ/kg
-        * a, Specific Helmholtz free energy, kJ/kg
-        * h, Specific enthalpy, kJ/kg
-        * u, Specific internal energy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * cp, Specific isobaric heat capacity, kJ/kg·K
-        * alfa, Cubic expansion coefficient, 1/K
-        * beta, Pressure coefficient, MPa/K
-        * kt, Isothermal compressibility, MPa
-        * ks, Isentropic compressibility, MPa
         
-            
-        Usage::
-            
+        .. code:: python
+        
             from iapws import _Ice
             ice=_Ice(273.15, 0.101325)            #Ice at normal melting point
             print(ice["rho"])                     #Calculated density
         
-            
-        IAPWS-05 for Heavy water
-        --------------------------------------------
-        
-        Same properties as for  IAPWS-95
-        Reference state set at liquid at normal boiling point (1 atm)
         
-        Usage::
+        IAPWS-08 for seawater
         
-        	from iapws import D2O
-        	sat_liquid=D2O(T=370, x=0)            #saturated liquid with known T
-        	print(sat_liquid.h) #calculated enthalpy
+        .. code:: python
         
-            
-        IAPWS-08 for seawater
-        --------------------------------------------
-        
-        Incoming properties:
-        
-        * T: Temperature, K
-        * P: Pressure, MPa
-        * S: Salinity, kg/kg
-        
-        S is the Reference-Composition Salinity as defined in Millero, F.J., R. Feistel, D.G. Wright and T.J. McDougall, "The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale", Deep-Sea Res. I 55, 50 (2008).
-        
-        Calculated properties:
-        
-        * T: Temperature, K
-        * P: Pressure, MPa
-        * rho: Density, kg/m³
-        * v: Specific volume, m³/kg
-        * h: Specific enthalpy, kJ/kg
-        * s: Specific entropy, kJ/kg·K
-        * u: Specific internal energy, kJ/kg
-        * g: Specific Gibbs free energy, kJ/kg
-        * a: Specific Helmholtz free energy, kJ/kg
-        * cp: Specific isobaric heat capacity, kJ/kg·K
-        
-        * gt: Derivative Gibbs energy with temperature, kJ/kg·K
-        * gp: Derivative Gibbs energy with pressure, m³/kg
-        * gtt: Derivative Gibbs energy with temperature square, kJ/kg·K²
-        * gtp: Derivative Gibbs energy with pressure and temperature, m³/kg·K
-        * gpp: Derivative Gibbs energy with temperature square, m³/kg·MPa
-        * gs: Derivative Gibbs energy with salinity, kJ/kg
-        * gsp: Derivative Gibbs energy with salinity and pressure, m³/kg
-        
-        * alfa: Thermal expansion coefficient, 1/K
-        * betas: Isentropic temperature-pressure coefficient, K/MPa
-        * kt: Isothermal compressibility, 1/MPa
-        * ks: Isentropic compressibility, 1/MPa
-        * w: Sound Speed, m/s
-        
-        * mu: Relative chemical potential, kJ/kg
-        * muw: Chemical potential of H2O, kJ/kg
-        * mus: Chemical potential of sea salt, kJ/kg
-        * osm: Osmotic coefficient, [-]
-        * haline: Haline contraction coefficient, kg/kg
-        
-                
-        Usage::
-            
             from iapws import SeaWater
             state = SeaWater(T=300, P=0.101325, S=0.001)    #Seawater with 0.1% Salinity
-            print(state.cp)     # Get cp
+            print(state.cp)                                 # Get cp
+        
+        
+        TODO
+        ====
+        
+        * FIXME: Electrolytic conductiviy
+        * TODO: Improve convergence in two phase region for IAPWS95 and D2O class
+        * TODO: Implement SBTL method for fast calculation
+        * TODO: Implement TTSE method for fast calculation
+        
+        Ammonia-water mixture:
+        
+        * FIXME: Ammonia-water mixture residual helmholtz. The values are good, bad difer by 1%
+        * TODO: Add equilibrium routine
+        
+        I've tried to test all code and use all values for computer verification the standards give, but anyway the code can have hidden problem.
+        For any suggestions, comments, bugs ... you can usage the `github issue section <https://github.com/jjgomera/iapws/issues>`__, or contact directly with me at `email <jjgomera at gmail.com>`__.
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff --git a/README.rst b/README.rst
index e97406b..c700feb 100644
--- a/README.rst
+++ b/README.rst
@@ -1,14 +1,40 @@
+.. image:: https://api.travis-ci.org/jjgomera/iapws.svg?branch=master
+    :target: https://travis-ci.org/jjgomera/iapws
+    :alt: Build Status
+
+.. image:: https://ci.appveyor.com/api/projects/status/a128sh8e50cjsiya?svg=true
+    :target: https://ci.appveyor.com/project/jjgomera/iapws
+    :alt: Windows Build Status
+
+.. image:: https://coveralls.io/repos/github/jjgomera/iapws/badge.svg?branch=master
+    :target: https://coveralls.io/github/jjgomera/iapws?branch=master
+    :alt: coveralls.io analysis
+
+.. image:: https://codecov.io/gh/jjgomera/iapws/branch/master/graph/badge.svg
+    :target: https://codecov.io/gh/jjgomera/iapws
+    :alt: codecov.io analysis
+
+.. image:: https://landscape.io/github/jjgomera/iapws/master/landscape.svg?style=flat
+   :target: https://landscape.io/github/jjgomera/iapws/master
+   :alt: Code Health
+
+.. image:: http://readthedocs.org/projects/iapws/badge/?version=latest
+    :target: http://iapws.readthedocs.io/en/latest/?badge=latest
+    :alt: Documentation Status
+
 iapws
 =====
 
-Python implementation of standard from IAPWS (http://www.iapws.org/release.html). The available standard are::
+Python implementation of standard from IAPWS (http://www.iapws.org/release.html). The module implements the full set of standards, including::
 
     IAPWS-IF97
     IAPWS-95
     IAPWS-06 for Ice
     IAPWS-08 for seawater
     IAPWS-05 for Heavy water
+    ...
     
+
 dependences
 --------------------
 
@@ -19,92 +45,30 @@ dependences
 install
 --------------------
 
-In debian you can find in official repositories in testing and sid. In stable you can install using pip::
+In debian you can find in official repositories in jessie, testing and sid. In ubuntu it's in official repositories from ubuntu saucy (13.10). In other system you can install using pip::
 
 	pip install iapws
+ 
+or directly cloning the github repository::
 
-In ubuntu it's in official repositories from ubuntu saucy (13.10)
-
-In other SO you can download from its webpage in `pypi <http://pypi.python.org/pypi/iapws>`_ and unzipped in python folder dist-packages. This is the recommended options to have the latest version.
-
-
-TODO
---------------------
+    git clone https://github.com/jjgomera/iapws.git
 
-Improve convergence in two phase region for IAPWS95 and D2O class
+and adding the folder to a python path. This is the recommended option to have the latest version.
 
 
-IAPWS-IF97
+documentation
 --------------------
+ 
+To see the full documentation of package, see `readthedocs <http://iapws.readthedocs.io/>`__
 
-Class to model a state for liquid water or steam with the Industrial Formulation IAPWS-IF97
+.. inclusion-marker-do-not-remove
 
-Incoming properties:
+For a rapid usage demostration, see this examples 
 
-* T, Temperature, K
-* P, Pressure, MPa
-* h, Specific enthalpy, kJ/kg
-* s, Specific entropy, kJ/kg·K
-* x, Quality, [-]
-    
-Definitions options:
-
-* T, P (Not valid for two-phases region)
-* P, h
-* P, s
-* h, s
-* T, x (Only for two-phases region)
-* P, x (Only for two-phases region)
-    
-Properties:
-
-* P, Pressure, MPa
-* T, Temperature, K
-* g, Specific Gibbs free energy, kJ/kg
-* a, Specific Helmholtz free energy, kJ/kg
-* v, Specific volume, m³/kg
-* rho, Density, kg/m³
-* x, quality, [-]
-* h, Specific enthalpy, kJ/kg
-* u, Specific internal energy, kJ/kg
-* s, Specific entropy, kJ/kg·K
-* cp, Specific isobaric heat capacity, kJ/kg·K
-* cv, Specific isochoric heat capacity, kJ/kg·K
-* Z, Compression factor. [-]
-* gamma, Isoentropic exponent, [-]
-* alfav, Isobaric cubic expansion coefficient, 1/K
-* kt, Isothermal compressibility, 1/MPa
-* alfap, Relative pressure coefficient, 1/K
-* betap, Isothermal stress coefficient, kg/m³
-* joule, Joule-Thomson coefficient, K/MPa
-* deltat, Isothermal throttling coefficient, kJ/kg·MPa
-* region, Region
-
-* v0, Ideal specific volume, m³/kg
-* u0, Ideal specific internal energy, kJ/kg
-* h0, Ideal specific enthalpy, kJ/kg
-* s0, Ideal specific entropy, kJ/kg·K
-* a0, Ideal specific Helmholtz free energy, kJ/kg
-* g0, Ideal specific Gibbs free energy, kJ/kg
-* cp0, Ideal specific isobaric heat capacity, kJ/kg·K
-* cv0, Ideal specific isochoric heat capacity, kJ/kg·K
-* w0, Ideal speed of sound, m/s
-* gamma0, Ideal isoentropic exponent [-]
-    
-* w, Speed of sound, m/s
-* mu, Dynamic viscosity, Pa·s
-* nu, Kinematic viscosity, m²/s
-* k, Thermal conductivity, W/m·K
-* alfa, Thermal diffusivity, m²/s
-* sigma, Surface tension, N/m
-* epsilon, Dielectric constant, [-]
-* n, Refractive index, [-]
-* Prandt, Prandtl number, [-]
-* Tr, Reduced temperature, [-]
-* Pr, Reduced pressure, [-]
 
+IAPWS-IF97
 
-Usage::
+.. code:: python
 
 	from iapws import IAPWS97
 	sat_steam=IAPWS97(P=1,x=1)                #saturated steam with known P
@@ -112,218 +76,57 @@ Usage::
 	steam=IAPWS97(P=2.5, T=500)               #steam with known P and T
 	print(sat_steam.h, sat_liquid.h, steam.h) #calculated enthalpies
     
-    
-    
+
 IAPWS-95
---------------------------------
-
-Class to model a state for liquid water or steam with the general and scientific formulation IAPWS-95
-
-Incoming properties:
-
-* T, Temperature, K
-* P, Pressure, MPa
-* rho, Density, kg/m3
-* v, Specific volume, m3/kg
-* h, Specific enthalpy, kJ/kg
-* s, Specific entropy, kJ/kg·K
-* x, Quality, [-]
-* l, Optional parameter to light wavelength for Refractive index, mm
-
-rho and v are equivalent, only one can be defined
-Definitions options:
-
-* T, P (Not valid for two-phases region)
-* T, rho
-* T, h
-* T, s
-* T, u
-* P, rho
-* P, h
-* P, s
-* P, u
-* rho, h
-* rho, s
-* rho, u
-* h, s
-* h, u
-* s, u
-* T, x (Only for two-phases region)
-* P, x (Only for two-phases region) Very slow
-
-Properties:
-
-* P,  Pressure, MPa
-* Pr, Reduced pressure, [-]
-* T, Temperature, K
-* Tr, Reduced temperature, [-]
-* x, Quality, [-]
-* v, Specific volume, m³/kg
-* rho, Density, kg/m³
-* h, Specific enthalpy, kJ/kg
-* s, Specific entropy, kJ/kg·K
-* u, Specific internal energy, kJ/kg
-* g, Specific Gibbs free energy, kJ/kg
-* a, Specific Helmholtz free energy, kJ/kg
-* cp, Specific isobaric heat capacity, kJ/kg·K
-* cv, Specific isochoric heat capacity, kJ/kg·K
-* cp_cv, Heat capacity ratio, [-]
-* w, Speed of sound, m/s
-* Z, Compression factor, [-]
-* fi, Fugacity coefficient, [-]
-* f, Fugacity, MPa
-* gamma, Isoentropic exponent, [-]
-
-* alfav, Thermal expansion coefficient (Volume expansivity), 1/K
-* kappa, Isothermal compressibility, 1/MPa
-* alfap, Relative pressure coefficient, 1/K
-* betap, Isothermal stress coefficient, kg/m³
-* betas, Isoentropic temperature-pressure coefficient, [-]
-* joule, Joule-Thomson coefficient, K/MPa
-* Gruneisen, Gruneisen parameter, [-]
-* virialB, Second virial coefficient, m³/kg
-* virialC, Third virial coefficient, m⁶/kg²
-* dpdT_rho, Derivatives, dp/dT at constant rho, MPa/K
-* dpdrho_T, Derivatives, dp/drho at constant T, MPa·m³/kg
-* drhodT_P, Derivatives, drho/dT at constant P, kg/m³·K
-* drhodP_T, Derivatives, drho/dP at constant T, kg/m³·MPa
-* dhdT_rho, Derivatives, dh/dT at constant rho, kJ/kg·K
-* dhdP_T, Isothermal throttling coefficient, kJ/kg·MPa
-* dhdT_P, Derivatives, dh/dT at constant P, kJ/kg·K
-* dhdrho_T, Derivatives, dh/drho at constant T, kJ·m³/kg²
-* dhdrho_P, Derivatives, dh/drho at constant P, kJ·m³/kg²
-* dhdP_rho, Derivatives, dh/dP at constant rho, kJ/kg·MPa
-* kt, Isothermal Expansion Coefficient, [-]
-* ks, Adiabatic Compressibility, 1/MPa
-* Ks, Adiabatic bulk modulus, MPa
-* Kt, Isothermal bulk modulus, MPa
-
-* Hvap, Vaporization heat, kJ/kg
-* Z_rho, (Z-1) over the density, m³/kg
-* IntP,  Internal pressure, MPa
-* invT, Negative reciprocal temperature, 1/K
-* hInput, Specific heat input, kJ/kg
-
-* mu, Dynamic viscosity, Pa·s
-* nu, Kinematic viscosity, m²/s
-* k, Thermal conductivity, W/m·K
-* sigma, Surface tension, N/m
-* alfa, Thermal diffusivity, m²/s
-* Pramdt, Prandtl number, [-]
-* epsilon, Dielectric constant, [-]
-* n, Refractive index, [-]
-
-* v0, Ideal gas Specific volume, m³/kg
-* rho0, Ideal gas Density, kg/m³
-* h0, Ideal gas Specific enthalpy, kJ/kg
-* u0, Ideal gas Specific internal energy, kJ/kg
-* s0, Ideal gas Specific entropy, kJ/kg·K
-* a0, Ideal gas Specific Helmholtz free energy, kJ/kg
-* g0, Ideal gas Specific Gibbs free energy, kJ/kg
-* cp0, Ideal gas Specific isobaric heat capacity, kJ/kg·K
-* cv0, Ideal gas Specific isochoric heat capacity, kJ/kg·K
-* cp0_cv, Ideal gas Heat capacity ratio, [-]
-* gamma0, Ideal gas Isoentropic exponent, [-]
-
-
-Usage::
+
+.. code:: python
 
 	from iapws import IAPWS95
 	sat_steam=IAPWS95(P=1,x=1)                #saturated steam with known P
 	sat_liquid=IAPWS95(T=370, x=0)            #saturated liquid with known T
 	steam=IAPWS95(P=2.5, T=500)               #steam with known P and T
 	print(sat_steam.h, sat_liquid.h, steam.h) #calculated enthalpies
+    
+
+IAPWS-05 for Heavy water
+
+.. code:: python
+
+	from iapws import D2O
+	sat_liquid=D2O(T=370, x=0)            #saturated liquid with known T
+	print(sat_liquid.h)                   #calculated enthalpy
 
 
-    
 IAPWS-06 for Ice Ih
---------------------------------------------
-
-There is too implemented a function to calculate properties of ice Ih from 2009 revision, in this case only let temperature and pressure as input for calculate properties, the function return a dict with properties available:
-
-* P, Pressure, MPa
-* T, Temperature, K
-* v, Specific volume, m³/kg
-* rho, Density, kg/m³
-* g, Specific Gibbs free energy, kJ/kg
-* a, Specific Helmholtz free energy, kJ/kg
-* h, Specific enthalpy, kJ/kg
-* u, Specific internal energy, kJ/kg
-* s, Specific entropy, kJ/kg·K
-* cp, Specific isobaric heat capacity, kJ/kg·K
-* alfa, Cubic expansion coefficient, 1/K
-* beta, Pressure coefficient, MPa/K
-* kt, Isothermal compressibility, MPa
-* ks, Isentropic compressibility, MPa
 
-    
-Usage::
-    
+.. code:: python
+
     from iapws import _Ice
     ice=_Ice(273.15, 0.101325)            #Ice at normal melting point
     print(ice["rho"])                     #Calculated density
 
-    
-IAPWS-05 for Heavy water
---------------------------------------------
-
-Same properties as for  IAPWS-95
-Reference state set at liquid at normal boiling point (1 atm)
 
-Usage::
+IAPWS-08 for seawater
 
-	from iapws import D2O
-	sat_liquid=D2O(T=370, x=0)            #saturated liquid with known T
-	print(sat_liquid.h) #calculated enthalpy
+.. code:: python
 
-    
-IAPWS-08 for seawater
---------------------------------------------
-
-Incoming properties:
-
-* T: Temperature, K
-* P: Pressure, MPa
-* S: Salinity, kg/kg
-
-S is the Reference-Composition Salinity as defined in Millero, F.J., R. Feistel, D.G. Wright and T.J. McDougall, "The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale", Deep-Sea Res. I 55, 50 (2008).
-
-Calculated properties:
-
-* T: Temperature, K
-* P: Pressure, MPa
-* rho: Density, kg/m³
-* v: Specific volume, m³/kg
-* h: Specific enthalpy, kJ/kg
-* s: Specific entropy, kJ/kg·K
-* u: Specific internal energy, kJ/kg
-* g: Specific Gibbs free energy, kJ/kg
-* a: Specific Helmholtz free energy, kJ/kg
-* cp: Specific isobaric heat capacity, kJ/kg·K
-
-* gt: Derivative Gibbs energy with temperature, kJ/kg·K
-* gp: Derivative Gibbs energy with pressure, m³/kg
-* gtt: Derivative Gibbs energy with temperature square, kJ/kg·K²
-* gtp: Derivative Gibbs energy with pressure and temperature, m³/kg·K
-* gpp: Derivative Gibbs energy with temperature square, m³/kg·MPa
-* gs: Derivative Gibbs energy with salinity, kJ/kg
-* gsp: Derivative Gibbs energy with salinity and pressure, m³/kg
-
-* alfa: Thermal expansion coefficient, 1/K
-* betas: Isentropic temperature-pressure coefficient, K/MPa
-* kt: Isothermal compressibility, 1/MPa
-* ks: Isentropic compressibility, 1/MPa
-* w: Sound Speed, m/s
-
-* mu: Relative chemical potential, kJ/kg
-* muw: Chemical potential of H2O, kJ/kg
-* mus: Chemical potential of sea salt, kJ/kg
-* osm: Osmotic coefficient, [-]
-* haline: Haline contraction coefficient, kg/kg
-
-        
-Usage::
-    
     from iapws import SeaWater
     state = SeaWater(T=300, P=0.101325, S=0.001)    #Seawater with 0.1% Salinity
-    print(state.cp)     # Get cp
+    print(state.cp)                                 # Get cp
+
+
+TODO
+====
+
+* FIXME: Electrolytic conductiviy
+* TODO: Improve convergence in two phase region for IAPWS95 and D2O class
+* TODO: Implement SBTL method for fast calculation
+* TODO: Implement TTSE method for fast calculation
+
+Ammonia-water mixture:
+
+* FIXME: Ammonia-water mixture residual helmholtz. The values are good, bad difer by 1%
+* TODO: Add equilibrium routine
+
+I've tried to test all code and use all values for computer verification the standards give, but anyway the code can have hidden problem.
+For any suggestions, comments, bugs ... you can usage the `github issue section <https://github.com/jjgomera/iapws/issues>`__, or contact directly with me at `email <jjgomera at gmail.com>`__.
diff --git a/iapws.egg-info/PKG-INFO b/iapws.egg-info/PKG-INFO
index f189454..d8d6fbe 100644
--- a/iapws.egg-info/PKG-INFO
+++ b/iapws.egg-info/PKG-INFO
@@ -1,23 +1,49 @@
 Metadata-Version: 1.1
 Name: iapws
-Version: 1.1.3
+Version: 1.2
 Summary: Python implementation of standards from The InternationalAssociation for the Properties of Water and Steam
 Home-page: https://github.com/jjgomera/iapws
 Author: jjgomera
 Author-email: jjgomera at gmail.com
 License: gpl v3
-Download-URL: https://github.com/jjgomera/iapws/tarball/v1.1.3
-Description: iapws
+Download-URL: https://github.com/jjgomera/iapws/tarball/v1.2
+Description: .. image:: https://api.travis-ci.org/jjgomera/iapws.svg?branch=master
+            :target: https://travis-ci.org/jjgomera/iapws
+            :alt: Build Status
+        
+        .. image:: https://ci.appveyor.com/api/projects/status/a128sh8e50cjsiya?svg=true
+            :target: https://ci.appveyor.com/project/jjgomera/iapws
+            :alt: Windows Build Status
+        
+        .. image:: https://coveralls.io/repos/github/jjgomera/iapws/badge.svg?branch=master
+            :target: https://coveralls.io/github/jjgomera/iapws?branch=master
+            :alt: coveralls.io analysis
+        
+        .. image:: https://codecov.io/gh/jjgomera/iapws/branch/master/graph/badge.svg
+            :target: https://codecov.io/gh/jjgomera/iapws
+            :alt: codecov.io analysis
+        
+        .. image:: https://landscape.io/github/jjgomera/iapws/master/landscape.svg?style=flat
+           :target: https://landscape.io/github/jjgomera/iapws/master
+           :alt: Code Health
+        
+        .. image:: http://readthedocs.org/projects/iapws/badge/?version=latest
+            :target: http://iapws.readthedocs.io/en/latest/?badge=latest
+            :alt: Documentation Status
+        
+        iapws
         =====
         
-        Python implementation of standard from IAPWS (http://www.iapws.org/release.html). The available standard are::
+        Python implementation of standard from IAPWS (http://www.iapws.org/release.html). The module implements the full set of standards, including::
         
             IAPWS-IF97
             IAPWS-95
             IAPWS-06 for Ice
             IAPWS-08 for seawater
             IAPWS-05 for Heavy water
+            ...
             
+        
         dependences
         --------------------
         
@@ -28,92 +54,30 @@ Description: iapws
         install
         --------------------
         
-        In debian you can find in official repositories in testing and sid. In stable you can install using pip::
+        In debian you can find in official repositories in jessie, testing and sid. In ubuntu it's in official repositories from ubuntu saucy (13.10). In other system you can install using pip::
         
         	pip install iapws
+         
+        or directly cloning the github repository::
         
-        In ubuntu it's in official repositories from ubuntu saucy (13.10)
-        
-        In other SO you can download from its webpage in `pypi <http://pypi.python.org/pypi/iapws>`_ and unzipped in python folder dist-packages. This is the recommended options to have the latest version.
-        
-        
-        TODO
-        --------------------
+            git clone https://github.com/jjgomera/iapws.git
         
-        Improve convergence in two phase region for IAPWS95 and D2O class
+        and adding the folder to a python path. This is the recommended option to have the latest version.
         
         
-        IAPWS-IF97
+        documentation
         --------------------
+         
+        To see the full documentation of package, see `readthedocs <http://iapws.readthedocs.io/>`__
         
-        Class to model a state for liquid water or steam with the Industrial Formulation IAPWS-IF97
+        .. inclusion-marker-do-not-remove
         
-        Incoming properties:
+        For a rapid usage demostration, see this examples 
         
-        * T, Temperature, K
-        * P, Pressure, MPa
-        * h, Specific enthalpy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * x, Quality, [-]
-            
-        Definitions options:
-        
-        * T, P (Not valid for two-phases region)
-        * P, h
-        * P, s
-        * h, s
-        * T, x (Only for two-phases region)
-        * P, x (Only for two-phases region)
-            
-        Properties:
-        
-        * P, Pressure, MPa
-        * T, Temperature, K
-        * g, Specific Gibbs free energy, kJ/kg
-        * a, Specific Helmholtz free energy, kJ/kg
-        * v, Specific volume, m³/kg
-        * rho, Density, kg/m³
-        * x, quality, [-]
-        * h, Specific enthalpy, kJ/kg
-        * u, Specific internal energy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * cp, Specific isobaric heat capacity, kJ/kg·K
-        * cv, Specific isochoric heat capacity, kJ/kg·K
-        * Z, Compression factor. [-]
-        * gamma, Isoentropic exponent, [-]
-        * alfav, Isobaric cubic expansion coefficient, 1/K
-        * kt, Isothermal compressibility, 1/MPa
-        * alfap, Relative pressure coefficient, 1/K
-        * betap, Isothermal stress coefficient, kg/m³
-        * joule, Joule-Thomson coefficient, K/MPa
-        * deltat, Isothermal throttling coefficient, kJ/kg·MPa
-        * region, Region
-        
-        * v0, Ideal specific volume, m³/kg
-        * u0, Ideal specific internal energy, kJ/kg
-        * h0, Ideal specific enthalpy, kJ/kg
-        * s0, Ideal specific entropy, kJ/kg·K
-        * a0, Ideal specific Helmholtz free energy, kJ/kg
-        * g0, Ideal specific Gibbs free energy, kJ/kg
-        * cp0, Ideal specific isobaric heat capacity, kJ/kg·K
-        * cv0, Ideal specific isochoric heat capacity, kJ/kg·K
-        * w0, Ideal speed of sound, m/s
-        * gamma0, Ideal isoentropic exponent [-]
-            
-        * w, Speed of sound, m/s
-        * mu, Dynamic viscosity, Pa·s
-        * nu, Kinematic viscosity, m²/s
-        * k, Thermal conductivity, W/m·K
-        * alfa, Thermal diffusivity, m²/s
-        * sigma, Surface tension, N/m
-        * epsilon, Dielectric constant, [-]
-        * n, Refractive index, [-]
-        * Prandt, Prandtl number, [-]
-        * Tr, Reduced temperature, [-]
-        * Pr, Reduced pressure, [-]
         
+        IAPWS-IF97
         
-        Usage::
+        .. code:: python
         
         	from iapws import IAPWS97
         	sat_steam=IAPWS97(P=1,x=1)                #saturated steam with known P
@@ -121,221 +85,60 @@ Description: iapws
         	steam=IAPWS97(P=2.5, T=500)               #steam with known P and T
         	print(sat_steam.h, sat_liquid.h, steam.h) #calculated enthalpies
             
-            
-            
+        
         IAPWS-95
-        --------------------------------
-        
-        Class to model a state for liquid water or steam with the general and scientific formulation IAPWS-95
-        
-        Incoming properties:
-        
-        * T, Temperature, K
-        * P, Pressure, MPa
-        * rho, Density, kg/m3
-        * v, Specific volume, m3/kg
-        * h, Specific enthalpy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * x, Quality, [-]
-        * l, Optional parameter to light wavelength for Refractive index, mm
-        
-        rho and v are equivalent, only one can be defined
-        Definitions options:
-        
-        * T, P (Not valid for two-phases region)
-        * T, rho
-        * T, h
-        * T, s
-        * T, u
-        * P, rho
-        * P, h
-        * P, s
-        * P, u
-        * rho, h
-        * rho, s
-        * rho, u
-        * h, s
-        * h, u
-        * s, u
-        * T, x (Only for two-phases region)
-        * P, x (Only for two-phases region) Very slow
-        
-        Properties:
-        
-        * P,  Pressure, MPa
-        * Pr, Reduced pressure, [-]
-        * T, Temperature, K
-        * Tr, Reduced temperature, [-]
-        * x, Quality, [-]
-        * v, Specific volume, m³/kg
-        * rho, Density, kg/m³
-        * h, Specific enthalpy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * u, Specific internal energy, kJ/kg
-        * g, Specific Gibbs free energy, kJ/kg
-        * a, Specific Helmholtz free energy, kJ/kg
-        * cp, Specific isobaric heat capacity, kJ/kg·K
-        * cv, Specific isochoric heat capacity, kJ/kg·K
-        * cp_cv, Heat capacity ratio, [-]
-        * w, Speed of sound, m/s
-        * Z, Compression factor, [-]
-        * fi, Fugacity coefficient, [-]
-        * f, Fugacity, MPa
-        * gamma, Isoentropic exponent, [-]
-        
-        * alfav, Thermal expansion coefficient (Volume expansivity), 1/K
-        * kappa, Isothermal compressibility, 1/MPa
-        * alfap, Relative pressure coefficient, 1/K
-        * betap, Isothermal stress coefficient, kg/m³
-        * betas, Isoentropic temperature-pressure coefficient, [-]
-        * joule, Joule-Thomson coefficient, K/MPa
-        * Gruneisen, Gruneisen parameter, [-]
-        * virialB, Second virial coefficient, m³/kg
-        * virialC, Third virial coefficient, m⁶/kg²
-        * dpdT_rho, Derivatives, dp/dT at constant rho, MPa/K
-        * dpdrho_T, Derivatives, dp/drho at constant T, MPa·m³/kg
-        * drhodT_P, Derivatives, drho/dT at constant P, kg/m³·K
-        * drhodP_T, Derivatives, drho/dP at constant T, kg/m³·MPa
-        * dhdT_rho, Derivatives, dh/dT at constant rho, kJ/kg·K
-        * dhdP_T, Isothermal throttling coefficient, kJ/kg·MPa
-        * dhdT_P, Derivatives, dh/dT at constant P, kJ/kg·K
-        * dhdrho_T, Derivatives, dh/drho at constant T, kJ·m³/kg²
-        * dhdrho_P, Derivatives, dh/drho at constant P, kJ·m³/kg²
-        * dhdP_rho, Derivatives, dh/dP at constant rho, kJ/kg·MPa
-        * kt, Isothermal Expansion Coefficient, [-]
-        * ks, Adiabatic Compressibility, 1/MPa
-        * Ks, Adiabatic bulk modulus, MPa
-        * Kt, Isothermal bulk modulus, MPa
-        
-        * Hvap, Vaporization heat, kJ/kg
-        * Z_rho, (Z-1) over the density, m³/kg
-        * IntP,  Internal pressure, MPa
-        * invT, Negative reciprocal temperature, 1/K
-        * hInput, Specific heat input, kJ/kg
-        
-        * mu, Dynamic viscosity, Pa·s
-        * nu, Kinematic viscosity, m²/s
-        * k, Thermal conductivity, W/m·K
-        * sigma, Surface tension, N/m
-        * alfa, Thermal diffusivity, m²/s
-        * Pramdt, Prandtl number, [-]
-        * epsilon, Dielectric constant, [-]
-        * n, Refractive index, [-]
-        
-        * v0, Ideal gas Specific volume, m³/kg
-        * rho0, Ideal gas Density, kg/m³
-        * h0, Ideal gas Specific enthalpy, kJ/kg
-        * u0, Ideal gas Specific internal energy, kJ/kg
-        * s0, Ideal gas Specific entropy, kJ/kg·K
-        * a0, Ideal gas Specific Helmholtz free energy, kJ/kg
-        * g0, Ideal gas Specific Gibbs free energy, kJ/kg
-        * cp0, Ideal gas Specific isobaric heat capacity, kJ/kg·K
-        * cv0, Ideal gas Specific isochoric heat capacity, kJ/kg·K
-        * cp0_cv, Ideal gas Heat capacity ratio, [-]
-        * gamma0, Ideal gas Isoentropic exponent, [-]
-        
-        
-        Usage::
+        
+        .. code:: python
         
         	from iapws import IAPWS95
         	sat_steam=IAPWS95(P=1,x=1)                #saturated steam with known P
         	sat_liquid=IAPWS95(T=370, x=0)            #saturated liquid with known T
         	steam=IAPWS95(P=2.5, T=500)               #steam with known P and T
         	print(sat_steam.h, sat_liquid.h, steam.h) #calculated enthalpies
+            
+        
+        IAPWS-05 for Heavy water
+        
+        .. code:: python
+        
+        	from iapws import D2O
+        	sat_liquid=D2O(T=370, x=0)            #saturated liquid with known T
+        	print(sat_liquid.h)                   #calculated enthalpy
         
         
-            
         IAPWS-06 for Ice Ih
-        --------------------------------------------
-        
-        There is too implemented a function to calculate properties of ice Ih from 2009 revision, in this case only let temperature and pressure as input for calculate properties, the function return a dict with properties available:
-        
-        * P, Pressure, MPa
-        * T, Temperature, K
-        * v, Specific volume, m³/kg
-        * rho, Density, kg/m³
-        * g, Specific Gibbs free energy, kJ/kg
-        * a, Specific Helmholtz free energy, kJ/kg
-        * h, Specific enthalpy, kJ/kg
-        * u, Specific internal energy, kJ/kg
-        * s, Specific entropy, kJ/kg·K
-        * cp, Specific isobaric heat capacity, kJ/kg·K
-        * alfa, Cubic expansion coefficient, 1/K
-        * beta, Pressure coefficient, MPa/K
-        * kt, Isothermal compressibility, MPa
-        * ks, Isentropic compressibility, MPa
         
-            
-        Usage::
-            
+        .. code:: python
+        
             from iapws import _Ice
             ice=_Ice(273.15, 0.101325)            #Ice at normal melting point
             print(ice["rho"])                     #Calculated density
         
-            
-        IAPWS-05 for Heavy water
-        --------------------------------------------
-        
-        Same properties as for  IAPWS-95
-        Reference state set at liquid at normal boiling point (1 atm)
         
-        Usage::
+        IAPWS-08 for seawater
         
-        	from iapws import D2O
-        	sat_liquid=D2O(T=370, x=0)            #saturated liquid with known T
-        	print(sat_liquid.h) #calculated enthalpy
+        .. code:: python
         
-            
-        IAPWS-08 for seawater
-        --------------------------------------------
-        
-        Incoming properties:
-        
-        * T: Temperature, K
-        * P: Pressure, MPa
-        * S: Salinity, kg/kg
-        
-        S is the Reference-Composition Salinity as defined in Millero, F.J., R. Feistel, D.G. Wright and T.J. McDougall, "The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale", Deep-Sea Res. I 55, 50 (2008).
-        
-        Calculated properties:
-        
-        * T: Temperature, K
-        * P: Pressure, MPa
-        * rho: Density, kg/m³
-        * v: Specific volume, m³/kg
-        * h: Specific enthalpy, kJ/kg
-        * s: Specific entropy, kJ/kg·K
-        * u: Specific internal energy, kJ/kg
-        * g: Specific Gibbs free energy, kJ/kg
-        * a: Specific Helmholtz free energy, kJ/kg
-        * cp: Specific isobaric heat capacity, kJ/kg·K
-        
-        * gt: Derivative Gibbs energy with temperature, kJ/kg·K
-        * gp: Derivative Gibbs energy with pressure, m³/kg
-        * gtt: Derivative Gibbs energy with temperature square, kJ/kg·K²
-        * gtp: Derivative Gibbs energy with pressure and temperature, m³/kg·K
-        * gpp: Derivative Gibbs energy with temperature square, m³/kg·MPa
-        * gs: Derivative Gibbs energy with salinity, kJ/kg
-        * gsp: Derivative Gibbs energy with salinity and pressure, m³/kg
-        
-        * alfa: Thermal expansion coefficient, 1/K
-        * betas: Isentropic temperature-pressure coefficient, K/MPa
-        * kt: Isothermal compressibility, 1/MPa
-        * ks: Isentropic compressibility, 1/MPa
-        * w: Sound Speed, m/s
-        
-        * mu: Relative chemical potential, kJ/kg
-        * muw: Chemical potential of H2O, kJ/kg
-        * mus: Chemical potential of sea salt, kJ/kg
-        * osm: Osmotic coefficient, [-]
-        * haline: Haline contraction coefficient, kg/kg
-        
-                
-        Usage::
-            
             from iapws import SeaWater
             state = SeaWater(T=300, P=0.101325, S=0.001)    #Seawater with 0.1% Salinity
-            print(state.cp)     # Get cp
+            print(state.cp)                                 # Get cp
+        
+        
+        TODO
+        ====
+        
+        * FIXME: Electrolytic conductiviy
+        * TODO: Improve convergence in two phase region for IAPWS95 and D2O class
+        * TODO: Implement SBTL method for fast calculation
+        * TODO: Implement TTSE method for fast calculation
+        
+        Ammonia-water mixture:
+        
+        * FIXME: Ammonia-water mixture residual helmholtz. The values are good, bad difer by 1%
+        * TODO: Add equilibrium routine
+        
+        I've tried to test all code and use all values for computer verification the standards give, but anyway the code can have hidden problem.
+        For any suggestions, comments, bugs ... you can usage the `github issue section <https://github.com/jjgomera/iapws/issues>`__, or contact directly with me at `email <jjgomera at gmail.com>`__.
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff --git a/iapws.egg-info/SOURCES.txt b/iapws.egg-info/SOURCES.txt
index 9b35027..203c3ee 100644
--- a/iapws.egg-info/SOURCES.txt
+++ b/iapws.egg-info/SOURCES.txt
@@ -4,6 +4,9 @@ README.rst
 setup.py
 iapws/__init__.py
 iapws/_iapws.py
+iapws/_utils.py
+iapws/ammonia.py
+iapws/humidAir.py
 iapws/iapws08.py
 iapws/iapws95.py
 iapws/iapws97.py
diff --git a/iapws/__init__.py b/iapws/__init__.py
index cc03d07..93ee4f9 100644
--- a/iapws/__init__.py
+++ b/iapws/__init__.py
@@ -2,10 +2,12 @@
 # -*- coding: utf-8 -*-
 
 
-from .iapws97 import IAPWS97
-from .iapws95 import IAPWS95, D2O
-from .iapws08 import SeaWater
-from ._iapws import (_Ice, _Sublimation_Pressure, _Melting_Pressure,
+from ._iapws import (_Ice, _Sublimation_Pressure, _Melting_Pressure,  # noqa
                      _Viscosity, _ThCond, _Tension, _Dielectric, _Refractive)
+from .iapws97 import IAPWS97  # noqa
+from .iapws95 import IAPWS95, D2O  # noqa
+from .iapws08 import SeaWater  # noqa
+from .humidAir import HumidAir  # noqa
+from .ammonia import H2ONH3  # noqa
 
-__version__ = "1.1.3"
+__version__ = "1.2"
diff --git a/iapws/_iapws.py b/iapws/_iapws.py
index fdcaf1d..a688f12 100644
--- a/iapws/_iapws.py
+++ b/iapws/_iapws.py
@@ -1,69 +1,117 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
-
-###############################################################################
-# Several IAPWS standards
-###############################################################################
+"""
+Miscelaneous IAPWS standards
+"""
 
 from __future__ import division
 
-from math import log, exp, tan, atan, acos, sin, pi
 from cmath import log as log_c
+from math import log, exp, tan, atan, acos, sin, pi, log10
+import warnings
+
+from scipy.optimize import minimize
+
+from ._utils import deriv_H
 
 
 # Constants
-Rm = 8.31451      # kJ/kmol·K
-M = 18.015257     # kg/kmol
+M = 18.015268     # g/mol
 R = 0.461526      # kJ/kg·K
+
+# Table 1 from Release on the Values of Temperature, Pressure and Density of
+# Ordinary and Heavy Water Substances at their Respective Critical Points
 Tc = 647.096      # K
 Pc = 22.064       # MPa
 rhoc = 322.       # kg/m³
+Tc_D2O = 643.847  # K
+Pc_D2O = 21.671   # MPa
+rhoc_D2O = 356    # kg/m³
+
 Tt = 273.16       # K
 Pt = 611.657e-6   # MPa
 Tb = 373.1243     # K
-Dipole = 1.855    # Debye
 f_acent = 0.3443
 
+# IAPWS, Guideline on the Use of Fundamental Physical Constants and Basic
+# Constants of Water, http://www.iapws.org/relguide/fundam.pdf
+Dipole = 1.85498  # Debye
+
 
 # IAPWS-06 for Ice
 def _Ice(T, P):
-    """Basic equation for Ice Ih
-
-    >>> "%.9f" % _Ice(100,100)["rho"]
-    '941.678203297'
-    >>> "%.9f" % _Ice(100,100)["h"]
-    '-483.491635676'
-    >>> "%.11f" % _Ice(100,100)["s"]
-    '-2.61195122589'
-    >>> "%.11f" % _Ice(273.152519,0.101325)["a"]
-    '-0.00918701567'
-    >>> "%.9f" % _Ice(273.152519,0.101325)["u"]
-    '-333.465403393'
-    >>> "%.11f" % _Ice(273.152519,0.101325)["cp"]
-    '2.09671391024'
-    >>> "%.15f" % _Ice(273.16,611.657e-6)["alfav"]
-    '0.000159863102566'
-    >>> "%.11f" % _Ice(273.16,611.657e-6)["beta"]
-    '1.35714764659'
-    >>> "%.11e" % _Ice(273.16,611.657e-6)["kt"]
-    '1.17793449348e-04'
-    >>> "%.11e" % _Ice(273.16,611.657e-6)["ks"]
-    '1.14161597779e-04'
+    """Basic state equation for Ice Ih
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties of ice. The available properties are:
+
+            * rho: Density [kg/m³]
+            * h: Specific enthalpy [kJ/kg]
+            * u: Specific internal energy [kJ/kg]
+            * a: Specific Helmholtz energy [kJ/kg]
+            * g: Specific Gibbs energy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * alfav: Cubic expansion coefficient [1/K]
+            * beta: Pressure coefficient [MPa/K]
+            * xkappa: Isothermal compressibility [1/MPa]
+            * ks: Isentropic compressibility [1/MPa]
+            * gt: [∂g/∂T]P
+            * gtt: [∂²g/∂T²]P
+            * gp: [∂g/∂P]T
+            * gpp: [∂²g/∂P²]T
+            * gtp: [∂²g/∂T∂P]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * T ≤ 273.16
+        * P ≤ 208.566
+        * State below the melting and sublimation lines
+
+    Examples
+    --------
+    >>> st1 = _Ice(100, 100)
+    >>> st1["rho"], st1["h"], st1["s"]
+    941.678203297 -483.491635676 -2.61195122589
+    >>> st2 = _Ice(273.152519,0.101325)
+    >>> st2["a"], st2["u"], st2["cp"]
+    -0.00918701567 -333.465403393 2.09671391024
+    >>> st3 = _Ice(273.16,611.657e-6)
+    >>> st3["alfav"], st3["beta"], st3["xkappa"], st3["ks"]
+    0.000159863102566 1.35714764659 1.17793449348e-04 1.14161597779e-04
+
+    References
+    ----------
+    IAPWS, Revised Release on the Equation of State 2006 for H2O Ice Ih
+    September 2009, http://iapws.org/relguide/Ice-2009.html
     """
     # Check input in range of validity
-    if P < Pt:
-        Psub = _Sublimation_Pressure(T)
-        if Psub > P:
-            # Zone Gas
-            raise NotImplementedError("Incoming out of bound")
+    if T > 273.16:
+        # No Ice Ih stable
+        warnings.warn("Metastable ice")
     elif P > 208.566:
         # Ice Ih limit upper pressure
         raise NotImplementedError("Incoming out of bound")
-    else:
-        Pmel = _Melting_Pressure(T, P)
+    elif P < Pt:
+        Psub = _Sublimation_Pressure(T)
+        if Psub > P:
+            # Zone Gas
+            warnings.warn("Metastable ice in vapor region")
+    elif 251.165 < T:
+        Pmel = _Melting_Pressure(T)
         if Pmel < P:
             # Zone Liquid
-            raise NotImplementedError("Incoming out of bound")
+            warnings.warn("Metastable ice in liquid region")
 
     Tr = T/Tt
     Pr = P/Pt
@@ -130,25 +178,439 @@ def _Ice(T, P):
     propiedades["a"] = g-P*gp
     propiedades["alfav"] = gtp/gp
     propiedades["beta"] = -gtp/gpp
-    propiedades["kt"] = -gpp/gp
+    propiedades["xkappa"] = -gpp/gp
     propiedades["ks"] = (gtp**2-gtt*gpp)/gp/gtt
     return propiedades
 
 
+# IAPWS-08 for Liquid water at 0.1 MPa
+def _Liquid(T, P=0.1):
+    """Supplementary release on properties of liquid water at 0.1 MPa
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    optional, although this relation is for P=0.1MPa, can be extrapoled at
+    pressure 0.3MPa
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties of water. The available properties are:
+
+            * h: Specific enthalpy [kJ/kg]
+            * u: Specific internal energy [kJ/kg]
+            * a: Specific Helmholtz energy [kJ/kg]
+            * g: Specific Gibbs energy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * cv: Specific isochoric heat capacity [kJ/kgK]
+            * w: Speed of sound [m/s²]
+            * rho: Density [kg/m³]
+            * v: Specific volume [m³/kg]
+            * vt: [∂v/∂T]P [m³/kgK]
+            * vtt: [∂²v/∂T²]P [m³/kgK²]
+            * vp: [∂v/∂P]T [m³/kg/MPa]
+            * vtp: [∂²v/∂T∂P] [m³/kg/MPa]
+            * alfav: Cubic expansion coefficient [1/K]
+            * xkappa : Isothermal compressibility [1/MPa]
+            * ks: Isentropic compressibility [1/MPa]
+            * mu: Viscosity [mPas]
+            * k: Thermal conductivity [W/mK]
+            * epsilon: Dielectric constant [-]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 253.15 ≤ T ≤ 383.15
+        * 0.1 ≤ P ≤ 0.3
+
+    Examples
+    --------
+    >>> st1 = _Liquid(260)
+    >>> st1["rho"], st1["h"], st1["s"]
+    997.0683602710492 -55.86223174460868 -0.20998554842619535
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Properties of Liquid Water at 0.1
+    MPa, http://www.iapws.org/relguide/LiquidWater.html
+    """
+    # Check input in range of validity
+    if T <= 253.15 or T >= 383.15 or P < 0.1 or P > 0.3:
+        raise NotImplementedError("Incoming out of bound")
+    elif P != 0.1:
+        # Raise a warning if the P value is extrapolated
+        warnings.warn("Using extrapolated values")
+
+    R = 0.46151805   # kJ/kgK
+    Po = 0.1
+    Tr = 10
+    tau = T/Tr
+    alfa = Tr/(593-T)
+    beta = Tr/(T-232)
+
+    a = [None, -1.661470539e5, 2.708781640e6, -1.557191544e8, None,
+         1.93763157e-2, 6.74458446e3, -2.22521604e5, 1.00231247e8,
+         -1.63552118e9, 8.32299658e9, -7.5245878e-6, -1.3767418e-2,
+         1.0627293e1, -2.0457795e2, 1.2037414e3]
+    b = [None, -8.237426256e-1, 1.908956353, -2.017597384, 8.546361348e-1,
+         5.78545292e-3, -1.53195665E-2, 3.11337859e-2, -4.23546241e-2,
+         3.38713507e-2, -1.19946761e-2, -3.1091470e-6, 2.8964919e-5,
+         -1.3112763e-4, 3.0410453e-4, -3.9034594e-4, 2.3403117e-4,
+         -4.8510101e-5]
+    c = [None, -2.452093414e2, 3.869269598e1, -8.983025854]
+    n = [None, 4, 5, 7, None, None, 4, 5, 7, 8, 9, 1, 3, 5, 6, 7]
+    m = [None, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 3, 4, 5, 6, 7, 9]
+
+    suma1 = sum([a[i]*alfa**n[i] for i in range(1, 4)])
+    suma2 = sum([b[i]*beta**m[i] for i in range(1, 5)])
+    go = R*Tr*(c[1]+c[2]*tau+c[3]*tau*log(tau)+suma1+suma2)
+
+    suma1 = sum([a[i]*alfa**n[i] for i in range(6, 11)])
+    suma2 = sum([b[i]*beta**m[i] for i in range(5, 11)])
+    vo = R*Tr/Po/1000*(a[5]+suma1+suma2)
+
+    suma1 = sum([a[i]*alfa**n[i] for i in range(11, 16)])
+    suma2 = sum([b[i]*beta**m[i] for i in range(11, 18)])
+    vpo = R*Tr/Po**2/1000*(suma1+suma2)
+
+    suma1 = sum([n[i]*a[i]*alfa**(n[i]+1) for i in range(1, 4)])
+    suma2 = sum([m[i]*b[i]*beta**(m[i]+1) for i in range(1, 5)])
+    so = -R*(c[2]+c[3]*(1+log(tau))+suma1-suma2)
+
+    suma1 = sum([n[i]*(n[i]+1)*a[i]*alfa**(n[i]+2) for i in range(1, 4)])
+    suma2 = sum([m[i]*(m[i]+1)*b[i]*beta**(m[i]+2) for i in range(1, 5)])
+    cpo = -R*(c[3]+tau*suma1+tau*suma2)
+
+    suma1 = sum([n[i]*a[i]*alfa**(n[i]+1) for i in range(6, 11)])
+    suma2 = sum([m[i]*b[i]*beta**(m[i]+1) for i in range(5, 11)])
+    vto = R/Po/1000*(suma1-suma2)
+
+    # This properties are only neccessary for computing thermodynamic
+    # properties at pressures different from 0.1 MPa
+    suma1 = sum([n[i]*(n[i]+1)*a[i]*alfa**(n[i]+2) for i in range(6, 11)])
+    suma2 = sum([m[i]*(m[i]+1)*b[i]*beta**(m[i]+2) for i in range(5, 11)])
+    vtto = R/Tr/Po/1000*(suma1+suma2)
+
+    suma1 = sum([n[i]*a[i]*alfa**(n[i]+1) for i in range(11, 16)])
+    suma2 = sum([m[i]*b[i]*beta**(m[i]+1) for i in range(11, 18)])
+    vpto = R/Po**2/1000*(suma1-suma2)
+
+    if P != 0.1:
+        go += vo*(P-0.1)
+        so -= vto*(P-0.1)
+        cpo -= T*vtto*(P-0.1)
+        vo -= vpo*(P-0.1)
+        vto += vpto*(P-0.1)
+        vppo = 3.24e-10*R*Tr/0.1**3
+        vpo += vppo*(P-0.1)
+
+    h = go+T*so
+    u = h-P*vo
+    a = go-P*vo
+    cv = cpo+T*vto**2/vpo
+    xkappa = -vpo/vo
+    alfa = vto/vo
+    ks = -(T*vto**2/cpo+vpo)/vo
+    w = (-vo**2*1e9/(vpo*1e3+T*vto**2*1e6/cpo))**0.5
+
+    propiedades = {}
+    propiedades["g"] = go
+    propiedades["T"] = T
+    propiedades["P"] = P
+    propiedades["v"] = vo
+    propiedades["vt"] = vto
+    propiedades["vp"] = vpo
+    propiedades["vpt"] = vpto
+    propiedades["vtt"] = vtto
+    propiedades["rho"] = 1/vo
+    propiedades["h"] = h
+    propiedades["s"] = so
+    propiedades["cp"] = cpo
+    propiedades["cv"] = cv
+    propiedades["u"] = u
+    propiedades["a"] = a
+    propiedades["xkappa"] = xkappa
+    propiedades["alfav"] = vto/vo
+    propiedades["ks"] = ks
+    propiedades["w"] = w
+
+    # Viscosity correlation, Eq 7
+    a = [None, 280.68, 511.45, 61.131, 0.45903]
+    b = [None, -1.9, -7.7, -19.6, -40]
+    T_ = T/300
+    mu = sum([a[i]*T_**b[i] for i in range(1, 5)])/1e6
+    propiedades["mu"] = mu
+
+    # Thermal conductivity correlation, Eq 8
+    c = [None, 1.6630, -1.7781, 1.1567, -0.432115]
+    d = [None, -1.15, -3.4, -6.0, -7.6]
+    k = sum([c[i]*T_**d[i] for i in range(1, 5)])
+    propiedades["k"] = k
+
+    # Dielectric constant correlation, Eq 9
+    e = [None, -43.7527, 299.504, -399.364, 221.327]
+    f = [None, -0.05, -1.47, -2.11, -2.31]
+    epsilon = sum([e[i]*T_**f[i] for i in range(1, 5)])
+    propiedades["epsilon"] = epsilon
+
+    return propiedades
+
+
+# IAPWS-15 for supercooled liquid water
+def _Supercooled(T, P):
+    """Guideline on thermodynamic properties of supercooled water
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties of water. The available properties are:
+
+            * L: Ordering field [-]
+            * x: Mole fraction of low-density structure [-]
+            * rho: Density [kg/m³]
+            * s: Specific entropy [kJ/kgK]
+            * h: Specific enthalpy [kJ/kg]
+            * u: Specific internal energy [kJ/kg]
+            * a: Specific Helmholtz energy [kJ/kg]
+            * g: Specific Gibbs energy [kJ/kg]
+            * alfap: Thermal expansion coefficient [1/K]
+            * xkappa : Isothermal compressibility [1/MPa]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * cv: Specific isochoric heat capacity [kJ/kgK]
+            * w: Speed of sound [m/s²]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * Tm ≤ T ≤ 300
+        * 0 < P ≤ 1000
+
+    The minimum temperature in range of validity is the melting temperature, it
+    depend of pressure
+
+    Examples
+    --------
+    >>> liq = _Supercooled(235.15, 0.101325)
+    >>> liq["rho"], liq["cp"], liq["w"]
+    968.09999 5.997563 1134.5855
+
+    References
+    ----------
+    IAPWS, Guideline on Thermodynamic Properties of Supercooled Water,
+    http://iapws.org/relguide/Supercooled.html
+    """
+
+    # Check input in range of validity
+    if P < 198.9:
+        Tita = T/235.15
+        Ph = 0.1+228.27*(1-Tita**6.243)+15.724*(1-Tita**79.81)
+        if P < Ph or T > 300:
+            raise NotImplementedError("Incoming out of bound")
+    else:
+        Th = 172.82+0.03718*P+3.403e-5*P**2-1.573e-8*P**3
+        if T < Th or T > 300 or P > 1000:
+            raise NotImplementedError("Incoming out of bound")
+
+    # Parameters, Table 1
+    Tll = 228.2
+    rho0 = 1081.6482
+    R = 0.461523087
+    pi0 = 300e3/rho0/R/Tll
+    omega0 = 0.5212269
+    L0 = 0.76317954
+    k0 = 0.072158686
+    k1 = -0.31569232
+    k2 = 5.2992608
+
+    # Reducing parameters, Eq 2
+    tau = T/Tll-1
+    p = P*1000/rho0/R/Tll
+    tau_ = tau+1
+    p_ = p+pi0
+
+    # Eq 3
+    ci = [-8.1570681381655, 1.2875032, 7.0901673598012, -3.2779161e-2,
+          7.3703949e-1, -2.1628622e-1, -5.1782479, 4.2293517e-4, 2.3592109e-2,
+          4.3773754, -2.9967770e-3, -9.6558018e-1, 3.7595286, 1.2632441,
+          2.8542697e-1, -8.5994947e-1, -3.2916153e-1, 9.0019616e-2,
+          8.1149726e-2, -3.2788213]
+    ai = [0, 0, 1, -0.2555, 1.5762, 1.6400, 3.6385, -0.3828, 1.6219, 4.3287,
+          3.4763, 5.1556, -0.3593, 5.0361, 2.9786, 6.2373, 4.0460, 5.3558,
+          9.0157, 1.2194]
+    bi = [0, 1, 0, 2.1051, 1.1422, 0.9510, 0, 3.6402, 2.0760, -0.0016, 2.2769,
+          0.0008, 0.3706, -0.3975, 2.9730, -0.3180, 2.9805, 2.9265, 0.4456,
+          0.1298]
+    di = [0, 0, 0, -0.0016, 0.6894, 0.0130, 0.0002, 0.0435, 0.0500, 0.0004,
+          0.0528, 0.0147, 0.8584, 0.9924, 1.0041, 1.0961, 1.0228, 1.0303,
+          1.6180, 0.5213]
+    phir = phirt = phirp = phirtt = phirtp = phirpp = 0
+    for c, a, b, d in zip(ci, ai, bi, di):
+        phir += c*tau_**a*p_**b*exp(-d*p_)
+        phirt += c*a*tau_**(a-1)*p_**b*exp(-d*p_)
+        phirp += c*tau_**a*p_**(b-1)*(b-d*p_)*exp(-d*p_)
+        phirtt += c*a*(a-1)*tau_**(a-2)*p_**b*exp(-d*p_)
+        phirtp += c*a*tau_**(a-1)*p_**(b-1)*(b-d*p_)*exp(-d*p_)
+        phirpp += c*tau_**a*p_**(b-2)*((d*p_-b)**2-b)*exp(-d*p_)
+
+    # Eq 5
+    K1 = ((1+k0*k2+k1*(p-k2*tau))**2-4*k0*k1*k2*(p-k2*tau))**0.5
+    K2 = (1+k2**2)**0.5
+
+    # Eq 6
+    omega = 2+omega0*p
+
+    # Eq 4
+    L = L0*K2/2/k1/k2*(1+k0*k2+k1*(p+k2*tau)-K1)
+
+    # Define interval of solution, Table 4
+    if omega < 10/9*(log(19)-L):
+        xmin = 0.049
+        xmax = 0.5
+    elif 10/9*(log(19)-L) <= omega < 50/49*(log(99)-L):
+        xmin = 0.0099
+        xmax = 0.051
+    else:
+        xmin = 0.99*exp(-50/49*L-omega)
+        xmax = min(1.1*exp(-L-omega), 0.0101)
+
+    def f(x):
+        return abs(L+log(x/(1-x))+omega*(1-2*x))
+
+    x = minimize(f, ((xmin+xmax)/2,), bounds=((xmin, xmax),))["x"][0]
+
+    # Eq 12
+    fi = 2*x-1
+    Xi = 1/(2/(1-fi**2)-omega)
+
+    # Derivatives, Table 3
+    Lt = L0*K2/2*(1+(1-k0*k2+k1*(p-k2*tau))/K1)
+    Lp = L0*K2*(K1+k0*k2-k1*p+k1*k2*tau-1)/2/k2/K1
+    Ltt = -2*L0*K2*k0*k1*k2**2/K1**3
+    Ltp = 2*L0*K2*k0*k1*k2/K1**3
+    Lpp = -2*L0*K2*k0*k1/K1**3
+
+    prop = {}
+    prop["L"] = L
+    prop["x"] = x
+
+    # Eq 13
+    prop["rho"] = rho0/((tau+1)/2*(omega0/2*(1-fi**2)+Lp*(fi+1))+phirp)
+
+    # Eq 1
+    prop["g"] = phir+(tau+1)*(x*L+x*log(x)+(1-x)*log(1-x)+omega*x*(1-x))
+
+    # Eq 14
+    prop["s"] = -R*((tau+1)/2*Lt*(fi+1) +
+                    (x*L+x*log(x)+(1-x)*log(1-x)+omega*x*(1-x))+phirt)
+
+    # Basic derived state properties
+    prop["h"] = prop["g"]+T*prop["s"]
+    prop["u"] = prop["h"]+P/prop["rho"]
+    prop["a"] = prop["u"]-T*prop["s"]
+
+    # Eq 15
+    prop["xkappa"] = prop["rho"]/rho0**2/R*1000/Tll*(
+        (tau+1)/2*(Xi*(Lp-omega0*fi)**2-(fi+1)*Lpp)-phirpp)
+    prop["alfap"] = prop["rho"]/rho0/Tll*(
+        Ltp/2*(tau+1)*(fi+1) + (omega0*(1-fi**2)/2+Lp*(fi+1))/2 -
+        (tau+1)*Lt/2*Xi*(Lp-omega0*fi) + phirtp)
+    prop["cp"] = -R*(tau+1)*(Lt*(fi+1)+(tau+1)/2*(Ltt*(fi+1)-Lt**2*Xi)+phirtt)
+
+    # Eq 16
+    prop["cv"] = prop["cp"]-T*prop["alfap"]**2/prop["rho"]/prop["xkappa"]*1e3
+
+    # Eq 17
+    prop["w"] = (prop["rho"]*prop["xkappa"]*1e-6*prop["cv"]/prop["cp"])**-0.5
+    return prop
+
+
 def _Sublimation_Pressure(T):
-    """Sublimation Pressure correlation"""
-    Tita = T/Tt
-    suma = 0
-    a = [-0.212144006e2, 0.273203819e2, -0.61059813e1]
-    expo = [0.333333333e-2, 1.20666667, 1.70333333]
-    for ai, expi in zip(a, expo):
-        suma += ai*Tita**expi
-    return exp(suma/Tita)*Pt
-
-
-def _Melting_Pressure(T, P):
-    """Melting Pressure correlation"""
-    if P < 208.566 and 251.165 <= T <= 273.16:
+    """Sublimation Pressure correlation
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    P : float
+        Pressure at sublimation line [MPa]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 50 ≤ T ≤ 273.16
+
+    Examples
+    --------
+    >>> _Sublimation_Pressure(230)
+    8.947352740189152e-06
+
+    References
+    ----------
+    IAPWS, Revised Release on the Pressure along the Melting and Sublimation
+    Curves of Ordinary Water Substance, http://iapws.org/relguide/MeltSub.html.
+    """
+    if 50 <= T <= 273.16:
+        Tita = T/Tt
+        suma = 0
+        a = [-0.212144006e2, 0.273203819e2, -0.61059813e1]
+        expo = [0.333333333e-2, 1.20666667, 1.70333333]
+        for ai, expi in zip(a, expo):
+            suma += ai*Tita**expi
+        return exp(suma/Tita)*Pt
+    else:
+        raise NotImplementedError("Incoming out of bound")
+
+
+def _Melting_Pressure(T, ice="Ih"):
+    """Melting Pressure correlation
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    ice: string
+        Type of ice: Ih, III, V, VI, VII.
+        Below 273.15 is a mandatory input, the ice Ih is the default value.
+        Above 273.15, the ice type is unnecesary.
+
+    Returns
+    -------
+    P : float
+        Pressure at sublimation line [MPa]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 251.165 ≤ T ≤ 715
+
+    Examples
+    --------
+    >>> _Melting_Pressure(260)
+    8.947352740189152e-06
+    >>> _Melting_Pressure(254, "III")
+    268.6846466336108
+
+    References
+    ----------
+    IAPWS, Revised Release on the Pressure along the Melting and Sublimation
+    Curves of Ordinary Water Substance, http://iapws.org/relguide/MeltSub.html.
+    """
+    if ice == "Ih" and 251.165 <= T <= 273.16:
         # Ice Ih
         Tref = Tt
         Pref = Pt
@@ -159,32 +621,33 @@ def _Melting_Pressure(T, P):
         for ai, expi in zip(a, expo):
             suma += ai*(1-Tita**expi)
         P = suma*Pref
-    elif 208.566 < P < 350.1 and 251.165 < T <= 256.164:
+    elif ice == "III" and 251.165 < T <= 256.164:
         # Ice III
         Tref = 251.165
         Pref = 208.566
         Tita = T/Tref
         P = Pref*(1-0.299948*(1-Tita**60.))
-    elif 350.1 < P < 632.4 and 256.164 < T <= 273.31:
+    elif (ice == "V" and 256.164 < T <= 273.15) or 273.15 < T <= 273.31:
         # Ice V
         Tref = 256.164
         Pref = 350.100
         Tita = T/Tref
         P = Pref*(1-1.18721*(1-Tita**8.))
-    elif 632.4 < P < 2216 and 273.31 < T <= 355:
+    elif 273.31 < T <= 355:
         # Ice VI
         Tref = 273.31
         Pref = 632.400
         Tita = T/Tref
         P = Pref*(1-1.07476*(1-Tita**4.6))
-    elif 2216 < P and 355. < T <= 715:
+    elif 355. < T <= 715:
         # Ice VII
         Tref = 355
         Pref = 2216.000
         Tita = T/Tref
         P = Pref*exp(1.73683*(1-1./Tita)-0.544606e-1*(1-Tita**5) +
                      0.806106e-7*(1-Tita**22))
-
+    else:
+        raise NotImplementedError("Incoming out of bound")
     return P
 
 
@@ -192,138 +655,266 @@ def _Melting_Pressure(T, P):
 def _Viscosity(rho, T, fase=None, drho=None):
     """Equation for the Viscosity
 
-    >>> "%.12f" % _Viscosity(997.047435,298.15)
-    '0.000890022551'
-    >>> "%.13f" % _Viscosity(54.9921814,873.15)
-    '0.0000339743835'
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+    fase: dict
+        phase properties
+    drho: float
+        [∂ρ/∂P]T at reference state,
+        optional for calculate critical enhancement
+
+    Returns
+    -------
+    mu : float
+        Viscosity [Pa·s]
+
+    Examples
+    --------
+    >>> _Viscosity(998, 298.15)
+    0.0008897351001498108
+    >>> _Viscosity(600, 873.15)
+    7.743019522728247e-05
+
+    References
+    ----------
+    IAPWS, Release on the IAPWS Formulation 2008 for the Viscosity of Ordinary
+    Water Substance, http://www.iapws.org/relguide/viscosity.html
     """
     Tr = T/Tc
     Dr = rho/rhoc
 
-    no = [1.67752, 2.20462, 0.6366564, -0.241605]
-    suma = 0
-    for i in range(4):
-        suma += no[i]/Tr**i
-    fi0 = 100*Tr**0.5/suma
-
-    I = [0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6]
-    J = [0, 1, 2, 3, 0, 1, 2, 3, 5, 0, 1, 2, 3, 4, 0, 1, 0, 3, 4, 3, 5]
-    nr = [0.520094, 0.850895e-1, -0.108374e1, -0.289555, 0.222531, 0.999115,
-          0.188797e1, 0.126613e1, 0.120573, -0.281378, -0.906851, -0.772479,
-          -0.489837, -0.257040, 0.161913, 0.257399, -0.325372e-1, 0.698452e-1,
-          0.872102e-2, -0.435673e-2, -0.593264e-3]
-    suma = 0
-    for i in range(21):
-        suma += nr[i]*(Dr-1)**I[i]*(1/Tr-1)**J[i]
-    fi1 = exp(Dr*suma)
+    # Eq 11
+    H = [1.67752, 2.20462, 0.6366564, -0.241605]
+    mu0 = 100*Tr**0.5/sum([Hi/Tr**i for i, Hi in enumerate(H)])
+
+    # Eq 12
+    I = [0, 1, 2, 3, 0, 1, 2, 3, 5, 0, 1, 2, 3, 4, 0, 1, 0, 3, 4, 3, 5]
+    J = [0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6]
+    Hij = [0.520094, 0.850895e-1, -0.108374e1, -0.289555, 0.222531, 0.999115,
+           0.188797e1, 0.126613e1, 0.120573, -0.281378, -0.906851, -0.772479,
+           -0.489837, -0.257040, 0.161913, 0.257399, -0.325372e-1, 0.698452e-1,
+           0.872102e-2, -0.435673e-2, -0.593264e-3]
+    mu1 = exp(Dr*sum([(1/Tr-1)**i*H*(Dr-1)**j for i, j, H in zip(I, J, Hij)]))
+
+    # Critical enhancement
     if fase and drho:
         qc = 1/1.9
         qd = 1/1.1
 
+        # Eq 21
         DeltaX = Pc*Dr**2*(fase.drhodP_T/rho-drho/rho*1.5/Tr)
         if DeltaX < 0:
             DeltaX = 0
+
+        # Eq 20
         X = 0.13*(DeltaX/0.06)**(0.63/1.239)
+
         if X <= 0.3817016416:
+            # Eq 15
             Y = qc/5*X*(qd*X)**5*(1-qc*X+(qc*X)**2-765./504*(qd*X)**2)
+
         else:
-            Fid = acos((1+qd**2*X**2)**-0.5)
-            w = abs((qc*X-1)/(qc*X+1))**0.5*tan(Fid/2)
+            Fid = acos((1+qd**2*X**2)**-0.5)                            # Eq 17
+            w = abs((qc*X-1)/(qc*X+1))**0.5*tan(Fid/2)                  # Eq 19
+
+            # Eq 18
             if qc*X > 1:
                 Lw = log((1+w)/(1-w))
             else:
                 Lw = 2*atan(abs(w))
+
+            # Eq 16
             Y = sin(3*Fid)/12-sin(2*Fid)/4/qc/X+(1-5/4*(qc*X)**2)/(
                 qc*X)**2*sin(Fid)-((1-3/2*(qc*X)**2)*Fid-abs((
                     qc*X)**2-1)**1.5*Lw)/(qc*X)**3
-        fi2 = exp(0.068*Y)
+
+        # Eq 14
+        mu2 = exp(0.068*Y)
     else:
-        fi2 = 1
-    return fi0*fi1*fi2*1e-6
+        mu2 = 1
+
+    # Eq 10
+    mu = mu0*mu1*mu2
+    return mu*1e-6
 
 
 def _ThCond(rho, T, fase=None, drho=None):
     """Equation for the thermal conductivity
 
-    >>> "%.9f" % _ThCond(997.047435,298.15)
-    '0.606515826'
-    >>> "%.10f" % _ThCond(26.0569558,873.15)
-    '0.0870480934'
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+    fase: dict
+        phase properties
+    drho: float
+        [∂ρ/∂P]T at reference state,
+        optional for calculate critical enhancement
+
+    Returns
+    -------
+    k : float
+        Thermal conductivity [W/mK]
+
+    Examples
+    --------
+    >>> _ThCond(998, 298.15)
+    0.6077128675880629
+    >>> _ThCond(0, 873.15)
+    0.07910346589648833
+
+    References
+    ----------
+    IAPWS, Release on the IAPWS Formulation 2011 for the Thermal Conductivity
+    of Ordinary Water Substance, http://www.iapws.org/relguide/ThCond.html
     """
-    d = rho/322.
-    Tr = T/647.096
+    d = rho/rhoc
+    Tr = T/Tc
 
+    # Eq 16
     no = [2.443221e-3, 1.323095e-2, 6.770357e-3, -3.454586e-3, 4.096266e-4]
-    suma = 0
-    for i in range(5):
-        suma += no[i]/Tr**i
-    L0 = Tr**0.5/suma
-
-    nij = [
-        [1.60397357, -0.646013523, 0.111443906, 0.102997357, -0.0504123634,
-         0.00609859258],
-        [2.33771842, -2.78843778, 1.53616167, -0.463045512, 0.0832827019,
-         -0.00719201245],
-        [2.19650529, -4.54580785, 3.55777244, -1.40944978, 0.275418278,
-         -0.0205938816],
-        [-1.21051378, 1.60812989, -0.621178141, 0.0716373224, 0, 0],
-        [-2.7203370, 4.57586331, -3.18369245, 1.1168348, -0.19268305,
-         0.012913842]]
-    suma = 0
-    for i in range(len(nij)):
-        suma2 = 0
-        for j in range(len(nij[i])):
-            suma2 += nij[i][j]*(d-1)**j
-        suma += (1/Tr-1)**i*suma2
-    L1 = exp(d*suma)
-
-    L2 = 0
-    if fase and drho:
+    k0 = Tr**0.5/sum([n/Tr**i for i, n in enumerate(no)])
+
+    # Eq 17
+    I = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
+         4, 4, 4, 4, 4]
+    J = [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 0,
+         1, 2, 3, 4, 5]
+    nij = [1.60397357, -0.646013523, 0.111443906, 0.102997357, -0.0504123634,
+           0.00609859258, 2.33771842, -2.78843778, 1.53616167, -0.463045512,
+           0.0832827019, -0.00719201245, 2.19650529, -4.54580785, 3.55777244,
+           -1.40944978, 0.275418278, -0.0205938816, -1.21051378, 1.60812989,
+           -0.621178141, 0.0716373224, -2.7203370, 4.57586331, -3.18369245,
+           1.1168348, -0.19268305, 0.012913842]
+    k1 = exp(d*sum([(1/Tr-1)**i*n*(d-1)**j for i, j, n in zip(I, J, nij)]))
+
+    # Critical enhancement
+    if fase:
         R = 0.46151805
 
-        DeltaX = Pc*d**2*(fase.drhodP_T/rho-drho/rho*1.5/Tr)
+        if not drho:
+            # Industrial formulation
+            # Eq 25
+            if d <= 0.310559006:
+                ai = [6.53786807199516, -5.61149954923348, 3.39624167361325,
+                      -2.27492629730878, 10.2631854662709, 1.97815050331519]
+            elif d <= 0.776397516:
+                ai = [6.52717759281799, -6.30816983387575, 8.08379285492595,
+                      -9.82240510197603, 12.1358413791395, -5.54349664571295]
+            elif d <= 1.242236025:
+                ai = [5.35500529896124, -3.96415689925446, 8.91990208918795,
+                      -12.0338729505790, 9.19494865194302, -2.16866274479712]
+            elif d <= 1.863354037:
+                ai = [1.55225959906681, 0.464621290821181, 8.93237374861479,
+                      -11.0321960061126, 6.16780999933360, -0.965458722086812]
+            else:
+                ai = [1.11999926419994, 0.595748562571649, 9.88952565078920,
+                      -10.3255051147040, 4.66861294457414, -0.503243546373828]
+            drho = 1/sum([a*d**i for i, a in enumerate(ai)])*rhoc/Pc
+
+        DeltaX = d*(Pc/rhoc*fase.drhodP_T-Pc/rhoc*drho*1.5/Tr)
         if DeltaX < 0:
             DeltaX = 0
-        X = 0.13*(DeltaX/0.06)**(0.63/1.239)
-        y = X/0.4
+
+        X = 0.13*(DeltaX/0.06)**(0.63/1.239)                            # Eq 22
+        y = X/0.4                                                       # Eq 20
+
+        # Eq 19
         if y < 1.2e-7:
             Z = 0
         else:
             Z = 2/pi/y*(((1-1/fase.cp_cv)*atan(y)+y/fase.cp_cv)-(
                 1-exp(-1/(1/y+y**2/3/d**2))))
-        L2 = 177.8514*d*fase.cp/R*Tr/fase.mu*1e-6*Z
-    return 1e-3*(L0*L1+L2)
+
+        # Eq 18
+        k2 = 177.8514*d*fase.cp/R*Tr/fase.mu*1e-6*Z
+
+    else:
+        # No critical enhancement
+        k2 = 0
+
+    # Eq 10
+    k = k0*k1+k2
+    return 1e-3*k
 
 
 def _Tension(T):
     """Equation for the surface tension
 
-    >>> "%.10f" % _Tension(300)
-    '0.0716859625'
-    >>> "%.10f" % _Tension(450)
-    '0.0428914992'
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    sigma : float
+        Surface tension [N/m]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 248.15 ≤ T ≤ 647
+        * Estrapolate to -25ºC in supercooled liquid metastable state
+
+    Examples
+    --------
+    >>> _Tension(300)
+    0.0716859625
+    >>> _Tension(450)
+    0.0428914992
+
+    References
+    ----------
+    IAPWS, Revised Release on Surface Tension of Ordinary Water Substance
+    June 2014, http://www.iapws.org/relguide/Surf-H2O.html
     """
-    Tr = T/Tc
-    if 273.15 <= T < Tc:
+    if 248.15 <= T <= Tc:
+        Tr = T/Tc
         return 1e-3*(235.8*(1-Tr)**1.256*(1-0.625*(1-Tr)))
     else:
-        return 0
+        raise NotImplementedError("Incoming out of bound")
 
 
 def _Dielectric(rho, T):
     """Equation for the Dielectric constant
 
-    >>> "%.7f" % _Dielectric(999.242866, 298.15)
-    '78.5907250'
-    >>> "%.8f" % _Dielectric(26.0569558, 873.15)
-    '1.12620970'
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    epsilon : float
+        Dielectric constant [-]
+
+    Examples
+    --------
+    >>> _Dielectric(999.242866, 298.15)
+    78.5907250
+    >>> _Dielectric(26.0569558, 873.15)
+    1.12620970
+
+    References
+    ----------
+    IAPWS, Release on the Static Dielectric Constant of Ordinary Water
+    Substance for Temperatures from 238 K to 873 K and Pressures up to 1000
+    MPa, http://www.iapws.org/relguide/Dielec.html
     """
     k = 1.380658e-23
     Na = 6.0221367e23
     alfa = 1.636e-40
     epsilon0 = 8.854187817e-12
     mu = 6.138e-30
-    M = 0.018015268
 
     d = rho/rhoc
     Tr = Tc/T
@@ -337,8 +928,8 @@ def _Dielectric(rho, T):
     g = 1+n[11]*d/(Tc/228/Tr-1)**1.2
     for i in range(11):
         g += n[i]*d**I[i]*Tr**J[i]
-    A = Na*mu**2*rho*g/M/epsilon0/k/T
-    B = Na*alfa*rho/3/M/epsilon0
+    A = Na*mu**2*rho*g/M*1000/epsilon0/k/T
+    B = Na*alfa*rho/3/M*1000/epsilon0
     e = (1+A+5*B+(9+2*A+18*B+A**2+10*A*B+9*B**2)**0.5)/4/(1-B)
     return e
 
@@ -346,11 +937,44 @@ def _Dielectric(rho, T):
 def _Refractive(rho, T, l=0.5893):
     """Equation for the refractive index
 
-    >>> "%.8f" % _Refractive(997.047435, 298.15, 0.2265)
-    '1.39277824'
-    >>> "%.8f" % _Refractive(30.4758534, 773.15, 0.5893)
-    '1.00949307'
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+    l : float, optional
+        Light Wavelength [μm]
+
+    Returns
+    -------
+    n : float
+        Refractive index [-]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 0 ≤ ρ ≤ 1060
+        * 261.15 ≤ T ≤ 773.15
+        * 0.2 ≤ λ ≤ 1.1
+
+    Examples
+    --------
+    >>> _Refractive(997.047435, 298.15, 0.2265)
+    1.39277824
+    >>> _Refractive(30.4758534, 773.15, 0.5893)
+    1.00949307
+
+    References
+    ----------
+    IAPWS, Release on the Refractive Index of Ordinary Water Substance as a
+    Function of Wavelength, Temperature and Pressure,
+    http://www.iapws.org/relguide/rindex.pdf
     """
+    # Check input parameters
+    if rho < 0 or rho > 1060 or T < 261.15 or T > 773.15 or l < 0.2 or l > 1.1:
+        raise NotImplementedError("Incoming out of bound")
+
     Lir = 5.432937
     Luv = 0.229202
     d = rho/1000.
@@ -363,86 +987,486 @@ def _Refractive(rho, T, l=0.5893):
     return ((2*A+1)/(1-A))**0.5
 
 
-def getphase(Tc, Pc, T, P, x, region):
-    """Return fluid phase"""
-    if P > Pc and T > Tc:
-        phase = "Supercritical fluid"
-    elif T > Tc:
-        phase = "Gas"
-    elif P > Pc:
-        phase = "Compressible liquid"
-    elif P == Pc and T == Tc:
-        phase = "Critical point"
-    elif region == 4 and x == 1:
-        phase = "Saturated vapor"
-    elif region == 4 and x == 0:
-        phase = "Saturated liquid"
-    elif region == 4:
-        phase = "Two phases"
-    elif x == 1:
-        phase = "Vapour"
-    elif x == 0:
-        phase = "Liquid"
+def _Kw(rho, T):
+    """Equation for the ionization constant of ordinary water
+
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    pKw : float
+        Ionization constant in -log10(kw) [-]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 0 ≤ ρ ≤ 1250
+        * 273.15 ≤ T ≤ 1073.15
+
+    Examples
+    --------
+    >>> _Kw(1000, 300)
+    13.906565
+
+    References
+    ----------
+    IAPWS, Release on the Ionization Constant of H2O,
+    http://www.iapws.org/relguide/Ionization.pdf
+    """
+    # Check input parameters
+    if rho < 0 or rho > 1250 or T < 273.15 or T > 1073.15:
+        raise NotImplementedError("Incoming out of bound")
+
+    # The internal method of calculation use rho in g/cm³
+    d = rho/1000.
+
+    # Water molecular weight different
+    Mw = 18.015268
+
+    gamma = [6.1415e-1, 4.825133e4, -6.770793e4, 1.01021e7]
+    pKg = 0
+    for i, g in enumerate(gamma):
+        pKg += g/T**i
+
+    Q = d*exp(-0.864671+8659.19/T-22786.2/T**2*d**(2./3))
+    pKw = -12*(log10(1+Q)-Q/(Q+1)*d*(0.642044-56.8534/T-0.375754*d)) + \
+        pKg+2*log10(Mw/1000)
+    return pKw
+
+
+def _Conductivity(rho, T):
+    """Equation for the electrolytic conductivity of liquid and dense
+    supercrítical water
+
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    K : float
+        Electrolytic conductivity [S/m]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 600 ≤ ρ ≤ 1200
+        * 273.15 ≤ T ≤ 1073.15
+
+    Examples
+    --------
+    >>> _Conductivity(1000, 373.15)
+    1.13
+
+    References
+    ----------
+    IAPWS, Electrolytic Conductivity (Specific Conductance) of Liquid and Dense
+    Supercritical Water from 0°C to 800°C and Pressures up to 1000 MPa,
+    http://www.iapws.org/relguide/conduct.pdf
+    """
+    # FIXME: Dont work
+    rho_ = rho/1000
+    kw = 10**-_Kw(rho, T)
+
+    A = [1850., 1410., 2.16417e-6, 1.81609e-7, -1.75297e-9, 7.20708e-12]
+    B = [16., 11.6, 3.26e-4, -2.3e-6, 1.1e-8]
+    t = T-273.15
+
+    Loo = A[0]-1/(1/A[1]+sum([A[i+2]*t**(i+1) for i in range(4)]))      # Eq 5
+    rho_h = B[0]-1/(1/B[1]+sum([B[i+2]*t**(i+1) for i in range(3)]))    # Eq 6
+
+    # Eq 4
+    L_o = (rho_h-rho_)*Loo/rho_h
+
+    # Eq 1
+    k = 100*1e-3*L_o*kw**0.5*rho_
+    return k
+
+
+# Heavy water transport properties
+def _D2O_Viscosity(rho, T):
+    """Equation for the Viscosity of heavy water
+
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    mu : float
+        Viscosity [Pa·s]
+
+    Examples
+    --------
+    >>> _D2O_Viscosity(998, 298.15)
+    0.0008897351001498108
+    >>> _D2O_Viscosity(600, 873.15)
+    7.743019522728247e-05
+
+    References
+    ----------
+    IAPWS, Revised Release on Viscosity and Thermal Conductivity of Heavy
+    Water Substance, http://www.iapws.org/relguide/TransD2O-2007.pdf
+    """
+    Tr = T/643.847
+    rhor = rho/358.0
+
+    no = [1.0, 0.940695, 0.578377, -0.202044]
+    fi0 = Tr**0.5/sum([n/Tr**i for i, n in enumerate(no)])
+
+    Li = [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 0, 1, 2, 5, 0, 1, 2, 3, 0, 1, 3,
+          5, 0, 1, 5, 3]
+    Lj = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
+          4, 5, 5, 5, 6]
+    Lij = [0.4864192, -0.2448372, -0.8702035, 0.8716056, -1.051126,
+           0.3458395, 0.3509007, 1.315436, 1.297752, 1.353448, -0.2847572,
+           -1.037026, -1.287846, -0.02148229, 0.07013759, 0.4660127,
+           0.2292075, -0.4857462, 0.01641220, -0.02884911, 0.1607171,
+           -.009603846, -.01163815, -.008239587, 0.004559914, -0.003886659]
+
+    arr = [lij*(1./Tr-1)**i*(rhor-1)**j for i, j, lij in zip(Li, Lj, Lij)]
+    fi1 = exp(rhor*sum(arr))
+
+    return 55.2651e-6*fi0*fi1
+
+
+def _D2O_ThCond(rho, T):
+    """Equation for the thermal conductivity of heavy water
+
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    k : float
+        Thermal conductivity [W/mK]
+
+    Examples
+    --------
+    >>> _D2O_ThCond(998, 298.15)
+    0.6077128675880629
+    >>> _D2O_ThCond(0, 873.15)
+    0.07910346589648833
+
+    References
+    ----------
+    IAPWS, Revised Release on Viscosity and Thermal Conductivity of Heavy
+    Water Substance, http://www.iapws.org/relguide/TransD2O-2007.pdf
+    """
+    rhor = rho/358
+    Tr = T/643.847
+    tau = Tr/(abs(Tr-1.1)+1.1)
+
+    no = [1.0, 37.3223, 22.5485, 13.0465, 0.0, -2.60735]
+    Lo = sum([Li*Tr**i for i, Li in enumerate(no)])
+
+    nr = [483.656, -191.039, 73.0358, -7.57467]
+    Lr = -167.31*(1-exp(-2.506*rhor))+sum(
+        [Li*rhor**(i+1) for i, Li in enumerate(nr)])
+
+    f1 = exp(0.144847*Tr-5.64493*Tr**2)
+    f2 = exp(-2.8*(rhor-1)**2)-0.080738543*exp(-17.943*(rhor-0.125698)**2)
+    f3 = 1+exp(60*(tau-1)+20)
+    f4 = 1+exp(100*(tau-1)+15)
+    Lc = 35429.6*f1*f2*(1+f2**2*(5e9*f1**4/f3+3.5*f2/f4))
+
+    Ll = -741.112*f1**1.2*(1-exp(-(rhor/2.5)**10))
+
+    return 0.742128e-3*(Lo+Lr+Lc+Ll)
+
+
+def _D2O_Tension(T):
+    """Equation for the surface tension of heavy water
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    sigma : float
+        Surface tension [N/m]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 269.65 ≤ T ≤ 643.847
+
+    Examples
+    --------
+    >>> _D2O_Tension(298.15)
+    0.07186
+    >>> _D2O_Tension(573.15)
+    0.01399
+
+    References
+    ----------
+    IAPWS, Release on Surface Tension of Heavy Water Substance,
+    http://www.iapws.org/relguide/surfd2o.pdf
+    """
+    Tr = T/643.847
+    if 269.65 <= T < 643.847:
+        return 1e-3*(238*(1-Tr)**1.25*(1-0.639*(1-Tr)))
     else:
-        phase = "Unknown"
-    return phase
-
-
-class _fase(object):
-    """Class to implement a null phase"""
-    v = None
-    rho = None
-
-    h = None
-    s = None
-    u = None
-    a = None
-    g = None
-
-    cp = None
-    cv = None
-    cp_cv = None
-    w = None
-    Z = None
-    fi = None
-    f = None
-
-    mu = None
-    k = None
-    nu = None
-    Prandt = None
-    epsilon = None
-    alfa = None
-    n = None
-
-    alfap = None
-    betap = None
-    joule = None
-    Gruneisen = None
-    alfav = None
-    kappa = None
-    betas = None
-    gamma = None
-    Kt = None
-    kt = None
-    Ks = None
-    ks = None
-    dpdT_rho = None
-    dpdrho_T = None
-    drhodT_P = None
-    drhodP_T = None
-    dhdT_rho = None
-    dhdT_P = None
-    dhdrho_T = None
-    dhdrho_P = None
-    dhdP_T = None
-    dhdP_rho = None
-
-    Z_rho = None
-    IntP = None
-    hInput = None
-
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
+        raise NotImplementedError("Incoming out of bound")
+
+
+def _Henry(T, gas, liquid="H2O"):
+    """Equation for the calculation of Henry's constant
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    gas : string
+        Name of gas to calculate solubility
+    liquid : string
+        Name of liquid solvent, can be H20 (default) or D2O
+
+    Returns
+    -------
+    kw : float
+        Henry's constant [MPa]
+
+    Notes
+    -----
+    The gas availables for H2O solvent are:
+        He, Ne, Ar, Kr, Xe, H2, N2, O2, CO, CO2, H2S, CH4, C2H6, SF6
+    For D2O as solvent:
+        He, Ne, Ar, Kr, Xe, D2, CH4
+
+    Examples
+    --------
+    >>> _Henry(500, "He")
+    1.1973
+    >>> _Henry(300, "D2", "D2O")
+    1.6594
+
+    References
+    ----------
+    IAPWS, Guideline on the Henry's Constant and Vapor-Liquid Distribution
+    Constant for Gases in H2O and D2O at High Temperatures,
+    http://www.iapws.org/relguide/HenGuide.html
+    """
+    if liquid == "D2O":
+        gas += "(D2O)"
+
+    limit = {
+        "He": (273.21, 553.18),
+        "Ne": (273.20, 543.36),
+        "Ar": (273.19, 568.36),
+        "Kr": (273.19, 525.56),
+        "Xe": (273.22, 574.85),
+        "H2": (273.15, 636.09),
+        "N2": (278.12, 636.46),
+        "O2": (274.15, 616.52),
+        "CO": (278.15, 588.67),
+        "CO2": (274.19, 642.66),
+        "H2S": (273.15, 533.09),
+        "CH4": (275.46, 633.11),
+        "C2H6": (275.44, 473.46),
+        "SF6": (283.14, 505.55),
+        "He(D2O)": (288.15, 553.18),
+        "Ne(D2O)": (288.18, 549.96),
+        "Ar(D2O)": (288.30, 583.76),
+        "Kr(D2O)": (288.19, 523.06),
+        "Xe(D2O)": (295.39, 574.85),
+        "D2(D2O)": (288.17, 581.00),
+        "CH4(D2O)": (288.16, 517.46)}
+
+    # Check input parameters
+    if liquid != "D2O" and liquid != "H2O":
+        raise NotImplementedError("Solvent liquid unsupported")
+    if gas not in limit:
+        raise NotImplementedError("Gas unsupported")
+
+    Tmin, Tmax = limit[gas]
+    if T < Tmin or T > Tmax:
+        warnings.warn("Temperature out of data of correlation")
+
+    if liquid == "D2O":
+        Tc = 643.847
+        Pc = 21.671
+    else:
+        Tc = 647.096
+        Pc = 22.064
+
+    Tr = T/Tc
+    tau = 1-Tr
+
+    # Eq 4
+    if liquid == "H2O":
+        ai = [-7.85951783, 1.84408259, -11.7866497, 22.6807411, -15.9618719,
+              1.80122502]
+        bi = [1, 1.5, 3, 3.5, 4, 7.5]
+    else:
+        ai = [-7.896657, 24.73308, -27.81128, 9.355913, -9.220083]
+        bi = [1, 1.89, 2, 3, 3.6]
+    ps = Pc*exp(1/Tr*sum([a*tau**b for a, b in zip(ai, bi)]))
+
+    # Select values from Table 2
+    par = {
+        "He": (-3.52839, 7.12983, 4.47770),
+        "Ne": (-3.18301, 5.31448, 5.43774),
+        "Ar": (-8.40954, 4.29587, 10.52779),
+        "Kr": (-8.97358, 3.61508, 11.29963),
+        "Xe": (-14.21635, 4.00041, 15.60999),
+        "H2": (-4.73284, 6.08954, 6.06066),
+        "N2": (-9.67578, 4.72162, 11.70585),
+        "O2": (-9.44833, 4.43822, 11.42005),
+        "CO": (-10.52862, 5.13259, 12.01421),
+        "CO2": (-8.55445, 4.01195, 9.52345),
+        "H2S": (-4.51499, 5.23538, 4.42126),
+        "CH4": (-10.44708, 4.66491, 12.12986),
+        "C2H6": (-19.67563, 4.51222, 20.62567),
+        "SF6": (-16.56118, 2.15289, 20.35440),
+        "He(D2O)": (-0.72643, 7.02134, 2.04433),
+        "Ne(D2O)": (-0.91999, 5.65327, 3.17247),
+        "Ar(D2O)": (-7.17725, 4.48177, 9.31509),
+        "Kr(D2O)": (-8.47059, 3.91580, 10.69433),
+        "Xe(D2O)": (-14.46485, 4.42330, 15.60919),
+        "D2(D2O)": (-5.33843, 6.15723, 6.53046),
+        "CH4(D2O)": (-10.01915, 4.73368, 11.75711)}
+    A, B, C = par[gas]
+
+    # Eq 3
+    kh = ps*exp(A/Tr+B*tau**0.355/Tr+C*Tr**-0.41*exp(tau))
+    return kh
+
+
+def _Kvalue(T, gas, liquid="H2O"):
+    """Equation for the vapor-liquid distribution constant
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    gas : string
+        Name of gas to calculate solubility
+    liquid : string
+        Name of liquid solvent, can be H20 (default) or D2O
+
+    Returns
+    -------
+    kd : float
+        Vapor-liquid distribution constant [-]
+
+    Notes
+    -----
+    The gas availables for H2O solvent are:
+        He, Ne, Ar, Kr, Xe, H2, N2, O2, CO, CO2, H2S, CH4, C2H6, SF6
+    For D2O as solvent:
+        He, Ne, Ar, Kr, Xe, D2, CH4
+
+    Examples
+    --------
+    >>> _Kvalue(600, "He")
+    3.8019
+    >>> _Kvalue(300, "D2", "D2O")
+    14.3520
+
+    References
+    ----------
+    IAPWS, Guideline on the Henry's Constant and Vapor-Liquid Distribution
+    Constant for Gases in H2O and D2O at High Temperatures,
+    http://www.iapws.org/relguide/HenGuide.html
+    """
+    if liquid == "D2O":
+        gas += "(D2O)"
+
+    limit = {
+        "He": (273.21, 553.18),
+        "Ne": (273.20, 543.36),
+        "Ar": (273.19, 568.36),
+        "Kr": (273.19, 525.56),
+        "Xe": (273.22, 574.85),
+        "H2": (273.15, 636.09),
+        "N2": (278.12, 636.46),
+        "O2": (274.15, 616.52),
+        "CO": (278.15, 588.67),
+        "CO2": (274.19, 642.66),
+        "H2S": (273.15, 533.09),
+        "CH4": (275.46, 633.11),
+        "C2H6": (275.44, 473.46),
+        "SF6": (283.14, 505.55),
+        "He(D2O)": (288.15, 553.18),
+        "Ne(D2O)": (288.18, 549.96),
+        "Ar(D2O)": (288.30, 583.76),
+        "Kr(D2O)": (288.19, 523.06),
+        "Xe(D2O)": (295.39, 574.85),
+        "D2(D2O)": (288.17, 581.00),
+        "CH4(D2O)": (288.16, 517.46)}
+
+    # Check input parameters
+    if liquid != "D2O" and liquid != "H2O":
+        raise NotImplementedError("Solvent liquid unsupported")
+    if gas not in limit:
+        raise NotImplementedError("Gas unsupported")
+
+    Tmin, Tmax = limit[gas]
+    if T < Tmin or T > Tmax:
+        warnings.warn("Temperature out of data of correlation")
+
+    if liquid == "D2O":
+        Tc = 643.847
+    else:
+        Tc = 647.096
+
+    Tr = T/Tc
+    tau = 1-Tr
+
+    # Eq 6
+    if liquid == "H2O":
+        ci = [1.99274064, 1.09965342, -0.510839303, -1.75493479, -45.5170352,
+              -6.7469445e5]
+        di = [1/3, 2/3, 5/3, 16/3, 43/3, 110/3]
+        q = -0.023767
+    else:
+        ci = [2.7072, 0.58662, -1.3069, -45.663]
+        di = [0.374, 1.45, 2.6, 12.3]
+        q = -0.024552
+    f = sum([c*tau**d for c, d in zip(ci, di)])
+
+    # Select values from Table 2
+    par = {"He": (2267.4082, -2.9616, -3.2604, 7.8819),
+           "Ne": (2507.3022, -38.6955, 110.3992, -71.9096),
+           "Ar": (2310.5463, -46.7034, 160.4066, -118.3043),
+           "Kr": (2276.9722, -61.1494, 214.0117, -159.0407),
+           "Xe": (2022.8375, 16.7913, -61.2401, 41.9236),
+           "H2": (2286.4159, 11.3397, -70.7279, 63.0631),
+           "N2": (2388.8777, -14.9593, 42.0179, -29.4396),
+           "O2": (2305.0674, -11.3240, 25.3224, -15.6449),
+           "CO": (2346.2291, -57.6317, 204.5324, -152.6377),
+           "CO2": (1672.9376, 28.1751, -112.4619, 85.3807),
+           "H2S": (1319.1205, 14.1571, -46.8361, 33.2266),
+           "CH4": (2215.6977, -0.1089, -6.6240, 4.6789),
+           "C2H6": (2143.8121, 6.8859, -12.6084, 0),
+           "SF6": (2871.7265, -66.7556, 229.7191, -172.7400),
+           "He(D2O)": (2293.2474, -54.7707, 194.2924, -142.1257),
+           "Ne(D2O)": (2439.6677, -93.4934, 330.7783, -243.0100),
+           "Ar(D2O)": (2269.2352, -53.6321, 191.8421, -143.7659),
+           "Kr(D2O)": (2250.3857, -42.0835, 140.7656, -102.7592),
+           "Xe(D2O)": (2038.3656, 68.1228, -271.3390, 207.7984),
+           "D2(D2O)": (2141.3214, -1.9696, 1.6136, 0),
+           "CH4(D2O)": (2216.0181, -40.7666, 152.5778, -117.7430)}
+    E, F, G, H = par[gas]
+
+    # Eq 5
+    kd = exp(q*F+E/T*f+(F+G*tau**(2./3)+H*tau)*exp((273.15-T)/100))
+    return kd
diff --git a/iapws/_utils.py b/iapws/_utils.py
new file mode 100644
index 0000000..2ec6191
--- /dev/null
+++ b/iapws/_utils.py
@@ -0,0 +1,216 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+Miscelaneous utilities
+"""
+
+from __future__ import division
+
+
+def getphase(Tc, Pc, T, P, x, region):
+    """Return fluid phase string name
+
+    Parameters
+    ----------
+    Tc : float
+        Critical temperature [K]
+    Pc : float
+        Critical pressure [MPa]
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    x : float
+        Quality [-]
+    region: integer
+        Region number, specific to IAPWS97 region definition
+
+    Returns
+    -------
+    phase : string
+        Phase name
+    """
+    # Avoid round problem
+    P = round(P, 8)
+    T = round(T, 8)
+    if P > Pc and T > Tc:
+        phase = "Supercritical fluid"
+    elif T > Tc:
+        phase = "Gas"
+    elif P > Pc:
+        phase = "Compressible liquid"
+    elif P == Pc and T == Tc:
+        phase = "Critical point"
+    elif region == 4 and x == 1:
+        phase = "Saturated vapor"
+    elif region == 4 and x == 0:
+        phase = "Saturated liquid"
+    elif region == 4:
+        phase = "Two phases"
+    elif x == 1:
+        phase = "Vapour"
+    elif x == 0:
+        phase = "Liquid"
+    return phase
+
+
+class _fase(object):
+    """Class to implement a null phase"""
+    v = None
+    rho = None
+
+    h = None
+    s = None
+    u = None
+    a = None
+    g = None
+
+    cp = None
+    cv = None
+    cp_cv = None
+    w = None
+    Z = None
+    fi = None
+    f = None
+
+    mu = None
+    k = None
+    nu = None
+    Prandt = None
+    epsilon = None
+    alfa = None
+    n = None
+
+    alfap = None
+    betap = None
+    joule = None
+    Gruneisen = None
+    alfav = None
+    kappa = None
+    betas = None
+    gamma = None
+    Kt = None
+    kt = None
+    Ks = None
+    ks = None
+    dpdT_rho = None
+    dpdrho_T = None
+    drhodT_P = None
+    drhodP_T = None
+    dhdT_rho = None
+    dhdT_P = None
+    dhdrho_T = None
+    dhdrho_P = None
+    dhdP_T = None
+    dhdP_rho = None
+
+    Z_rho = None
+    IntP = None
+    hInput = None
+
+
+def deriv_H(state, z, x, y, fase):
+    """Calculate generic partial derivative: (∂z/∂x)y from a fundamental
+    helmholtz free energy equation of state
+
+    Parameters
+    ----------
+    state : any python object
+        Only need define P and T properties
+    x, y, z : string
+        Name of variables of derivate, can be: P, T, v, rho, u, h, s, g, a
+    fase : any python object
+        Define other phase properties v, cv, alfap, s, betap
+
+    Returns
+    -------
+    deriv : float
+        ∂z/∂x|y
+
+    References
+    ----------
+    IAPWS, Revised Advisory Note No. 3: Thermodynamic Derivatives from IAPWS
+    Formulations, http://www.iapws.org/relguide/Advise3.pdf
+    """
+    # We use the relation between rho and v and his partial derivative
+    # ∂v/∂b|c = -1/ρ² ∂ρ/∂b|c
+    # ∂a/∂v|c = -ρ² ∂a/∂ρ|c
+    mul = 1
+    if z == "rho":
+        mul = -fase.rho**2
+        z = "v"
+    if x == "rho":
+        mul = -1/fase.rho**2
+        x = "v"
+    if y == "rho":
+        y = "v"
+
+    dT = {"P": state.P*1000*fase.alfap,
+          "T": 1,
+          "v": 0,
+          "u": fase.cv,
+          "h": fase.cv+state.P*1000*fase.v*fase.alfap,
+          "s": fase.cv/state.T,
+          "g": state.P*1000*fase.v*fase.alfap-fase.s,
+          "a": -fase.s}
+    dv = {"P": -state.P*1000*fase.betap,
+          "T": 0,
+          "v": 1,
+          "u": state.P*1000*(state.T*fase.alfap-1),
+          "h": state.P*1000*(state.T*fase.alfap-fase.v*fase.betap),
+          "s": state.P*1000*fase.alfap,
+          "g": -state.P*1000*fase.v*fase.betap,
+          "a": -state.P*1000}
+    deriv = (dv[z]*dT[y]-dT[z]*dv[y])/(dv[x]*dT[y]-dT[x]*dv[y])
+    return mul*deriv
+
+
+def deriv_G(state, z, x, y, fase):
+    """Calculate generic partial derivative: (∂z/∂x)y from a fundamental
+    Gibbs free energy equation of state
+
+    Parameters
+    ----------
+    state : any python object
+        Only need define P and T properties
+    x, y, z : string
+        Name of variables of derivate, can be: P, T, v, rho, u, h, s, g, a
+    fase : any python object
+        Define other phase properties v, cp, alfav, s, xkappa
+
+    Returns
+    -------
+    deriv : float
+        ∂z/∂x|y
+
+    References
+    ----------
+    IAPWS, Revised Advisory Note No. 3: Thermodynamic Derivatives from IAPWS
+    Formulations, http://www.iapws.org/relguide/Advise3.pdf
+    """
+    mul = 1
+    if z == "rho":
+        mul = -fase.rho**2
+        z = "v"
+    if x == "rho":
+        mul = -1/fase.rho**2
+        x = "v"
+
+    dT = {"P": 0,
+          "T": 1,
+          "v": fase.v*fase.alfav,
+          "u": fase.cp-state.P*1000*fase.v*fase.alfav,
+          "h": fase.cp,
+          "s": fase.cp/state.T,
+          "g": -fase.s,
+          "a": -state.P*1000*fase.v*fase.alfav-fase.s}
+    dP = {"P": 1,
+          "T": 0,
+          "v": -fase.v*fase.xkappa,
+          "u": fase.v*(state.P*1000*fase.xkappa-state.T*fase.alfav),
+          "h": fase.v*(1-state.T*fase.alfav),
+          "s": -fase.v*fase.alfav,
+          "g": fase.v,
+          "a": state.P*1000*fase.v*fase.xkappa}
+    deriv = (dP[z]*dT[y]-dT[z]*dP[y])/(dP[x]*dT[y]-dT[x]*dP[y])
+    return mul*deriv
diff --git a/iapws/ammonia.py b/iapws/ammonia.py
new file mode 100644
index 0000000..bfb5ae2
--- /dev/null
+++ b/iapws/ammonia.py
@@ -0,0 +1,891 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+Guideline on the IAPWS Formulation 2001 for the Thermodynamic Properties of
+Ammonia-Water Mistures
+"""
+
+
+from __future__ import division
+from math import exp, log, pi
+import warnings
+
+from scipy.constants import Boltzmann as kb
+from scipy.optimize import fsolve
+from .iapws95 import MEoS, IAPWS95
+
+
+class NH3(MEoS):
+    """Multiparameter equation of state for ammonia"""
+    name = "ammonia"
+    CASNumber = "7664-41-7"
+    formula = "NH3"
+    synonym = "R-717"
+    rhoc = 225.
+    Tc = 405.40
+    Pc = 11333.0  # kPa
+    M = 17.03026  # g/mol
+    Tt = 195.495
+    Tb = 239.823
+    f_acent = 0.25601
+    momentoDipolar = 1.470
+
+    Fi0 = {"ao_log": [1, -1],
+           "pow": [0, 1, 1./3, -1.5, -1.75],
+           "ao_pow": [-15.81502, 4.255726, 11.47434, -1.296211, 0.5706757],
+           "ao_exp": [], "titao": [],
+           "ao_hyp": [], "hyp": []}
+
+    _constants = {
+        "R": 8.314471,
+
+        "nr1": [-0.1858814e01, 0.4554431e-1, 0.7238548, 0.1229470e-1,
+                0.2141882e-10],
+        "d1": [1, 2, 1, 4, 15],
+        "t1": [1.5, -0.5, 0.5, 1., 3.],
+
+        "nr2": [-0.1430020e-1, 0.3441324, -0.2873571, 0.2352589e-4,
+                -0.3497111e-1, 0.1831117e-2, 0.2397852e-1, -0.4085375e-1,
+                0.2379275, -0.3548972e-1, -0.1823729, 0.2281556e-1,
+                -0.6663444e-2, -0.8847486e-2, 0.2272635e-2, -0.5588655e-3],
+        "d2": [3, 3, 1, 8, 2, 8, 1, 1, 2, 3, 2, 4, 3, 1, 2, 4],
+        "t2": [0, 3, 4, 4, 5, 5, 3, 6, 8, 8, 10, 10, 5, 7.5, 15, 30],
+        "c2": [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3],
+        "gamma2": [1]*16}
+
+    _melting = {"eq": 1, "Tref": Tt, "Pref": 1000,
+                "Tmin": Tt, "Tmax": 700.0,
+                "a1": [], "exp1": [], "a2": [], "exp2": [],
+                "a3": [0.2533125e4], "exp3": [1]}
+
+    _surf = {"sigma": [0.1028, -0.09453], "exp": [1.211, 5.585]}
+    _Pv = {
+        "eq": 5,
+        "ao": [-0.70993e1, -0.24330e1, 0.87591e1, -0.64091e1, -0.21185e1],
+        "exp": [1., 1.5, 1.7, 1.95, 4.2]}
+    _rhoL = {
+        "eq": 1,
+        "ao": [0.34488e2, -0.12849e3, 0.17382e3, -0.10699e3, 0.30339e2],
+        "exp": [0.58, 0.75, 0.9, 1.1, 1.3]}
+    _rhoG = {
+        "eq": 3,
+        "ao": [-.38435, -4.0846, -6.6634, -0.31881e2, 0.21306e3, -0.24648e3],
+        "exp": [0.218, 0.55, 1.5, 3.7, 5.5, 5.8]}
+
+    def _visco(self, rho, T, fase=None):
+        """Equation for the Viscosity
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        mu : float
+            Viscosity [Pa·s]
+
+        References
+        ----------
+        Fenghour, A., Wakeham, W.A., Vesovic, V., Watson, J.T.R., Millat, J.,
+        and Vogel, E., The viscosity of ammonia, J. Phys. Chem. Ref. Data 24,
+        1649 (1995). doi:10.1063/1.555961
+        """
+        ek = 386
+        sigma = 0.2957
+
+        rho = rho/self.M
+        T_ = T/ek
+
+        # Eq 4
+        a = [4.99318220, -0.61122364, 0.0, 0.18535124, -0.11160946]
+        omega = exp(sum([ai*log(T_)**i for i, ai in enumerate(a)]))
+
+        # Eq 2, Zero-Density Limit
+        muo = 2.1357*(T*self.M)**0.5/sigma**2/omega
+
+        # Eq 8, Viscosity virial coefficient
+        cv = [-0.17999496e1, 0.46692621e2, -0.53460794e3, 0.33604074e4,
+              -0.13019164e5, 0.33414230e5, -0.58711743e5, 0.71426686e5,
+              -0.59834012e5, 0.33652741e5, -0.1202735e5, 0.24348205e4,
+              -0.20807957e3]
+        Bn = 0.6022137*sigma**3*sum([c*T_**(-i/2) for i, c in enumerate(cv)])
+        # Eq 7
+        mub = Bn*muo*rho
+
+        # Eq 10
+        dij = [2.19664285e-1, -0.83651107e-1, 0.17366936e-2, -0.64250359e-2,
+               1.67668649e-4, -1.49710093e-4, 0.77012274e-4]
+        ji = [2, 4, 0, 1, 2, 3, 4]
+        ii = [2, 2, 3, 3, 4, 4, 4]
+        mur = sum([d/T_**j*rho**i for d, j, i in zip(dij, ji, ii)])
+
+        # Eq 1
+        mu = muo + mub + mur
+        return mu*1e-6
+
+    def _thermo(self, rho, T, fase):
+        """Equation for the thermal conductivity
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+        fase: dict
+            phase properties
+
+        Returns
+        -------
+        k : float
+            Thermal conductivity [W/mK]
+
+        References
+        ----------
+        Tufeu, R., Ivanov, D.Y., Garrabos, Y., and Le Neindre, B., Thermal
+        conductivity of ammonia in a large temperature and pressure range
+        including the critical region, Ber. Bunsenges. Phys. Chem., 88:422-427,
+        1984. doi:10.1002/bbpc.19840880421
+        """
+        # The paper use a diferent rhoc value to the EoS
+        rhoc = 235
+
+        if rho == rhoc and T == self.Tc:
+            warnings.warn("Thermal conductiviy undefined in critical point")
+            return None
+
+        # Eq 6
+        no = [0.3589e-1, -0.1750e-3, 0.4551e-6, 0.1685e-9, -0.4828e-12]
+        Lo = sum([n*T**i for i, n in enumerate(no)])
+
+        # Eq 7
+        nb = [0.16207e-3, 0.12038e-5, -0.23139e-8, 0.32749e-11]
+        L_ = sum([n*rho**(i+1) for i, n in enumerate(nb)])
+
+        # Critical enchancement
+        t = abs(T-405.4)/405.4
+        dPT = 1e5*(2.18-0.12/exp(17.8*t))
+        nb = 1e-5*(2.6+1.6*t)
+
+        DL = 1.2*kb*T**2/6/pi/nb/(1.34e-10/t**0.63*(1+t**0.5))*dPT**2 * \
+            0.423e-8/t**1.24*(1+t**0.5/0.7)
+
+        # Add correction for entire range of temperature, Eq 10
+        DL *= exp(-36*t**2)
+
+        X = 0.61*rhoc+16.5*log(t)
+        if rho > 0.6*rhoc:
+            # Eq 11
+            DL *= X**2/(X**2+(rho-0.96*rhoc)**2)
+        else:
+            # Eq 14
+            DL = X**2/(X**2+(0.6*rhoc-0.96*rhoc)**2)
+            DL *= rho**2/(0.6*rhoc)**2
+
+        # Eq 5
+        k = Lo+L_+DL
+        return k
+
+
+class H2ONH3(object):
+    """
+    Water-Ammonia mixture class with complete functionality
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    rho : float
+        Density [kg/m³]
+    v : float
+        Specific volume [m³/kg]
+    A : float
+        Mass fraction of dry air in humid air [kg/kg]
+    xa : float
+        Mole fraction of dry air in humid air [-]
+    W : float
+        Mass fraction of water in humid air [kg/kg]
+    xw : float
+        Mole fraction of water in humid air [-]
+
+    Notes
+    -----
+    * It needs two incoming properties of T, P, rho.
+    * v as a alternate input parameter to rho
+    * For composition need one of A, xa, W, xw.
+
+    Returns
+    -------
+    The calculated instance has the following properties:
+        * P: Pressure [MPa]
+        * T: Temperature [K]
+        * g: Specific Gibbs free energy [kJ/kg]
+        * a: Specific Helmholtz free energy [kJ/kg]
+        * v: Specific volume [m³/kg]
+        * rho: Density [kg/m³]
+        * h: Specific enthalpy [kJ/kg]
+        * u: Specific internal energy [kJ/kg]
+        * s: Specific entropy [kJ/kg·K]
+        * cp: Specific isobaric heat capacity [kJ/kg·K]
+        * w: Speed of sound [m/s]
+
+        * alfav: Isobaric cubic expansion coefficient [1/K]
+        * betas: Isoentropic temperature-pressure coefficient [-]
+        * xkappa: Isothermal Expansion Coefficient [-]
+        * ks: Adiabatic Compressibility [1/MPa]
+
+        * A: Mass fraction of dry air in humid air [kg/kg]
+        * xa: Mole fraction of dry air in humid air [-]
+        * W: Mass fraction of water in humid air [kg/kg]
+        * xw: Mole fraction of water in humid air [-]
+        * mu: Relative chemical potential [kJ/kg]
+        * muw: Chemical potential of water [kJ/kg]
+        * M: Molar mass of humid air [g/mol]
+        * HR: Humidity ratio [-]
+        * xa: Mole fraction of dry air [-]
+        * xw: Mole fraction of water [-]
+        * xa_sat: Mole fraction of dry air at saturation state [-]
+        * RH: Relative humidity
+    """
+    kwargs = {"T": 0.0,
+              "P": 0.0,
+              "rho": 0.0,
+              "v": 0.0,
+              "x": None
+              }
+    status = 0
+    msg = "Undefined"
+
+    def __init__(self, **kwargs):
+        """Constructor, define common constant and initinialice kwargs"""
+        self.kwargs = H2ONH3.kwargs.copy()
+        self.__call__(**kwargs)
+
+    def __call__(self, **kwargs):
+        """Make instance callable to can add input parameter one to one"""
+        # Check alernate input parameters
+        if kwargs.get("v", 0):
+            kwargs["rho"] = 1./kwargs["v"]
+            del kwargs["v"]
+
+        self.kwargs.update(kwargs)
+
+        if self.calculable:
+            self.status = 1
+            self.calculo()
+            self.msg = ""
+
+    @property
+    def calculable(self):
+        """Check if inputs are enough to define state"""
+        self._mode = ""
+        if self.kwargs["T"] and self.kwargs["P"]:
+            self._mode = "TP"
+        elif self.kwargs["T"] and self.kwargs["rho"]:
+            self._mode = "Trho"
+        elif self.kwargs["P"] and self.kwargs["rho"]:
+            self._mode = "Prho"
+
+        # Composition definition
+        self._composition = ""
+        if self.kwargs["x"] is not None:
+            self._composition = "x"
+
+        return bool(self._mode) and bool(self._composition)
+
+    def calculo(self):
+        """Calculate procedure"""
+        T = self.kwargs["T"]
+        rho = self.kwargs["rho"]
+        P = self.kwargs["P"]
+
+        # Composition alternate definition
+        if self._composition == "z":
+            z = self.kwargs["z"]
+
+        # Thermodynamic definition
+        if self._mode == "TP":
+            def f(rho):
+                fav = self._fav(T, rho, A)
+                return rho**2*fav["fird"]/1000-P
+            rho = fsolve(f, 1)[0]
+        elif self._mode == "Prho":
+            def f(T):
+                fav = self._fav(T, rho, A)
+                return rho**2*fav["fird"]/1000-P
+            T = fsolve(f, 300)[0]
+
+
+        prop = self._prop(rho, T, z)
+        self.T = T
+        self.rho = rho
+        self.v = 1/rho
+        self.P = prop["P"]
+        self.u = prop["u"]
+        self.s = prop["s"]
+        self.h = prop["h"]
+        self.g = prop["g"]
+        self.a = prop["a"]
+
+        self.cp = prop["cp"]
+        self.cv = prop["cv"]
+        self.w = prop["w"]
+
+        self.fugH2O = prop["fugH2O"]
+        self.fugNH3 = prop["fugNH3"]
+
+    # def derivative(self, z, x, y):
+        # """Wrapper derivative for custom derived properties
+        # where x, y, z can be: P, T, v, rho, u, h, s, g, a"""
+        # return deriv_G(self, z, x, y, self)
+
+    def _eq(self, rho, T, z):
+        def f(parr):
+            rhol, rhov, x, y = parr
+            propl = self._prop(rhol, T, x)
+            propv = self._prop(rhov, T, y)
+
+            return (propl["P"]-propv["P"],
+                    (1-x)*propl["fugH2O"]-(1-y)*propv["fugH2O"],
+                    x*propl["fugNH3"]-y*propv["fugNH3"],)
+
+
+
+
+
+
+        # # TODO: Add equilibrium routine
+        # """Procedure for calculate the composition in saturation state
+
+        # Parameters
+        # ----------
+        # T : float
+            # Temperature [K]
+        # P : float
+            # Pressure [MPa]
+
+        # Returns
+        # -------
+        # Asat : float
+            # Saturation mass fraction of dry air in humid air [kg/kg]
+        # """
+        # if T <= 273.16:
+            # ice = _Ice(T, P)
+            # gw = ice["g"]
+            # rho = ice["rho"]
+        # else:
+            # water = IAPWS95(T=T, P=P)
+            # gw = water.g
+            # rho = water.rho
+
+        # def f(a):
+            # fa = self._fav(T, rho, a)
+            # muw = fa["fir"]+rho*fa["fird"]-a*fa["fira"]
+            # return gw-muw
+        # Asat = fsolve(f, 0.9)[0]
+        # return Asat
+
+    def _Flash(self, T, P, z):
+        """Flash calculation
+        Ref Naji - Conventional and rapid flash claculations"""
+
+        # Generation of trial pahse composition using Wilson correlation
+        k_h2o = IAPWS95.Pc/P*exp(5.373*(1.+IAPWS95.f_acent)*(1.-IAPWS95.Tc/T))
+        k_nh3 = NH3.Pc/P*exp(5.373*(1.+NH3.f_acent)*(1.-NH3.Tc/T))
+
+        def Rachford(beta):
+            return z*(k_nh3-1)/(1-beta*(1-k_nh3)) + \
+                (1-z)*(k_h2o-1)/(1-beta*(1-k_h2o))
+
+        bubble = Rachford(0)
+        dew = Rachford(1)
+        if bubble < 0:
+            # beta < 0, only liquid phase
+            x = z
+            y = z*k_nh3/(bubble+1)
+            beta = 0
+        elif dew >= 0:
+            # beta > 1, only vapor phase
+            x = z/k_nh3/(1-dew)
+            y = z
+            beta = 1
+        else:
+            beta = 0.5
+            while True:
+                betao = beta
+                solucion = fsolve(Rachford, betao, full_output=True)
+                if solucion[2]!=1:
+                    print(solucion)
+                    break
+                else:
+                    beta = solucion[0][0]
+
+                    xi=[]
+                    yi=[]
+                    for zi, ki in zip(self.fraccion, Ki):
+                        xi.append(float(zi/(1-x+x*ki)))
+                        yi.append(float(zi*ki/(1-x+x*ki)))
+
+                    tital=self._fug(self.Z[1], xi)
+                    titav=self._fug(self.Z[0], yi)
+                    fiv=[z*t*self.P for z, t in zip(yi, titav)]
+                    fil=[z*t*self.P for z, t in zip(xi, tital)]
+                    #criterio de convergencia Eq 21
+                    if sum([abs(l/v-1) for l, v in zip(fil, fiv)])< 1e-14 and abs(x-xo) < 1e-10:
+                        break
+                    else:
+                        Ki=[l/v for l, v in zip(tital, titav)]
+
+        if x < 0:
+            x = 0
+        elif x > 1:
+            x = 1
+
+        return x, xi, yi, Ki
+
+
+    def _Bubble_T(self):
+        def f(T):
+            eq=self.__class__(T, self.P.atm, self.mezcla)
+            return sum([k*x for k, x in zip(eq.Ki, self.fraccion)])-1.
+
+        T=fsolve(f, self.T)
+        return unidades.Temperature(T)
+
+    def _Bubble_P(self):
+        def f(P):
+            eq=self.__class__(self.T, P, self.mezcla)
+            return sum([k*x for k, x in zip(eq.Ki, self.fraccion)])-1.
+
+        P=fsolve(f, self.P.atm)
+        return unidades.Pressure(P, "atm")
+
+    def _Dew_T(self):
+        def f(T):
+            eq=self.__class__(T, self.P.atm, self.mezcla)
+            return 1./sum([x/k for k, x in zip(eq.Ki, self.fraccion)])-1.
+
+        T=fsolve(f, self.T)
+        return unidades.Temperature(T)
+
+    def _Dew_P(self):
+        def f(P):
+            eq=self.__class__(self.T, P, self.mezcla)
+            return sum([x/k for k, x in zip(eq.Ki, self.fraccion)])-1.
+
+        P=fsolve(f, self.P.atm)
+        return unidades.Pressure(P, "atm")
+
+
+
+    def _bubbleP(self, T, xl):
+        def f(parr):
+            rhol, rhov, xv = parr
+            propl = self._prop(rhol, T, xl)
+            propv = self._prop(rhov, T, xv)
+            K_h2o = propv["fugH2O"]/propl["fugH2O"]
+            K_nh3 = propv["fugNH3"]/propl["fugNH3"]
+
+            return (propl["P"]-propv["P"],
+                    xl*propl["fugNH3"]-xv*propv["fugNH3"],
+                    K_nh3*xl+K_h2o*(1-xl)-1)
+        rhol, rhov, xv = fsolve(f, (5, 0.01, 1))
+        print(f([rhol, rhov, xv]))
+
+        prop = {}
+        prop["T"] = T
+        liq = self._prop(rhol, T, xl)
+        prop["P"] = liq["P"]
+        prop["rhol"] = rhol
+        prop["rhov"] = rhov
+        prop["xl"] = xl
+        prop["xv"] = xv
+        print(prop)
+        return prop
+
+    def _prop(self, rho, T, x):
+        """Thermodynamic properties of ammonia-water mixtures
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+        rho : float
+            Density [kg/m³]
+        x : float
+            Mole fraction of ammonia in mixture [mol/mol]
+
+        Returns
+        -------
+        prop : dictionary with thermodynamic properties of humid air
+            M: Mixture molecular mass [g/mol]
+            P: Pressure [MPa]
+            u: Specific internal energy [kJ/kg]
+            s: Specific entropy [kJ/kgK]
+            h: Specific enthalpy [kJ/kg]
+            a: Specific Helmholtz energy [kJ/kg]
+            g: Specific gibbs energy [kJ/kg]
+            cv: Specific isochoric heat capacity [kJ/kgK]
+            cp: Specific isobaric heat capacity [kJ/kgK]
+            w: Speed of sound [m/s]
+            fugH2O: Fugacity of water [-]
+            fugNH3: Fugacity of ammonia [-]
+
+        References
+        ----------
+        IAPWS, Guideline on the IAPWS Formulation 2001 for the Thermodynamic
+        Properties of Ammonia-Water Mixtures,
+        http://www.iapws.org/relguide/nh3h2o.pdf, Table 4
+        """
+        # FIXME: The values are good, bad difer by 1%, a error I can find
+        # In Pressure happen and only use fird
+
+        M = (1-x)*IAPWS95.M + x*NH3.M
+        R = 8.314471/M
+
+        phio = self._phi0(rho, T, x)
+        fio = phio["fio"]
+        tau0 = phio["tau"]
+        fiot = phio["fiot"]
+        fiott = phio["fiott"]
+
+        phir = self._phir(rho, T, x)
+        fir = phir["fir"]
+        tau = phir["tau"]
+        delta = phir["delta"]
+        firt = phir["firt"]
+        firtt = phir["firtt"]
+        fird = phir["fird"]
+        firdd = phir["firdd"]
+        firdt = phir["firdt"]
+        F = phir["F"]
+
+        prop = {}
+        Z = 1 + delta*fird
+        prop["M"] = M
+        prop["P"] = Z*R*T*rho/1000
+        prop["u"] = R*T*(tau0*fiot + tau*firt)
+        prop["s"] = R*(tau0*fiot + tau*firt - fio - fir)
+        prop["h"] = R*T*(1+delta*fird+tau0*fiot+tau*firt)
+        prop["g"] = prop["h"]-T*prop["s"]
+        prop["a"] = prop["u"]-T*prop["s"]
+        cvR = -tau0**2*fiott - tau**2*firtt
+        prop["cv"] = R*cvR
+        prop["cp"] = R*(cvR+(1+delta*fird-delta*tau*firdt)**2 /
+                        (1+2*delta*fird+delta**2*firdd))
+        prop["w"] = (R*T*1000*(1+2*delta*fird+delta**2*firdd +
+                               (1+delta*fird-delta*tau*firdt)**2 / cvR))**0.5
+        prop["fugH2O"] = Z*exp(fir+delta*fird-x*F)
+        prop["fugNH3"] = Z*exp(fir+delta*fird+(1-x)*F)
+        return prop
+
+    def _phi0(self, rho, T, x):
+        """Ideal gas Helmholtz energy of binary mixtures and derivatives
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+        x : float
+            Mole fraction of ammonia in mixture [mol/mol]
+
+        Returns
+        -------
+        prop : dictionary with ideal adimensional helmholtz energy and deriv
+            tau: the adimensional temperature variable [-]
+            delta: the adimensional density variable [-]
+            fio  [-]
+            fiot: [∂fio/∂τ]δ  [-]
+            fiod: [∂fio/∂δ]τ  [-]
+            fiott: [∂²fio/∂τ²]δ  [-]
+            fiodt: [∂²fio/∂τ∂δ]  [-]
+            fiodd: [∂²fio/∂δ²]τ  [-]
+
+        References
+        ----------
+        IAPWS, Guideline on the IAPWS Formulation 2001 for the Thermodynamic
+        Properties of Ammonia-Water Mixtures,
+        http://www.iapws.org/relguide/nh3h2o.pdf, Eq 2
+        """
+        # Define reducing parameters for mixture model
+        M = (1-x)*IAPWS95.M + x*NH3.M
+        tau = 500/T
+        delta = rho/15/M
+
+        # Table 2
+        Fi0 = {
+            "log_water": 3.006320,
+            "ao_water": [-7.720435, 8.649358],
+            "pow_water": [0, 1],
+            "ao_exp": [0.012436, 0.97315, 1.279500, 0.969560, 0.248730],
+            "titao": [1.666, 4.578, 10.018, 11.964, 35.600],
+            "log_nh3": -1.0,
+            "ao_nh3": [-16.444285, 4.036946, 10.69955, -1.775436, 0.82374034],
+            "pow_nh3": [0, 1, 1/3, -3/2, -7/4]}
+
+        fiod = 1/delta
+        fiodd = -1/delta**2
+        fiodt = 0
+        fiow = fiotw = fiottw = 0
+        fioa = fiota = fiotta = 0
+
+        # Water section
+        if x < 1:
+            fiow = Fi0["log_water"]*log(tau) + log(1-x)
+            fiotw = Fi0["log_water"]/tau
+            fiottw = -Fi0["log_water"]/tau**2
+            for n, t in zip(Fi0["ao_water"], Fi0["pow_water"]):
+                fiow += n*tau**t
+                if t != 0:
+                    fiotw += t*n*tau**(t-1)
+                if t not in [0, 1]:
+                    fiottw += n*t*(t-1)*tau**(t-2)
+            for n, t in zip(Fi0["ao_exp"], Fi0["titao"]):
+                fiow += n*log(1-exp(-tau*t))
+                fiotw += n*t*((1-exp(-t*tau))**-1-1)
+                fiottw -= n*t**2*exp(-t*tau)*(1-exp(-t*tau))**-2
+
+        # ammonia section
+        if x > 0:
+            fioa = Fi0["log_nh3"]*log(tau) + log(x)
+            fiota = Fi0["log_nh3"]/tau
+            fiotta = -Fi0["log_nh3"]/tau**2
+            for n, t in zip(Fi0["ao_nh3"], Fi0["pow_nh3"]):
+                fioa += n*tau**t
+                if t != 0:
+                    fiota += t*n*tau**(t-1)
+                if t not in [0, 1]:
+                    fiotta += n*t*(t-1)*tau**(t-2)
+
+        prop = {}
+        prop["tau"] = tau
+        prop["delta"] = delta
+        prop["fio"] = log(delta) + (1-x)*fiow + x*fioa
+        prop["fiot"] = (1-x)*fiotw + x*fiota
+        prop["fiott"] = (1-x)*fiottw + x*fiotta
+        prop["fiod"] = fiod
+        prop["fiodd"] = fiodd
+        prop["fiodt"] = fiodt
+        return prop
+
+    def _phir(self, rho, T, x):
+        """Residual contribution to the free Helmholtz energy
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+        x : float
+            Mole fraction of ammonia in mixture [mol/mol]
+
+        Returns
+        -------
+        prop : dictionary with residual adimensional helmholtz energy and deriv
+            tau: the adimensional temperature variable [-]
+            delta: the adimensional density variable [-]
+            fir  [-]
+            firt: [∂fir/∂τ]δ,x  [-]
+            fird: [∂fir/∂δ]τ,x  [-]
+            firtt: [∂²fir/∂τ²]δ,x  [-]
+            firdt: [∂²fir/∂τ∂δ]x  [-]
+            firdd: [∂²fir/∂δ²]τ,x  [-]
+            firx: [∂fir/∂x]τ,δ  [-]
+            F: Function for fugacity calculation [-]
+
+        References
+        ----------
+        IAPWS, Guideline on the IAPWS Formulation 2001 for the Thermodynamic
+        Properties of Ammonia-Water Mixtures,
+        http://www.iapws.org/relguide/nh3h2o.pdf, Eq 3
+        """
+
+        # Temperature reducing value, Eq 4
+        Tc12 = 0.9648407/2*(IAPWS95.Tc+NH3.Tc)
+        Tn = (1-x)**2*IAPWS95.Tc + x**2*NH3.Tc + 2*x*(1-x**1.125455)*Tc12
+        dTnx = -2*IAPWS95.Tc*(1-x) + 2*x*NH3.Tc + 2*Tc12*(1-x**1.125455) - \
+            2*Tc12*1.12455*x**1.12455
+
+        # Density reducing value, Eq 5
+        b = 0.8978069
+        rhoc12 = 1/(1.2395117/2*(1/IAPWS95.rhoc+1/NH3.rhoc))
+        rhon = 1/((1-x)**2/IAPWS95.rhoc + x**2/NH3.rhoc +
+                  2*x*(1-x**b)/rhoc12)
+        drhonx = -(2*b*x**b/rhoc12 + 2*(1-x**b)/rhoc12 +
+                   2*x/NH3.rhoc - 2*(1-x)/IAPWS95.rhoc)/(
+                       2*x*(1-x**b)/rhoc12 + x**2/NH3.rhoc +
+                       (1-x)**2/IAPWS95.rhoc)**2
+
+        tau = Tn/T
+        delta = rho/rhon
+
+        water = IAPWS95()
+        phi1 = water._phir(tau, delta)
+
+        ammonia = NH3()
+        phi2 = ammonia._phir(tau, delta)
+
+        Dphi = self._Dphir(tau, delta, x)
+
+        prop = {}
+        prop["tau"] = tau
+        prop["delta"] = delta
+        prop["fir"] = (1-x)*phi1["fir"] + x*phi2["fir"] + Dphi["fir"]
+        prop["firt"] = (1-x)*phi1["firt"] + x*phi2["firt"] + Dphi["firt"]
+        prop["firtt"] = (1-x)*phi1["firtt"] + x*phi2["firtt"] + Dphi["firtt"]
+        prop["fird"] = (1-x)*phi1["fird"] + x*phi2["fird"] + Dphi["fird"]
+        prop["firdd"] = (1-x)*phi1["firdd"] + x*phi2["firdd"] + Dphi["firdd"]
+        prop["firdt"] = (1-x)*phi1["firdt"] + x*phi2["firdt"] + Dphi["firdt"]
+        prop["firx"] = -phi1["fir"] + phi2["fir"] + Dphi["firx"]
+        prop["F"] = prop["firx"] - delta/rhon*drhonx*prop["fird"] + \
+            tau/Tn*dTnx*prop["firt"]
+        return prop
+
+    def _Dphir(self, tau, delta, x):
+        """Departure function to the residual contribution to the free
+        Helmholtz energy
+
+        Parameters
+        ----------
+        tau : float
+            Adimensional temperature [-]
+        delta : float
+            Adimensional density [-]
+        x : float
+            Mole fraction of ammonia in mixture [mol/mol]
+
+        Returns
+        -------
+        prop : dictionary with departure contribution to the residual
+        adimensional helmholtz energy and deriv
+            fir  [-]
+            firt: [∂Δfir/∂τ]δ,x  [-]
+            fird: [∂Δfir/∂δ]τ,x  [-]
+            firtt: [∂²Δfir/∂τ²]δ,x  [-]
+            firdt: [∂²Δfir/∂τ∂δ]x  [-]
+            firdd: [∂²Δfir/∂δ²]τ,x  [-]
+            firx: [∂Δfir/∂x]τ,δ  [-]
+
+        References
+        ----------
+        IAPWS, Guideline on the IAPWS Formulation 2001 for the Thermodynamic
+        Properties of Ammonia-Water Mixtures,
+        http://www.iapws.org/relguide/nh3h2o.pdf, Eq 8
+        """
+        fx = x*(1-x**0.5248379)
+        dfx = 1-1.5248379*x**0.5248379
+
+        # Polinomial terms
+        n = -1.855822e-2
+        t = 1.5
+        d = 4
+        fir = n*delta**d*tau**t
+        fird = n*d*delta**(d-1)*tau**t
+        firdd = n*d*(d-1)*delta**(d-2)*tau**t
+        firt = n*t*delta**d*tau**(t-1)
+        firtt = n*t*(t-1)*delta**d*tau**(t-2)
+        firdt = n*t*d*delta**(d-1)*tau**(t-1)
+        firx = dfx*n*delta**d*tau**t
+
+        # Exponential terms
+        nr2 = [5.258010e-2, 3.552874e-10, 5.451379e-6, -5.998546e-13,
+               -3.687808e-6]
+        t2 = [0.5, 6.5, 1.75, 15, 6]
+        d2 = [5, 15, 12, 12, 15]
+        c2 = [1, 1, 1, 1, 2]
+        for n, d, t, c in zip(nr2, d2, t2, c2):
+            fir += n*delta**d*tau**t*exp(-delta**c)
+            fird += n*exp(-delta**c)*delta**(d-1)*tau**t*(d-c*delta**c)
+            firdd += n*exp(-delta**c)*delta**(d-2)*tau**t * \
+                ((d-c*delta**c)*(d-1-c*delta**c)-c**2*delta**c)
+            firt += n*t*delta**d*tau**(t-1)*exp(-delta**c)
+            firtt += n*t*(t-1)*delta**d*tau**(t-2)*exp(-delta**c)
+            firdt += n*t*delta**(d-1)*tau**(t-1)*(d-c*delta**c)*exp(
+                -delta**c)
+            firx += dfx*n*delta**d*tau**t*exp(-delta**c)
+
+        # Exponential terms with composition
+        nr3 = [0.2586192, -1.368072e-8, 1.226146e-2, -7.181443e-2, 9.970849e-2,
+               1.0584086e-3, -0.1963687]
+        t3 = [-1, 4, 3.5, 0, -1, 8, 7.5]
+        d3 = [4, 15, 4, 5, 6, 10, 6]
+        c3 = [1, 1, 1, 1, 2, 2, 2]
+        for n, d, t, c in zip(nr3, d3, t3, c3):
+            fir += x*n*delta**d*tau**t*exp(-delta**c)
+            fird += x*n*exp(-delta**c)*delta**(d-1)*tau**t*(d-c*delta**c)
+            firdd += x*n*exp(-delta**c)*delta**(d-2)*tau**t * \
+                ((d-c*delta**c)*(d-1-c*delta**c)-c**2*delta**c)
+            firt += x*n*t*delta**d*tau**(t-1)*exp(-delta**c)
+            firtt += x*n*t*(t-1)*delta**d*tau**(t-2)*exp(-delta**c)
+            firdt += x*n*t*delta**(d-1)*tau**(t-1)*(d-c*delta**c)*exp(
+                -delta**c)
+            firx += x*dfx*n*delta**d*tau**t*exp(-delta**c)
+
+        n = -0.7777897
+        t = 4
+        d = 2
+        c = 2
+        fir += x**2*n*delta**d*tau**t*exp(-delta**c)
+        fird += x**2*n*exp(-delta**c)*delta**(d-1)*tau**t*(d-c*delta**c)
+        firdd += x**2*n*exp(-delta**c)*delta**(d-2)*tau**t * \
+            ((d-c*delta**c)*(d-1-c*delta**c)-c**2*delta**c)
+        firt += x**2*n*t*delta**d*tau**(t-1)*exp(-delta**c)
+        firtt += x**2*n*t*(t-1)*delta**d*tau**(t-2)*exp(-delta**c)
+        firdt += x**2*n*t*delta**(d-1)*tau**(t-1)*(d-c*delta**c)*exp(
+            -delta**c)
+        firx += x**2*dfx*n*delta**d*tau**t*exp(-delta**c)
+
+        prop = {}
+        prop["fir"] = fir*fx
+        prop["firt"] = firt*fx
+        prop["firtt"] = firtt*fx
+        prop["fird"] = fird*fx
+        prop["firdd"] = firdd*fx
+        prop["firdt"] = firdt*fx
+        prop["firx"] = firx
+        return prop
+
+
+def Ttr(x):
+    """Equation for the triple point of ammonia-water mixture
+
+    Parameters
+    ----------
+    x : float
+        Mole fraction of ammonia in mixture [mol/mol]
+
+    Returns
+    -------
+    Ttr : float
+        Triple point temperature [K]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 0 ≤ x ≤ 1
+
+    References
+    ----------
+    IAPWS, Guideline on the IAPWS Formulation 2001 for the Thermodynamic
+    Properties of Ammonia-Water Mixtures,
+    http://www.iapws.org/relguide/nh3h2o.pdf, Eq 9
+    """
+    if 0 <= x <= 0.33367:
+        Ttr = 273.16*(1-0.3439823*x-1.3274271*x**2-274.973*x**3)
+    elif 0.33367 < x <= 0.58396:
+        Ttr = 193.549*(1-4.987368*(x-0.5)**2)
+    elif 0.58396 < x <= 0.81473:
+        Ttr = 194.38*(1-4.886151*(x-2/3)**2+10.37298*(x-2/3)**3)
+    elif 0.81473 < x <= 1:
+        Ttr = 195.495*(1-0.323998*(1-x)-15.87560*(1-x)**4)
+    else:
+        raise NotImplementedError("Incoming out of bound")
+    return Ttr
diff --git a/iapws/humidAir.py b/iapws/humidAir.py
new file mode 100644
index 0000000..ed0c048
--- /dev/null
+++ b/iapws/humidAir.py
@@ -0,0 +1,983 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+Guideline on the IAPWS Formulation 2001 for the Thermodynamic Properties of
+Ammonia-Water Mistures
+"""
+
+
+from __future__ import division
+from math import exp, log, pi, atan
+import warnings
+
+from scipy.optimize import fsolve
+
+from ._iapws import M as Mw
+from ._iapws import _Ice
+from ._utils import deriv_G
+from .iapws95 import MEoS, IAPWS95
+
+
+Ma = 28.96546  # g/mol
+R = 8.314472  # J/molK
+
+
+def _virial(T):
+    """Virial equations for humid air
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    prop : float
+        dictionary with critical coefficient
+        Baa: Second virial coefficient of dry air [m³/mol]
+        Baw: Second air-water cross virial coefficient [m³/mol]
+        Bww: Second virial coefficient of water [m³/mol]
+        Caaa: Third virial coefficient of dry air [m⁶/mol]
+        Caaw: Third air-water cross virial coefficient [m⁶/mol]
+        Caww: Third air-water cross virial coefficient [m⁶/mol]
+        Cwww: Third virial coefficient of dry air [m⁶/mol]
+        Bawt: dBaw/dT [m³/molK]
+        Bawtt: d²Baw/dT² [m³/molK²]
+        Caawt: dCaaw/dT [m⁶/molK]
+        Caawtt: d²Caaw/dT² [m⁶/molK²]
+        Cawwt: dCaww/dT [m⁶/molK]
+        Cawwtt: d²Caww/dT² [m⁶/molK²]
+
+    Raises
+    ------
+    Warning : If T isn't in range of validity
+        * Baa: 60 ≤ T ≤ 2000
+        * Baw: 130 ≤ T ≤ 2000
+        * Bww: 130 ≤ T ≤ 1273
+        * Caaa: 60 ≤ T ≤ 2000
+        * Caaw: 193 ≤ T ≤ 493
+        * Caww: 173 ≤ T ≤ 473
+        * Cwww: 130 ≤ T ≤ 1273
+
+    Examples
+    --------
+    >>> _virial(200)["Baa"]
+    -3.92722567e-5
+
+    References
+    ----------
+    IAPWS, Guideline on a Virial Equation for the Fugacity of H2O in Humid Air,
+    http://www.iapws.org/relguide/VirialFugacity.html
+    IAPWS, Guideline on an Equation of State for Humid Air in Contact with
+    Seawater and Ice, Consistent with the IAPWS Formulation 2008 for the
+    Thermodynamic Properties of Seawater, Table 10,
+    http://www.iapws.org/relguide/SeaAir.html
+    """
+    # Check input parameters
+    if T < 60 or T > 2000:
+        warnings.warn("Baa out of validity range")
+    if T < 130 or T > 2000:
+        warnings.warn("Baw out of validity range")
+    if T < 130 or T > 1273:
+        warnings.warn("Bww out of validity range")
+    if T < 60 or T > 2000:
+        warnings.warn("Caaa out of validity range")
+    if T < 193 or T > 493:
+        warnings.warn("Caaw out of validity range")
+    if T < 173 or T > 473:
+        warnings.warn("Caww out of validity range")
+    if T < 130 or T > 1273:
+        warnings.warn("Cwww out of validity range")
+
+    T_ = T/100
+    tau = IAPWS95.Tc/T
+
+    # Table 1
+    # Reorganizated to easy use in equations
+    tb = [-0.5, 0.875, 1, 4, 6, 12, 7]
+    nb = [0.12533547935523e-1, 0.78957634722828e1, -0.87803203303561e1,
+          -0.66856572307965, 0.20433810950965, -0.66212605039687e-4,
+          -0.10793600908932]
+    bc = [0.5, 0.75, 1, 5, 1, 9, 10]
+    nc = [0.31802509345418, -0.26145533859358, -0.19232721156002,
+          -0.25709043003438, 0.17611491008752e-1, 0.22132295167546,
+          -0.40247669763528]
+    bc2 = [4, 6, 12]
+    nc2 = [-0.66856572307965, 0.20433810950965, -0.66212605039687e-4]
+
+    # Table 2
+    ai = [3.5, 3.5]
+    bi = [0.85, 0.95]
+    Bi = [0.2, 0.2]
+    ni = [-0.14874640856724, 0.31806110878444]
+    Ci = [28, 32]
+    Di = [700, 800]
+    Ai = [0.32, 0.32]
+    betai = [0.3, 0.3]
+
+    # Eq 5
+    sum1 = sum([n*tau**t for n, t in zip(nb, tb)])
+    sum2 = 0
+    for n, b, B, A, C, D in zip(ni, bi, Bi, Ai, Ci, Di):
+        sum2 += n*((A+1-tau)**2+B)**b*exp(-C-D*(tau-1)**2)
+    Bww = Mw/IAPWS95.rhoc*(sum1+sum2)
+
+    # Eq 6
+    sum1 = sum([n*tau**t for n, t in zip(nc, bc)])
+    sum2 = sum([n*tau**t for n, t in zip(nc2, bc2)])
+    sum3 = 0
+    for a, b, B, n, C, D, A, beta in zip(ai, bi, Bi, ni, Ci, Di, Ai, betai):
+        Tita = A+1-tau
+        sum3 += n*(C*(Tita**2+B)-b*(A*Tita/beta+B*a))*(Tita**2+B)**(b-1) * \
+            exp(-C-D*(tau-1)**2)
+    Cwww = 2*(Mw/IAPWS95.rhoc)**2*(sum1-sum2+2*sum3)
+
+    # Table 3
+    ai = [0.482737e-3, 0.105678e-2, -0.656394e-2, 0.294442e-1, -0.319317e-1]
+    bi = [-10.728876, 34.7802, -38.3383, 33.406]
+    ci = [66.5687, -238.834, -176.755]
+    di = [-0.237, -1.048, -3.183]
+
+    Baw = 1e-6*sum([c*T_**d for c, d in zip(ci, di)])                  # Eq 7
+    Caaw = 1e-6*sum([a/T_**i for i, a in enumerate(ai)])               # Eq 8
+    Caww = -1e-6*exp(sum([b/T_**i for i, b in enumerate(bi)]))         # Eq 9
+
+    # Eq T56
+    Bawt = 1e-6*T_/T*sum([c*d*T_**(d-1) for c, d in zip(ci, di)])
+    # Eq T57
+    Bawtt = 1e-6*T_**2/T**2*sum(
+        [c*d*(d-1)*T_**(d-2) for c, d in zip(ci, di)])
+    # Eq T59
+    Caawt = -1e-6*T_/T*sum([i*a*T_**(-i-1) for i, a in enumerate(ai)])
+    # Eq T60
+    Caawtt = 1e-6*T_**2/T**2*sum(
+        [i*(i+1)*a*T_**(-i-2) for i, a in enumerate(ai)])
+    # Eq T62
+    Cawwt = 1e-6*T_/T*sum([i*b*T_**(-i-1) for i, b in enumerate(bi)]) * \
+        exp(sum([b/T_**i for i, b in enumerate(bi)]))
+    # Eq T63
+    Cawwtt = -1e-6*T_**2/T**2*((
+        sum([i*(i+1)*b*T_**(-i-2) for i, b in enumerate(bi)]) +
+        sum([i*b*T_**(-i-1) for i, b in enumerate(bi)])**2) *
+        exp(sum([b/T_**i for i, b in enumerate(bi)])))
+
+    # Table 4
+    # Reorganizated to easy use in equations
+    ji = [0, 0.33, 1.01, 1.6, 3.6, 3.5]
+    ni = [0.118160747229, 0.713116392079, -0.161824192067e1, -0.101365037912,
+          -0.146629609713, 0.148287891978e-1]
+    tau = 132.6312/T
+
+    Baa = 1/10.4477*sum([n*tau**j for j, n in zip(ji, ni)])          # Eq 10
+    Caaa = 2/10.4477**2*(0.714140178971e-1+0.101365037912*tau**1.6)  # Eq 11
+
+    prop = {}
+    prop["Baa"] = Baa/1000
+    prop["Baw"] = Baw
+    prop["Bww"] = Bww/1000
+    prop["Caaa"] = Caaa/1e6
+    prop["Caaw"] = Caaw
+    prop["Caww"] = Caww
+    prop["Cwww"] = Cwww/1e6
+    prop["Bawt"] = Bawt
+    prop["Bawtt"] = Bawtt
+    prop["Caawt"] = Caawt
+    prop["Caawtt"] = Caawtt
+    prop["Cawwt"] = Cawwt
+    prop["Cawwtt"] = Cawwtt
+    return prop
+
+
+def _fugacity(T, P, x):
+    """Fugacity equation for humid air
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    x : float
+        Mole fraction of water-vapor [-]
+
+    Returns
+    -------
+    fv : float
+        fugacity coefficient [MPa]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in range of validity
+        * 193 ≤ T ≤ 473
+        * 0 ≤ P ≤ 5
+        * 0 ≤ x ≤ 1
+        Really the xmax is the xsaturation but isn't implemented
+
+    Examples
+    --------
+    >>> _fugacity(300, 1, 0.1)
+    0.0884061686
+
+    References
+    ----------
+    IAPWS, Guideline on a Virial Equation for the Fugacity of H2O in Humid Air,
+    http://www.iapws.org/relguide/VirialFugacity.html
+    """
+    # Check input parameters
+    if T < 193 or T > 473 or P < 0 or P > 5 or x < 0 or x > 1:
+        raise(NotImplementedError("Input not in range of validity"))
+
+    R = 8.314462  # J/molK
+
+    # Virial coefficients
+    vir = _virial(T)
+
+    # Eq 3
+    beta = x*(2-x)*vir["Bww"]+(1-x)**2*(2*vir["Baw"]-vir["Baa"])
+
+    # Eq 4
+    gamma = x**2*(3-2*x)*vir["Cwww"] + \
+        (1-x)**2*(6*x*vir["Caww"]+3*(1-2*x)*vir["Caaw"]-2*(1-x)*vir["Caaa"]) +\
+        (x**2*vir["Bww"]+2*x*(1-x)*vir["Baw"]+(1-x)**2*vir["Baa"]) * \
+        (x*(3*x-4)*vir["Bww"]+2*(1-x)*(3*x-2)*vir["Baw"]+3*(1-x)**2*vir["Baa"])
+
+    # Eq 2
+    fv = x*P*exp(beta*P*1e6/R/T+0.5*gamma*(P*1e6/R/T)**2)
+    return fv
+
+
+class MEoSBlend(MEoS):
+    """Special meos class to im:plement pseudocomponent blend and defining its
+    ancillary dew and bubble point"""
+    @classmethod
+    def _dewP(cls, T):
+        """Using ancillary equation return the pressure of dew point"""
+        c = cls._blend["dew"]
+        Tj = cls._blend["Tj"]
+        Pj = cls._blend["Pj"]
+        Tita = 1-T/Tj
+
+        suma = 0
+        for i, n in zip(c["i"], c["n"]):
+            suma += n*Tita**(i/2.)
+        P = Pj*exp(Tj/T*suma)
+        return P
+
+    @classmethod
+    def _bubbleP(cls, T):
+        """Using ancillary equation return the pressure of bubble point"""
+        c = cls._blend["bubble"]
+        Tj = cls._blend["Tj"]
+        Pj = cls._blend["Pj"]
+        Tita = 1-T/Tj
+
+        suma = 0
+        for i, n in zip(c["i"], c["n"]):
+            suma += n*Tita**(i/2.)
+        P = Pj*exp(Tj/T*suma)
+        return P
+
+
+class Air(MEoSBlend):
+    """Multiparameter equation of state for Air as pseudocomponent"""
+    name = "air"
+    CASNumber = "1"
+    formula = "N2+Ar+O2"
+    synonym = "R-729"
+    rhoc = 10.4477*Ma
+    Tc = 132.6306
+    Pc = 3786.0  # kPa
+    M = Ma
+    Tt = 59.75
+    Tb = 78.903
+    f_acent = 0.0335
+    momentoDipolar = 0.0
+
+    Fi0 = {"ao_log": [1, 2.490888032],
+           "pow": [-3, -2, -1, 0, 1, 1.5],
+           "ao_pow": [0.6057194e-7, -0.210274769e-4, -0.158860716e-3,
+                      9.7450251743948, 10.0986147428912, -0.19536342e-3],
+           "ao_exp": [0.791309509, 0.212236768],
+           "titao": [25.36365, 16.90741],
+           "ao_exp2": [-0.197938904],
+           "titao2": [87.31279],
+           "sum2": [2./3]
+           }
+
+    _constants = {
+        "R": 8.31451,
+        "Tref": 132.6312, "rhoref": 10.4477*Ma,
+
+        "nr1": [0.118160747229, 0.713116392079, -0.161824192067e1,
+                0.714140178971e-1, -0.865421396646e-1, 0.134211176704,
+                0.112626704218e-1, -0.420533228842e-1, 0.349008431982e-1,
+                0.164957183186e-3],
+        "d1": [1, 1, 1, 2, 3, 3, 4, 4, 4, 6],
+        "t1": [0, 0.33, 1.01, 0, 0, 0.15, 0, 0.2, 0.35, 1.35],
+
+        "nr2": [-0.101365037912, -0.173813690970, -0.472103183731e-1,
+                -0.122523554253e-1, -0.146629609713, -0.316055879821e-1,
+                0.233594806142e-3, 0.148287891978e-1, -0.938782884667e-2],
+        "d2": [1, 3, 5, 6, 1, 3, 11, 1, 3],
+        "t2": [1.6, 0.8, 0.95, 1.25, 3.6, 6, 3.25, 3.5, 15],
+        "c2": [1, 1, 1, 1, 2, 2, 2, 3, 3],
+        "gamma2": [1]*9}
+
+    _blend = {
+        "Tj": 132.6312, "Pj": 3.78502,
+        "dew": {"i": [1, 2, 5, 8],
+                "n": [-0.1567266, -5.539635, 0.7567212, -3.514322]},
+        "bubble": {"i": [1, 2, 3, 4, 5, 6],
+                   "n": [0.2260724, -7.080499, 5.700283, -12.44017, 17.81926,
+                         -10.81364]}}
+
+    _melting = {"eq": 1, "Tref": Tb, "Pref": 5.265,
+                "Tmin": 59.75, "Tmax": 2000.0,
+                "a1": [1, 0.354935e5, -0.354935e5],
+                "exp1": [0, 0.178963e1, 0],
+                "a2": [], "exp2": [], "a3": [], "exp3": []}
+    _surf = {"sigma": [0.03046], "exp": [1.28]}
+    _rhoG = {
+        "eq": 3,
+        "ao": [-0.20466e1, -0.4752e1, -0.13259e2, -0.47652e2],
+        "exp": [0.41, 1, 2.8, 6.5]}
+    _Pv = {
+        "ao": [-0.1567266, -0.5539635e1, 0.7567212, -0.3514322e1],
+        "exp": [0.5, 1, 2.5, 4]}
+
+    @classmethod
+    def _Liquid_Density(cls, T):
+        """Auxiliary equation for the density or saturated liquid
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        rho : float
+            Saturated liquid density [kg/m³]
+        """
+        Tc = 132.6312
+        rhoc = 10.4477*cls.M
+        Ni = [44.3413, -240.073, 285.139, -88.3366]
+        ti = [0.65, 0.85, 0.95, 1.1]
+        Tita = 1-T/Tc
+        suma = 1
+        for n, t in zip(Ni, ti):
+            suma += n*Tita**t
+        suma -= 0.892181*log(T/Tc)
+        rho = suma*rhoc
+        return rho
+
+    @staticmethod
+    def _visco(rho, T, fase=None):
+        """Equation for the Viscosity
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        mu : float
+            Viscosity [Pa·s]
+
+        References
+        ----------
+        Lemmon, E.W. and Jacobsen, R.T., Viscosity and Thermal Conductivity
+        Equations for Nitrogen, Oxygen, Argon, and Air, Int. J. Thermophys.,
+        25:21-69, 2004. doi:10.1023/B:IJOT.0000022327.04529.f3
+        """
+        ek = 103.3
+        sigma = 0.36
+        M = 28.9586
+        rhoc = 10.4477*M
+        tau = 132.6312/T
+        delta = rho/rhoc
+
+        b = [0.431, -0.4623, 0.08406, 0.005341, -0.00331]
+        T_ = log(T/ek)
+        suma = 0
+        for i, bi in enumerate(b):
+            suma += bi*T_**i
+        omega = exp(suma)
+
+        # Eq 2
+        muo = 0.0266958*(M*T)**0.5/(sigma**2*omega)
+
+        n_poly = [10.72, 1.122, 0.002019, -8.876, -0.02916]
+        t_poly = [.2, .05, 2.4, .6, 3.6]
+        d_poly = [1, 4, 9, 1, 8]
+        l_poly = [0, 0, 0, 1, 1]
+        g_poly = [0, 0, 0, 1, 1]
+
+        # Eq 3
+        mur = 0
+        for n, t, d, l, g in zip(n_poly, t_poly, d_poly, l_poly, g_poly):
+            mur += n*tau**t*delta**d*exp(-g*delta**l)
+
+        # Eq 1
+        mu = muo+mur
+        return mu*1e-6
+
+    def _thermo(self, rho, T, fase=None):
+        """Equation for the thermal conductivity
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+        fase: dict
+            phase properties
+
+        Returns
+        -------
+        k : float
+            Thermal conductivity [W/mK]
+
+        References
+        ----------
+        Lemmon, E.W. and Jacobsen, R.T., Viscosity and Thermal Conductivity
+        Equations for Nitrogen, Oxygen, Argon, and Air, Int. J. Thermophys.,
+        25:21-69, 2004. doi:10.1023/B:IJOT.0000022327.04529.f3
+        """
+        ek = 103.3
+        sigma = 0.36
+        M = 28.9586
+        rhoc = 10.4477*M
+        tau = 132.6312/T
+        delta = rho/rhoc
+
+        b = [0.431, -0.4623, 0.08406, 0.005341, -0.00331]
+        T_ = log(T/ek)
+        suma = 0
+        for i, bi in enumerate(b):
+            suma += bi*T_**i
+        omega = exp(suma)
+
+        # Eq 2
+        muo = 0.0266958*(M*T)**0.5/(sigma**2*omega)
+
+        # Eq 5
+        N = [1.308, 1.405, -1.036]
+        t = [-1.1, -0.3]
+        lo = N[0]*muo+N[1]*tau**t[0]+N[2]*tau**t[1]
+
+        n_poly = [8.743, 14.76, -16.62, 3.793, -6.142, -0.3778]
+        t_poly = [0.1, 0, 0.5, 2.7, 0.3, 1.3]
+        d_poly = [1, 2, 3, 7, 7, 11]
+        g_poly = [0, 0, 1, 1, 1, 1]
+        l_poly = [0, 0, 2, 2, 2, 2]
+
+        # Eq 6
+        lr = 0
+        for n, t, d, l, g in zip(n_poly, t_poly, d_poly, l_poly, g_poly):
+            lr += n*tau**t*delta**d*exp(-g*delta**l)
+
+        lc = 0
+        # FIXME: Tiny desviation in the test in paper, 0.06% at critical point
+        if fase:
+            qd = 0.31
+            Gamma = 0.055
+            Xio = 0.11
+            Tref = 265.262
+            k = 1.380658e-23  # J/K
+
+            # Eq 11
+            X = self.Pc*1e-3*rho/rhoc**2*fase.drhodP_T
+
+            ref = Air()
+            st = ref._Helmholtz(rho, Tref)
+            drho = 1e3/self.R/Tref/(1+2*delta*st["fird"]+delta**2*st["firdd"])
+
+            Xref = self.Pc*1e-3*rho/rhoc**2*drho
+
+            # Eq 10
+            bracket = X-Xref*Tref/T
+            if bracket > 0:
+                Xi = Xio*(bracket/Gamma)**(0.63/1.2415)
+
+                Xq = Xi/qd
+                # Eq 8
+                Omega = 2/pi*((fase.cp-fase.cv)/fase.cp*atan(Xq) +
+                              fase.cv/fase.cp*(Xq))
+                # Eq 9
+                Omega0 = 2/pi*(1-exp(-1/(1/Xq+Xq**2/3*rhoc**2/rho**2)))
+
+                # Eq 7
+                lc = rho*fase.cp*k*1.01*T/6/pi/Xi/fase.mu*(Omega-Omega0)*1e15
+            else:
+                lc = 0
+
+        # Eq 4
+        k = lo+lr+lc
+
+        return k*1e-3
+
+
+class HumidAir(object):
+    """
+    Humid air class with complete functionality
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    rho : float
+        Density [kg/m³]
+    v : float
+        Specific volume [m³/kg]
+    A : float
+        Mass fraction of dry air in humid air [kg/kg]
+    xa : float
+        Mole fraction of dry air in humid air [-]
+    W : float
+        Mass fraction of water in humid air [kg/kg]
+    xw : float
+        Mole fraction of water in humid air [-]
+
+    Notes
+    -----
+    * It needs two incoming properties of T, P, rho.
+    * v as a alternate input parameter to rho
+    * For composition need one of A, xa, W, xw.
+
+    Returns
+    -------
+    The calculated instance has the following properties:
+        * P: Pressure [MPa]
+        * T: Temperature [K]
+        * g: Specific Gibbs free energy [kJ/kg]
+        * a: Specific Helmholtz free energy [kJ/kg]
+        * v: Specific volume [m³/kg]
+        * rho: Density [kg/m³]
+        * h: Specific enthalpy [kJ/kg]
+        * u: Specific internal energy [kJ/kg]
+        * s: Specific entropy [kJ/kg·K]
+        * cp: Specific isobaric heat capacity [kJ/kg·K]
+        * w: Speed of sound [m/s]
+
+        * alfav: Isobaric cubic expansion coefficient [1/K]
+        * betas: Isoentropic temperature-pressure coefficient [-]
+        * xkappa: Isothermal Expansion Coefficient [-]
+        * ks: Adiabatic Compressibility [1/MPa]
+
+        * A: Mass fraction of dry air in humid air [kg/kg]
+        * xa: Mole fraction of dry air in humid air [-]
+        * W: Mass fraction of water in humid air [kg/kg]
+        * xw: Mole fraction of water in humid air [-]
+        * mu: Relative chemical potential [kJ/kg]
+        * muw: Chemical potential of water [kJ/kg]
+        * M: Molar mass of humid air [g/mol]
+        * HR: Humidity ratio [-]
+        * xa: Mole fraction of dry air [-]
+        * xw: Mole fraction of water [-]
+        * xa_sat: Mole fraction of dry air at saturation state [-]
+        * RH: Relative humidity
+    """
+    kwargs = {"T": 0.0,
+              "P": 0.0,
+              "rho": 0.0,
+              "v": 0.0,
+              "A": None,
+              "xa": None,
+              "W": None,
+              "xw": None}
+    status = 0
+    msg = "Undefined"
+
+    def __init__(self, **kwargs):
+        """Constructor, define common constant and initinialice kwargs"""
+        self.kwargs = HumidAir.kwargs.copy()
+        self.__call__(**kwargs)
+
+    def __call__(self, **kwargs):
+        """Make instance callable to can add input parameter one to one"""
+        # Check alernate input parameters
+        if kwargs.get("v", 0):
+            kwargs["rho"] = 1./kwargs["v"]
+            del kwargs["v"]
+        if kwargs.get("W", 0):
+            kwargs["A"] = 1-kwargs["W"]
+            del kwargs["W"]
+        if kwargs.get("xw", 0):
+            kwargs["xa"] = 1-kwargs["xw"]
+            del kwargs["xw"]
+
+        self.kwargs.update(kwargs)
+
+        if self.calculable:
+            self.status = 1
+            self.calculo()
+            self.msg = ""
+
+    @property
+    def calculable(self):
+        """Check if inputs are enough to define state"""
+        self._mode = ""
+        if self.kwargs["T"] and self.kwargs["P"]:
+            self._mode = "TP"
+        elif self.kwargs["T"] and self.kwargs["rho"]:
+            self._mode = "Trho"
+        elif self.kwargs["P"] and self.kwargs["rho"]:
+            self._mode = "Prho"
+
+        # Composition definition
+        self._composition = ""
+        if self.kwargs["A"] is not None:
+            self._composition = "A"
+        elif self.kwargs["xa"] is not None:
+            self._composition = "xa"
+
+        return bool(self._mode) and bool(self._composition)
+
+    def calculo(self):
+        """Calculate procedure"""
+        T = self.kwargs["T"]
+        rho = self.kwargs["rho"]
+        P = self.kwargs["P"]
+
+        # Composition alternate definition
+        if self._composition == "A":
+            A = self.kwargs["A"]
+        elif self._composition == "xa":
+            xa = self.kwargs["xa"]
+            A = xa/(1-(1-xa)*(1-Mw/Ma))
+
+        # Thermodynamic definition
+        if self._mode == "TP":
+            def f(rho):
+                fav = self._fav(T, rho, A)
+                return rho**2*fav["fird"]/1000-P
+            rho = fsolve(f, 1)[0]
+        elif self._mode == "Prho":
+            def f(T):
+                fav = self._fav(T, rho, A)
+                return rho**2*fav["fird"]/1000-P
+            T = fsolve(f, 300)[0]
+
+        # General calculation procedure
+        fav = self._fav(T, rho, A)
+
+        # Common thermodynamic properties
+        prop = self._prop(T, rho, fav)
+        self.T = T
+        self.rho = rho
+        self.v = 1/rho
+        self.P = prop["P"]
+        self.s = prop["s"]
+        self.cp = prop["cp"]
+        self.h = prop["h"]
+        self.g = prop["g"]
+        self.u = self.h-self.P*1000*self.v
+        self.alfav = prop["alfav"]
+        self.betas = prop["betas"]
+        self.xkappa = prop["xkappa"]
+        self.ks = prop["ks"]
+        self.w = prop["w"]
+
+        # Coligative properties
+        coligative = self._coligative(rho, A, fav)
+        self.A = A
+        self.W = 1-A
+        self.mu = coligative["mu"]
+        self.muw = coligative["muw"]
+        self.M = coligative["M"]
+        self.HR = coligative["HR"]
+        self.xa = coligative["xa"]
+        self.xw = coligative["xw"]
+        self.Pv = (1-self.xa)*self.P
+
+        # Saturation related properties
+        A_sat = self._eq(self.T, self.P)
+        self.xa_sat = A_sat*Mw/Ma/(1-A_sat*(1-Mw/Ma))
+        self.RH = (1-self.xa)/(1-self.xa_sat)
+
+    def derivative(self, z, x, y):
+        """Wrapper derivative for custom derived properties
+        where x, y, z can be: P, T, v, rho, u, h, s, g, a"""
+        return deriv_G(self, z, x, y, self)
+
+    def _eq(self, T, P):
+        """Procedure for calculate the composition in saturation state
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+        P : float
+            Pressure [MPa]
+
+        Returns
+        -------
+        Asat : float
+            Saturation mass fraction of dry air in humid air [kg/kg]
+        """
+        if T <= 273.16:
+            ice = _Ice(T, P)
+            gw = ice["g"]
+            rho = ice["rho"]
+        else:
+            water = IAPWS95(T=T, P=P)
+            gw = water.g
+            rho = water.rho
+
+        def f(a):
+            fa = self._fav(T, rho, a)
+            muw = fa["fir"]+rho*fa["fird"]-a*fa["fira"]
+            return gw-muw
+        Asat = fsolve(f, 0.9)[0]
+        return Asat
+
+    def _prop(self, T, rho, fav):
+        """Thermodynamic properties of humid air
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+        rho : float
+            Density [kg/m³]
+        fav : dict
+            dictionary with helmholtz energy and derivatives
+
+        Returns
+        -------
+        prop : dictionary with thermodynamic properties of humid air
+            P: Pressure [MPa]
+            s: Specific entropy [kJ/kgK]
+            cp: Specific isobaric heat capacity [kJ/kgK]
+            h: Specific enthalpy [kJ/kg]
+            g: Specific gibbs energy [kJ/kg]
+            alfav: Thermal expansion coefficient [1/K]
+            betas: Isentropic T-P coefficient [K/MPa]
+            xkappa: Isothermal compressibility [1/MPa]
+            ks: Isentropic compressibility [1/MPa]
+            w: Speed of sound [m/s]
+
+        References
+        ----------
+        IAPWS, Guideline on an Equation of State for Humid Air in Contact with
+        Seawater and Ice, Consistent with the IAPWS Formulation 2008 for the
+        Thermodynamic Properties of Seawater, Table 5,
+        http://www.iapws.org/relguide/SeaAir.html
+        """
+        prop = {}
+        prop["P"] = rho**2*fav["fird"]/1000                             # Eq T1
+        prop["s"] = -fav["firt"]                                        # Eq T2
+        prop["cp"] = -T*fav["firtt"]+T*rho*fav["firdt"]**2/(            # Eq T3
+            2*fav["fird"]+rho*fav["firdd"])
+        prop["h"] = fav["fir"]-T*fav["firt"]+rho*fav["fird"]            # Eq T4
+        prop["g"] = fav["fir"]+rho*fav["fird"]                          # Eq T5
+        prop["alfav"] = fav["firdt"]/(2*fav["fird"]+rho*fav["firdd"])   # Eq T6
+        prop["betas"] = 1000*fav["firdt"]/rho/(                         # Eq T7
+            rho*fav["firdt"]**2-fav["firtt"]*(2*fav["fird"]+rho*fav["firdd"]))
+        prop["xkappa"] = 1e3/(rho**2*(2*fav["fird"]+rho*fav["firdd"]))  # Eq T8
+        prop["ks"] = 1000*fav["firtt"]/rho**2/(                         # Eq T9
+            fav["firtt"]*(2*fav["fird"]+rho*fav["firdd"])-rho*fav["firdt"]**2)
+        prop["w"] = (rho**2*1000*(fav["firtt"]*fav["firdd"]-fav["firdt"]**2) /
+                     fav["firtt"]+2*rho*fav["fird"]*1000)**0.5         # Eq T10
+        return prop
+
+    def _coligative(self, rho, A, fav):
+        """Miscelaneous properties of humid air
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        A : float
+            Mass fraction of dry air in humid air [kg/kg]
+        fav : dict
+            dictionary with helmholtz energy and derivatives
+
+        Returns
+        -------
+        prop : dictionary with calculated properties
+            mu: Relative chemical potential [kJ/kg]
+            muw: Chemical potential of water [kJ/kg]
+            M: Molar mass of humid air [g/mol]
+            HR: Humidity ratio [-]
+            xa: Mole fraction of dry air [-]
+            xw: Mole fraction of water [-]
+
+        References
+        ----------
+        IAPWS, Guideline on an Equation of State for Humid Air in Contact with
+        Seawater and Ice, Consistent with the IAPWS Formulation 2008 for the
+        Thermodynamic Properties of Seawater, Table 12,
+        http://www.iapws.org/relguide/SeaAir.html
+        """
+        prop = {}
+        prop["mu"] = fav["fira"]
+        prop["muw"] = fav["fir"]+rho*fav["fird"]-A*fav["fira"]
+        prop["M"] = 1/((1-A)/Mw+A/Ma)
+        prop["HR"] = 1/A-1
+        prop["xa"] = A*Mw/Ma/(1-A*(1-Mw/Ma))
+        prop["xw"] = 1-prop["xa"]
+        return prop
+
+    def _fav(self, T, rho, A):
+        """Specific Helmholtz energy of humid air and derivatives
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+        rho : float
+            Density [kg/m³]
+        A : float
+            Mass fraction of dry air in humid air [kg/kg]
+
+        Returns
+        -------
+        prop : dictionary with helmholtz energy and derivatives
+            fir  [kJ/kg]
+            fira: [∂fav/∂A]T,ρ  [kJ/kg]
+            firt: [∂fav/∂T]A,ρ  [kJ/kgK]
+            fird: [∂fav/∂ρ]A,T  [kJ/m³kg²]
+            firaa: [∂²fav/∂A²]T,ρ  [kJ/kg]
+            firat: [∂²fav/∂A∂T]ρ  [kJ/kgK]
+            firad: [∂²fav/∂A∂ρ]T  [kJ/m³kg²]
+            firtt: [∂²fav/∂T²]A,ρ  [kJ/kgK²]
+            firdt: [∂²fav/∂T∂ρ]A  [kJ/m³kg²K]
+            firdd: [∂²fav/∂ρ²]A,T  [kJ/m⁶kg³]
+
+        References
+        ----------
+        IAPWS, Guideline on an Equation of State for Humid Air in Contact with
+        Seawater and Ice, Consistent with the IAPWS Formulation 2008 for the
+        Thermodynamic Properties of Seawater, Table 6,
+        http://www.iapws.org/relguide/SeaAir.html
+        """
+        water = IAPWS95()
+        rhov = (1-A)*rho
+        fv = water._derivDimensional(rhov, T)
+
+        air = Air()
+        rhoa = A*rho
+        fa = air._derivDimensional(rhoa, T)
+
+        fmix = self._fmix(T, rho, A)
+
+        prop = {}
+        # Eq T11
+        prop["fir"] = (1-A)*fv["fir"] + A*fa["fir"] + fmix["fir"]
+        # Eq T12
+        prop["fira"] = -fv["fir"]-rhov*fv["fird"]+fa["fir"] + \
+            rhoa*fa["fird"]+fmix["fira"]
+        # Eq T13
+        prop["firt"] = (1-A)*fv["firt"]+A*fa["firt"]+fmix["firt"]
+        # Eq T14
+        prop["fird"] = (1-A)**2*fv["fird"]+A**2*fa["fird"]+fmix["fird"]
+        # Eq T15
+        prop["firaa"] = rho*(2*fv["fird"]+rhov*fv["firdd"] +
+                             2*fa["fird"]+rhoa*fa["firdd"])+fmix["firaa"]
+        # Eq T16
+        prop["firat"] = -fv["firt"]-rhov*fv["firdt"]+fa["firt"] + \
+            rhoa*fa["firdt"]+fmix["firat"]
+        # Eq T17
+        prop["firad"] = -(1-A)*(2*fv["fird"]+rhov*fv["firdd"]) + \
+            A*(2*fa["fird"]+rhoa*fa["firdd"])+fmix["firad"]
+        # Eq T18
+        prop["firtt"] = (1-A)*fv["firtt"]+A*fa["firtt"]+fmix["firtt"]
+        # Eq T19
+        prop["firdt"] = (1-A)**2*fv["firdt"]+A**2*fa["firdt"]+fmix["firdt"]
+        # Eq T20
+        prop["firdd"] = (1-A)**3*fv["firdd"]+A**3*fa["firdd"]+fmix["firdd"]
+        return prop
+
+    def _fmix(self, T, rho, A):
+        """Specific Helmholtz energy of air-water interaction
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+        rho : float
+            Density [kg/m³]
+        A : float
+            Mass fraction of dry air in humid air [kg/kg]
+
+        Returns
+        -------
+        prop : dictionary with helmholtz energy and derivatives
+            fir
+            fira: [∂fmix/∂A]T,ρ
+            firt: [∂fmix/∂T]A,ρ
+            fird: [∂fmix/∂ρ]A,T
+            firaa: [∂²fmix/∂A²]T,ρ
+            firat: [∂²fmix/∂A∂T]ρ
+            firad: [∂²fmix/∂A∂ρ]T
+            firtt: [∂²fmix/∂T²]A,ρ
+            firdt: [∂²fmix/∂T∂ρ]A
+            firdd: [∂²fmix/∂ρ²]A,T
+
+        References
+        ----------
+        IAPWS, Guideline on an Equation of State for Humid Air in Contact with
+        Seawater and Ice, Consistent with the IAPWS Formulation 2008 for the
+        Thermodynamic Properties of Seawater, Table 10,
+        http://www.iapws.org/relguide/SeaAir.html
+        """
+        Ma = Air.M/1000
+        Mw = IAPWS95.M/1000
+        vir = _virial(T)
+        Baw = vir["Baw"]
+        Bawt = vir["Bawt"]
+        Bawtt = vir["Bawtt"]
+        Caaw = vir["Caaw"]
+        Caawt = vir["Caawt"]
+        Caawtt = vir["Caawtt"]
+        Caww = vir["Caww"]
+        Cawwt = vir["Cawwt"]
+        Cawwtt = vir["Cawwtt"]
+
+        # Eq T45
+        f = 2*A*(1-A)*rho*R*T/Ma/Mw*(Baw+3*rho/4*(A/Ma*Caaw+(1-A)/Mw*Caww))
+        # Eq T46
+        fa = 2*rho*R*T/Ma/Mw*((1-2*A)*Baw+3*rho/4*(
+            A*(2-3*A)/Ma*Caaw+(1-A)*(1-3*A)/Mw*Caww))
+        # Eq T47
+        ft = 2*A*(1-A)*rho*R/Ma/Mw*(
+            Baw+T*Bawt+3*rho/4*(A/Ma*(Caaw+T*Caawt)+(1-A)/Mw*(Caww+T*Cawwt)))
+        # Eq T48
+        fd = A*(1-A)*R*T/Ma/Mw*(2*Baw+3*rho*(A/Ma*Caaw+(1-A)/Mw*Caww))
+        # Eq T49
+        faa = rho*R*T/Ma/Mw*(-4*Baw+3*rho*((1-3*A)/Ma*Caaw-(2-3*A)/Mw*Caww))
+        # Eq T50
+        fat = 2*rho*R/Ma/Mw*(1-2*A)*(Baw+T*Bawt)+3*rho**2*R/2/Ma/Mw*(
+            A*(2-3*A)/Ma*(Caaw+T*Caawt)+(1-A)*(1-3*A)/Mw*(Caww+T*Cawwt))
+        # Eq T51
+        fad = 2*R*T/Ma/Mw*((1-2*A)*Baw+3/2*rho*(
+            A*(2-3*A)/Ma*Caaw+(1-A)*(1-3*A)/Mw*Caww))
+        # Eq T52
+        ftt = 2*A*(1-A)*rho*R/Ma/Mw*(2*Bawt+T*Bawtt+3*rho/4*(
+            A/Ma*(2*Caawt+T*Caawtt)+(1-A)/Mw*(2*Cawwt+T*Cawwtt)))
+        # Eq T53
+        ftd = 2*A*(1-A)*R/Ma/Mw*(Baw+T*Bawt+3*rho/2*(
+            A/Ma*(Caaw+T*Caawt)+(1-A)/Mw*(Caww+T*Cawwt)))
+        # Eq T54
+        fdd = 3*A*(1-A)*R*T/Ma/Mw*(A/Ma*Caaw+(1-A)/Mw*Caww)
+
+        prop = {}
+        prop["fir"] = f/1000
+        prop["fira"] = fa/1000
+        prop["firt"] = ft/1000
+        prop["fird"] = fd/1000
+        prop["firaa"] = faa/1000
+        prop["firat"] = fat/1000
+        prop["firad"] = fad/1000
+        prop["firtt"] = ftt/1000
+        prop["firdt"] = ftd/1000
+        prop["firdd"] = fdd/1000
+        return prop
diff --git a/iapws/iapws08.py b/iapws/iapws08.py
index c2dbe2f..0a1820a 100644
--- a/iapws/iapws08.py
+++ b/iapws/iapws08.py
@@ -1,14 +1,19 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
-
-###############################################################################
-# IAPWS for seawater
-###############################################################################
+"""
+IAPWS standard for Seawater IAPWS08
+"""
 
 from __future__ import division
-from math import log
+from math import exp, log
+import warnings
+
+from scipy.optimize import fsolve
 
 from .iapws95 import IAPWS95
+from .iapws97 import IAPWS97, _Region1, _Region2
+from ._iapws import _ThCond, Tc, Pc, rhoc, _Ice
+from ._utils import deriv_G
 
 
 # Constants
@@ -25,46 +30,119 @@ To = 273.15
 class SeaWater(object):
     """
     Class to model seawater with standard IAPWS-08
-    Incoming properties:
-        T   -   Temperature, K
-        P   -   Pressure, MPa
-        S   -   Salinity, kg/kg
-
-    Calculated properties:
-        T: Temperature, K
-        P: Pressure, MPa
-        rho: Density, kg/m³
-        v: Specific volume, m³/kg
-        h: Specific enthalpy, kJ/kg
-        s: Specific entropy, kJ/kg·K
-        u: Specific internal energy, kJ/kg
-        g: Specific Gibbs free energy, kJ/kg
-        a: Specific Helmholtz free energy, kJ/kg
-        cp: Specific isobaric heat capacity, kJ/kg·K
-
-        gt: Derivative Gibbs energy with temperature, kJ/kg·K
-        gp: Derivative Gibbs energy with pressure, m³/kg
-        gtt: Derivative Gibbs energy with temperature square, kJ/kg·K²
-        gtp: Derivative Gibbs energy with pressure and temperature, m³/kg·K
-        gpp: Derivative Gibbs energy with temperature square, m³/kg·MPa
-        gs: Derivative Gibbs energy with salinity, kJ/kg
-        gsp: Derivative Gibbs energy with salinity and pressure, m³/kg
-
-        alfa: Thermal expansion coefficient, 1/K
-        betas: Isentropic temperature-pressure coefficient, K/MPa
-        kt: Isothermal compressibility, 1/MPa
-        ks: Isentropic compressibility, 1/MPa
-        w: Sound Speed, m/s
-
-        mu: Relative chemical potential, kJ/kg
-        muw: Chemical potential of H2O, kJ/kg
-        mus: Chemical potential of sea salt, kJ/kg
-        osm: Osmotic coefficient, [-]
-        haline: Haline contraction coefficient, kg/kg
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    S : float
+        Salinity [kg/kg]
+
+    fast : Boolean, default False
+        Use the Supplementary release SR7-09 to speed up the calculation
+    IF97 : Boolean, default False
+        Use the Advisory Note No. 5 with industrial formulation
+
+    Returns
+    -------
+    rho : float
+        Density [kg/m³]
+    v : float
+        Specific volume [m³/kg]
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kg·K]
+    u : float
+        Specific internal energy [kJ/kg]
+    g : float
+        Specific Gibbs free energy [kJ/kg]
+    a : float
+        Specific Helmholtz free energy [kJ/kg]
+    cp : float
+        Specific isobaric heat capacity [kJ/kg·K]
+    cv : float
+        Specific isochoric heat capacity [kJ/kg·K]
+    gt : float
+        Derivative Gibbs energy with temperature [kJ/kg·K]
+    gp : float
+        Derivative Gibbs energy with pressure [m³/kg]
+    gtt : float
+        Derivative Gibbs energy with temperature square [kJ/kg·K²]
+    gtp : float
+        Derivative Gibbs energy with pressure and temperature [m³/kg·K]
+    gpp : float
+        Derivative Gibbs energy with temperature square [m³/kg·MPa]
+    gs : float
+        Derivative Gibbs energy with salinity [kJ/kg]
+    gsp : float
+        Derivative Gibbs energy with salinity and pressure [m³/kg]
+    alfav : float
+        Thermal expansion coefficient [1/K]
+    betas : float
+        Isentropic temperature-pressure coefficient [K/MPa]
+    xkappa : float
+        Isothermal compressibility [1/MPa]
+    ks : float
+        Isentropic compressibility [1/MPa]
+    w : float
+        Sound Speed [m/s]
+
+    m : float
+        Molality of seawater [mol/kg]
+    mu : float
+        Relative chemical potential [kJ/kg]
+    muw : float
+        Chemical potential of H2O [kJ/kg]
+    mus : float
+        Chemical potential of sea salt [kJ/kg]
+    osm : float
+        Osmotic coefficient, [-]
+    haline : float
+        Haline contraction coefficient [kg/kg]
+
+    Raises
+    ------
+    Warning : If input isn't in limit
+        * 261 ≤ T ≤ 353
+        * 0 < P ≤ 100
+        * 0 ≤ S ≤ 0.12
+
+    References
+    ----------
+    IAPWS, Release on the IAPWS Formulation 2008 for the Thermodynamic
+    Properties of Seawater, http://www.iapws.org/relguide/Seawater.html
+
+    IAPWS, Supplementary Release on a Computationally Efficient Thermodynamic
+    Formulation for Liquid Water for Oceanographic Use,
+    http://www.iapws.org/relguide/OceanLiquid.html
+
+    IAPWS, Guideline on the Thermal Conductivity of Seawater,
+    http://www.iapws.org/relguide/Seawater-ThCond.html
+
+    IAPWS, Revised Advisory Note No. 3: Thermodynamic Derivatives from IAPWS
+    Formulations, http://www.iapws.org/relguide/Advise3.pdf
+
+    IAPWS,  Advisory Note No. 5: Industrial Calculation of the Thermodynamic
+    Properties of Seawater, http://www.iapws.org/relguide/Advise5.html
+
+    Examples
+    --------
+    >>> salt = iapws.SeaWater(T=300, P=1, S=0.04)
+    >>> salt.rho
+    1026.7785717245113
+    >>> salt.gs
+    88.56221805501536
+    >>> salt.haline
+    0.7311487666026304
     """
     kwargs = {"T": 0.0,
               "P": 0.0,
-              "S": None}
+              "S": None,
+              "fast": False,
+              "IF97": False}
     status = 0
     msg = "Undefined"
 
@@ -89,8 +167,13 @@ class SeaWater(object):
         P = self.kwargs["P"]
         S = self.kwargs["S"]
 
-        m = S/(1-S)/Ms
-        pw = self._water(T, P)
+        self.m = S/(1-S)/Ms
+        if self.kwargs["fast"] and T <= 313.15:
+            pw = self._waterSupp(T, P)
+        elif self.kwargs["IF97"]:
+            pw = self._waterIF97(T, P)
+        else:
+            pw = self._water(T, P)
         ps = self._saline(T, P, S)
 
         prop = {}
@@ -104,21 +187,41 @@ class SeaWater(object):
         self.v = prop["gp"]
         self.s = -prop["gt"]
         self.cp = -T*prop["gtt"]
+        self.cv = T*(prop["gtp"]**2/prop["gpp"]-prop["gtt"])
         self.h = prop["g"]-T*prop["gt"]
         self.u = prop["g"]-T*prop["gt"]-P*1000*prop["gp"]
         self.a = prop["g"]-P*1000*prop["gp"]
-        self.alfa = prop["gtp"]/prop["gp"]
+        self.alfav = prop["gtp"]/prop["gp"]
         self.betas = -prop["gtp"]/prop["gtt"]
-        self.kt = -prop["gpp"]/prop["gp"]
-        self.ks = (prop["gtp"]**2-prop["gt"]*prop["gpp"])/prop["gp"]/prop["gtt"]
+        self.xkappa = -prop["gpp"]/prop["gp"]
+        self.ks = (prop["gtp"]**2-prop["gt"]*prop["gpp"])/prop["gp"] / \
+            prop["gtt"]
         self.w = prop["gp"]*(prop["gtt"]*1000/(prop["gtp"]**2 -
                              prop["gtt"]*1000*prop["gpp"]*1e-6))**0.5
 
-        self.mu = prop["gs"]
-        self.muw = prop["g"]-S*prop["gs"]
-        self.mus = prop["g"]+(1-S)*prop["gs"]
-        self.osm = -(ps["g"]-S*prop["gs"])/m/Rm/T
-        self.haline = -prop["gsp"]/prop["gp"]
+        try:
+            kw = _ThCond(1/pw["gp"], T)
+            self.k = _ThCond_SeaWater(T, P, S)+kw
+        except NotImplementedError:
+            self.k = None
+
+        if S:
+            self.mu = prop["gs"]
+            self.muw = prop["g"]-S*prop["gs"]
+            self.mus = prop["g"]+(1-S)*prop["gs"]
+            self.osm = -(ps["g"]-S*prop["gs"])/self.m/Rm/T
+            self.haline = -prop["gsp"]/prop["gp"]
+        else:
+            self.mu = None
+            self.muw = None
+            self.mus = None
+            self.osm = None
+            self.haline = None
+
+    def derivative(self, z, x, y):
+        """Wrapper derivative for custom derived properties
+        where x, y, z can be: P, T, v, u, h, s, g, a"""
+        return deriv_G(self, z, x, y, self)
 
     @classmethod
     def _water(cls, T, P):
@@ -136,8 +239,79 @@ class SeaWater(object):
         return prop
 
     @classmethod
+    def _waterIF97(cls, T, P):
+        water = IAPWS97(P=P, T=T)
+        betas = water.derivative("T", "P", "s", water)
+        prop = {}
+        prop["g"] = water.h-T*water.s
+        prop["gt"] = -water.s
+        prop["gp"] = 1./water.rho
+        prop["gtt"] = -water.cp/T
+        prop["gtp"] = betas*water.cp/T
+        prop["gpp"] = -1e6/(water.rho*water.w)**2-betas**2*1e3*water.cp/T
+        prop["gs"] = 0
+        prop["gsp"] = 0
+        return prop
+
+    @classmethod
+    def _waterSupp(cls, T, P):
+        """Get properties of pure water using the supplementary release SR7-09,
+        Table4 pag 6"""
+        tau = (T-273.15)/40
+        pi = (P-0.101325)/100
+
+        J = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3,
+             3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7]
+        K = [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2,
+             3, 4, 5, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1]
+        G = [0.101342743139674e3, 0.100015695367145e6, -0.254457654203630e4,
+             0.284517778446287e3, -0.333146754253611e2, 0.420263108803084e1,
+             -0.546428511471039, 0.590578347909402e1, -0.270983805184062e3,
+             0.776153611613101e3, -0.196512550881220e3, 0.289796526294175e2,
+             -0.213290083518327e1, -0.123577859330390e5, 0.145503645404680e4,
+             -0.756558385769359e3, 0.273479662323528e3, -0.555604063817218e2,
+             0.434420671917197e1, 0.736741204151612e3, -0.672507783145070e3,
+             0.499360390819152e3, -0.239545330654412e3, 0.488012518593872e2,
+             -0.166307106208905e1, -0.148185936433658e3, 0.397968445406972e3,
+             -0.301815380621876e3, 0.152196371733841e3, -0.263748377232802e2,
+             0.580259125842571e2, -0.194618310617595e3, 0.120520654902025e3,
+             -0.552723052340152e2, 0.648190668077221e1, -0.189843846514172e2,
+             0.635113936641785e2, -0.222897317140459e2, 0.817060541818112e1,
+             0.305081646487967e1, -0.963108119393062e1]
+
+        g, gt, gp, gtt, gtp, gpp = 0, 0, 0, 0, 0, 0
+        for j, k, gi in zip(J, K, G):
+            g += gi*tau**j*pi**k
+            if j >= 1:
+                gt += gi*j*tau**(j-1)*pi**k
+            if k >= 1:
+                gp += k*gi*tau**j*pi**(k-1)
+            if j >= 2:
+                gtt += j*(j-1)*gi*tau**(j-2)*pi**k
+            if j >= 1 and k >= 1:
+                gtp += j*k*gi*tau**(j-1)*pi**(k-1)
+            if k >= 2:
+                gpp += k*(k-1)*gi*tau**j*pi**(k-2)
+
+        prop = {}
+        prop["g"] = g*1e-3
+        prop["gt"] = gt/40*1e-3
+        prop["gp"] = gp/100*1e-6
+        prop["gtt"] = gtt/40**2*1e-3
+        prop["gtp"] = gtp/40/100*1e-6
+        prop["gpp"] = gpp/100**2*1e-6
+        prop["gs"] = 0
+        prop["gsp"] = 0
+        return prop
+
+    @classmethod
     def _saline(cls, T, P, S):
         """Eq 4"""
+
+        # Check input in range of validity
+        if T <= 261 or T > 353 or P <= 0 or P > 100 or S < 0 or S > 0.12:
+            warnings.warn("Incoming out of bound")
+
         S_ = 0.03516504*40/35
         X = (S/S_)**0.5
         tau = (T-273.15)/40
@@ -176,27 +350,30 @@ class SeaWater(object):
              -0.792001547211682e1]
 
         g, gt, gp, gtt, gtp, gpp, gs, gsp = 0, 0, 0, 0, 0, 0, 0, 0
-        for i, j, k, gi in zip(I, J, K, G):
-            if i == 1:
-                g += gi*X**2*log(X)*tau**j*pi**k
-                gs += gi*(2*log(X)+1)*tau**j*pi**k
-            else:
-                g += gi*X**i*tau**j*pi**k
-                gs += i*gi*X**(i-2)*tau**j*pi**k
-            if j >= 1:
+
+        # Calculate only for some salinity
+        if S != 0:
+            for i, j, k, gi in zip(I, J, K, G):
                 if i == 1:
-                    gt += gi*X**2*log(X)*j*tau**(j-1)*pi**k
+                    g += gi*X**2*log(X)*tau**j*pi**k
+                    gs += gi*(2*log(X)+1)*tau**j*pi**k
                 else:
-                    gt += gi*X**i*j*tau**(j-1)*pi**k
-            if k >= 1:
-                gp += k*gi*X**i*tau**j*pi**(k-1)
-                gsp += i*k*gi*X**(i-2)*tau**j*pi**(k-1)
-            if j >= 2:
-                gtt += j*(j-1)*gi*X**i*tau**(j-2)*pi**k
-            if j >= 1 and k >= 1:
-                gtp += j*k*gi*X**i*tau**(j-1)*pi**(k-1)
-            if k >= 2:
-                gpp += k*(k-1)*gi*X**i*tau**j*pi**(k-2)
+                    g += gi*X**i*tau**j*pi**k
+                    gs += i*gi*X**(i-2)*tau**j*pi**k
+                if j >= 1:
+                    if i == 1:
+                        gt += gi*X**2*log(X)*j*tau**(j-1)*pi**k
+                    else:
+                        gt += gi*X**i*j*tau**(j-1)*pi**k
+                if k >= 1:
+                    gp += k*gi*X**i*tau**j*pi**(k-1)
+                    gsp += i*k*gi*X**(i-2)*tau**j*pi**(k-1)
+                if j >= 2:
+                    gtt += j*(j-1)*gi*X**i*tau**(j-2)*pi**k
+                if j >= 1 and k >= 1:
+                    gtp += j*k*gi*X**i*tau**(j-1)*pi**(k-1)
+                if k >= 2:
+                    gpp += k*(k-1)*gi*X**i*tau**j*pi**(k-2)
 
         prop = {}
         prop["g"] = g*1e-3
@@ -209,6 +386,315 @@ class SeaWater(object):
         prop["gsp"] = gsp/S_/2/100*1e-6
         return prop
 
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
+
+def _Tb(P, S):
+    """Procedure to calculate the boiling temperature of seawater
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    S : float
+        Salinity [kg/kg]
+
+    Returns
+    -------
+    Tb : float
+        Boiling temperature [K]
+
+    References
+    ----------
+    IAPWS,  Advisory Note No. 5: Industrial Calculation of the Thermodynamic
+    Properties of Seawater, http://www.iapws.org/relguide/Advise5.html, Eq 7
+    """
+    def f(T):
+        pw = _Region1(T, P)
+        gw = pw["h"]-T*pw["s"]
+
+        pv = _Region2(T, P)
+        gv = pv["h"]-T*pv["s"]
+
+        ps = SeaWater._saline(T, P, S)
+        return -ps["g"]+S*ps["gs"]-gw+gv
+
+    Tb = fsolve(f, 300)[0]
+    return Tb
+
+
+def _Tf(P, S):
+    """Procedure to calculate the freezing temperature of seawater
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    S : float
+        Salinity [kg/kg]
+
+    Returns
+    -------
+    Tf : float
+        Freezing temperature [K]
+
+    References
+    ----------
+    IAPWS,  Advisory Note No. 5: Industrial Calculation of the Thermodynamic
+    Properties of Seawater, http://www.iapws.org/relguide/Advise5.html, Eq 12
+    """
+    def f(T):
+        T = float(T)
+        pw = _Region1(T, P)
+        gw = pw["h"]-T*pw["s"]
+
+        gih = _Ice(T, P)["g"]
+
+        ps = SeaWater._saline(T, P, S)
+        return -ps["g"]+S*ps["gs"]-gw+gih
+
+    Tf = fsolve(f, 300)[0]
+    return Tf
+
+
+def _Triple(S):
+    """Procedure to calculate the triple point pressure and temperature for
+    seawater
+
+    Parameters
+    ----------
+    S : float
+        Salinity [kg/kg]
+
+    Returns
+    -------
+    Tt : float
+        Triple point temperature [K]
+    Pt: float
+        Triple point pressure [MPa]
+
+    References
+    ----------
+    IAPWS,  Advisory Note No. 5: Industrial Calculation of the Thermodynamic
+    Properties of Seawater, http://www.iapws.org/relguide/Advise5.html, Eq 7
+    """
+    def f(parr):
+        T, P = parr
+        pw = _Region1(T, P)
+        gw = pw["h"]-T*pw["s"]
+
+        pv = _Region2(T, P)
+        gv = pv["h"]-T*pv["s"]
+
+        gih = _Ice(T, P)["g"]
+        ps = SeaWater._saline(T, P, S)
+
+        return -ps["g"]+S*ps["gs"]-gw+gih, -ps["g"]+S*ps["gs"]-gw+gv
+
+    Tt, Pt = fsolve(f, [273, 6e-4])
+
+    prop = {}
+    prop["Tt"] = Tt
+    prop["Pt"] = Pt
+    return prop
+
+
+def _OsmoticPressure(T, P, S):
+    """Procedure to calculate the osmotic pressure of seawater
+
+    Parameters
+    ----------
+    T : float
+        Tmperature [K]
+    P : float
+        Pressure [MPa]
+    S : float
+        Salinity [kg/kg]
+
+    Returns
+    -------
+    Posm : float
+        Osmotic pressure [MPa]
+
+    References
+    ----------
+    IAPWS,  Advisory Note No. 5: Industrial Calculation of the Thermodynamic
+    Properties of Seawater, http://www.iapws.org/relguide/Advise5.html, Eq 15
+    """
+    pw = _Region1(T, P)
+    gw = pw["h"]-T*pw["s"]
+
+    def f(Posm):
+        pw2 = _Region1(T, P+Posm)
+        gw2 = pw2["h"]-T*pw2["s"]
+        ps = SeaWater._saline(T, P+Posm, S)
+        return -ps["g"]+S*ps["gs"]-gw+gw2
+
+    Posm = fsolve(f, 0)[0]
+    return Posm
+
+
+def _ThCond_SeaWater(T, P, S):
+    """Equation for the thermal conductivity of seawater
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    S : float
+        Salinity [kg/kg]
+
+    Returns
+    -------
+    k : float
+        Thermal conductivity excess relative to that of the pure water [W/mK]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 273.15 ≤ T ≤ 523.15
+        * 0 ≤ P ≤ 140
+        * 0 ≤ S ≤ 0.17
+
+    Examples
+    --------
+    >>> _ThCond_Seawater(293.15, 0.1, 0.035)
+    -0.00418604
+
+    References
+    ----------
+    IAPWS, Guideline on the Thermal Conductivity of Seawater,
+    http://www.iapws.org/relguide/Seawater-ThCond.html
+    """
+    # Check input parameters
+    if T < 273.15 or T > 523.15 or P < 0 or P > 140 or S < 0 or S > 0.17:
+        raise NotImplementedError("Incoming out of bound")
+
+    # Eq 4
+    a1 = -7.180891e-5+1.831971e-7*P
+    a2 = 1.048077e-3-4.494722e-6*P
+
+    # Eq 5
+    b1 = 1.463375e-1+9.208586e-4*P
+    b2 = -3.086908e-3+1.798489e-5*P
+
+    a = a1*exp(a2*(T-273.15))  # Eq 2
+    b = b1*exp(b2*(T-273.15))  # Eq 3
+
+    # Eq 1
+    DL = a*(1000*S)**(1+b)
+    return DL
+
+
+def _solNa2SO4(T, mH2SO4, mNaCl):
+    """Equation for the solubility of sodium sulfate in aqueous mixtures of
+    sodium chloride and sulfuric acid
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    mH2SO4 : float
+        Molality of sufuric acid [mol/kg(water)]
+    mNaCl : float
+        Molality of sodium chloride [mol/kg(water)]
+
+    Returns
+    -------
+    S : float
+        Molal solutility of sodium sulfate [mol/kg(water)]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 523.15 ≤ T ≤ 623.15
+        * 0 ≤ mH2SO4 ≤ 0.75
+        * 0 ≤ mNaCl ≤ 2.25
+
+    Examples
+    --------
+    >>> _solNa2SO4(523.15, 0.25, 0.75)
+    2.68
+
+    References
+    ----------
+    IAPWS, Solubility of Sodium Sulfate in Aqueous Mixtures of Sodium Chloride
+    and Sulfuric Acid from Water to Concentrated Solutions,
+    http://www.iapws.org/relguide/na2so4.pdf
+    """
+    # Check input parameters
+    if T < 523.15 or T > 623.15 or mH2SO4 < 0 or mH2SO4 > 0.75 or \
+            mNaCl < 0 or mNaCl > 2.25:
+        raise NotImplementedError("Incoming out of bound")
+
+    A00 = -0.8085987*T+81.4613752+0.10537803*T*log(T)
+    A10 = 3.4636364*T-281.63322-0.46779874*T*log(T)
+    A20 = -6.0029634*T+480.60108+0.81382854*T*log(T)
+    A30 = 4.4540258*T-359.36872-0.60306734*T*log(T)
+    A01 = 0.4909061*T-46.556271-0.064612393*T*log(T)
+    A02 = -0.002781314*T+1.722695+0.0000013319698*T*log(T)
+    A03 = -0.014074108*T+0.99020227+0.0019397832*T*log(T)
+    A11 = -0.87146573*T+71.808756+0.11749585*T*log(T)
+
+    S = A00 + A10*mH2SO4 + A20*mH2SO4**2 + A30*mH2SO4**3 + A01*mNaCl + \
+        A02*mNaCl**2 + A03*mNaCl**3 + A11*mH2SO4*mNaCl
+
+    return S
+
+
+def _critNaCl(x):
+    """Equation for the critical locus of aqueous solutions of sodium chloride
+
+    Parameters
+    ----------
+    x : float
+        Mole fraction of NaCl [-]
+
+    Returns
+    -------
+    Tc: critical temperature [K]
+    Pc: critical pressure [MPa]
+    rhoc: critical density [kg/m³]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 0 ≤ x ≤ 0.12
+
+    Examples
+    --------
+    >>> _critNaCl(0.1)
+    975.571016
+
+    References
+    ----------
+    IAPWS, Revised Guideline on the Critical Locus of Aqueous Solutions of
+    Sodium Chloride, http://www.iapws.org/relguide/critnacl.html
+    """
+    # Check input parameters
+    if x < 0 or x > 0.12:
+        raise NotImplementedError("Incoming out of bound")
+
+    T1 = Tc*(1 + 2.3e1*x - 3.3e2*x**1.5 - 1.8e3*x**2)
+    T2 = Tc*(1 + 1.757e1*x - 3.026e2*x**1.5 + 2.838e3*x**2 - 1.349e4*x**2.5 +
+             3.278e4*x**3 - 3.674e4*x**3.5 + 1.437e4*x**4)
+    f1 = (abs(10000*x-10-1)-abs(10000*x-10+1))/4+0.5
+    f2 = (abs(10000*x-10+1)-abs(10000*x-10-1))/4+0.5
+
+    # Eq 1
+    tc = f1*T1+f2*T2
+
+    # Eq 7
+    rc = rhoc*(1 + 1.7607e2*x - 2.9693e3*x**1.5 + 2.4886e4*x**2 -
+               1.1377e5*x**2.5 + 2.8847e5*x**3 - 3.8195e5*x**3.5 +
+               2.0633e5*x**4)
+
+    # Eq 8
+    DT = tc-Tc
+    pc = Pc*(1+9.1443e-3*DT+5.1636e-5*DT**2-2.5360e-7*DT**3+3.6494e-10*DT**4)
+
+    prop = {}
+    prop["Tc"] = tc
+    prop["rhoc"] = rc
+    prop["Pc"] = pc
+    return prop
diff --git a/iapws/iapws95.py b/iapws/iapws95.py
index 0770345..a8e76af 100644
--- a/iapws/iapws95.py
+++ b/iapws/iapws95.py
@@ -1,118 +1,148 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 
+"""
+Implemented multiparameter equation of state as a Helmholtz free energy
+    * IAPWS-95 implementation
+    * Heavy water formulation 2005
+"""
 
-###############################################################################
-# Implemented multiparameter equation of state
-#   o   IAPWS-95  implementation
-#   o   Heavy water formulation 2005
-###############################################################################
 
+from __future__ import division
+from itertools import product
+import warnings
 
-from scipy import exp, log
+from scipy import exp, log, ndarray
 from scipy.optimize import fsolve
 
-from ._iapws import _fase, getphase
+from .iapws97 import _TSat_P, IAPWS97
+from ._iapws import M, Tc, Pc, rhoc, Tc_D2O, Pc_D2O, rhoc_D2O
 from ._iapws import _Viscosity, _ThCond, _Dielectric, _Refractive, _Tension
-from .iapws97 import _TSat_P
+from ._iapws import _D2O_Viscosity, _D2O_ThCond, _D2O_Tension
+from ._utils import _fase, getphase, deriv_H
 
 
 class MEoS(_fase):
     """
-    General implementation of multiparameter equation of state
-    From this derived all child class specified per individual compounds
-
-    Incoming properties:
-        T   -   Temperature, K
-        P   -   Pressure, MPa
-        rho -   Density, kg/m3
-        v   -   Specific volume, m3/kg
-        h   -   Specific enthalpy, kJ/kg
-        s   -   Specific entropy, kJ/kg·K
-        u   -   Specific internal energy, kJ/kg·K
-        x   -   Quality
-        l   -   Opcional parameter to light wavelength for Refractive index
-
-    It needs two incoming properties
-
-    Calculated properties:
-        P         -   Pressure, MPa
-        Pr        -   Reduce pressure
-        T         -   Temperature, K
-        Tr        -   Reduced temperature
-        x         -   Quality
-        v         -   Specific volume, m³/kg
-        rho       -   Density, kg/m³
-        h         -   Specific enthalpy, kJ/kg
-        s         -   Specific entropy, kJ/kg·K
-        u         -   Specific internal energy, kJ/kg
-        g         -   Specific Gibbs free energy, kJ/kg
-        a         -   Specific Helmholtz free energy, kJ/kg
-        cp        -   Specific isobaric heat capacity, kJ/kg·K
-        cv        -   Specific isochoric heat capacity, kJ/kg·K
-        cp_cv     -   Heat capacity ratio
-        w         -   Speed of sound, m/s
-        Z         -   Compression factor
-        fi        -   Fugacity coefficient
-        f         -   Fugacity, MPa
-        gamma     -   Isoentropic exponent
-        Hvap      -   Vaporization heat, kJ/kg
-        alfav     -   Thermal expansion coefficient (Volume expansivity), 1/K
-        kappa     -   Isothermal compressibility, 1/MPa
-        alfap     -   Relative pressure coefficient, 1/K
-        betap     -   Isothermal stress coefficient, kg/m³
-        betas     -   Isoentropic temperature-pressure coefficient
-        joule     -   Joule-Thomson coefficient, K/MPa
-        Gruneisen -   Gruneisen parameter
-        virialB   -   Second virial coefficient, m³/kg
-        virialC   -   Third virial coefficient, m⁶/kg²
-        dpdT_rho  -   Derivatives, dp/dT at constant rho, MPa/K
-        dpdrho_T  -   Derivatives, dp/drho at constant T, MPa·m³/kg
-        drhodT_P  -   Derivatives, drho/dT at constant P, kg/m³·K
-        drhodP_T  -   Derivatives, drho/dP at constant T, kg/m³·MPa
-        dhdT_rho  -   Derivatives, dh/dT at constant rho, kJ/kg·K
-        dhdP_T    -   Isothermal throttling coefficient, kJ/kg·MPa
-        dhdT_P    -   Derivatives, dh/dT at constant P, kJ/kg·K
-        dhdrho_T  -   Derivatives, dh/drho at constant T, kJ·m³/kg²
-        dhdrho_P  -   Derivatives, dh/drho at constant P, kJ·m³/kg²
-        dhdP_rho  -   Derivatives, dh/dP at constant rho, kJ/kg·MPa
-        kt        -   Isothermal Expansion Coefficient
-        ks        -   Adiabatic Compressibility, 1/MPa
-        Ks        -   Adiabatic bulk modulus, MPa
-        Kt        -   Isothermal bulk modulus, MPa
-
-        Z_rho     -   (Z-1) over the density, m³/kg
-        IntP      -   Internal pressure
-        invT      -   Negative reciprocal temperature
-        hInput    -   Specific heat input, kJ/kg
-        mu        -   Dynamic viscosity, Pa·s
-        nu        -   Kinematic viscosity, m²/s
-        k         -   Thermal conductivity, W/m·K
-        sigma     -   Surface tension, N/m
-        alfa      -   Thermal diffusivity, m²/s
-        Pramdt    -   Prandtl number
-        epsilon   -   Dielectric constant
-        n         -   Refractive index
-
-        v0        -   Ideal gas Specific volume, m³/kg
-        rho0      -   Ideal gas Density, kg/m³
-        h0        -   Ideal gas Specific enthalpy, kJ/kg
-        u0        -   Ideal gas Specific internal energy, kJ/kg
-        s0        -   Ideal gas Specific entropy, kJ/kg·K
-        a0        -   Ideal gas Specific Helmholtz free energy, kJ/kg
-        g0        -   Ideal gas Specific Gibbs free energy, kJ/kg
-        cp0       -   Ideal gas Specific isobaric heat capacity, kJ/kg·K
-        cv0       -   Ideal gas Specific isochoric heat capacity, kJ/kg·K
-        cp0_cv    -   Ideal gas Heat capacity ratio
-        gamma0    -   Ideal gas Isoentropic exponent
-
+    General implementation of multiparameter equation of state. From this
+    derived all child class specified per individual compounds
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    rho : float
+        Density [kg/m³]
+    v : float
+        Specific volume [m³/kg]
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+    u : float
+        Specific internal energy [kJ/kg]
+    x : float
+        Vapor quality [-]
+
+    l : float, optional
+        Wavelength of light, for refractive index [nm]
+    rho0 : float, optional
+        Initial value of density, to improve iteration [kg/m³]
+    T0 : float, optional
+        Initial value of temperature, to improve iteration [K]
+    x0 : Initial value of vapor quality, necessary in bad input pair definition
+        where there are two valid solution (T-h, T-s)
+
+    Notes
+    -----
+    * It needs two incoming properties of T, P, rho, h, s, u.
+    * v as a alternate input parameter to rho
+    * T-x, P-x, preferred input pair to specified a point in two phases region
+
+    Returns
+    -------
+    The calculated instance has the following properties:
+        * P: Pressure [MPa]
+        * T: Temperature [K]
+        * x: Vapor quality [-]
+        * g: Specific Gibbs free energy [kJ/kg]
+        * a: Specific Helmholtz free energy [kJ/kg]
+        * v: Specific volume [m³/kg]
+        * r: Density [kg/m³]
+        * h: Specific enthalpy [kJ/kg]
+        * u: Specific internal energy [kJ/kg]
+        * s: Specific entropy [kJ/kg·K]
+        * cp: Specific isobaric heat capacity [kJ/kg·K]
+        * cv: Specific isochoric heat capacity [kJ/kg·K]
+        * cp_cv: Heat capacity ratio, [-]
+        * Z: Compression factor [-]
+        * fi: Fugacity coefficient [-]
+        * f: Fugacity [MPa]
+        * gamma: Isoentropic exponent [-]
+
+        * alfav: Isobaric cubic expansion coefficient [1/K]
+        * kappa: Isothermal compressibility [1/MPa]
+        * kappas: Adiabatic compresibility [1/MPa]
+        * alfap: Relative pressure coefficient [1/K]
+        * betap: Isothermal stress coefficient [kg/m³]
+        * joule: Joule-Thomson coefficient [K/MPa]
+
+        * betas: Isoentropic temperature-pressure coefficient [-]
+        * Gruneisen: Gruneisen parameter [-]
+        * virialB: Second virial coefficient [m³/kg]
+        * virialC: Third virial coefficient [m⁶/kg²]
+        * dpdT_rho: Derivatives, dp/dT at constant rho [MPa/K]
+        * dpdrho_T: Derivatives, dp/drho at constant T [MPa·m³/kg]
+        * drhodT_P: Derivatives, drho/dT at constant P [kg/m³·K]
+        * drhodP_T: Derivatives, drho/dP at constant T [kg/m³·MPa]
+        * dhdT_rho: Derivatives, dh/dT at constant rho [kJ/kg·K]
+        * dhdP_T: Isothermal throttling coefficient [kJ/kg·MPa]
+        * dhdT_P: Derivatives, dh/dT at constant P [kJ/kg·K]
+        * dhdrho_T: Derivatives, dh/drho at constant T [kJ·m³/kg²]
+        * dhdrho_P: Derivatives, dh/drho at constant P [kJ·m³/kg²]
+        * dhdP_rho: Derivatives, dh/dP at constant rho [kJ/kg·MPa]
+        * kt: Isothermal Expansion Coefficient [-]
+        * ks: Adiabatic Compressibility [1/MPa]
+        * Ks: Adiabatic bulk modulus [MPa]
+        * Kt: Isothermal bulk modulus [MPa]
+
+        * v0: Ideal specific volume [m³/kg]
+        * rho0: Ideal gas density [kg/m³]
+        * u0: Ideal specific internal energy [kJ/kg]
+        * h0: Ideal specific enthalpy [kJ/kg]
+        * s0: Ideal specific entropy [kJ/kg·K]
+        * a0: Ideal specific Helmholtz free energy [kJ/kg]
+        * g0: Ideal specific Gibbs free energy [kJ/kg]
+        * cp0: Ideal specific isobaric heat capacity [kJ/kg·K]
+        * cv0: Ideal specific isochoric heat capacity [kJ/kg·K]
+        * w0: Ideal speed of sound [m/s]
+        * gamma0: Ideal isoentropic exponent [-]
+
+        * w: Speed of sound [m/s]
+        * mu: Dynamic viscosity [Pa·s]
+        * nu: Kinematic viscosity [m²/s]
+        * k: Thermal conductivity [W/m·K]
+        * alfa: Thermal diffusivity [m²/s]
+        * sigma: Surface tension [N/m]
+        * epsilon: Dielectric constant [-]
+        * n: Refractive index [-]
+        * Prandt: Prandtl number [-]
+        * Pr: Reduced Pressure [-]
+        * Tr: Reduced Temperature [-]
+        * Hvap: Vaporization heat [kJ/kg]
+        * Svap: Vaporization entropy [kJ/kg·K]
+
+        * Z_rho: (Z-1) over the density [m³/kg]
+        * IntP: Internal pressure [MPa]
+        * invT: Negative reciprocal temperature [1/K]
+        * hInput: Specific heat input [kJ/kg]
     """
-
     CP = None
-    _surface = None
-    _vapor_Pressure = None
-    _liquid_Density = None
-    _vapor_Density = None
+    _Pv = None
+    _rhoL = None
+    _rhoG = None
 
     kwargs = {"T": 0.0,
               "P": 0.0,
@@ -122,13 +152,16 @@ class MEoS(_fase):
               "s": None,
               "u": None,
               "x": None,
-              "l": 0.5893}
+              "l": 0.5893,
+              "rho0": None,
+              "T0": None,
+              "x0": 0.5}
     status = 0
     msg = "Undefined"
 
     def __init__(self, **kwargs):
         """Constructor, define common constant and initinialice kwargs"""
-        self.R = self._constants["R"]/self.M
+        self.R = self._constants["R"]/self._constants.get("M", self.M)
         self.Zc = self.Pc/self.rhoc/self.R/self.Tc
         self.kwargs = MEoS.kwargs.copy()
         self.__call__(**kwargs)
@@ -141,9 +174,25 @@ class MEoS(_fase):
         self.kwargs.update(kwargs)
 
         if self.calculable:
-            self.status = 1
-            self.calculo()
-            self.msg = ""
+            try:
+                self.status = 1
+                self.calculo()
+                self.msg = ""
+            except RuntimeError as err:
+                self.status = 0
+                self.msg = err.args[0]
+                raise(err)
+
+            # Add msg for extrapolation state
+            if self.name == "water" and 130 <= self.T < 273.15:
+                self.msg = "Extrapolated state"
+                self.status = 3
+                warnings.warn("Using extrapolated values")
+            elif self.name == "water" and 50 <= self.T < 130:
+                self.msg = "Extrapolated state using Low-Temperature extension"
+                self.status = 3
+                warnings.warn("Using extrapolated values and Low-Temperature"
+                              "extension")
 
     @property
     def calculable(self):
@@ -179,7 +228,6 @@ class MEoS(_fase):
             self._mode = "hu"
         elif self.kwargs["s"] is not None and self.kwargs["u"] is not None:
             self._mode = "su"
-
         elif self.kwargs["T"] and self.kwargs["x"] is not None:
             self._mode = "Tx"
         elif self.kwargs["P"] and self.kwargs["x"] is not None:
@@ -191,85 +239,200 @@ class MEoS(_fase):
         T = self.kwargs["T"]
         rho = self.kwargs["rho"]
         P = self.kwargs["P"]
-        v = self.kwargs["v"]
         s = self.kwargs["s"]
         h = self.kwargs["h"]
         u = self.kwargs["u"]
         x = self.kwargs["x"]
 
-        self.R = self._constants["R"]/self.M
+        # Initial values
+        T0 = self.kwargs["T0"]
+        rho0 = self.kwargs["rho0"]
+
+        if T0 or rho0:
+            To = T0
+            rhoo = rho0
+        elif self.name == "air":
+            To = 300
+            rhoo = 1e-3
+        else:
+            try:
+                st0 = IAPWS97(**self.kwargs)
+            except NotImplementedError:
+                To = 300
+                rhoo = 900
+            else:
+                if st0.status:
+                    To = st0.T
+                    rhoo = st0.rho
+                else:
+                    To = 300
+                    rhoo = 900
+
+        self.R = self._constants["R"]/self._constants.get("M", self.M)
 
         propiedades = None
-        if v and not rho:
-            rho = 1./v
 
         if x is None:
             # Method with iteration necessary to get x
             if self._mode == "TP":
-                if T < self.Tc and P < self.Pc and \
-                        self._Vapor_Pressure(T) < P:
-                    rhoo = self._Liquid_Density(T)
-                elif T < self.Tc and P < self.Pc:
-                    rhoo = self._Vapor_Density(T)
-                else:
-                    rhoo = self.rhoc*3
+                try:
+                    if self.name == "air":
+                        raise ValueError
+                    st0 = IAPWS97(**self.kwargs)
+                    rhoo = st0.rho
+                except NotImplementedError:
+                    if rho0:
+                        rhoo = rho0
+                    elif T < self.Tc and P < self.Pc and \
+                            self._Vapor_Pressure(T) < P:
+                        rhoo = self._Liquid_Density(T)
+                    elif T < self.Tc and P < self.Pc:
+                        rhoo = self._Vapor_Density(T)
+                    else:
+                        rhoo = self.rhoc*3
+                except ValueError:
+                    rhoo = 1e-3
                 rho = fsolve(
-                    lambda rho: self._Helmholtz(rho, T)["P"]-P*1000, rhoo)
+                    lambda rho: self._Helmholtz(rho, T)["P"]-P*1000, rhoo)[0]
 
             elif self._mode == "Th":
-                rhol = self._Liquid_Density(T)
-                rhov = self._Vapor_Density(T)
-                hv = self._Helmholtz(rhov, T)["h"]
-                if h > hv:
-                    rhoo = rhov
+                def f(rho):
+                    return self._Helmholtz(rho, T)["h"]-h
+
+                if T >= self.Tc:
+                    rhoo = self.rhoc
+                    rho = fsolve(f, rhoo)[0]
                 else:
-                    rhoo = 1000
-                rho = fsolve(lambda rho: self._Helmholtz(rho, T)["h"]-h, rhoo)
+                    x0 = self.kwargs["x0"]
+                    rhov = self._Vapor_Density(T)
+                    rhol = self._Liquid_Density(T)
+                    hl = self._Helmholtz(rhol, T)["h"]
+                    hv = self._Helmholtz(rhov, T)["h"]
+                    if x0 not in (0, 1) and hl <= h <= hv:
+                        rhol, rhov, Ps = self._saturation(T)
+                        vapor = self._Helmholtz(rhov, T)
+                        liquido = self._Helmholtz(rhol, T)
+                        hv = vapor["h"]
+                        hl = liquido["h"]
+                        x = (h-hl)/(hv-hl)
+                        rho = 1/(x/rhov+(1-x)/rhol)
+                        P = Ps/1000
+                    else:
+                        if h > hv:
+                            rhoo = rhov
+                        else:
+                            rhoo = rhol
+                        rho = fsolve(f, rhoo)[0]
 
             elif self._mode == "Ts":
-                rhol = self._Liquid_Density(T)
-                rhov = self._Vapor_Density(T)
-                sv = self._Helmholtz(rhov, T)["s"]
-                if s > sv:
-                    rhoo = rhov
+                def f(rho):
+                    if rho < 0:
+                        rho = 1e-20
+                    return self._Helmholtz(rho, T)["s"]-s
+
+                if T >= self.Tc:
+                    rhoo = self.rhoc
+                    rho = fsolve(f, rhoo)[0]
                 else:
-                    rhoo = 1000
-                rho = fsolve(lambda rho: self._Helmholtz(rho, T)["s"]-s, rhoo)
+                    rhov = self._Vapor_Density(T)
+                    rhol = self._Liquid_Density(T)
+                    sl = self._Helmholtz(rhol, T)["s"]
+                    sv = self._Helmholtz(rhov, T)["s"]
+                    if sl <= s <= sv:
+                        rhol, rhov, Ps = self._saturation(T)
+                        vapor = self._Helmholtz(rhov, T)
+                        liquido = self._Helmholtz(rhol, T)
+                        sv = vapor["s"]
+                        sl = liquido["s"]
+                        x = (s-sl)/(sv-sl)
+                        rho = 1/(x/rhov+(1-x)/rhol)
+                        P = Ps/1000
+                    else:
+                        if s > sv:
+                            rhoo = rhov
+                        else:
+                            rhoo = rhol
+                        rho = fsolve(f, rhoo)[0]
 
             elif self._mode == "Tu":
-                rhol = self._Liquid_Density(T)
-                rhov = self._Vapor_Density(T)
-                Ps = self._Vapor_Pressure(T)
-                vapor = self._Helmholtz(rhov, T)
-                uv = vapor["h"]-Ps*vapor["v"]
-                if u > uv:
-                    rhoo = rhov
-                else:
-                    rhoo = 1000
+                def f(rho):
+                    prop = self._Helmholtz(rho, T)
+                    return prop["h"]-prop["P"]/rho-u
 
-                def funcion(rho):
-                    par = self._Helmholtz(rho, T)
-                    return par["h"]-par["P"]*par["v"]-u
-                rho = fsolve(funcion, rhoo)
+                if T >= self.Tc:
+                    rhoo = self.rhoc
+                    rho = fsolve(f, rhoo)[0]
+                else:
+                    rhov = self._Vapor_Density(T)
+                    rhol = self._Liquid_Density(T)
+                    vapor = self._Helmholtz(rhov, T)
+                    liquido = self._Helmholtz(rhol, T)
+                    uv = vapor["h"]-vapor["P"]/rhov
+                    ul = liquido["h"]-liquido["P"]/rhol
+                    if ul <= u <= uv:
+                        rhol, rhov, Ps = self._saturation(T)
+                        vapor = self._Helmholtz(rhov, T)
+                        liquido = self._Helmholtz(rhol, T)
+                        uv = vapor["h"]-vapor["P"]/rhov
+                        ul = liquido["h"]-liquido["P"]/rhol
+                        x = (u-ul)/(uv-ul)
+                        rho = 1/(x/rhov-(1-x)/rhol)
+                        P = Ps/1000
+                    else:
+                        if u > uv:
+                            rhoo = rhov
+                        else:
+                            rhoo = rhol
+                        rho = fsolve(f, rhoo)[0]
 
             elif self._mode == "Prho":
-                T = fsolve(lambda T: self._Helmholtz(rho, T)["P"]-P*1000, 600)
+                T = fsolve(
+                    lambda T: self._Helmholtz(rho, T)["P"]-P*1000, To)[0]
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if T[0] == 600 or rhov <= rho <= rhol:
-                    def funcion(T):
-                        rhol, rhov, Ps = self._saturation(T)
-                        return Ps-P*1000
-                    T = fsolve(funcion, 600)
+                if T == To or rhov <= rho <= rhol:
+
+                    def f(parr):
+                        T, rhol, rhog = parr
+                        deltaL = rhol/self.rhoc
+                        deltaG = rhog/self.rhoc
+                        liquido = self._Helmholtz(rhol, T)
+                        vapor = self._Helmholtz(rhog, T)
+                        Jl = rhol*(1+deltaL*liquido["fird"])
+                        Jv = rhog*(1+deltaG*vapor["fird"])
+                        K = liquido["fir"]-vapor["fir"]
+                        Ps = self.R*T*rhol*rhog/(rhol-rhog)*(
+                            liquido["fir"]-vapor["fir"]+log(rhol/rhog))
+                        return (Jl-Jv,
+                                Jl*(1/rhog-1/rhol)-log(rhol/rhog)-K,
+                                Ps - P*1000)
+
+                    for to in [To, 300, 400, 500, 600]:
+                        rhoLo = self._Liquid_Density(to)
+                        rhoGo = self._Vapor_Density(to)
+                        sol = fsolve(f, [to, rhoLo, rhoGo], full_output=True)
+                        T, rhoL, rhoG = sol[0]
+                        x = (1./rho-1/rhoL)/(1/rhoG-1/rhoL)
+                        if sol[2] == 1 and 0 <= x <= 1 and \
+                                sum(abs(sol[1]["fvec"])) < 1e-5:
+                            break
+
+                    if sum(abs(sol[1]["fvec"])) > 1e-5:
+                        raise(RuntimeError(sol[3]))
+
+                    liquido = self._Helmholtz(rhoL, T)
+                    vapor = self._Helmholtz(rhoG, T)
+                    P = self.R*T*rhoL*rhoG/(rhoL-rhoG)*(
+                        liquido["fir"]-vapor["fir"]+log(rhoL/rhoG))/1000
 
             elif self._mode == "Ph":
                 def funcion(parr):
                     par = self._Helmholtz(parr[0], parr[1])
                     return par["P"]-P*1000, par["h"]-h
-                rho, T = fsolve(funcion, [1000, 300])
+                rho, T = fsolve(funcion, [rhoo, To])
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if rho == 1000 or rhov <= rho <= rhol:
+                if rho == rhoo or rhov <= rho <= rhol:
                     def funcion(parr):
                         rho, T = parr
                         rhol, rhov, Ps = self._saturation(T)
@@ -278,15 +441,26 @@ class MEoS(_fase):
                         x = (1./rho-1/rhol)/(1/rhov-1/rhol)
                         return Ps-P*1000, vapor["h"]*x+liquido["h"]*(1-x)-h
                     rho, T = fsolve(funcion, [2., 500.])
+                    rhol, rhov, Ps = self._saturation(T)
+                    vapor = self._Helmholtz(rhov, T)
+                    liquido = self._Helmholtz(rhol, T)
+                    hv = vapor["h"]
+                    hl = liquido["h"]
+                    x = (h-hl)/(hv-hl)
 
             elif self._mode == "Ps":
-                def funcion(parr):
-                    par = self._Helmholtz(parr[0], parr[1])
-                    return par["P"]-P*1000, par["s"]-s
-                rho, T = fsolve(funcion, [2., 400])
-                rhol = self._Liquid_Density(T)
-                rhov = self._Vapor_Density(T)
-                if rho == 2. or rhov <= rho <= rhol:
+                try:
+                    x0 = st0.x
+                except NameError:
+                    x0 = None
+
+                if x0 is None or x0 == 0 or x0 == 1:
+                    def funcion(parr):
+                        par = self._Helmholtz(parr[0], parr[1])
+                        return par["P"]-P*1000, par["s"]-s
+                    rho, T = fsolve(funcion, [rhoo, To])
+
+                else:
                     def funcion(parr):
                         rho, T = parr
                         rhol, rhov, Ps = self._saturation(T)
@@ -295,15 +469,23 @@ class MEoS(_fase):
                         x = (1./rho-1/rhol)/(1/rhov-1/rhol)
                         return Ps-P*1000, vapor["s"]*x+liquido["s"]*(1-x)-s
                     rho, T = fsolve(funcion, [2., 500.])
+                    rhol, rhov, Ps = self._saturation(T)
+                    vapor = self._Helmholtz(rhov, T)
+                    liquido = self._Helmholtz(rhol, T)
+                    sv = vapor["s"]
+                    sl = liquido["s"]
+                    x = (s-sl)/(sv-sl)
 
             elif self._mode == "Pu":
                 def funcion(parr):
-                    par = self._Helmholtz(parr[0], parr[1])
-                    return par["h"]-par["P"]*par["v"]-u, par["P"]-P*1000
-                rho, T = fsolve(funcion, [1000, 600])
+                    rho, T = parr
+                    par = self._Helmholtz(rho, T)
+                    return par["h"]-par["P"]/rho-u, par["P"]-P*1000
+                sol = fsolve(funcion, [rhoo, To], full_output=True)
+                rho, T = sol[0]
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if rho == 1000 or rhov <= rho <= rhol:
+                if rho == rhoo or sol[2] != 1:
                     def funcion(parr):
                         rho, T = parr
                         rhol, rhov, Ps = self._saturation(T)
@@ -314,56 +496,136 @@ class MEoS(_fase):
                         x = (1./rho-1/rhol)/(1/rhov-1/rhol)
                         return Ps-P*1000, vu*x+lu*(1-x)-u
                     rho, T = fsolve(funcion, [2., 500.])
+                    rhol, rhov, Ps = self._saturation(T)
+                    vapor = self._Helmholtz(rhov, T)
+                    liquido = self._Helmholtz(rhol, T)
+                    uv = vapor["h"]-Ps/rhov
+                    ul = liquido["h"]-Ps/rhol
+                    x = (u-ul)/(uv-ul)
 
             elif self._mode == "rhoh":
-                T = fsolve(lambda T: self._Helmholtz(rho, T)["h"]-h, 600)
+                T = fsolve(lambda T: self._Helmholtz(rho, T)["h"]-h, To)[0]
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if T[0] == 600 or rhov <= rho <= rhol:
-                    def funcion(T):
-                        rhol, rhov, Ps = self._saturation(T)
-                        vapor = self._Helmholtz(rhov, T)
+                if T == To or rhov <= rho <= rhol:
+                    def f(parr):
+                        T, rhol, rhog = parr
+                        deltaL = rhol/self.rhoc
+                        deltaG = rhog/self.rhoc
                         liquido = self._Helmholtz(rhol, T)
-                        x = (1./rho-1/rhol)/(1/rhov-1/rhol)
-                        return vapor["h"]*x+liquido["h"]*(1-x)-h
-                    T = fsolve(funcion, 500.)
+                        vapor = self._Helmholtz(rhog, T)
+                        Jl = rhol*(1+deltaL*liquido["fird"])
+                        Jv = rhog*(1+deltaG*vapor["fird"])
+                        K = liquido["fir"]-vapor["fir"]
+                        x = (1./rho-1/rhol)/(1/rhog-1/rhol)
+                        return (Jl-Jv,
+                                Jl*(1/rhog-1/rhol)-log(rhol/rhog)-K,
+                                liquido["h"]*(1-x)+vapor["h"]*x - h)
+
+                    for to in [To, 300, 400, 500, 600]:
+                        rhoLo = self._Liquid_Density(to)
+                        rhoGo = self._Vapor_Density(to)
+                        sol = fsolve(f, [to, rhoLo, rhoGo], full_output=True)
+                        T, rhoL, rhoG = sol[0]
+                        x = (1./rho-1/rhoL)/(1/rhoG-1/rhoL)
+                        if sol[2] == 1 and 0 <= x <= 1 and \
+                                sum(abs(sol[1]["fvec"])) < 1e-5:
+                            break
+
+                    if sum(abs(sol[1]["fvec"])) > 1e-5:
+                        raise(RuntimeError(sol[3]))
+
+                    liquido = self._Helmholtz(rhoL, T)
+                    vapor = self._Helmholtz(rhoG, T)
+                    P = self.R*T*rhoL*rhoG/(rhoL-rhoG)*(
+                        liquido["fir"]-vapor["fir"]+log(rhoL/rhoG))/1000
 
             elif self._mode == "rhos":
-                T = fsolve(lambda T: self._Helmholtz(rho, T)["s"]-s, 600)
+                T = fsolve(lambda T: self._Helmholtz(rho, T)["s"]-s, To)[0]
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if T[0] == 600 or rhov <= rho <= rhol:
-                    def funcion(T):
-                        rhol, rhov, Ps = self._saturation(T)
-                        vapor = self._Helmholtz(rhov, T)
+                if T == To or rhov <= rho <= rhol:
+                    def f(parr):
+                        T, rhol, rhog = parr
+                        deltaL = rhol/self.rhoc
+                        deltaG = rhog/self.rhoc
                         liquido = self._Helmholtz(rhol, T)
-                        x = (1./rho-1/rhol)/(1/rhov-1/rhol)
-                        return vapor["s"]*x+liquido["s"]*(1-x)-s
-                    T = fsolve(funcion, 500.)
+                        vapor = self._Helmholtz(rhog, T)
+                        Jl = rhol*(1+deltaL*liquido["fird"])
+                        Jv = rhog*(1+deltaG*vapor["fird"])
+                        K = liquido["fir"]-vapor["fir"]
+                        x = (1./rho-1/rhol)/(1/rhog-1/rhol)
+                        return (Jl-Jv,
+                                Jl*(1/rhog-1/rhol)-log(rhol/rhog)-K,
+                                liquido["s"]*(1-x)+vapor["s"]*x - s)
+
+                    for to in [To, 300, 400, 500, 600]:
+                        rhoLo = self._Liquid_Density(to)
+                        rhoGo = self._Vapor_Density(to)
+                        sol = fsolve(f, [to, rhoLo, rhoGo], full_output=True)
+                        T, rhoL, rhoG = sol[0]
+                        x = (1./rho-1/rhoL)/(1/rhoG-1/rhoL)
+                        if sol[2] == 1 and 0 <= x <= 1 and \
+                                sum(abs(sol[1]["fvec"])) < 1e-5:
+                            break
+
+                    if sum(abs(sol[1]["fvec"])) > 1e-5:
+                        raise(RuntimeError(sol[3]))
+
+                    liquido = self._Helmholtz(rhoL, T)
+                    vapor = self._Helmholtz(rhoG, T)
+                    P = self.R*T*rhoL*rhoG/(rhoL-rhoG)*(
+                        liquido["fir"]-vapor["fir"]+log(rhoL/rhoG))/1000
 
             elif self._mode == "rhou":
                 def funcion(T):
                     par = self._Helmholtz(rho, T)
-                    return par["h"]-par["P"]/1000*par["v"]-u
-                T = fsolve(funcion, 600)
+                    return par["h"]-par["P"]/rho-u
+                T = fsolve(funcion, To)[0]
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if T[0] == 600 or rhov <= rho <= rhol:
-                    def funcion(T):
-                        rhol, rhov, Ps = self._saturation(T)
-                        vapor = self._Helmholtz(rhov, T)
+                if T == To or rhov <= rho <= rhol:
+                    def f(parr):
+                        T, rhol, rhog = parr
+                        deltaL = rhol/self.rhoc
+                        deltaG = rhog/self.rhoc
                         liquido = self._Helmholtz(rhol, T)
-                        vu = vapor["h"]-Ps/rhov
+                        vapor = self._Helmholtz(rhog, T)
+                        Jl = rhol*(1+deltaL*liquido["fird"])
+                        Jv = rhog*(1+deltaG*vapor["fird"])
+                        K = liquido["fir"]-vapor["fir"]
+                        x = (1./rho-1/rhol)/(1/rhog-1/rhol)
+                        Ps = self.R*T*rhol*rhog/(rhol-rhog)*(
+                            liquido["fir"]-vapor["fir"]+log(rhol/rhog))
+                        vu = vapor["h"]-Ps/rhog
                         lu = liquido["h"]-Ps/rhol
-                        x = (1./rho-1/rhol)/(1/rhov-1/rhol)
-                        return vu*x+lu*(1-x)-u
-                    T = fsolve(funcion, 500.)
+                        return (Jl-Jv,
+                                Jl*(1/rhog-1/rhol)-log(rhol/rhog)-K,
+                                lu*(1-x)+vu*x - u)
+
+                    for to in [To, 300, 400, 500, 600]:
+                        rhoLo = self._Liquid_Density(to)
+                        rhoGo = self._Vapor_Density(to)
+                        sol = fsolve(f, [to, rhoLo, rhoGo], full_output=True)
+                        T, rhoL, rhoG = sol[0]
+                        x = (1./rho-1/rhoL)/(1/rhoG-1/rhoL)
+                        if sol[2] == 1 and 0 <= x <= 1 and \
+                                sum(abs(sol[1]["fvec"])) < 1e-5:
+                            break
+
+                    if sum(abs(sol[1]["fvec"])) > 1e-5:
+                        raise(RuntimeError(sol[3]))
+
+                    liquido = self._Helmholtz(rhoL, T)
+                    vapor = self._Helmholtz(rhoG, T)
+                    P = self.R*T*rhoL*rhoG/(rhoL-rhoG)*(
+                        liquido["fir"]-vapor["fir"]+log(rhoL/rhoG))/1000
 
             elif self._mode == "hs":
                 def funcion(parr):
                     par = self._Helmholtz(parr[0], parr[1])
                     return par["h"]-h, par["s"]-s
-                rho, T = fsolve(funcion, [1000, 300])
+                rho, T = fsolve(funcion, [rhoo, To])
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
                 if rhov <= rho <= rhol:
@@ -376,15 +638,24 @@ class MEoS(_fase):
                         return (vapor["h"]*x+liquido["h"]*(1-x)-h,
                                 vapor["s"]*x+liquido["s"]*(1-x)-s)
                     rho, T = fsolve(funcion, [0.5, 400.])
+                    rhol, rhov, Ps = self._saturation(T)
+                    vapor = self._Helmholtz(rhov, T)
+                    liquido = self._Helmholtz(rhol, T)
+                    sv = vapor["s"]
+                    sl = liquido["s"]
+                    x = (s-sl)/(sv-sl)
+                    P = Ps/1000
 
             elif self._mode == "hu":
                 def funcion(parr):
-                    par = self._Helmholtz(parr[0], parr[1])
-                    return par["h"]-par["P"]/1000*par["v"]-u, par["h"]-h
-                rho, T = fsolve(funcion, [1000, 600])
+                    rho, T = parr
+                    par = self._Helmholtz(rho, T)
+                    return par["h"]-par["P"]/rho-u, par["h"]-h
+                sol = fsolve(funcion, [rhoo, To], full_output=True)
+                rho, T = sol[0]
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if T == 600 or rhov <= rho <= rhol:
+                if sol[2] != 1 or rhov <= rho <= rhol:
                     def funcion(parr):
                         rho, T = parr
                         rhol, rhov, Ps = self._saturation(T)
@@ -395,16 +666,43 @@ class MEoS(_fase):
                         x = (1./rho-1/rhol)/(1/rhov-1/rhol)
                         return (vapor["h"]*x+liquido["h"]*(1-x)-h,
                                 vu*x+lu*(1-x)-u)
-                    rho, T = fsolve(funcion, [2., 500.])
+
+                    To = [500, 700, 300, 900]
+                    if self.kwargs["T0"]:
+                        To.insert(0, self.kwargs["T0"])
+                    rhov = self._Vapor_Density(self.Tt)
+                    rhol = self._Liquid_Density(self.Tt)
+                    ro = [1, 1e-3, rhov, rhol]
+                    if self.kwargs["rho0"]:
+                        ro.insert(0, self.kwargs["rho0"])
+
+                    for r, t in product(ro, To):
+                        sol = fsolve(funcion, [r, t], full_output=True)
+                        rho, T = sol[0]
+                        if sol[2] == 1 and sum(abs(sol[1]["fvec"])) < 1e-5:
+                            break
+
+                    if sum(abs(sol[1]["fvec"])) > 1e-5:
+                        raise(RuntimeError(sol[3]))
+
+                    rhol, rhov, Ps = self._saturation(T)
+                    vapor = self._Helmholtz(rhov, T)
+                    liquido = self._Helmholtz(rhol, T)
+                    hv = vapor["h"]
+                    hl = liquido["h"]
+                    x = (h-hl)/(hv-hl)
+                    P = Ps/1000
 
             elif self._mode == "su":
                 def funcion(parr):
-                    par = self._Helmholtz(parr[0], parr[1])
-                    return par["h"]-par["P"]/1000*par["v"]-u, par["s"]-s
-                rho, T = fsolve(funcion, [1000, 600])
+                    rho, T = parr
+                    par = self._Helmholtz(rho, T)
+                    return par["h"]-par["P"]/rho-u, par["s"]-s
+                sol = fsolve(funcion, [rhoo, To], full_output=True)
+                rho, T = sol[0]
                 rhol = self._Liquid_Density(T)
                 rhov = self._Vapor_Density(T)
-                if T == 600 or rhov <= rho <= rhol:
+                if sol[2] != 1 or rhov <= rho <= rhol:
                     def funcion(parr):
                         rho, T = parr
                         rhol, rhov, Ps = self._saturation(T)
@@ -415,42 +713,61 @@ class MEoS(_fase):
                         x = (1./rho-1/rhol)/(1/rhov-1/rhol)
                         return (vapor["s"]*x+liquido["s"]*(1-x)-s,
                                 vu*x+lu*(1-x)-u)
-                    rho, T = fsolve(funcion, [2., 500.])
 
-            rho = float(rho)
-            T = float(T)
-            propiedades = self._Helmholtz(rho, T)
-            if T <= self.Tc:
-                rhol = self._Liquid_Density(T)
-                rhov = self._Vapor_Density(T)
-                if rhol > rho > rhov:
+                    To = [500, 700, 300, 900]
+                    if self.kwargs["T0"]:
+                        To.insert(0, self.kwargs["T0"])
+                    rhov = self._Vapor_Density(self.Tt)
+                    rhol = self._Liquid_Density(self.Tt)
+                    ro = [1, 1e-3, rhov, rhol]
+                    if self.kwargs["rho0"]:
+                        ro.insert(0, self.kwargs["rho0"])
+
+                    for r, t in product(ro, To):
+                        sol = fsolve(funcion, [r, t], full_output=True)
+                        rho, T = sol[0]
+                        if sol[2] == 1 and sum(abs(sol[1]["fvec"])) < 1e-5:
+                            break
+
+                    if sum(abs(sol[1]["fvec"])) > 1e-5:
+                        raise(RuntimeError(sol[3]))
+
                     rhol, rhov, Ps = self._saturation(T)
-                    x = (1/rho-1/rhol)/(1/rhov-1/rhol)
-                    if x < 0:
-                        x = 0
-                    elif x > 1:
-                        x = 1
+                    vapor = self._Helmholtz(rhov, T)
+                    liquido = self._Helmholtz(rhol, T)
+                    sv = vapor["s"]
+                    sl = liquido["s"]
+                    x = (s-sl)/(sv-sl)
                     P = Ps/1000
-                elif rho <= rhov:
-                    x = 1
-                elif rho >= rhol:
-                    x = 0
 
-                vapor = self._Helmholtz(rhov, T)
-                liquido = self._Helmholtz(rhol, T)
+            elif self._mode == "Trho":
+                if T < self.Tc:
+                    rhov = self._Vapor_Density(T)
+                    rhol = self._Liquid_Density(T)
+                    if rhol > rho > rhov:
+                        rhol, rhov, Ps = self._saturation(T)
+                        vapor = self._Helmholtz(rhov, T)
+                        liquido = self._Helmholtz(rhol, T)
+                        x = (1/rho-1/rhol)/(1/rhov-1/rhol)
+                        rho = 1/(x/rhov-(1-x)/rhol)
+                        P = Ps/1000
 
-            elif T > self.Tc:
+            rho = float(rho)
+            T = float(T)
+            propiedades = self._Helmholtz(rho, T)
+
+            if T > self.Tc:
                 x = 1
-            else:
-                raise NotImplementedError("Incoming out of bound")
+            elif x is None:
+                x = 0
 
             if not P:
                 P = propiedades["P"]/1000.
 
         elif self._mode == "Tx":
             # Check input T in saturation range
-            if self.Tt > T or self.Tc < T:
-                raise ValueError("Wrong input values")
+            if self.Tt > T or self.Tc < T or x > 1 or x < 0:
+                raise NotImplementedError("Incoming out of bound")
 
             rhol, rhov, Ps = self._saturation(T)
             vapor = self._Helmholtz(rhov, T)
@@ -462,8 +779,11 @@ class MEoS(_fase):
             P = Ps/1000.
 
         elif self._mode == "Px":
-            # Iterate over saturation routine to get T
+            # Check input P in saturation range
+            if self.Pc < P or x > 1 or x < 0:
+                raise NotImplementedError("Incoming out of bound")
 
+            # Iterate over saturation routine to get T
             def funcion(T):
                 rhol = self._Liquid_Density(T)
                 rhog = self._Vapor_Density(T)
@@ -476,7 +796,12 @@ class MEoS(_fase):
                     liquido["fir"]-vapor["fir"]+log(deltaL/deltaG))
                 return Ps/1000-P
 
-            To = _TSat_P(P)
+            if T0:
+                To = T0
+            elif self.name == "water":
+                To = _TSat_P(P)
+            else:
+                To = (self.Tc+self.Tt)/2
             T = fsolve(funcion, To)[0]
             rhol, rhov, Ps = self._saturation(T)
             vapor = self._Helmholtz(rhov, T)
@@ -528,29 +853,26 @@ class MEoS(_fase):
 
         # Calculate special properties useful only for one phase
         if self._mode in ("Px", "Tx") or (x < 1 and self.Tt <= T <= self.Tc):
-            if self.name == "water":
-                self.sigma = _Tension(T)
-            else:
-                self.sigma = self._Tension(T)
+            self.sigma = self._surface(T)
         else:
             self.sigma = None
 
-        if 0 < x < 1:
-            self.virialB = vapor["B"]/self.rhoc
-            self.virialC = vapor["C"]/self.rhoc**2
-        else:
-            self.virialB = propiedades["B"]/self.rhoc
-            self.virialC = propiedades["C"]/self.rhoc**2
+        vir = self._virial(T)
+        self.virialB = vir["B"]/self.rhoc
+        self.virialC = vir["C"]/self.rhoc**2
 
-        if self.Tt <= T <= self.Tc:
+        if 0 < x < 1:
             self.Hvap = vapor["h"]-liquido["h"]
+            self.Svap = vapor["s"]-liquido["s"]
         else:
             self.Hvap = None
+            self.Svap = None
+
         self.invT = -1/self.T
 
         # Ideal properties
         cp0 = self._prop0(self.rho, self.T)
-        self.v0 = cp0.v
+        self.v0 = self.R*self.T/self.P/1000
         self.rho0 = 1./self.v0
         self.h0 = cp0.h
         self.u0 = self.h0-self.P*self.v0
@@ -560,12 +882,13 @@ class MEoS(_fase):
         self.cp0 = cp0.cp
         self.cv0 = cp0.cv
         self.cp0_cv = self.cp0/self.cv0
+        cp0.v = self.v0
         self.gamma0 = -self.v0/self.P/1000*self.derivative("P", "v", "s", cp0)
 
     def fill(self, fase, estado):
         """Fill phase properties"""
-        fase.v = estado["v"]
-        fase.rho = 1/fase.v
+        fase.rho = estado["rho"]
+        fase.v = 1/fase.rho
 
         fase.h = estado["h"]
         fase.s = estado["s"]
@@ -574,16 +897,27 @@ class MEoS(_fase):
         fase.g = fase.h-self.T*fase.s
 
         fase.Z = self.P*fase.v/self.T/self.R*1e3
-        fase.fi = estado["fugacity"]
+        fase.fi = exp(estado["fir"]+estado["delta"]*estado["fird"] -
+                      log(1+estado["delta"]*estado["fird"]))
         fase.f = fase.fi*self.P
-        fase.cp = estado["cp"]
         fase.cv = estado["cv"]
-        fase.cp_cv = fase.cp/fase.cv
-        fase.w = estado["w"]
+
+        fase.rhoM = fase.rho/self.M
+        fase.hM = fase.h*self.M
+        fase.sM = fase.s*self.M
+        fase.uM = fase.u*self.M
+        fase.aM = fase.a*self.M
+        fase.gM = fase.g*self.M
 
         fase.alfap = estado["alfap"]
         fase.betap = estado["betap"]
 
+        fase.cp = self.derivative("h", "T", "P", fase)
+        fase.cp_cv = fase.cp/fase.cv
+        fase.w = (self.derivative("P", "rho", "s", fase)*1000)**0.5
+        fase.cvM = fase.cv*self.M
+        fase.cpM = fase.cp*self.M
+
         fase.joule = self.derivative("T", "P", "h", fase)*1e3
         fase.Gruneisen = fase.v/fase.cv*self.derivative("P", "T", "v", fase)
         fase.alfav = self.derivative("v", "T", "P", fase)/fase.v
@@ -599,12 +933,12 @@ class MEoS(_fase):
         fase.dhdT_P = self.derivative("h", "T", "P", fase)
         fase.dhdP_T = self.derivative("h", "P", "T", fase)*1e3
         fase.dhdP_rho = self.derivative("h", "P", "rho", fase)*1e3
-        fase.dhdrho_T = estado["dhdrho"]
-        fase.dhdrho_P = estado["dhdrho"]+fase.dhdT_rho/estado["drhodt"]
+        fase.dhdrho_T = self.derivative("h", "rho", "T", fase)
+        fase.dhdrho_P = self.derivative("h", "rho", "P", fase)
         fase.dpdT_rho = self.derivative("P", "T", "rho", fase)*1e-3
-        fase.dpdrho_T = estado["dpdrho"]*1e-3
-        fase.drhodP_T = 1/estado["dpdrho"]*1e3
-        fase.drhodT_P = estado["drhodt"]
+        fase.dpdrho_T = self.derivative("P", "rho", "T", fase)*1e-3
+        fase.drhodP_T = self.derivative("rho", "P", "T", fase)*1e3
+        fase.drhodT_P = self.derivative("rho", "T", "P", fase)
 
         fase.Z_rho = (fase.Z-1)/fase.rho
         fase.IntP = self.T*self.derivative("P", "T", "rho", fase)*1e-3-self.P
@@ -617,16 +951,23 @@ class MEoS(_fase):
         fase.Prandt = fase.mu*fase.cp*1000/fase.k
         if self.name == "water":
             fase.epsilon = _Dielectric(fase.rho, self.T)
-            fase.n = _Refractive(fase.rho, self.T, self.kwargs["l"])
+            try:
+                fase.n = _Refractive(fase.rho, self.T, self.kwargs["l"])
+            except NotImplementedError:
+                fase.n = None
         else:
             fase.epsilon = None
             fase.n = None
 
-    def _saturation(self, T=None):
-        """Saturation calculation for two phase search"""
-        if not T:
-            T = self.T
+    def derivative(self, z, x, y, fase):
+        """Wrapper derivative for custom derived properties
+        where x, y, z can be: P, T, v, rho, u, h, s, g, a"""
+        return deriv_H(self, z, x, y, fase)
 
+    def _saturation(self, T):
+        """Saturation calculation for two phase search"""
+        if T > self.Tc:
+            T = self.Tc
         rhoLo = self._Liquid_Density(T)
         rhoGo = self._Vapor_Density(T)
 
@@ -655,95 +996,76 @@ class MEoS(_fase):
                 liquido["fir"]-vapor["fir"]+log(deltaL/deltaG))
         return rhoL, rhoG, Ps
 
-#    def _saturation2(self, T):
-#        """Akasaka (2008) "A Reliable and Useful Method to Determine the
-#        Saturation State from Helmholtz Energy Equations of State", Journal of
-#        Thermal Science and Technology, 3, 442-451
-#        http://dx.doi.org/10.1299/jtst.3.442"""
-#
-#        rhoL = self._Liquid_Density(T)
-#        rhoG = self._Vapor_Density(T)
-#        g = 500.
-#        erroro = 1e6
-#        rholo = rhoL
-#        rhogo = rhoG
-#        contador = 0
-#        while True:
-#            contador += 1
-#            deltaL = rhoL/self.rhoc
-#            deltaG = rhoG/self.rhoc
-#            liquido = self._Helmholtz(rhoL, T)
-#            vapor = self._Helmholtz(rhoG, T)
-#            Jl = deltaL*(1+deltaL*liquido["fird"])
-#            Jv = deltaG*(1+deltaG*vapor["fird"])
-#            Kl = deltaL*liquido["fird"]+liquido["fir"]+log(deltaL)
-#            Kv = deltaG*vapor["fird"]+vapor["fir"]+log(deltaG)
-#            Jdl = 1+2*deltaL*liquido["fird"]+deltaL**2*liquido["firdd"]
-#            Jdv = 1+2*deltaG*vapor["fird"]+deltaG**2*vapor["firdd"]
-#            Kdl = 2*liquido["fird"]+deltaL*liquido["firdd"]+1/deltaL
-#            Kdv = 2*vapor["fird"]+deltaG*vapor["firdd"]+1/deltaG
-#            Delta = Jdv*Kdl-Jdl*Kdv
-#            error = abs(Kv-Kl)+abs(Jv-Jl)
-#            if error < 1e-12 or contador > 100:
-#                break
-#            elif error > erroro:
-#                rhoL = rholo
-#                rhoG = rhogo
-#                g = g*0.5
-#            else:
-#                erroro = error
-#                rholo = rhoL
-#                rhogo = rhoG
-#                rhoL = rhoL+g/Delta*((Kv-Kl)*Jdv-(Jv-Jl)*Kdv)
-#                rhoG = rhoG+g/Delta*((Kv-Kl)*Jdl-(Jv-Jl)*Kdl)
-#        if error > 1e-3:
-#            print("Iteration don´t converge, residual error %g" % error)
-#
-#        Ps = self.R*T*rhoL*rhoG/(rhoL-rhoG)*(
-#            liquido["fir"]-vapor["fir"]+log(deltaL/deltaG))
-#        return rhoL, rhoG, Ps
-
     def _Helmholtz(self, rho, T):
-        """Calculated properties, table 3 pag 10"""
+        """Calculated properties from helmholtz free energy and derivatives
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        prop : dictionary with calculated properties
+            fir:  [-]
+            fird: [∂fir/∂δ]τ  [-]
+            firdd: [∂²fir/∂δ²]τ  [-]
+            delta: Reducen density, rho/rhoc [-]
+            P: Pressure [kPa]
+            h: Enthalpy [kJ/kg]
+            s: Entropy [kJ/kgK]
+            cv: Isochoric specific heat [kJ/kgK]
+            alfav: Thermal expansion coefficient [1/K]
+            betap: Isothermal compressibility [1/kPa]
+
+        References
+        ----------
+        IAPWS, Revised Release on the IAPWS Formulation 1995 for the
+        Thermodynamic Properties of Ordinary Water Substance for General and
+        Scientific Use, September 2016, Table 3
+        http://www.iapws.org/relguide/IAPWS-95.html
+        """
+        if isinstance(rho, ndarray):
+            rho = rho[0]
+        if isinstance(T, ndarray):
+            T = T[0]
+        if rho < 0:
+            rho = 1e-20
+        if T < 50:
+            T = 50
         rhoc = self._constants.get("rhoref", self.rhoc)
         Tc = self._constants.get("Tref", self.Tc)
         delta = rho/rhoc
         tau = Tc/T
-        fio, fiot, fiott, fiod, fiodd, fiodt = self._phi0(tau, delta)
-        fir, firt, firtt, fird, firdd, firdt, firdtt, B, C = self._phir(
-            tau, delta)
+        ideal = self._phi0(tau, delta)
+        fio = ideal["fio"]
+        fiot = ideal["fiot"]
+        fiott = ideal["fiott"]
+
+        res = self._phir(tau, delta)
+        fir = res["fir"]
+        firt = res["firt"]
+        firtt = res["firtt"]
+        fird = res["fird"]
+        firdd = res["firdd"]
+        firdt = res["firdt"]
 
         propiedades = {}
         propiedades["fir"] = fir
         propiedades["fird"] = fird
         propiedades["firdd"] = firdd
+        propiedades["delta"] = delta
 
-        propiedades["T"] = T
+        propiedades["rho"] = rho
         propiedades["P"] = (1+delta*fird)*self.R*T*rho
-        propiedades["v"] = 1./rho
         propiedades["h"] = self.R*T*(1+tau*(fiot+firt)+delta*fird)
         propiedades["s"] = self.R*(tau*(fiot+firt)-fio-fir)
         propiedades["cv"] = -self.R*tau**2*(fiott+firtt)
-        propiedades["cp"] = self.R*(
-            -tau**2*(fiott+firtt) + (1+delta*fird-delta*tau*firdt)**2/(
-                1+2*delta*fird+delta**2*firdd))
-        propiedades["w"] = (
-            self.R*1000*T*(1+2*delta*fird+delta**2*firdd - (
-                1+delta*fird-delta*tau*firdt)**2/tau**2/(fiott+firtt)))**0.5
         propiedades["alfap"] = (1-delta*tau*firdt/(1+delta*fird))/T
         propiedades["betap"] = rho*(
             1+(delta*fird+delta**2*firdd)/(1+delta*fird))
-        propiedades["fugacity"] = exp(fir+delta*fird-log(1+delta*fird))
-        propiedades["B"] = B
-        propiedades["C"] = C
-        propiedades["dpdrho"] = self.R*T*(1+2*delta*fird+delta**2*firdd)
-        propiedades["drhodt"] = -rho*(1+delta*fird-delta*tau*firdt) / \
-            (T*(1+2*delta*fird+delta**2*firdd))
-        propiedades["dhdrho"] = self.R*T/rho * \
-            (tau*delta*(fiodt+firdt)+delta*fird+delta**2*firdd)
-#        dbt=-phi11/rho/t
-#        propiedades["cps"] = propiedades["cv"] Add cps from Argon pag.27
-
         return propiedades
 
     def _prop0(self, rho, T):
@@ -752,10 +1074,12 @@ class MEoS(_fase):
         Tc = self._constants.get("Tref", self.Tc)
         delta = rho/rhoc
         tau = Tc/T
-        fio, fiot, fiott, fiod, fiodd, fiodt = self._phi0(tau, delta)
+        ideal = self._phi0(tau, delta)
+        fio = ideal["fio"]
+        fiot = ideal["fiot"]
+        fiott = ideal["fiott"]
 
         propiedades = _fase()
-        propiedades.v = self.R*T/self.P/1000
         propiedades.h = self.R*T*(1+tau*fiot)
         propiedades.s = self.R*(tau*fiot-fio)
         propiedades.cv = -self.R*tau**2*fiott
@@ -765,6 +1089,32 @@ class MEoS(_fase):
         return propiedades
 
     def _phi0(self, tau, delta):
+        """Ideal gas Helmholtz free energy and derivatives
+
+        Parameters
+        ----------
+        tau : float
+            Inverse reduced temperature, Tc/T [-]
+        delta : float
+            Reduced density, rho/rhoc [-]
+
+        Returns
+        -------
+        prop : dictionary with ideal adimensional helmholtz energy and deriv
+            fio  [-]
+            fiot: [∂fio/∂τ]δ  [-]
+            fiod: [∂fio/∂δ]τ  [-]
+            fiott: [∂²fio/∂τ²]δ  [-]
+            fiodt: [∂²fio/∂τ∂δ]  [-]
+            fiodd: [∂²fio/∂δ²]τ  [-]
+
+        References
+        ----------
+        IAPWS, Revised Release on the IAPWS Formulation 1995 for the
+        Thermodynamic Properties of Ordinary Water Substance for General and
+        Scientific Use, September 2016, Table 4
+        http://www.iapws.org/relguide/IAPWS-95.html
+        """
         Fi0 = self.Fi0
 
         fio = Fi0["ao_log"][0]*log(delta)+Fi0["ao_log"][1]*log(tau)
@@ -787,12 +1137,63 @@ class MEoS(_fase):
             fiot += n*t*((1-exp(-t*tau))**-1-1)
             fiott -= n*t**2*exp(-t*tau)*(1-exp(-t*tau))**-2
 
-        return fio, fiot, fiott, fiod, fiodd, fiodt
+        # Especial term for heavy water
+        # if "tau*logtau" in Fi0:
+        #     fio += Fi0["tau*logtau"]*tau*log(tau)
+        #     fiot += Fi0["tau*logtau"]*(log(tau)+1)
+        #     fiot += Fi0["tau*logtau"]/tau
+        # if "tau*logdelta" in Fi0 and delta:
+        #     fio += Fi0["tau*logdelta"]*tau*log(delta)
+        #     fiot += Fi0["tau*logdelta"]*log(delta)
+        #     fiod += Fi0["tau*logdelta"]*tau/delta
+        #     fiodd -= Fi0["tau*logdelta"]*tau/delta**2
+        #     fiodt += Fi0["tau*logdelta"]/delta
+
+        # Extension to especial terms of air
+        if "ao_exp2" in Fi0:
+            for n, g, C in zip(Fi0["ao_exp2"], Fi0["titao2"], Fi0["sum2"]):
+                fio += n*log(C+exp(g*tau))
+                fiot += n*g/(C*exp(-g*tau)+1)
+                fiott += C*n*g**2*exp(-g*tau)/(C*exp(-g*tau)+1)**2
+
+        prop = {}
+        prop["fio"] = fio
+        prop["fiot"] = fiot
+        prop["fiott"] = fiott
+        prop["fiod"] = fiod
+        prop["fiodd"] = fiodd
+        prop["fiodt"] = fiodt
+        return prop
 
     def _phir(self, tau, delta):
-        delta_0 = 1e-200
-
-        fir = fird = firdd = firt = firtt = firdt = firdtt = B = C = 0
+        """Residual contribution to the free Helmholtz energy
+
+        Parameters
+        ----------
+        tau : float
+            Inverse reduced temperature, Tc/T [-]
+        delta : float
+            Reduced density, rho/rhoc [-]
+
+        Returns
+        -------
+        prop : dictionary with residual adimensional helmholtz energy and deriv
+            fir  [-]
+            firt: [∂fir/∂τ]δ,x  [-]
+            fird: [∂fir/∂δ]τ,x  [-]
+            firtt: [∂²fir/∂τ²]δ,x  [-]
+            firdt: [∂²fir/∂τ∂δ]x  [-]
+            firdd: [∂²fir/∂δ²]τ,x  [-]
+            firx: [∂fir/∂x]τ,δ  [-]
+
+        References
+        ----------
+        IAPWS, Revised Release on the IAPWS Formulation 1995 for the
+        Thermodynamic Properties of Ordinary Water Substance for General and
+        Scientific Use, September 2016, Table 5
+        http://www.iapws.org/relguide/IAPWS-95.html
+        """
+        fir = fird = firdd = firt = firtt = firdt = 0
 
         # Polinomial terms
         nr1 = self._constants.get("nr1", [])
@@ -805,9 +1206,6 @@ class MEoS(_fase):
             firt += n*t*delta**d*tau**(t-1)
             firtt += n*t*(t-1)*delta**d*tau**(t-2)
             firdt += n*t*d*delta**(d-1)*tau**(t-1)
-            firdtt += n*t*d*(t-1)*delta**(d-1)*tau**(t-2)
-            B += n*d*delta_0**(d-1)*tau**t
-            C += n*d*(d-1)*delta_0**(d-2)*tau**t
 
         # Exponential terms
         nr2 = self._constants.get("nr2", [])
@@ -824,11 +1222,6 @@ class MEoS(_fase):
             firtt += n*t*(t-1)*delta**d*tau**(t-2)*exp(-g*delta**c)
             firdt += n*t*delta**(d-1)*tau**(t-1)*(d-g*c*delta**c)*exp(
                 -g*delta**c)
-            firdtt += n*t*(t-1)*delta**(d-1)*tau**(t-2)*(d-g*c*delta**c) * \
-                exp(-g*delta**c)
-            B += n*exp(-g*delta_0**c)*delta_0**(d-1)*tau**t*(d-g*c*delta_0**c)
-            C += n*exp(-g*delta_0**c)*(delta_0**(d-2)*tau**t*(
-                (d-g*c*delta_0**c)*(d-1-g*c*delta_0**c)-g**2*c**2*delta_0**c))
 
         # Gaussian terms
         nr3 = self._constants.get("nr3", [])
@@ -838,339 +1231,488 @@ class MEoS(_fase):
         e3 = self._constants.get("epsilon3", [])
         b3 = self._constants.get("beta3", [])
         g3 = self._constants.get("gamma3", [])
-        for i in range(len(nr3)):
-            exp1 = self._constants.get("exp1", [2]*len(nr3))
-            exp2 = self._constants.get("exp2", [2]*len(nr3))
-            fir += nr3[i]*delta**d3[i]*tau**t3[i]*exp(-a3[i]*(
-                delta-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])
-            fird += nr3[i]*delta**d3[i]*tau**t3[i]*exp(
-                -a3[i]*(delta-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])*(
-                    d3[i]/delta-2*a3[i]*(delta-e3[i]))
-            firdd += nr3[i]*tau**t3[i]*exp(
-                -a3[i]*(delta-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])*(
-                    -2*a3[i]*delta**d3[i]+4*a3[i]**2*delta**d3[i]*(
-                        delta-e3[i])**exp1[i]-4*d3[i]*a3[i]*delta**2*(
-                            delta-e3[i])+d3[i]*2*delta)
-            firt += nr3[i]*delta**d3[i]*tau**t3[i]*exp(-a3[i]*(
-                delta-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])*(
-                    t3[i]/tau-2*b3[i]*(tau-g3[i]))
-            firtt += nr3[i]*delta**d3[i]*tau**t3[i]*exp(-a3[i]*(
-                delta-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])*(
-                    (t3[i]/tau-2*b3[i]*(tau-g3[i]))**exp2[i]-t3[i]/tau**2 -
-                    2*b3[i])
-            firdt += nr3[i]*delta**d3[i]*tau**t3[i]*exp(-a3[i]*(
-                delta-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])*(
-                    t3[i]/tau-2*b3[i]*(tau-g3[i]))*(d3[i]/delta-2*a3[i]*(
-                        delta-e3[i]))
-            firdtt += nr3[i]*delta**d3[i]*tau**t3[i]*exp(-a3[i]*(
-                delta-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])*((
-                    t3[i]/tau-2*b3[i]*(tau-g3[i]))**exp2[i]-t3[i]/tau**2-2 *
-                    b3[i])*(d3[i]/delta-2*a3[i]*(delta-e3[i]))
-            B += nr3[i]*delta_0**d3[i]*tau**t3[i]*exp(-a3[i]*(
-                delta_0-e3[i])**exp1[i]-b3[i]*(tau-g3[i])**exp2[i])*(
-                    d3[i]/delta_0-2*a3[i]*(delta_0-e3[i]))
-            C += nr3[i]*tau**t3[i]*exp(-a3[i]*(delta_0-e3[i])**exp1[i]-b3[i]*(
-                tau-g3[i])**exp2[i])*(
-                    -2*a3[i]*delta_0**d3[i]+4*a3[i]**2*delta_0**d3[i]*(
-                        delta_0-e3[i])**exp1[i]-4*d3[i]*a3[i]*delta_0**2*(
-                            delta_0-e3[i])+d3[i]*2*delta_0)
+        for n, d, t, a, e, b, g in zip(nr3, d3, t3, a3, e3, b3, g3):
+            fir += n*delta**d*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)
+            fird += n*delta**d*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)*(
+                    d/delta-2*a*(delta-e))
+            firdd += n*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)*(
+                    -2*a*delta**d+4*a**2*delta**d*(delta-e)**2-4*d*a*delta**2*(
+                            delta-e)+d*2*delta)
+            firt += n*delta**d*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)*(
+                    t/tau-2*b*(tau-g))
+            firtt += n*delta**d*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)*(
+                    (t/tau-2*b*(tau-g))**2-t/tau**2-2*b)
+            firdt += n*delta**d*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)*(
+                    t/tau-2*b*(tau-g))*(d/delta-2*a*(delta-e))
 
         # Non analitic terms
         nr4 = self._constants.get("nr4", [])
         a4 = self._constants.get("a4", [])
-        b = self._constants.get("b4", [])
-        A = self._constants.get("A", [])
+        b4 = self._constants.get("b4", [])
+        Ai = self._constants.get("A", [])
         Bi = self._constants.get("B", [])
         Ci = self._constants.get("C", [])
-        D = self._constants.get("D", [])
-        bt = self._constants.get("beta4", [])
-        for i in range(len(nr4)):
-            Tita = (1-tau)+A[i]*((delta-1)**2)**(0.5/bt[i])
-            F = exp(-Ci[i]*(delta-1)**2-D[i]*(tau-1)**2)
-            Fd = -2*Ci[i]*F*(delta-1)
-            Fdd = 2*Ci[i]*F*(2*Ci[i]*(delta-1)**2-1)
-            Ft = -2*D[i]*F*(tau-1)
-            Ftt = 2*D[i]*F*(2*D[i]*(tau-1)**2-1)
-            Fdt = 4*Ci[i]*D[i]*F*(delta-1)*(tau-1)
-            Fdtt = 4*Ci[i]*D[i]*F*(delta-1)*(2*D[i]*(tau-1)**2-1)
-
-            Delta = Tita**2+Bi[i]*((delta-1)**2)**a4[i]
-            Deltad = (delta-1)*(A[i]*Tita*2/bt[i]*((delta-1)**2)**(
-                0.5/bt[i]-1)+2*Bi[i]*a4[i]*((delta-1)**2)**(a4[i]-1))
+        Di = self._constants.get("D", [])
+        bt4 = self._constants.get("beta4", [])
+        for n, a, b, A, B, C, D, bt in zip(nr4, a4, b4, Ai, Bi, Ci, Di, bt4):
+            Tita = (1-tau)+A*((delta-1)**2)**(0.5/bt)
+            F = exp(-C*(delta-1)**2-D*(tau-1)**2)
+            Fd = -2*C*F*(delta-1)
+            Fdd = 2*C*F*(2*C*(delta-1)**2-1)
+            Ft = -2*D*F*(tau-1)
+            Ftt = 2*D*F*(2*D*(tau-1)**2-1)
+            Fdt = 4*C*D*F*(delta-1)*(tau-1)
+
+            Delta = Tita**2+B*((delta-1)**2)**a
+            Deltad = (delta-1)*(A*Tita*2/bt*((delta-1)**2)**(0.5/bt-1) +
+                                2*B*a*((delta-1)**2)**(a-1))
             if delta == 1:
                 Deltadd = 0
             else:
-                Deltadd = Deltad/(delta-1)+(delta-1)**2*(4*Bi[i]*a4[i]*(
-                    a4[i]-1)*((delta-1)**2)**(a4[i]-2)+2*A[i]**2/bt[i]**2*(((
-                        delta-1)**2)**(0.5/bt[i]-1))**2+A[i]*Tita*4/bt[i]*(
-                            0.5/bt[i]-1)*((delta-1)**2)**(0.5/bt[i]-2))
-
-            DeltaBd = b[i]*Delta**(b[i]-1)*Deltad
-            DeltaBdd = b[i]*(Delta**(b[i]-1)*Deltadd+(b[i]-1)*Delta**(
-                b[i]-2)*Deltad**2)
-            DeltaBt = -2*Tita*b[i]*Delta**(b[i]-1)
-            DeltaBtt = 2*b[i]*Delta**(b[i]-1)+4*Tita**2*b[i]*(
-                b[i]-1)*Delta**(b[i]-2)
-            DeltaBdt = -A[i]*b[i]*2/bt[i]*Delta**(b[i]-1)*(delta-1)*((
-                delta-1)**2)**(0.5/bt[i]-1)-2*Tita*b[i]*(b[i]-1)*Delta**(
-                    b[i]-2)*Deltad
-            DeltaBdtt = 2*b[i]*(b[i]-1)*Delta**(b[i]-2)*(Deltad*(
-                1+2*Tita**2*(b[i]-2)/Delta)+4*Tita*A[i]*(delta-1)/bt[i]*((
-                    delta-1)**2)**(0.5/bt[i]-1))
-
-            fir += nr4[i]*Delta**b[i]*delta*F
-            fird += nr4[i]*(Delta**b[i]*(F+delta*Fd)+DeltaBd*delta*F)
-            firdd += nr4[i]*(Delta**b[i]*(2*Fd+delta*Fdd)+2*DeltaBd*(
-                F+delta*Fd)+DeltaBdd*delta*F)
-            firt += nr4[i]*delta*(DeltaBt*F+Delta**b[i]*Ft)
-            firtt += nr4[i]*delta*(DeltaBtt*F+2*DeltaBt*Ft+Delta**b[i]*Ftt)
-            firdt += nr4[i]*(Delta**b[i]*(Ft+delta*Fdt)+delta*DeltaBd*Ft +
-                             DeltaBt*(F+delta*Fd)+DeltaBdt*delta*F)
-            firdtt += nr4[i]*((DeltaBtt*F+2*DeltaBt*Ft+Delta**b[i]*Ftt)+delta*(
-                DeltaBdtt*F+DeltaBtt*Fd+2*DeltaBdt*Ft+2*DeltaBt*Fdt+DeltaBt *
-                Ftt+Delta**b[i]*Fdtt))
-
-            Tita_ = (1-tau)+A[i]*((delta_0-1)**2)**(0.5/bt[i])
-            Delta_ = Tita_**2+Bi[i]*((delta_0-1)**2)**a4[i]
-            Deltad_ = (delta_0-1)*(A[i]*Tita_*2/bt[i]*((delta_0-1)**2)**(
-                0.5/bt[i]-1)+2*Bi[i]*a4[i]*((delta_0-1)**2)**(a4[i]-1))
-            Deltadd_ = Deltad_/(delta_0-1)+(delta_0-1)**2*(
-                4*Bi[i]*a4[i]*(a4[i]-1)*((delta_0-1)**2)**(
-                    a4[i]-2)+2*A[i]**2/bt[i]**2*(((delta_0-1)**2)**(
-                        0.5/bt[i]-1))**2+A[i]*Tita_*4/bt[i]*(0.5/bt[i]-1)*((
-                            delta_0-1)**2)**(0.5/bt[i]-2))
-            DeltaBd_ = b[i]*Delta_**(b[i]-1)*Deltad_
-            DeltaBdd_ = b[i]*(Delta_**(b[i]-1)*Deltadd_+(b[i]-1)*Delta_**(
-                b[i]-2)*Deltad_**2)
-            F_ = exp(-Ci[i]*(delta_0-1)**2-D[i]*(tau-1)**2)
-            Fd_ = -2*Ci[i]*F_*(delta_0-1)
-            Fdd_ = 2*Ci[i]*F_*(2*Ci[i]*(delta_0-1)**2-1)
-
-            B += nr4[i]*(Delta_**b[i]*(F_+delta_0*Fd_)+DeltaBd_*delta_0*F_)
-            C += nr4[i]*(Delta_**b[i]*(2*Fd_+delta_0*Fdd_)+2*DeltaBd_*(
-                F_+delta_0*Fd_)+DeltaBdd_*delta_0*F_)
-
-        return fir, firt, firtt, fird, firdd, firdt, firdtt, B, C
+                Deltadd = Deltad/(delta-1)+(delta-1)**2*(
+                    4*B*a*(a-1)*((delta-1)**2)**(a-2) +
+                    2*A**2/bt**2*(((delta-1)**2)**(0.5/bt-1))**2 +
+                    A*Tita*4/bt*(0.5/bt-1)*((delta-1)**2)**(0.5/bt-2))
+
+            DeltaBd = b*Delta**(b-1)*Deltad
+            DeltaBdd = b*(Delta**(b-1)*Deltadd+(b-1)*Delta**(b-2)*Deltad**2)
+            DeltaBt = -2*Tita*b*Delta**(b-1)
+            DeltaBtt = 2*b*Delta**(b-1)+4*Tita**2*b*(b-1)*Delta**(b-2)
+            DeltaBdt = -A*b*2/bt*Delta**(b-1)*(delta-1)*((delta-1)**2)**(
+                0.5/bt-1)-2*Tita*b*(b-1)*Delta**(b-2)*Deltad
+
+            fir += n*Delta**b*delta*F
+            fird += n*(Delta**b*(F+delta*Fd)+DeltaBd*delta*F)
+            firdd += n*(Delta**b*(2*Fd+delta*Fdd) + 2*DeltaBd*(F+delta*Fd) +
+                        DeltaBdd*delta*F)
+            firt += n*delta*(DeltaBt*F+Delta**b*Ft)
+            firtt += n*delta*(DeltaBtt*F+2*DeltaBt*Ft+Delta**b*Ftt)
+            firdt += n*(Delta**b*(Ft+delta*Fdt)+delta*DeltaBd*Ft +
+                        DeltaBt*(F+delta*Fd)+DeltaBdt*delta*F)
+
+        prop = {}
+        prop["fir"] = fir
+        prop["firt"] = firt
+        prop["firtt"] = firtt
+        prop["fird"] = fird
+        prop["firdd"] = firdd
+        prop["firdt"] = firdt
+        return prop
+
+    def _virial(self, T):
+        """Virial coefficient
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        prop : dictionary with residual adimensional helmholtz energy and deriv
+            B: [∂fir/∂δ]δ->0  [-]
+            C: [∂²fir/∂δ²]δ->0  [-]
+        """
+        Tc = self._constants.get("Tref", self.Tc)
+        tau = Tc/T
+        B = C = 0
+        delta = 1e-200
 
-    def derivative(self, z, x, y, fase):
-        """Calculate generic partial derivative: (δz/δx)y
-        where x, y, z can be: P, T, v, u, h, s, g, a"""
-        dT = {"P": self.P*1000*fase.alfap,
-              "T": 1,
-              "v": 0,
-              "rho": 0,
-              "u": fase.cv,
-              "h": fase.cv+self.P*1000*fase.v*fase.alfap,
-              "s": fase.cv/self.T,
-              "g": self.P*1000*fase.v*fase.alfap-fase.s,
-              "a": -fase.s}
-        dv = {"P": -self.P*1000*fase.betap,
-              "T": 0,
-              "v": 1,
-              "rho": -1,
-              "u": self.P*1000*(self.T*fase.alfap-1),
-              "h": self.P*1000*(self.T*fase.alfap-fase.v*fase.betap),
-              "s": self.P*1000*fase.alfap,
-              "g": -self.P*1000*fase.v*fase.betap,
-              "a": -self.P*1000}
-        return (dv[z]*dT[y]-dT[z]*dv[y])/(dv[x]*dT[y]-dT[x]*dv[y])
-
-    def _Vapor_Pressure(self, T):
-        eq = self._vapor_Pressure["eq"]
-        Tita = 1-T/self.Tc
-        if eq in [2, 4, 6]:
-            Tita = Tita**0.5
-        suma = sum([n*Tita**x for n, x in zip(
-            self._vapor_Pressure["ao"], self._vapor_Pressure["exp"])])
-        if eq in [1, 2]:
-            Pr = suma+1
-        elif eq in [3, 4]:
-            Pr = exp(suma)
-        else:
-            Pr = exp(self.Tc/T*suma)
-        Pv = Pr*self.Pc
+        # Polinomial terms
+        nr1 = self._constants.get("nr1", [])
+        d1 = self._constants.get("d1", [])
+        t1 = self._constants.get("t1", [])
+        for n, d, t in zip(nr1, d1, t1):
+            B += n*d*delta**(d-1)*tau**t
+            C += n*d*(d-1)*delta**(d-2)*tau**t
+
+        # Exponential terms
+        nr2 = self._constants.get("nr2", [])
+        d2 = self._constants.get("d2", [])
+        g2 = self._constants.get("gamma2", [])
+        t2 = self._constants.get("t2", [])
+        c2 = self._constants.get("c2", [])
+        for n, d, g, t, c in zip(nr2, d2, g2, t2, c2):
+            B += n*exp(-g*delta**c)*delta**(d-1)*tau**t*(d-g*c*delta**c)
+            C += n*exp(-g*delta**c)*(delta**(d-2)*tau**t*(
+                (d-g*c*delta**c)*(d-1-g*c*delta**c)-g**2*c**2*delta**c))
+
+        # Gaussian terms
+        nr3 = self._constants.get("nr3", [])
+        d3 = self._constants.get("d3", [])
+        t3 = self._constants.get("t3", [])
+        a3 = self._constants.get("alfa3", [])
+        e3 = self._constants.get("epsilon3", [])
+        b3 = self._constants.get("beta3", [])
+        g3 = self._constants.get("gamma3", [])
+        for n, d, t, a, e, b, g in zip(nr3, d3, t3, a3, e3, b3, g3):
+            B += n*delta**d*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)*(
+                    d/delta-2*a*(delta-e))
+            C += n*tau**t*exp(-a*(delta-e)**2-b*(tau-g)**2)*(
+                    -2*a*delta**d+4*a**2*delta**d*(
+                        delta-e)**2-4*d*a*delta**2*(
+                            delta-e)+d*2*delta)
+
+        # Non analitic terms
+        nr4 = self._constants.get("nr4", [])
+        a4 = self._constants.get("a4", [])
+        b4 = self._constants.get("b4", [])
+        Ai = self._constants.get("A", [])
+        Bi = self._constants.get("B", [])
+        Ci = self._constants.get("C", [])
+        Di = self._constants.get("D", [])
+        bt4 = self._constants.get("beta4", [])
+        for n, a, b, A, B, C, D, bt in zip(nr4, a4, b4, Ai, Bi, Ci, Di, bt4):
+            Tita = (1-tau)+A*((delta-1)**2)**(0.5/bt)
+            Delta = Tita**2+B*((delta-1)**2)**a
+            Deltad = (delta-1)*(A*Tita*2/bt*((delta-1)**2)**(
+                0.5/bt-1)+2*B*a*((delta-1)**2)**(a-1))
+            Deltadd = Deltad/(delta-1) + (delta-1)**2*(
+                4*B*a*(a-1)*((delta-1)**2)**(a-2) +
+                2*A**2/bt**2*(((delta-1)**2)**(0.5/bt-1))**2 +
+                A*Tita*4/bt*(0.5/bt-1)*((delta-1)**2)**(0.5/bt-2))
+            DeltaBd = b*Delta**(b-1)*Deltad
+            DeltaBdd = b*(Delta**(b-1)*Deltadd+(b-1)*Delta**(b-2)*Deltad**2)
+            F = exp(-C*(delta-1)**2-D*(tau-1)**2)
+            Fd = -2*C*F*(delta-1)
+            Fdd = 2*C*F*(2*C*(delta-1)**2-1)
+
+            B += n*(Delta**b*(F+delta*Fd)+DeltaBd*delta*F)
+            C += n*(Delta**b*(2*Fd+delta*Fdd)+2*DeltaBd*(F+delta*Fd) +
+                    DeltaBdd*delta*F)
+
+        prop = {}
+        prop["B"] = B
+        prop["C"] = C
+        return prop
+
+    def _derivDimensional(self, rho, T):
+        """Calcule the dimensional form or Helmholtz free energy derivatives
+
+        Parameters
+        ----------
+        rho : float
+            Density [kg/m³]
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        prop : dictionary with residual helmholtz energy and derivatives
+            fir  [kJ/kg]
+            firt: [∂fir/∂T]ρ  [kJ/kgK]
+            fird: [∂fir/∂ρ]T  [kJ/m³kg²]
+            firtt: [∂²fir/∂T²]ρ  [kJ/kgK²]
+            firdt: [∂²fir/∂T∂ρ]  [kJ/m³kg²K]
+            firdd: [∂²fir/∂ρ²]T  [kJ/m⁶kg]
+
+        References
+        ----------
+        IAPWS, Guideline on an Equation of State for Humid Air in Contact with
+        Seawater and Ice, Consistent with the IAPWS Formulation 2008 for the
+        Thermodynamic Properties of Seawater, Table 7,
+        http://www.iapws.org/relguide/SeaAir.html
+        """
+        if not rho:
+            prop = {}
+            prop["fir"] = 0
+            prop["firt"] = 0
+            prop["fird"] = 0
+            prop["firtt"] = 0
+            prop["firdt"] = 0
+            prop["firdd"] = 0
+            return prop
+
+        R = self._constants.get("R")/self._constants.get("M", self.M)
+        rhoc = self._constants.get("rhoref", self.rhoc)
+        Tc = self._constants.get("Tref", self.Tc)
+        delta = rho/rhoc
+        tau = Tc/T
+
+        ideal = self._phi0(tau, delta)
+        fio = ideal["fio"]
+        fiot = ideal["fiot"]
+        fiott = ideal["fiott"]
+        fiod = ideal["fiod"]
+        fiodd = ideal["fiodd"]
+
+        res = self._phir(tau, delta)
+        fir = res["fir"]
+        firt = res["firt"]
+        firtt = res["firtt"]
+        fird = res["fird"]
+        firdd = res["firdd"]
+        firdt = res["firdt"]
+
+        prop = {}
+        prop["fir"] = R*T*(fio+fir)
+        prop["firt"] = R*(fio+fir-(fiot+firt)*tau)
+        prop["fird"] = R*T/rhoc*(fiod+fird)
+        prop["firtt"] = R*tau**2/T*(fiott+firtt)
+        prop["firdt"] = R/rhoc*(fiod+fird-firdt*tau)
+        prop["firdd"] = R*T/rhoc**2*(fiodd+firdd)
+        return prop
+
+    def _surface(self, T):
+        """Generic equation for the surface tension
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        sigma : float
+            Surface tension [N/m]
+
+        Notes
+        -----
+        Need a _surf dict in the derived class with the parameters keys:
+            sigma: coefficient
+            exp: exponent
+        """
+        tau = 1-T/self.Tc
+        sigma = 0
+        for n, t in zip(self._surf["sigma"], self._surf["exp"]):
+            sigma += n*tau**t
+        return sigma
+
+    @classmethod
+    def _Vapor_Pressure(cls, T):
+        """Auxiliary equation for the vapour pressure
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        Pv : float
+            Vapour pressure [Pa]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.1
+        """
+        Tita = 1-T/cls.Tc
+        suma = 0
+        for n, x in zip(cls._Pv["ao"], cls._Pv["exp"]):
+            suma += n*Tita**x
+        Pr = exp(cls.Tc/T*suma)
+        Pv = Pr*cls.Pc
         return Pv
 
-    def _Liquid_Density(self, T=None):
-        if not T:
-            T = self.T
-        eq = self._liquid_Density["eq"]
-        Tita = 1-T/self.Tc
-        if eq in [2, 4, 6]:
+    @classmethod
+    def _Liquid_Density(cls, T):
+        """Auxiliary equation for the density of saturated liquid
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        rho : float
+            Saturated liquid density [kg/m³]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.2
+        """
+        eq = cls._rhoL["eq"]
+        Tita = 1-T/cls.Tc
+        if eq == 2:
             Tita = Tita**(1./3)
-        suma = sum([n*Tita**x for n, x in zip(
-            self._liquid_Density["ao"], self._liquid_Density["exp"])])
-        if eq in [1, 2]:
-            Pr = suma+1
-        elif eq in [3, 4]:
-            Pr = exp(suma)
-        else:
-            Pr = exp(self.Tc/T*suma)
-        rho = Pr*self.rhoc
+        suma = 0
+        for n, x in zip(cls._rhoL["ao"], cls._rhoL["exp"]):
+            suma += n*Tita**x
+        Pr = suma+1
+        rho = Pr*cls.rhoc
         return rho
 
-    def _Vapor_Density(self, T=None):
-        eq = self._vapor_Density["eq"]
-        Tita = 1-T/self.Tc
-        if eq in [2, 4, 6]:
+    @classmethod
+    def _Vapor_Density(cls, T):
+        """Auxiliary equation for the density of saturated vapor
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        rho : float
+            Saturated vapor density [kg/m³]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.3
+        """
+        eq = cls._rhoG["eq"]
+        Tita = 1-T/cls.Tc
+        if eq == 4:
             Tita = Tita**(1./3)
-        suma = sum([n*Tita**x for n, x in zip(
-            self._vapor_Density["ao"], self._vapor_Density["exp"])])
-        if eq in [1, 2]:
-            Pr = suma+1
-        elif eq in [3, 4]:
-            Pr = exp(suma)
-        else:
-            Pr = exp(self.Tc/T*suma)
-        rho = Pr*self.rhoc
+        suma = 0
+        for n, x in zip(cls._rhoG["ao"], cls._rhoG["exp"]):
+            suma += n*Tita**x
+        Pr = exp(suma)
+        rho = Pr*cls.rhoc
         return rho
 
-    def _Tension(self, T):
-        """Equation for the surface tension"""
-        tau = 1-T/self.Tc
-        tension = 0
-        for sigma, n in zip(self._surface["sigma"],
-                            self._surface["exp"]):
-            tension += sigma*tau**n
-        return tension
+    @classmethod
+    def _dPdT_sat(cls, T):
+        """Auxiliary equation for the dP/dT along saturation line
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        dPdT : float
+            dPdT [MPa/K]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, derived from Eq.1
+        """
+        Tita = 1-T/cls.Tc
+        suma1 = 0
+        suma2 = 0
+        for n, x in zip(cls._Pv["ao"], cls._Pv["exp"]):
+            suma1 -= n*x*Tita**(x-1)/cls.Tc
+            suma2 += n*Tita**x
+        Pr = (cls.Tc*suma1/T-cls.Tc/T**2*suma2)*exp(cls.Tc/T*suma2)
+        dPdT = Pr*cls.Pc
+        return dPdT
 
 
 class IAPWS95(MEoS):
-    """Multiparameter equation of state for water (including IAPWS95)
+    """Implementation of IAPWS Formulation 1995 for ordinary water substance,
+    (revised release of 2016), see MEoS __doc__
 
+    Examples
+    --------
     >>> water=IAPWS95(T=300, rho=996.5560)
-    >>> print("%0.10f %0.8f %0.5f %0.9f" % ( \
-        water.P, water.cv, water.w, water.s))
+    >>> water.P, water.cv, water.w, water.s
     0.0992418350 4.13018112 1501.51914 0.393062643
 
     >>> water=IAPWS95(T=500, rho=0.435)
-    >>> print("%0.10f %0.8f %0.5f %0.9f" % ( \
-        water.P, water.cv, water.w, water.s))
+    >>> water.P, water.cv, water.w, water.s
     0.0999679423 1.50817541 548.31425 7.944882714
 
     >>> water=IAPWS95(T=900., P=700)
-    >>> print("%0.4f %0.8f %0.5f %0.8f" % ( \
-        water.rho, water.cv, water.w, water.s))
+    >>> water.rho, water.cv, water.w, water.s
     870.7690 2.66422350 2019.33608 4.17223802
 
     >>> water=IAPWS95(T=300., P=0.1)
-    >>> print("%0.2f %0.5f %0.2f %0.2f %0.5f %0.4f %0.1f %0.6f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.cp, water.w, \
-        water.virialB))
-    300.00 0.10000 996.56 112.65 0.39306 4.1806 1501.5 -0.066682
+    >>> water.P, water.rho, water.h, water.s, water.cp, water.w, water.virialB
+    0.10000 996.56 112.65 0.39306 4.1806 1501.5 -0.066682
 
     >>> water=IAPWS95(T=500., P=0.1)
-    >>> print("%0.2f %0.5f %0.5f %0.1f %0.4f %0.4f %0.2f %0.7f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.cp, water.w, \
-        water.virialB))
-    500.00 0.10000 0.43514 2928.6 7.9447 1.9813 548.31 -0.0094137
+    >>> water.P, water.rho, water.h, water.s, water.cp, water.w, water.virialB
+    0.10000 0.43514 2928.6 7.9447 1.9813 548.31 -0.0094137
 
     >>> water=IAPWS95(T=450., x=0.5)
-    >>> print("%0.2f %0.5f %0.4f %0.1f %0.4f %0.6f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.virialB))
+    >>> water.T, water.P, water.rho, water.h, water.s, water.virialB
     450.00 0.93220 9.5723 1761.8 4.3589 -0.013028
 
     >>> water=IAPWS95(P=1.5, rho=1000.)
-    >>> print("%0.2f %0.4f %0.1f %0.3f %0.5f %0.4f %0.1f %0.6f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.cp, water.w, \
-        water.virialB))
-    286.44 1.5000 1000.0 57.253 0.19931 4.1855 1462.1 -0.085566
+    >>> water.T, water.rho, water.h, water.s, water.cp, water.w, water.virialB
+    286.44 1000.0 57.253 0.19931 4.1855 1462.1 -0.085566
 
     >>> water=IAPWS95(h=3000, s=8.)
-    >>> print("%0.2f %0.5f %0.5f %0.1f %0.4f %0.4f %0.2f %0.7f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.cp, water.w, \
-        water.virialB))
-    536.24 0.11970 0.48547 3000.0 8.0000 1.9984 567.04 -0.0076606
+    >>> water.T, water.P, water.h, water.s, water.cp, water.w, water.virialB
+    536.24 0.11970 3000.0 8.0000 1.9984 567.04 -0.0076606
 
     >>> water=IAPWS95(h=150, s=0.4)
-    >>> print("%0.2f %0.5f %0.2f %0.2f %0.5f %0.4f %0.1f %0.6f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.cp, water.w, \
-        water.virialB))
-    301.27 35.50549 1011.48 150.00 0.40000 4.0932 1564.1 -0.065238
+    >>> water.T, water.P, water.rho, water.h, water.s, water.cp, water.w
+    301.27 35.50549 1011.48 150.00 0.40000 4.0932 1564.1
 
     >>> water=IAPWS95(T=450., rho=300)
-    >>> print("%0.2f %0.5f %0.2f %0.2f %0.4f %0.6f %0.6f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB))
+    >>> water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB
     450.00 0.93220 300.00 770.82 2.1568 0.010693 -0.013028
 
     >>> water=IAPWS95(rho=300., P=0.1)
-    >>> print("%0.2f %0.5f %0.2f %0.2f %0.4f %0.7f %0.6f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB))
+    >>> water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB
     372.76 0.10000 300.00 420.56 1.3110 0.0013528 -0.025144
 
     >>> water=IAPWS95(h=1500., P=0.1)
-    >>> print("%0.2f %0.5f %0.4f %0.1f %0.4f %0.5f %0.6f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB))
+    >>> water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB
     372.76 0.10000 1.2303 1500.0 4.2068 0.47952 -0.025144
 
     >>> water=IAPWS95(s=5., P=3.5)
-    >>> print("%0.2f %0.4f %0.3f %0.1f %0.4f %0.5f %0.7f" % ( \
-        water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB))
+    >>> water.T, water.P, water.rho, water.h, water.s, water.x, water.virialB
     515.71 3.5000 25.912 2222.8 5.0000 0.66921 -0.0085877
 
     >>> water=IAPWS95(T=500., u=900)
-    >>> print("%0.2f %0.2f %0.2f %0.2f %0.1f %0.4f %0.4f %0.1f %0.7f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.cp, \
-        water.w, water.virialB))
-    500.00 108.21 903.62 900.00 1019.8 2.4271 4.1751 1576.0 -0.0094137
+    >>> water.P, water.rho, water.u, water.h, water.s, water.cp, water.w
+    108.21 903.62 900.00 1019.8 2.4271 4.1751 1576.0
 
     >>> water=IAPWS95(P=0.3, u=1550.)
-    >>> print("%0.2f %0.5f %0.4f %0.1f %0.1f %0.4f %0.5f %0.6f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.x, \
-        water.virialB))
-    406.67 0.30000 3.3029 1550.0 1640.8 4.3260 0.49893 -0.018263
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.x
+    406.67 0.30000 3.3029 1550.0 1640.8 4.3260 0.49893
 
     >>> water=IAPWS95(rho=300, h=1000.)
-    >>> print("%0.2f %0.4f %0.2f %0.2f %0.1f %0.4f %0.6f %0.7f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.x, \
-        water.virialB))
-    494.92 2.3991 300.00 992.00 1000.0 2.6315 0.026071 -0.0097064
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.x
+    494.92 2.3991 300.00 992.00 1000.0 2.6315 0.026071
 
     >>> water=IAPWS95(rho=30, s=8.)
-    >>> print("%0.2f %0.3f %0.3f %0.1f %0.1f %0.4f %0.4f %0.2f %0.9f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.cp, \
-        water.w, water.virialB))
-    1562.42 21.671 30.000 4628.5 5350.9 8.0000 2.7190 943.53 0.000047165
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.cp
+    1562.42 21.671 30.000 4628.5 5350.9 8.0000 2.7190
 
     >>> water=IAPWS95(rho=30, s=4.)
-    >>> print("%0.2f %0.4f %0.3f %0.1f %0.1f %0.4f %0.5f %0.7f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.x, \
-        water.virialB))
-    495.00 2.4029 30.000 1597.3 1677.4 4.0000 0.39218 -0.0097015
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.x
+    495.00 2.4029 30.000 1597.3 1677.4 4.0000 0.39218
 
     >>> water=IAPWS95(rho=300, u=1000.)
-    >>> print("%0.2f %0.4f %0.3f %0.1f %0.1f %0.4f %0.5f %0.7f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.x, \
-        water.virialB))
-    496.44 2.4691 300.000 1000.0 1008.2 2.6476 0.02680 -0.0096173
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.x
+    496.44 2.4691 300.000 1000.0 1008.2 2.6476 0.02680
 
     >>> water=IAPWS95(s=3., h=1000.)
-    >>> print("%0.2f %0.6f %0.5f %0.2f %0.1f %0.4f %0.5f %0.6f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.x, \
-        water.virialB))
-    345.73 0.034850 0.73526 952.60 1000.0 3.0000 0.29920 -0.034124
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.x
+    345.73 0.034850 0.73526 952.60 1000.0 3.0000 0.29920
 
     >>> water=IAPWS95(u=995., h=1000.)
-    >>> print("%0.2f %0.4f %0.2f %0.2f %0.1f %0.4f %0.5f %0.6f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.x, \
-        water.virialB))
-    501.89 2.7329 546.58 995.00 1000.0 2.6298 0.00866 -0.009308
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.x
+    501.89 2.7329 546.58 995.00 1000.0 2.6298 0.00866
 
     >>> water=IAPWS95(u=1000., s=3.)
-    >>> print("%0.2f %0.6f %0.5f %0.2f %0.1f %0.4f %0.5f %0.6f" % ( \
-        water.T, water.P, water.rho, water.u, water.h, water.s, water.x, \
-        water.virialB))
-    371.24 0.094712 1.99072 1000.00 1047.6 3.0000 0.28144 -0.025543
-
+    >>> water.T, water.P, water.rho, water.u, water.h, water.s, water.x
+    371.24 0.094712 1.99072 1000.00 1047.6 3.0000 0.28144
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Formulation 1995 for the Thermodynamic
+    Properties of Ordinary Water Substance for General and Scientific Use,
+    September 2016, http://www.iapws.org/relguide/IAPWS-95.html
+    IAPWS, Revised Supplementary Release on Saturation Properties of Ordinary
+    Water Substance September 1992, http://www.iapws.org/relguide/Supp-sat.html
+    IAPWS, Guideline on a Low-Temperature Extension of the IAPWS-95 Formulation
+    for Water Vapor, http://www.iapws.org/relguide/LowT.html
+    IAPWS, Revised Advisory Note No. 3: Thermodynamic Derivatives from IAPWS
+    Formulations, http://www.iapws.org/relguide/Advise3.pdf
     """
     name = "water"
     CASNumber = "7732-18-5"
     formula = "H2O"
     synonym = "R-718"
-    Tc = 647.096
-    rhoc = 322.
-    Pc = 22.064
-    M = 18.015268  # g/mol
+    Tc = Tc
+    rhoc = rhoc
+    Pc = Pc
+    M = M
     Tt = 273.16
     Tb = 373.1243
     f_acent = 0.3443
@@ -1235,34 +1777,230 @@ class IAPWS95(MEoS):
         "A": [0.32, .32],
         "beta4": [0.3, 0.3]}
 
-    _vapor_Pressure = {
-        "eq": 6,
+    _Pv = {
         "ao": [-7.85951783, 1.84408259, -11.7866497, 22.6807411, -15.9618719,
                1.80122502],
-        "exp": [2, 3, 6, 7, 8, 15]}
-    _liquid_Density = {
+        "exp": [1, 1.5, 3, 3.5, 4, 7.5]}
+    _rhoL = {
         "eq": 2,
         "ao": [1.99274064, 1.09965342, -0.510839303, -1.75493479, -45.5170352,
                -6.74694450e5],
         "exp": [1, 2, 5, 16, 43, 110]}
-    _vapor_Density = {
+    _rhoG = {
         "eq": 4,
         "ao": [-2.0315024, -2.6830294, -5.38626492, -17.2991605, -44.7586581,
                -63.9201063],
         "exp": [1, 2, 4, 9, 18.5, 35.5]}
 
+    def _phi0(self, tau, delta):
+        """Low temperature extension of the IAPWS-95"""
+        prop = MEoS._phi0(self, tau, delta)
+
+        T = self.Tc/tau
+        if 50 <= T < 130:
+            fex, fext, fextt = self._phiex(T)
+            prop["fio"] += fex
+            prop["fiot"] += fext
+            prop["fiott"] += fextt
+        return prop
+
+    def _phiex(self, T):
+        """Low temperature extension"""
+        tau = self.Tc/T
+        E = 0.278296458178592
+        ep = self.Tc/130
+        fex = E*(-1/2/tau-3/ep**2*(tau+ep)*log(tau/ep)-9/2/ep+9*tau/2/ep**2 +
+                 tau**2/2/ep**3)
+        fext = E*(1/2/tau**2-3/tau/ep-3/ep**2*log(tau/ep)+3/2/ep**2+tau/ep**3)
+        fextt = E*(-1/tau+1/ep)**3
+        return fex, fext, fextt
+
+    @classmethod
+    def _alfa_sat(cls, T):
+        """Auxiliary equation for the alfa coefficient for calculate the
+        enthalpy along the saturation line
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        alfa : float
+            alfa coefficient [kJ/kg]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.4
+        """
+        di = [-1135.905627715, -5.65134998e-8, 2690.66631, 127.287297,
+              -135.003439, 0.981825814]
+        expi = [0, -19, 1, 4.5, 5, 54.5]
+        Tita = T/cls.Tc
+        alfa = 0
+        for d, x in zip(di, expi):
+            alfa += d*Tita**x
+        return alfa
+
+    @classmethod
+    def _phi_sat(cls, T):
+        """Auxiliary equation for the phi coefficient for calculate the
+        entropy along the saturation line
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        phi : float
+            phi coefficient [kJ/kgK]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.5
+        """
+        di = [2319.5246, -5.65134998e-8*19/20, 2690.66631, 127.287297*9/7,
+              -135.003439*5/4, 0.981825814*109/107]
+        expi = [0, -20, None, 3.5, 4, 53.5]
+        Tita = T/cls.Tc
+        suma = 0
+        for d, x in zip(di, expi):
+            if x is None:
+                suma += d*log(Tita)
+            else:
+                suma += d*Tita**x
+        phi = suma/cls.Tc
+        return phi
+
+    @classmethod
+    def _Liquid_Enthalpy(cls, T):
+        """Auxiliary equation for the specific enthalpy for saturated liquid
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        h : float
+            Saturated liquid enthalpy [kJ/kg]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.6
+        """
+        alfa = cls._alfa_sat(T)
+        rho = cls._Liquid_Density(T)
+        dpdT = cls._dPdT_sat(T)
+        h = alfa+T/rho*dpdT*1000
+        return h
+
+    @classmethod
+    def _Vapor_Enthalpy(cls, T):
+        """Auxiliary equation for the specific enthalpy for saturated vapor
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        h : float
+            Saturated vapor enthalpy [kJ/kg]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.7
+        """
+        alfa = cls._alfa_sat(T)
+        rho = cls._Vapor_Density(T)
+        dpdT = cls._dPdT_sat(T)
+        h = alfa+T/rho*dpdT*1000
+        return h
+
+    @classmethod
+    def _Liquid_Entropy(cls, T):
+        """Auxiliary equation for the specific entropy for saturated liquid
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        s : float
+            Saturated liquid entropy [kJ/kgK]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.8
+        """
+        phi = cls._phi_sat(T)
+        rho = cls._Liquid_Density(T)
+        dpdT = cls._dPdT_sat(T)
+        s = phi+dpdT/rho*1000
+        return s
+
+    @classmethod
+    def _Vapor_Entropy(cls, T):
+        """Auxiliary equation for the specific entropy for saturated vapor
+
+        Parameters
+        ----------
+        T : float
+            Temperature [K]
+
+        Returns
+        -------
+        s : float
+            Saturated liquid entropy [kJ/kgK]
+
+        References
+        ----------
+        IAPWS, Revised Supplementary Release on Saturation Properties of
+        Ordinary Water Substance September 1992,
+        http://www.iapws.org/relguide/Supp-sat.html, Eq.9
+        """
+        phi = cls._phi_sat(T)
+        rho = cls._Vapor_Density(T)
+        dpdT = cls._dPdT_sat(T)
+        s = phi+dpdT/rho*1000
+        return s
+
     def _visco(self, rho, T, fase):
         ref = IAPWS95()
-        estado = ref._Helmholtz(rho, 1.5*647.096)
-        drho = 1/estado["dpdrho"]*1e3
+        st = ref._Helmholtz(rho, 1.5*Tc)
+        delta = rho/rhoc
+        drho = 1e3/self.R/1.5/Tc/(1+2*delta*st["fird"]+delta**2*st["firdd"])
         return _Viscosity(rho, T, fase, drho)
 
     def _thermo(self, rho, T, fase):
         ref = IAPWS95()
-        estado = ref._Helmholtz(rho, 1.5*647.096)
-        drho = 1/estado["dpdrho"]*1e3
+        st = ref._Helmholtz(rho, 1.5*Tc)
+        delta = rho/rhoc
+        drho = 1e3/self.R/1.5/Tc/(1+2*delta*st["fird"]+delta**2*st["firdd"])
         return _ThCond(rho, T, fase, drho)
 
+    def _surface(self, T):
+        s = _Tension(T)
+        return s
+
 
 class IAPWS95_PT(IAPWS95):
     """Derivated class for direct P and T input"""
@@ -1282,10 +2020,10 @@ class IAPWS95_Ps(IAPWS95):
         IAPWS95.__init__(self, P=P, s=s)
 
 
-class IAPWS95_Pv(IAPWS95):
+class IAPWS95_Px(IAPWS95):
     """Derivated class for direct P and v input"""
-    def __init__(self, P, v):
-        IAPWS95.__init__(self, P=P, v=v)
+    def __init__(self, P, x):
+        IAPWS95.__init__(self, P=P, x=x)
 
 
 class IAPWS95_Tx(IAPWS95):
@@ -1295,126 +2033,139 @@ class IAPWS95_Tx(IAPWS95):
 
 
 class D2O(MEoS):
-    """Multiparameter equation of state for heavy water
+    """Implementation of IAPWS Formulation for heavy water substance,
+    see MEoS __doc__
 
-    >>> water=D2O(T=300, rho=996.5560)
-    >>> print("%0.10f %0.8f %0.5f" % ( \
-        water.P, water.Liquid.cv, water.Liquid.w))
+    Examples
+    --------
+    >>> hwater=D2O(T=300, rho=996.5560)
+    >>> hwater.P, hwater.Liquid.cv, hwater.Liquid.w
     0.0030675947 4.21191157 5332.04871
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPS Formulation 1984 for the Thermodynamic
+    Properties of Heavy Water Substance,
+    http://www.iapws.org/relguide/D2O-2005.pdf
+    IAPWS, Revised Advisory Note No. 3: Thermodynamic Derivatives from IAPWS
+    Formulations, http://www.iapws.org/relguide/Advise3.pdf
+
+    Notes
+    -----
+    The implemented correlation isn't the current IAPWS formulation, it's the
+    preliminary equation to be presented at the 2017 IAPWS meetings.
     """
     name = "heavy water"
     CASNumber = "7789-20-0"
     formula = "D2O"
     synonym = "deuterium oxide"
-    Tc = 643.847
-    rhoc = 356.0
-    Pc = 21.671
+    Tc = Tc_D2O
+    rhoc = rhoc_D2O
+    Pc = Pc_D2O
     M = 20.027508  # g/mol
     Tt = 276.97
     Tb = 374.563
     f_acent = 0.364
     momentoDipolar = 1.9
 
-    Fi0 = {'ao_log': [1, 2.9176485],
-           'ao_pow': [-5.60420745, 5.4495718, 0.100195196505025,
-                      -0.2844660508898171, 0.06437609920676933,
-                      -0.005436994367359454],
-           'pow': [0, 1, -1.0, -2.0, -3.0, -4.0],
-           'ao_exp': [], 'titao': []}
+    # Fi0 = {"ao_log": [0.5399322597e-2, 0],
+    #        "pow": [0, 1, 2, 3, 4, 5],
+    #        "ao_pow": [0.3087155964e2, -.3827264031e2, 0.4424799189,
+    #                   -.1256336874e1, 0.2843343470, -.2401555088e-1],
+    #        "tau*logtau": -.1288399716e2,
+    #        "tau*logdelta": 0.4415884023e1,
+    #        "ao_exp": [], "titao": [],
+    #        "ao_hyp": [], "hyp": []}
+
+    # _constants = {
+    #     "R": 8.3143565, "rhoref": 17.875414*M, "Tref": 643.89,
+
+    #     "nr1": [-0.384820628204e3, 0.108213047259e4, -0.110768260635e4,
+    #             0.164668954246e4, -0.137959852228e4, 0.598964185629e3,
+    #             -0.100451752702e3, 0.419192736351e3, -0.107279987867e4,
+    #             0.653852283544e3, -0.984305985655e3, 0.845444459339e3,
+    #             -0.376799930490e3, 0.644512590492e2, -0.214911115714e3,
+    #             0.531113962967e3, -0.135454224420e3, 0.202814416558e3,
+    #             -0.178293865031e3, 0.818739394970e2, -0.143312594493e2,
+    #             0.651202383207e2, -0.171227351208e3, 0.100859921516e2,
+    #             -0.144684680657e2, 0.128871134847e2, -0.610605957134e1,
+    #             0.109663804408e1, -0.115734899702e2, 0.374970075409e2,
+    #             0.897967147669, -0.527005883203e1, 0.438084681795e-1,
+    #             0.406772082680, -0.965258571044e-2, -0.119044600379e-1],
+    #     "d1": [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
+    #            4, 4, 4, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8],
+    #     "t1": [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6,
+    #            0, 1, 2, 3, 4, 5, 6, 0, 1, 0, 1, 0, 1, 0, 1],
+
+    #     "nr2": [0.382589102341e3, -0.106406466204e4, 0.105544952919e4,
+    #             -0.157579942855e4, 0.132703387531e4, -0.579348879870e3,
+    #             0.974163902526e2, 0.286799294226e3, -0.127543020847e4,
+    #             0.275802674911e4, -0.381284331492e4, 0.293755152012e4,
+    #             -0.117858249946e4, 0.186261198012e3],
+    #     "c2": [1]*14,
+    #     "d2": [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2],
+    #     "t2": [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6],
+    #     "gamma2": [1.5394]*14}
+
+    Fi0 = {"ao_log": [1, 3],
+           "pow": [0, 1, 2, 3, 4, 5],
+           "ao_pow": [-8.6739710041, 6.9611755531],
+           "tau*logtau": -.1288399716e2,
+           "tau*logdelta": 0.4415884023e1,
+           "ao_exp": [0.00863, 0.97454, 2.0646, 0.23528, 0.29555],
+           "titao": [0.4255669437, 2.6093155672, 6.0185106089, 11.3380974051,
+                     29.5101165339],
+           "ao_hyp": [], "hyp": []}
 
     _constants = {
-        "R": 8.3143565,
-        "rhoref": 358.,
-
-        "nr1": [-0.384820628204e3, 0.108213047259e4, -0.110768260635e4,
-                0.164668954246e4, -0.137959852228e4, 0.598964185629e3,
-                -0.100451752702e3, 0.419192736351e3, -0.107279987867e4,
-                0.653852283544e3, -0.984305985655e3, 0.845444459339e3,
-                -0.376799930490e3, 0.644512590492e2, -0.214911115714e3,
-                0.531113962967e3, -0.135454224420e3, 0.202814416558e3,
-                -0.178293865031e3, 0.818739394970e2, -0.143312594493e2,
-                0.651202383207e2, -0.171227351208e3, 0.100859921516e2,
-                -0.144684680657e2, 0.128871134847e2, -0.610605957134e1,
-                0.109663804408e1, -0.115734899702e2, 0.374970075409e2,
-                0.897967147669, -0.527005883203e1, 0.438084681795e-1,
-                0.406772082680, -0.965258571044e-2, -0.119044600379e-1],
-        "d1": [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
-               4, 4, 4, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8],
-        "t1": [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6,
-               0, 1, 2, 3, 4, 5, 6, 0, 1, 0, 1, 0, 1, 0, 1],
-
-        "nr2": [0.382589102341e3, -0.106406466204e4, 0.105544952919e4,
-                -0.157579942855e4, 0.132703387531e4, -0.579348879870e3,
-                0.974163902526e2, 0.286799294226e3, -0.127543020847e4,
-                0.275802674911e4, -0.381284331492e4, 0.293755152012e4,
-                -0.117858249946e4, 0.186261198012e3],
-        "c2": [1]*14,
-        "d2": [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2],
-        "t2": [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6],
-        "gamma2": [1.5394]*14}
-
-    _surface = {"sigma": [0.238, -0.152082], "exp": [1.25, 2.25]}
-    _vapor_Pressure = {
-        "eq": 5,
+        "R": 8.3144621, "rhoref": 17.77555*M, "Tref": 643.847,
+
+        "nr1": [0.0105835, 0.99127253, -1.224122, 1.710643, -2.189443,
+                0.1145315],
+        "d1": [4.0, 1.0, 1.0, 2.0, 2.0, 3.0],
+        "t1": [1.0, 0.463, 1.29, 1.307, 1.2165, 0.587],
+
+        "nr2": [-0.89875532, -1.597051, -2.804509, 0.33016885,
+                -3.396526, -0.001881],
+        "c2": [1.0, 2.0, 2.0, 1.0, 2.0, 1.0],
+        "d2": [1.0, 1.0, 3.0, 2.0, 2.0, 8.0],
+        "t2": [2.95, 1.713, 1.929, 0.94, 3.033, 0.765],
+        "gamma2": [1]*6,
+
+        "nr3": [-0.70355957, -0.20345481, -0.70691398, 2.094255, 3.042546,
+                0.8010728, 0.213384, 0.32335789, -0.0245055, 0.7380677,
+                -0.21484089],
+        "t3": [1.504, 2.85, 1.96, 0.969, 2.576, 2.79, 3.581, 3.67, 1.7, 1.0,
+               4.1],
+        "d3": [1.0, 2.0, 3.0, 1.0, 3.0, 1.0, 1.0, 2.0, 2.0, 2.0, 1.0],
+        "beta3": [0.907, 0.48, 1.223, 2.61, 4.283, 1.4, 0.735, 0.24, 1067.0,
+                  13.27, 1.48],
+        "alfa3": [0.982, 1.34, 1.658, 1.6235, 1.4, 2.206, 0.84, 1.535, 11.33,
+                  3.86, 7.56],
+        "epsilon3": [2.272, 1.375, 0.648, 0.8925, 0.145, 0.291, 2.01, 1.08,
+                     0.96, 0.181, 0.529],
+        "gamma3": [2.263, 2.343, 0.929, 1.0, 1.383, 0.968, 1.695, 2.23, 1.07,
+                   1.297, 2.41]}
+
+    _Pv = {
         "ao": [-0.80236e1, 0.23957e1, -0.42639e2, 0.99569e2, -0.62135e2],
         "exp": [1.0, 1.5, 2.75, 3.0, 3.2]}
-    _liquid_Density = {
+    _rhoL = {
         "eq": 1,
         "ao": [0.26406e1, 0.97090e1, -0.18058e2, 0.87202e1, -0.74487e1],
         "exp": [0.3678, 1.9, 2.2, 2.63, 7.3]}
-    _vapor_Density = {
+    _rhoG = {
         "eq": 3,
         "ao": [-0.37651e1, -0.38673e2, 0.73024e2, -0.13251e3, 0.75235e2,
                -0.70412e2],
         "exp": [0.409, 1.766, 2.24, 3.04, 3.42, 6.9]}
 
-    @classmethod
-    def _visco(cls, rho, T, fase=None):
-        Tr = T/643.847
-        rhor = rho/358.0
-
-        no = [1.0, 0.940695, 0.578377, -0.202044]
-        fi0 = Tr**0.5/sum([n/Tr**i for i, n in enumerate(no)])
-
-        Li = [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 0, 1, 2, 5, 0, 1, 2, 3, 0, 1, 3,
-              5, 0, 1, 5, 3]
-        Lj = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
-              4, 5, 5, 5, 6]
-        Lij = [0.4864192, -0.2448372, -0.8702035, 0.8716056, -1.051126,
-               0.3458395, 0.3509007, 1.315436, 1.297752, 1.353448, -0.2847572,
-               -1.037026, -1.287846, -0.02148229, 0.07013759, 0.4660127,
-               0.2292075, -0.4857462, 0.01641220, -0.02884911, 0.1607171,
-               -.009603846, -.01163815, -.008239587, 0.004559914, -0.003886659]
-
-        arr = [lij*(1./Tr-1)**i*(rhor-1)**j for i, j, lij in zip(Li, Lj, Lij)]
-        fi1 = exp(rhor*sum(arr))
-
-        return 55.2651e-6*fi0*fi1
-
-    @classmethod
-    def _thermo(cls, rho, T, fase=None):
-        rhor = rho/358
-        Tr = T/643.847
-        tau = Tr/(abs(Tr-1.1)+1.1)
-
-        no = [1.0, 37.3223, 22.5485, 13.0465, 0.0, -2.60735]
-        Lo = sum([Li*Tr**i for i, Li in enumerate(no)])
-
-        nr = [483.656, -191.039, 73.0358, -7.57467]
-        Lr = -167.31*(1-exp(-2.506*rhor))+sum(
-            [Li*rhor**(i+1) for i, Li in enumerate(nr)])
-
-        f1 = exp(0.144847*Tr-5.64493*Tr**2)
-        f2 = exp(-2.8*(rhor-1)**2)-0.080738543*exp(-17.943*(rhor-0.125698)**2)
-        f3 = 1+exp(60*(tau-1)+20)
-        f4 = 1+exp(100*(tau-1)+15)
-        Lc = 35429.6*f1*f2*(1+f2**2*(5e9*f1**4/f3+3.5*f2/f4))
-
-        Ll = -741.112*f1**1.2*(1-exp(-(rhor/2.5)**10))
-
-        return 0.742128e-3*(Lo+Lr+Lc+Ll)
+    def _visco(self, rho, T, fase):
+        return _D2O_Viscosity(rho, T)
 
+    def _thermo(self, rho, T, fase):
+        return _D2O_ThCond(rho, T)
 
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
+    def _surface(self, T):
+        s = _D2O_Tension(T)
+        return s
diff --git a/iapws/iapws97.py b/iapws/iapws97.py
index b6b3d6e..756c5d7 100644
--- a/iapws/iapws97.py
+++ b/iapws/iapws97.py
@@ -1,34 +1,145 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
-
-"IAPWS-IF97 Steam Tables implementation"
+"""IAPWS-IF97 standard implementation
+
+.. image:: https://raw.githubusercontent.com/jjgomera/iapws/master/images/iapws97.png
+    :alt: iapws97
+
+The module implement the fundamental equation for the five regions (rectangular
+boxes) and the backward equation (marked in grey).
+
+:func:`IAPWS97`: Global module class with all the functionality integrated
+
+Fundamental equations:
+   * :func:`_Region1`
+   * :func:`_Region2`
+   * :func:`_Region3`
+   * :func:`_Region4`
+   * :func:`_TSat_P`
+   * :func:`_PSat_T`
+   * :func:`_Region5`
+
+Backward equations:
+   * :func:`_Backward1_T_Ph`
+   * :func:`_Backward1_T_Ps`
+   * :func:`_Backward1_P_hs`
+   * :func:`_Backward2_T_Ph`
+   * :func:`_Backward2_T_Ps`
+   * :func:`_Backward2_P_hs`
+   * :func:`_Backward3_T_Ph`
+   * :func:`_Backward3_T_Ps`
+   * :func:`_Backward3_P_hs`
+   * :func:`_Backward3_v_Ph`
+   * :func:`_Backward3_v_Ps`
+   * :func:`_Backward3_v_PT`
+   * :func:`_Backward4_T_hs`
+
+Boundary equations:
+   * :func:`_h13_s`
+   * :func:`_h3a_s`
+   * :func:`_h1_s`
+   * :func:`_t_hs`
+   * :func:`_PSat_h`
+   * :func:`_h2ab_s`
+   * :func:`_h_3ab`
+   * :func:`_h2c3b_s`
+   * :func:`_hab_s`
+   * :func:`_hbc_P`
+
+
+References:
+
+IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+Thermodynamic Properties of Water and Steam August 2007,
+http://www.iapws.org/relguide/IF97-Rev.html
+
+IAPWS, Revised Supplementary Release on Backward Equations for Pressure
+as a Function of Enthalpy and Entropy p(h,s) for Regions 1 and 2 of the IAPWS
+Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+Steam, http://www.iapws.org/relguide/Supp-PHS12-2014.pdf
+
+IAPWS, Revised Supplementary Release on Backward Equations for the
+Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf
+
+IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+Region 3, Equations as a Function of h and s for the Region Boundaries, and an
+Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997 for
+the Thermodynamic Properties of Water and Steam,
+http://www.iapws.org/relguide/Supp-phs3-2014.pdf
+
+IAPWS, Revised Supplementary Release on Backward Equations for Specific
+Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf
+
+IAPWS, Revised Advisory Note No. 3: Thermodynamic Derivatives from IAPWS
+Formulations, http://www.iapws.org/relguide/Advise3.pdf
+
+Wagner, W; Kretzschmar, H-J: International Steam Tables: Properties of
+Water and Steam Based on the Industrial Formulation IAPWS-IF97; Springer, 2008;
+doi: 10.1007/978-3-540-74234-0
+"""
 
 from __future__ import division
 from math import sqrt, log, exp
 
 from scipy.optimize import fsolve, newton
 
-from ._iapws import M, R, Tc, Pc, rhoc, Tt, Pt, Tb, Dipole, f_acent, _fase
+from ._iapws import R, Tc, Pc, rhoc, Tt, Pt, Tb, Dipole, f_acent
 from ._iapws import _Viscosity, _ThCond, _Tension, _Dielectric, _Refractive
-from ._iapws import getphase
+from ._utils import getphase, deriv_G, _fase
+
 
+# Critic properties
+sc = 4.41202148223476
+hc = 2087.5468451171537
 
-sc = 4.41202148223476     # Critic entropy
 # Pmin = _PSat_T(273.15)   # Minimum pressure
 Pmin = 0.000611212677444
 # Ps_623 = _PSat_T(623.15)  # P Saturation at 623.15 K, boundary region 1-3
 Ps_623 = 16.5291642526
 
 
-# Boundary Region1-Region2
+# Boundary Region1-Region3
 def _h13_s(s):
     """Define the boundary between Region 1 and 3, h=f(s)
 
-    >>> "%.6f" % _h13_s(3.7)
-    '1632.525047'
-    >>> "%.6f" % _h13_s(3.5)
-    '1566.104611'
+    Parameters
+    ----------
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * s(100MPa,623.15K) ≤ s ≤ s'(623.15K)
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 7
+
+    Examples
+    --------
+    >>> _h13_s(3.7)
+    1632.525047
+    >>> _h13_s(3.5)
+    1566.104611
     """
+    # Check input parameters
+    if s < 3.397782955 or s > 3.77828134:
+        raise NotImplementedError("Incoming out of bound")
+
     sigma = s/3.8
     I = [0, 1, 1, 3, 5, 6]
     J = [0, -2, 2, -12, -4, -3]
@@ -36,8 +147,8 @@ def _h13_s(s):
          0.117518273082168e-17, 0.220000904781292, -0.690815545851641e2]
 
     suma = 0
-    for i in range(6):
-        suma += n[i] * (sigma-0.884)**I[i] * (sigma-0.864)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (sigma-0.884)**i * (sigma-0.864)**j
     return 1700 * suma
 
 
@@ -45,8 +156,26 @@ def _h13_s(s):
 def _P23_T(T):
     """Define the boundary between Region 2 and 3, P=f(T)
 
-    >>> "%.8f" % _P23_T(623.15)
-    '16.52916425'
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 5
+
+    Examples
+    --------
+    >>> _P23_T(623.15)
+    16.52916425
     """
     n = [0.34805185628969e3, -0.11671859879975e1, 0.10192970039326e-2]
     return n[0]+n[1]*T+n[2]*T**2
@@ -55,8 +184,26 @@ def _P23_T(T):
 def _t_P(P):
     """Define the boundary between Region 2 and 3, T=f(P)
 
-    >>> "%.2f" % _t_P(16.52916425)
-    '623.15'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 5
+
+    Examples
+    --------
+    >>> _t_P(16.52916425)
+    623.15
     """
     n = [0.10192970039326e-2, 0.57254459862746e3, 0.1391883977870e2]
     return n[1]+((P-n[2])/n[0])**0.5
@@ -65,11 +212,44 @@ def _t_P(P):
 def _t_hs(h, s):
     """Define the boundary between Region 2 and 3, T=f(h,s)
 
-    >>> "%.7f" % _t_hs(2600, 5.1)
-    '713.5259364'
-    >>> "%.7f" % _t_hs(2800, 5.2)
-    '817.6202120'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 5.048096828 ≤ s ≤ 5.260578707
+        * 2.563592004e3 ≤ h ≤ 2.812942061e3
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 8
+
+    Examples
+    --------
+    >>> _t_hs(2600, 5.1)
+    713.5259364
+    >>> _t_hs(2800, 5.2)
+    817.6202120
     """
+    # Check input parameters
+    if s < 5.048096828 or s > 5.260578707 or \
+            h < 2.563592004e3 or h > 2.812942061e3:
+        raise NotImplementedError("Incoming out of bound")
+
     nu = h/3000
     sigma = s/5.3
     I = [-12, -10, -8, -4, -3, -2, -2, -2, -2, 0, 1, 1, 1, 3, 3, 5, 6, 6, 8, 8,
@@ -87,8 +267,8 @@ def _t_hs(h, s):
          0.783237062349385e7]
 
     suma = 0
-    for i in range(25):
-        suma += n[i]*(nu-0.727)**I[i]*(sigma-0.864)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-0.727)**i * (sigma-0.864)**j
     return 900*suma
 
 
@@ -96,13 +276,36 @@ def _t_hs(h, s):
 def _PSat_T(T):
     """Define the saturated line, P=f(T)
 
-    >>> "%.8f" % _PSat_T(500)
-    '2.63889776'
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 273.15 ≤ T ≤ 647.096
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 30
+
+    Examples
+    --------
+    >>> _PSat_T(500)
+    2.63889776
     """
-    if T < 273.15:
-        T = 273.15
-    elif T > Tc:
-        T = Tc
+    # Check input parameters
+    if T < 273.15 or T > Tc:
+        raise NotImplementedError("Incoming out of bound")
+
     n = [0, 0.11670521452767E+04, -0.72421316703206E+06, -0.17073846940092E+02,
          0.12020824702470E+05, -0.32325550322333E+07, 0.14915108613530E+02,
          -0.48232657361591E+04, 0.40511340542057E+06, -0.23855557567849E+00,
@@ -117,13 +320,36 @@ def _PSat_T(T):
 def _TSat_P(P):
     """Define the saturated line, T=f(P)
 
-    >>> "%.6f" % _TSat_P(10)
-    '584.149488'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 0.00061121 ≤ P ≤ 22.064
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 31
+
+    Examples
+    --------
+    >>> _TSat_P(10)
+    584.149488
     """
-    if P < 611.212677/1e6:
-        P = 611.212677/1e6
-    elif P > 22.064:
-        P = 22.064
+    # Check input parameters
+    if P < 611.212677/1e6 or P > 22.064:
+        raise NotImplementedError("Incoming out of bound")
+
     n = [0, 0.11670521452767E+04, -0.72421316703206E+06, -0.17073846940092E+02,
          0.12020824702470E+05, -0.32325550322333E+07, 0.14915108613530E+02,
          -0.48232657361591E+04, 0.40511340542057E+06, -0.23855557567849E+00,
@@ -139,17 +365,41 @@ def _TSat_P(P):
 def _PSat_h(h):
     """Define the saturated line, P=f(h) for region 3
 
-    >>> "%.8f" % _PSat_h(1700)
-    '17.24175718'
-    >>> "%.8f" % _PSat_h(2400)
-    '20.18090839'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * h'(623.15K) ≤ h ≤ h''(623.15K)
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 10
+
+    Examples
+    --------
+    >>> _PSat_h(1700)
+    17.24175718
+    >>> _PSat_h(2400)
+    20.18090839
     """
+    # Check input parameters
     hmin_Ps3 = _Region1(623.15, Ps_623)["h"]
     hmax_Ps3 = _Region2(623.15, Ps_623)["h"]
-    if h < hmin_Ps3:
-        h = hmin_Ps3
-    if h > hmax_Ps3:
-        h = hmax_Ps3
+    if h < hmin_Ps3 or h > hmax_Ps3:
+        raise NotImplementedError("Incoming out of bound")
+
     nu = h/2600
     I = [0, 1, 1, 1, 1, 5, 7, 8, 14, 20, 22, 24, 28, 36]
     J = [0, 1, 3, 4, 36, 3, 0, 24, 16, 16, 3, 18, 8, 24]
@@ -160,19 +410,49 @@ def _PSat_h(h):
          0.330611514838798e19, 0.813641294467829e38]
 
     suma = 0
-    for i in range(14):
-        suma += n[i]*(nu-1.02)**I[i]*(nu-0.608)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-1.02)**i * (nu-0.608)**j
     return 22*suma
 
 
 def _PSat_s(s):
     """Define the saturated line, P=f(s) for region 3
 
-    >>> "%.8f" % _PSat_s(3.8)
-    '16.87755057'
-    >>> "%.8f" % _PSat_s(5.2)
-    '16.68968482'
+    Parameters
+    ----------
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * s'(623.15K) ≤ s ≤ s''(623.15K)
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 11
+
+    Examples
+    --------
+    >>> _PSat_s(3.8)
+    16.87755057
+    >>> _PSat_s(5.2)
+    16.68968482
     """
+    # Check input parameters
+    smin_Ps3 = _Region1(623.15, Ps_623)["s"]
+    smax_Ps3 = _Region2(623.15, Ps_623)["s"]
+    if s < smin_Ps3 or s > smax_Ps3:
+        raise NotImplementedError("Incoming out of bound")
+
     sigma = s/5.2
     I = [0, 1, 1, 4, 12, 12, 16, 24, 28, 32]
     J = [0, 1, 32, 7, 4, 14, 36, 10, 0, 18]
@@ -182,19 +462,48 @@ def _PSat_s(s):
          0.110649277244882e37]
 
     suma = 0
-    for i in range(10):
-        suma += n[i]*(sigma-1.03)**I[i]*(sigma-0.699)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (sigma-1.03)**i * (sigma-0.699)**j
     return 22*suma
 
 
 def _h1_s(s):
     """Define the saturated line boundary between Region 1 and 4, h=f(s)
 
-    >>> "%.7f" % _h1_s(1)
-    '308.5509647'
-    >>> "%.6f" % _h1_s(3)
-    '1198.359754'
+    Parameters
+    ----------
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * s'(273.15K) ≤ s ≤ s'(623.15K)
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 3
+
+    Examples
+    --------
+    >>> _h1_s(1)
+    308.5509647
+    >>> _h1_s(3)
+    1198.359754
     """
+    # Check input parameters
+    if s < -1.545495919e-4 or s > 3.77828134:
+        raise NotImplementedError("Incoming out of bound")
+
     sigma = s/3.8
     I = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 7, 8, 12, 12, 14, 14, 16, 20,
          20, 22, 24, 28, 32, 32]
@@ -211,19 +520,48 @@ def _h1_s(s):
          0.834596332878346e-6, 0.503611916682674e1, 0.655444787064505e2]
 
     suma = 0
-    for i in range(27):
-        suma += n[i]*(sigma-1.09)**I[i]*(sigma+0.366e-4)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (sigma-1.09)**i * (sigma+0.366e-4)**j
     return 1700*suma
 
 
 def _h3a_s(s):
     """Define the saturated line boundary between Region 4 and 3a, h=f(s)
 
-    >>> "%.6f" % _h3a_s(3.8)
-    '1685.025565'
-    >>> "%.6f" % _h3a_s(4.2)
-    '1949.352563'
+    Parameters
+    ----------
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * s'(623.15K) ≤ s ≤ sc
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 4
+
+    Examples
+    --------
+    >>> _h3a_s(3.8)
+    1685.025565
+    >>> _h3a_s(4.2)
+    1949.352563
     """
+    # Check input parameters
+    if s < 3.77828134 or s > 4.41202148223476:
+        raise NotImplementedError("Incoming out of bound")
+
     sigma = s/3.8
     I = [0, 0, 0, 0, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 10, 10, 10, 32, 32]
     J = [1, 4, 10, 16, 1, 36, 3, 16, 20, 36, 4, 2, 28, 32, 14, 32, 36, 0, 6]
@@ -236,19 +574,48 @@ def _h3a_s(s):
          0.631052532240980]
 
     suma = 0
-    for i in range(19):
-        suma += n[i]*(sigma-1.09)**I[i]*(sigma+0.366e-4)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (sigma-1.09)**i * (sigma+0.366e-4)**j
     return 1700*suma
 
 
 def _h2ab_s(s):
     """Define the saturated line boundary between Region 4 and 2a-2b, h=f(s)
 
-    >>> "%.6f" % _h2ab_s(7)
-    '2723.729985'
-    >>> "%.6f" % _h2ab_s(9)
-    '2511.861477'
+    Parameters
+    ----------
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * 5.85 ≤ s ≤ s"(273.15K)
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 5
+
+    Examples
+    --------
+    >>> _h2ab_s(7)
+    2723.729985
+    >>> _h2ab_s(9)
+    2511.861477
     """
+    # Check input parameters
+    if s < 5.85 or s > 9.155759395:
+        raise NotImplementedError("Incoming out of bound")
+
     sigma1 = s/5.21
     sigma2 = s/9.2
     I = [1, 1, 2, 2, 4, 4, 7, 8, 8, 10, 12, 12, 18, 20, 24, 28, 28, 28, 28, 28,
@@ -267,19 +634,48 @@ def _h2ab_s(s):
          -0.175407764869978e33, 0.347581490626396e35, -0.710971318427851e39]
 
     suma = 0
-    for i in range(30):
-        suma += n[i]*(1/sigma1-0.513)**I[i]*(sigma2-0.524)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (1/sigma1-0.513)**i * (sigma2-0.524)**j
     return 2800*exp(suma)
 
 
 def _h2c3b_s(s):
     """Define the saturated line boundary between Region 4 and 2c-3b, h=f(s)
 
-    >>> "%.6f" % _h2c3b_s(5.5)
-    '2687.693850'
-    >>> "%.6f" % _h2c3b_s(4.5)
-    '2144.360448'
+    Parameters
+    ----------
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Raises
+    ------
+    NotImplementedError : If input isn't in limit
+        * sc ≤ s ≤ 5.85
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 6
+
+    Examples
+    --------
+    >>> _h2c3b_s(5.5)
+    2687.693850
+    >>> _h2c3b_s(4.5)
+    2144.360448
     """
+    # Check input parameters
+    if s < 4.41202148223476 or s > 5.85:
+        raise NotImplementedError("Incoming out of bound")
+
     sigma = s/5.9
     I = [0, 0, 0, 1, 1, 5, 6, 7, 8, 8, 12, 16, 22, 22, 24, 36]
     J = [0, 3, 4, 0, 12, 36, 12, 16, 2, 20, 32, 36, 2, 32, 7, 20]
@@ -291,8 +687,8 @@ def _h2c3b_s(s):
          -0.116994334851995e41]
 
     suma = 0
-    for i in range(16):
-        suma += n[i]*(sigma-1.02)**I[i]*(sigma-0.726)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (sigma-1.02)**i * (sigma-0.726)**j
     return 2800*suma**4
 
 
@@ -300,24 +696,53 @@ def _h2c3b_s(s):
 def _Region1(T, P):
     """Basic equation for region 1
 
-    >>> "%.11f" % _Region1(300,3)["v"]
-    '0.00100215168'
-    >>> "%.6f" % _Region1(300,3)["h"]
-    '115.331273'
-    >>> "%.6f" % (_Region1(300,3)["h"]-3000*_Region1(300,3)["v"], )
-    '112.324818'
-    >>> "%.9f" % _Region1(300,80)["s"]
-    '0.368563852'
-    >>> "%.8f" % _Region1(300,80)["cp"]
-    '4.01008987'
-    >>> "%.8f" % _Region1(300,80)["cv"]
-    '3.91736606'
-    >>> "%.5f" % _Region1(500,3)["w"]
-    '1240.71337'
-    >>> "%.11f" % _Region1(500,3)["alfav"]
-    '0.00164118128'
-    >>> "%.11f" % _Region1(500,3)["kt"]
-    '0.00112892188'
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties. The available properties are:
+
+            * v: Specific volume [m³/kg]
+            * h: Specific enthalpy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * cv: Specific isocoric heat capacity [kJ/kgK]
+            * w: Speed of sound [m/s]
+            * alfav: Cubic expansion coefficient [1/K]
+            * kt: Isothermal compressibility [1/MPa]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 7
+
+    Examples
+    --------
+    >>> _Region1(300,3)["v"]
+    0.00100215168
+    >>> _Region1(300,3)["h"]
+    115.331273
+    >>> _Region1(300,3)["h"]-3000*_Region1(300,3)["v"]
+    112.324818
+    >>> _Region1(300,80)["s"]
+    0.368563852
+    >>> _Region1(300,80)["cp"]
+    4.01008987
+    >>> _Region1(300,80)["cv"]
+    3.91736606
+    >>> _Region1(500,3)["w"]
+    1240.71337
+    >>> _Region1(500,3)["alfav"]
+    0.00164118128
+    >>> _Region1(500,3)["kt"]
+    0.00112892188
     """
     I = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4,
          4, 4, 5, 8, 8, 21, 23, 29, 30, 31, 32]
@@ -338,13 +763,13 @@ def _Region1(T, P):
     Tr = 1386/T
     Pr = P/16.53
     g = gp = gpp = gt = gtt = gpt = 0
-    for i in range(34):
-        g += n[i]*(7.1-Pr)**I[i]*(Tr-1.222)**J[i]
-        gp -= n[i]*I[i]*(7.1-Pr)**(I[i]-1)*(Tr-1.222)**J[i]
-        gpp += n[i]*I[i]*(I[i]-1)*(7.1-Pr)**(I[i]-2)*(Tr-1.222)**J[i]
-        gt += n[i] * (7.1-Pr)**I[i] * J[i] * (Tr-1.222)**(J[i]-1)
-        gtt += n[i]*(7.1-Pr)**I[i]*J[i]*(J[i]-1)*(Tr-1.222)**(J[i]-2)
-        gpt -= n[i]*I[i]*(7.1-Pr)**(I[i]-1)*J[i]*(Tr-1.222)**(J[i]-1)
+    for i, j, ni in zip(I, J, n):
+        g += ni * (7.1-Pr)**i * (Tr-1.222)**j
+        gp -= ni*i * (7.1-Pr)**(i-1) * (Tr-1.222)**j
+        gpp += ni*i*(i-1) * (7.1-Pr)**(i-2) * (Tr-1.222)**j
+        gt += ni*j * (7.1-Pr)**i * (Tr-1.222)**(j-1)
+        gtt += ni*j*(j-1) * (7.1-Pr)**i * (Tr-1.222)**(j-2)
+        gpt -= ni*i*j * (7.1-Pr)**(i-1) * (Tr-1.222)**(j-1)
 
     propiedades = {}
     propiedades["T"] = T
@@ -363,12 +788,33 @@ def _Region1(T, P):
 
 
 def _Backward1_T_Ph(P, h):
-    """Backward equation for region 1, T=f(P,h)
-
-    >>> "%.6f" % _Backward1_T_Ph(3,500)
-    '391.798509'
-    >>> "%.6f" % _Backward1_T_Ph(80,1500)
-    '611.041229'
+    """
+    Backward equation for region 1, T=f(P,h)
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 11
+
+    Examples
+    --------
+    >>> _Backward1_T_Ph(3,500)
+    391.798509
+    >>> _Backward1_T_Ph(80,1500)
+    611.041229
     """
     I = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6]
     J = [0, 1, 2, 6, 22, 32, 0, 1, 2, 3, 4, 10, 32, 10, 32, 10, 32, 32, 32, 32]
@@ -383,18 +829,38 @@ def _Backward1_T_Ph(P, h):
     Pr = P/1
     nu = h/2500
     T = 0
-    for i in range(20):
-        T += n[i]*Pr**I[i]*(nu+1)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * Pr**i * (nu+1)**j
     return T
 
 
 def _Backward1_T_Ps(P, s):
     """Backward equation for region 1, T=f(P,s)
 
-    >>> "%.6f" % _Backward1_T_Ps(3,0.5)
-    '307.842258'
-    >>> "%.6f" % _Backward1_T_Ps(80,3)
-    '565.899909'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 13
+
+    Examples
+    --------
+    >>> _Backward1_T_Ps(3,0.5)
+    307.842258
+    >>> _Backward1_T_Ps(80,3)
+    565.899909
     """
     I = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4]
     J = [0, 1, 2, 3, 11, 31, 0, 1, 2, 3, 12, 31, 0, 1, 2, 9, 31, 10, 32, 32]
@@ -409,20 +875,41 @@ def _Backward1_T_Ps(P, s):
     Pr = P/1
     sigma = s/1
     T = 0
-    for i in range(20):
-        T += n[i]*Pr**I[i]*(sigma+2)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * Pr**i * (sigma+2)**j
     return T
 
 
 def _Backward1_P_hs(h, s):
     """Backward equation for region 1, P=f(h,s)
 
-    >>> "%.13f" % _Backward1_P_hs(0.001,0)
-    '0.0009800980612'
-    >>> "%.8f" % _Backward1_P_hs(90,0)
-    '91.92954727'
-    >>> "%.8f" % _Backward1_P_hs(1500,3.4)
-    '58.68294423'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Pressure
+    as a Function of Enthalpy and Entropy p(h,s) for Regions 1 and 2 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of
+    Water and Steam, http://www.iapws.org/relguide/Supp-PHS12-2014.pdf, Eq 1
+
+    Examples
+    --------
+    >>> _Backward1_P_hs(0.001,0)
+    0.0009800980612
+    >>> _Backward1_P_hs(90,0)
+    91.92954727
+    >>> _Backward1_P_hs(1500,3.4)
+    58.68294423
     """
     I = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 5]
     J = [0, 1, 2, 4, 5, 6, 8, 14, 0, 1, 4, 6, 0, 1, 10, 4, 1, 4, 0]
@@ -437,8 +924,8 @@ def _Backward1_P_hs(h, s):
     nu = h/3400
     sigma = s/7.6
     P = 0
-    for i in range(19):
-        P += n[i]*(nu+0.05)**I[i]*(sigma+0.05)**J[i]
+    for i, j, ni in zip(I, J, n):
+        P += ni * (nu+0.05)**i * (sigma+0.05)**j
     return 100*P
 
 
@@ -446,24 +933,53 @@ def _Backward1_P_hs(h, s):
 def _Region2(T, P):
     """Basic equation for region 2
 
-    >>> "%.11f" % _Region2(700,30)["v"]
-    '0.00542946619'
-    >>> "%.5f" % _Region2(700,30)["h"]
-    '2631.49474'
-    >>> "%.5f" % (_Region2(700,30)["h"]-30000*_Region2(700,30)["v"], )
-    '2468.61076'
-    >>> "%.7f" % _Region2(700,0.0035)["s"]
-    '10.1749996'
-    >>> "%.8f" % _Region2(700,0.0035)["cp"]
-    '2.08141274'
-    >>> "%.8f" % _Region2(700,0.0035)["cv"]
-    '1.61978333'
-    >>> "%.6f" % _Region2(300,0.0035)["w"]
-    '427.920172'
-    >>> "%.11f" % _Region2(300,0.0035)["alfav"]
-    '0.00337578289'
-    >>> "%.6f" % _Region2(300,0.0035)["kt"]
-    '286.239651'
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties. The available properties are:
+
+            * v: Specific volume [m³/kg]
+            * h: Specific enthalpy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * cv: Specific isocoric heat capacity [kJ/kgK]
+            * w: Speed of sound [m/s]
+            * alfav: Cubic expansion coefficient [1/K]
+            * kt: Isothermal compressibility [1/MPa]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 15-17
+
+    Examples
+    --------
+    >>> _Region2(700,30)["v"]
+    0.00542946619
+    >>> _Region2(700,30)["h"]
+    2631.49474
+    >>> _Region2(700,30)["h"]-30000*_Region2(700,30)["v"]
+    2468.61076
+    >>> _Region2(700,0.0035)["s"]
+    10.1749996
+    >>> _Region2(700,0.0035)["cp"]
+    2.08141274
+    >>> _Region2(700,0.0035)["cv"]
+    1.61978333
+    >>> _Region2(300,0.0035)["w"]
+    427.920172
+    >>> _Region2(300,0.0035)["alfav"]
+    0.00337578289
+    >>> _Region2(300,0.0035)["kt"]
+    286.239651
     """
     Tr = 540/T
     Pr = P/1
@@ -495,13 +1011,13 @@ def _Region2(T, P):
           -9.4369707241209998e-07]
 
     gr = grp = grpp = grt = grtt = grpt = 0
-    for i in range(43):
-        gr += nr[i]*Pr**Ir[i]*(Tr-0.5)**Jr[i]
-        grp += nr[i]*Ir[i]*Pr**(Ir[i]-1)*(Tr-0.5)**Jr[i]
-        grpp += nr[i]*Ir[i]*(Ir[i]-1)*Pr**(Ir[i]-2)*(Tr-0.5)**Jr[i]
-        grt += nr[i]*Pr**Ir[i]*Jr[i]*(Tr-0.5)**(Jr[i]-1)
-        grtt += nr[i]*Pr**Ir[i]*Jr[i]*(Jr[i]-1)*(Tr-0.5)**(Jr[i]-2)
-        grpt += nr[i]*Ir[i]*Pr**(Ir[i]-1)*Jr[i]*(Tr-0.5)**(Jr[i]-1)
+    for i, j, ni in zip(Ir, Jr, nr):
+        gr += ni * Pr**i * (Tr-0.5)**j
+        grp += ni*i * Pr**(i-1) * (Tr-0.5)**j
+        grpp += ni*i*(i-1) * Pr**(i-2) * (Tr-0.5)**j
+        grt += ni*j * Pr**i * (Tr-0.5)**(j-1)
+        grtt += ni*j*(j-1) * Pr**i * (Tr-0.5)**(j-2)
+        grpt += ni*i*j * Pr**(i-1) * (Tr-0.5)**(j-1)
 
     propiedades = {}
     propiedades["T"] = T
@@ -522,7 +1038,34 @@ def _Region2(T, P):
 
 
 def Region2_cp0(Tr, Pr):
-    """Ideal properties for Region 2"""
+    """Ideal properties for Region 2
+
+    Parameters
+    ----------
+    Tr : float
+        Reduced temperature [-]
+    Pr : float
+        Reduced pressure [-]
+
+    Returns
+    -------
+    prop : array
+        Array with ideal Gibbs energy partial derivatives:
+
+            * g: Ideal Specific Gibbs energy [kJ/kg]
+            * gp: [∂g/∂P]T
+            * gpp: [∂²g/∂P²]T
+            * gt: [∂g/∂T]P
+            * gtt: [∂²g/∂T²]P
+            * gpt: [∂²g/∂T∂P]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 16
+
+    """
     Jo = [0, 1, -5, -4, -3, -2, -1, 2, 3]
     no = [-0.96927686500217E+01, 0.10086655968018E+02, -0.56087911283020E-02,
           0.71452738081455E-01, -0.40710498223928E+00, 0.14240819171444E+01,
@@ -531,18 +1074,36 @@ def Region2_cp0(Tr, Pr):
     gop = Pr**-1
     gopp = -Pr**-2
     got = gott = gopt = 0
-    for i in range(9):
-        go += no[i]*Tr**Jo[i]
-        got += no[i]*Jo[i]*Tr**(Jo[i]-1)
-        gott += no[i]*Jo[i]*(Jo[i]-1)*Tr**(Jo[i]-2)
+    for j, ni in zip(Jo, no):
+        go += ni * Tr**j
+        got += ni*j * Tr**(j-1)
+        gott += ni*j*(j-1) * Tr**(j-2)
     return go, gop, gopp, got, gott, gopt
 
 
 def _P_2bc(h):
     """Define the boundary between Region 2b and 2c, P=f(h)
 
-    >>> "%.3f" % _P_2bc(3516.004323)
-    '100.000'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 20
+
+    Examples
+    --------
+    >>> _P_2bc(3516.004323)
+    100.0
     """
     return 905.84278514723-0.67955786399241*h+1.2809002730136e-4*h**2
 
@@ -550,8 +1111,26 @@ def _P_2bc(h):
 def _hbc_P(P):
     """Define the boundary between Region 2b and 2c, h=f(P)
 
-    >>> "%.6f" % _hbc_P(100)
-    '3516.004323'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 21
+
+    Examples
+    --------
+    >>> _hbc_P(100)
+    3516.004323
     """
     return 0.26526571908428e4+((P-0.45257578905948e1)/1.2809002730136e-4)**0.5
 
@@ -559,8 +1138,27 @@ def _hbc_P(P):
 def _hab_s(s):
     """Define the boundary between Region 2a and 2b, h=f(s)
 
-    >>> "%.6f" % _hab_s(7)
-    '3376.437884'
+    Parameters
+    ----------
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Pressure
+    as a Function of Enthalpy and Entropy p(h,s) for Regions 1 and 2 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of
+    Water and Steam, http://www.iapws.org/relguide/Supp-PHS12-2014.pdf, Eq 2
+
+    Examples
+    --------
+    >>> _hab_s(7)
+    3376.437884
     """
     smin = _Region2(_TSat_P(4), 4)["s"]
     smax = _Region2(1073.15, 4)["s"]
@@ -577,10 +1175,30 @@ def _hab_s(s):
 def _Backward2a_T_Ph(P, h):
     """Backward equation for region 2a, T=f(P,h)
 
-    >>> "%.6f" % _Backward2a_T_Ph(0.001,3000)
-    '534.433241'
-    >>> "%.5f" % _Backward2a_T_Ph(3,4000)
-    '1010.77577'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 22
+
+    Examples
+    --------
+    >>> _Backward2a_T_Ph(0.001,3000)
+    534.433241
+    >>> _Backward2a_T_Ph(3,4000)
+    1010.77577
     """
     I = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
          3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7]
@@ -602,18 +1220,38 @@ def _Backward2a_T_Ph(P, h):
     Pr = P/1
     nu = h/2000
     T = 0
-    for i in range(34):
-        T += n[i]*Pr**I[i]*(nu-2.1)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * Pr**i * (nu-2.1)**j
     return T
 
 
 def _Backward2b_T_Ph(P, h):
     """Backward equation for region 2b, T=f(P,h)
 
-    >>> "%.5f" % _Backward2b_T_Ph(5,4000)
-    '1015.31583'
-    >>> "%.6f" % _Backward2b_T_Ph(25,3500)
-    '875.279054'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 23
+
+    Examples
+    --------
+    >>> _Backward2b_T_Ph(5,4000)
+    1015.31583
+    >>> _Backward2b_T_Ph(25,3500)
+    875.279054
     """
     I = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3,
          3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7, 9, 9]
@@ -636,18 +1274,38 @@ def _Backward2b_T_Ph(P, h):
     Pr = P/1
     nu = h/2000
     T = 0
-    for i in range(38):
-        T += n[i]*(Pr-2)**I[i]*(nu-2.6)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * (Pr-2)**i * (nu-2.6)**j
     return T
 
 
 def _Backward2c_T_Ph(P, h):
     """Backward equation for region 2c, T=f(P,h)
 
-    >>> "%.6f" % _Backward2c_T_Ph(40,2700)
-    '743.056411'
-    >>> "%.6f" % _Backward2c_T_Ph(60,3200)
-    '882.756860'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 24
+
+    Examples
+    --------
+    >>> _Backward2c_T_Ph(40,2700)
+    743.056411
+    >>> _Backward2c_T_Ph(60,3200)
+    882.756860
     """
     I = [-7, -7, -6, -6, -5, -5, -2, -2, -1, -1, 0, 0, 1, 1, 2, 6, 6, 6, 6, 6,
          6, 6, 6]
@@ -665,14 +1323,26 @@ def _Backward2c_T_Ph(P, h):
     Pr = P/1
     nu = h/2000
     T = 0
-    for i in range(23):
-        T += n[i]*(Pr+25)**I[i]*(nu-1.8)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * (Pr+25)**i * (nu-1.8)**j
     return T
 
 
 def _Backward2_T_Ph(P, h):
-    """Backward equation for region 2, T=f(P,h)"""
-    Tsat = _TSat_P(P)
+    """Backward equation for region 2, T=f(P,h)
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+    """
     if P <= 4:
         T = _Backward2a_T_Ph(P, h)
     elif 4 < P <= 6.546699678:
@@ -683,16 +1353,40 @@ def _Backward2_T_Ph(P, h):
             T = _Backward2b_T_Ph(P, h)
         else:
             T = _Backward2c_T_Ph(P, h)
-    return max(Tsat, T)
+
+    if P <= 22.064:
+        Tsat = _TSat_P(P)
+        T = max(Tsat, T)
+    return T
 
 
 def _Backward2a_T_Ps(P, s):
     """Backward equation for region 2a, T=f(P,s)
 
-    >>> "%.6f" % _Backward2a_T_Ps(0.1,7.5)
-    '399.517097'
-    >>> "%.5f" % _Backward2a_T_Ps(2.5,8)
-    '1039.84917'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 25
+
+    Examples
+    --------
+    >>> _Backward2a_T_Ps(0.1,7.5)
+    399.517097
+    >>> _Backward2a_T_Ps(2.5,8)
+    1039.84917
     """
     I = [-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.25, -1.25, -1.25, -1.0, -1.0,
          -1.0, -1.0, -1.0, -1.0, -0.75, -0.75, -0.5, -0.5, -0.5, -0.5, -0.25,
@@ -721,18 +1415,38 @@ def _Backward2a_T_Ps(P, s):
     Pr = P/1
     sigma = s/2
     T = 0
-    for i in range(46):
-        T += n[i]*Pr**I[i]*(sigma-2)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * Pr**i * (sigma-2)**j
     return T
 
 
 def _Backward2b_T_Ps(P, s):
     """Backward equation for region 2b, T=f(P,s)
 
-    >>> "%.6f" % _Backward2b_T_Ps(8,6)
-    '600.484040'
-    >>> "%.5f" % _Backward2b_T_Ps(90,6)
-    '1038.01126'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 26
+
+    Examples
+    --------
+    >>> _Backward2b_T_Ps(8,6)
+    600.484040
+    >>> _Backward2b_T_Ps(90,6)
+    1038.01126
     """
     I = [-6, -6, -5, -5, -4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1,
          -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3,
@@ -758,18 +1472,38 @@ def _Backward2b_T_Ps(P, s):
     Pr = P/1
     sigma = s/0.7853
     T = 0
-    for i in range(44):
-        T += n[i]*Pr**I[i]*(10-sigma)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * Pr**i * (10-sigma)**j
     return T
 
 
 def _Backward2c_T_Ps(P, s):
     """Backward equation for region 2c, T=f(P,s)
 
-    >>> "%.6f" % _Backward2c_T_Ps(20,5.75)
-    '697.992849'
-    >>> "%.6f" % _Backward2c_T_Ps(80,5.75)
-    '949.017998'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 27
+
+    Examples
+    --------
+    >>> _Backward2c_T_Ps(20,5.75)
+    697.992849
+    >>> _Backward2c_T_Ps(80,5.75)
+    949.017998
     """
     I = [-2, -2, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
          5, 6, 6, 7, 7, 7, 7, 7]
@@ -789,33 +1523,69 @@ def _Backward2c_T_Ps(P, s):
     Pr = P/1
     sigma = s/2.9251
     T = 0
-    for i in range(30):
-        T += n[i]*Pr**I[i]*(2-sigma)**J[i]
+    for i, j, ni in zip(I, J, n):
+        T += ni * Pr**i * (2-sigma)**j
     return T
 
 
 def _Backward2_T_Ps(P, s):
-    """Backward equation for region 2, T=f(P,s)"""
-    sf = 5.85
-    Tsat = _TSat_P(P)
+    """Backward equation for region 2, T=f(P,s)
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+    """
     if P <= 4:
         T = _Backward2a_T_Ps(P, s)
-    elif s >= sf:
+    elif s >= 5.85:
         T = _Backward2b_T_Ps(P, s)
     else:
         T = _Backward2c_T_Ps(P, s)
-    return max(Tsat, T)
+
+    if P <= 22.064:
+        Tsat = _TSat_P(P)
+        T = max(Tsat, T)
+    return T
 
 
 def _Backward2a_P_hs(h, s):
     """Backward equation for region 2a, P=f(h,s)
 
-    >>> "%.9f" % _Backward2a_P_hs(2800,6.5)
-    '1.371012767'
-    >>> "%.12f" % _Backward2a_P_hs(2800,9.5)
-    '0.001879743844'
-    >>> "%.10f" % _Backward2a_P_hs(4100,9.5)
-    '0.1024788997'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Pressure
+    as a Function of Enthalpy and Entropy p(h,s) for Regions 1 and 2 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of
+    Water and Steam, http://www.iapws.org/relguide/Supp-PHS12-2014.pdf, Eq 3
+
+    Examples
+    --------
+    >>> _Backward2a_P_hs(2800,6.5)
+    1.371012767
+    >>> _Backward2a_P_hs(2800,9.5)
+    0.001879743844
+    >>> _Backward2a_P_hs(4100,9.5)
+    0.1024788997
     """
     I = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3,
          3, 4, 5, 5, 6, 7]
@@ -835,20 +1605,41 @@ def _Backward2a_P_hs(h, s):
     nu = h/4200
     sigma = s/12
     suma = 0
-    for i in range(29):
-        suma += n[i]*(nu-0.5)**I[i]*(sigma-1.2)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-0.5)**i * (sigma-1.2)**j
     return 4*suma**4
 
 
 def _Backward2b_P_hs(h, s):
     """Backward equation for region 2b, P=f(h,s)
 
-    >>> "%.9f" % _Backward2b_P_hs(2800,6)
-    '4.793911442'
-    >>> "%.8f" % _Backward2b_P_hs(3600,6)
-    '83.95519209'
-    >>> "%.9f" % _Backward2b_P_hs(3600,7)
-    '7.527161441'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Pressure
+    as a Function of Enthalpy and Entropy p(h,s) for Regions 1 and 2 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of
+    Water and Steam, http://www.iapws.org/relguide/Supp-PHS12-2014.pdf, Eq 4
+
+    Examples
+    --------
+    >>> _Backward2b_P_hs(2800,6)
+    4.793911442
+    >>> _Backward2b_P_hs(3600,6)
+    83.95519209
+    >>> _Backward2b_P_hs(3600,7)
+    7.527161441
     """
     I = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6,
          6, 6, 7, 7, 8, 8, 8, 8, 12, 14]
@@ -869,20 +1660,41 @@ def _Backward2b_P_hs(h, s):
     nu = h/4100
     sigma = s/7.9
     suma = 0
-    for i in range(33):
-        suma += n[i]*(nu-0.6)**I[i]*(sigma-1.01)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-0.6)**i * (sigma-1.01)**j
     return 100*suma**4
 
 
 def _Backward2c_P_hs(h, s):
     """Backward equation for region 2c, P=f(h,s)
 
-    >>> "%.8f" % _Backward2c_P_hs(2800,5.1)
-    '94.39202060'
-    >>> "%.9f" % _Backward2c_P_hs(2800,5.8)
-    '8.414574124'
-    >>> "%.8f" % _Backward2c_P_hs(3400,5.8)
-    '83.76903879'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Pressure
+    as a Function of Enthalpy and Entropy p(h,s) for Regions 1 and 2 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of
+    Water and Steam, http://www.iapws.org/relguide/Supp-PHS12-2014.pdf, Eq 5
+
+    Examples
+    --------
+    >>> _Backward2c_P_hs(2800,5.1)
+    94.39202060
+    >>> _Backward2c_P_hs(2800,5.8)
+    8.414574124
+    >>> _Backward2c_P_hs(3400,5.8)
+    83.76903879
     """
     I = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 5,
          5, 5, 5, 6, 6, 10, 12, 16]
@@ -903,13 +1715,26 @@ def _Backward2c_P_hs(h, s):
     nu = h/3500
     sigma = s/5.9
     suma = 0
-    for i in range(31):
-        suma += n[i]*(nu-0.7)**I[i]*(sigma-1.1)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-0.7)**i * (sigma-1.1)**j
     return 100*suma**4
 
 
 def _Backward2_P_hs(h, s):
-    """Backward equation for region 2, P=f(h,s)"""
+    """Backward equation for region 2, P=f(h,s)
+
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+    """
     sfbc = 5.85
     hamin = _hab_s(s)
     if h <= hamin:
@@ -925,62 +1750,87 @@ def _Backward2_P_hs(h, s):
 def _Region3(rho, T):
     """Basic equation for region 3
 
-    >>> "%.7f" % _Region3(500,650)["P"]
-    '25.5837018'
-    >>> "%.5f" % _Region3(500,650)["h"]
-    '1863.43019'
+    Parameters
+    ----------
+    rho : float
+        Density [kg/m³]
+    T : float
+        Temperature [K]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties. The available properties are:
+
+            * v: Specific volume [m³/kg]
+            * h: Specific enthalpy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * cv: Specific isocoric heat capacity [kJ/kgK]
+            * w: Speed of sound [m/s]
+            * alfav: Cubic expansion coefficient [1/K]
+            * kt: Isothermal compressibility [1/MPa]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 28
+
+    Examples
+    --------
+    >>> _Region3(500,650)["P"]
+    25.5837018
+    >>> _Region3(500,650)["h"]
+    1863.43019
     >>> p = _Region3(500, 650)
-    >>> "%.5f" % (p["h"]-p["P"]*1000*p["v"], )
-    '1812.26279'
-    >>> "%.8f" % _Region3(200,650)["s"]
-    '4.85438792'
-    >>> "%.7f" % _Region3(200,650)["cp"]
-    '44.6579342'
-    >>> "%.8f" % _Region3(200,650)["cv"]
-    '4.04118076'
-    >>> "%.6f" % _Region3(200,650)["w"]
-    '383.444594'
-    >>> "%.11f" % _Region3(500,750)["alfav"]
-    '0.00441515098'
-    >>> "%.11f" % _Region3(500,750)["kt"]
-    '0.00806710817'
-    >>> "%.11f" % _Region3(500,750)["alfap"]
-    '0.00698896514'
-    >>> "%.6f" % _Region3(500,750)["betap"]
-    '791.475213'
-    """
-
-    I = [None, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
-         3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 10, 10, 11]
-    J = [None, 0, 1, 2, 7, 10, 12, 23, 2, 6, 15, 17, 0, 2, 6, 7, 22, 26, 0, 2,
-         4, 16, 26, 0, 2, 4, 26, 1, 3, 26, 0, 2, 26, 2, 26, 2, 26, 0, 1, 26]
-    n = [0.10658070028513e1, -0.15732845290239e2, 0.20944396974307e2,
-         -0.76867707878716e1, 0.26185947787954e1, -0.28080781148620e1,
-         0.12053369696517e1, -0.84566812812502e-2, -0.12654315477714e1,
-         -0.11524407806681e1, 0.88521043984318, -0.64207765181607,
-         0.38493460186671, -0.85214708824206, 0.48972281541877e1,
-         -0.30502617256965e1, 0.39420536879154e-1, 0.12558408424308,
-         -0.27999329698710, 0.13899799569460e1, -0.20189915023570e1,
-         -0.82147637173963e-2, -0.47596035734923, 0.43984074473500e-1,
-         -0.44476435428739, 0.90572070719733, .70522450087967, .10770512626332,
-         -0.32913623258954, -0.50871062041158, -0.22175400873096e-1,
-         0.94260751665092e-1, 0.16436278447961, -0.13503372241348e-1,
-         -0.14834345352472e-1, 0.57922953628084e-3, 0.32308904703711e-2,
-         0.80964802996215e-4, -0.16557679795037e-3, -0.44923899061815e-4]
+    >>> p["h"]-p["P"]*1000*p["v"]
+    1812.26279
+    >>> _Region3(200,650)["s"]
+    4.85438792
+    >>> _Region3(200,650)["cp"]
+    44.6579342
+    >>> _Region3(200,650)["cv"]
+    4.04118076
+    >>> _Region3(200,650)["w"]
+    383.444594
+    >>> _Region3(500,750)["alfav"]
+    0.00441515098
+    >>> _Region3(500,750)["kt"]
+    0.00806710817
+    """
+
+    I = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4,
+         4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 10, 10, 11]
+    J = [0, 1, 2, 7, 10, 12, 23, 2, 6, 15, 17, 0, 2, 6, 7, 22, 26, 0, 2, 4, 16,
+         26, 0, 2, 4, 26, 1, 3, 26, 0, 2, 26, 2, 26, 2, 26, 0, 1, 26]
+    n = [-0.15732845290239e2, 0.20944396974307e2, -0.76867707878716e1,
+         0.26185947787954e1, -0.28080781148620e1, 0.12053369696517e1,
+         -0.84566812812502e-2, -0.12654315477714e1, -0.11524407806681e1,
+         0.88521043984318, -0.64207765181607, 0.38493460186671,
+         -0.85214708824206, 0.48972281541877e1, -0.30502617256965e1,
+         0.39420536879154e-1, 0.12558408424308, -0.27999329698710,
+         0.13899799569460e1, -0.20189915023570e1, -0.82147637173963e-2,
+         -0.47596035734923, 0.43984074473500e-1, -0.44476435428739,
+         0.90572070719733, .70522450087967, .10770512626332, -0.32913623258954,
+         -0.50871062041158, -0.22175400873096e-1, 0.94260751665092e-1,
+         0.16436278447961, -0.13503372241348e-1, -0.14834345352472e-1,
+         0.57922953628084e-3, 0.32308904703711e-2, 0.80964802996215e-4,
+         -0.16557679795037e-3, -0.44923899061815e-4]
 
     d = rho/rhoc
     Tr = Tc/T
-    g = n[0]*log(d)
-    gd = n[0]*d**-1
-    gdd = -n[0]*d**-2
+    g = 1.0658070028513*log(d)
+    gd = 1.0658070028513/d
+    gdd = -1.0658070028513/d**2
     gt = gtt = gdt = 0
-    for i in range(1, 40):
-        g += n[i]*d**I[i]*Tr**J[i]
-        gd += n[i]*I[i]*d**(I[i]-1)*Tr**J[i]
-        gdd += n[i]*I[i]*(I[i]-1)*d**(I[i]-2)*Tr**J[i]
-        gt += n[i] * d**I[i] * J[i] * Tr**(J[i]-1)
-        gtt += n[i]*d**I[i]*J[i]*(J[i]-1)*Tr**(J[i]-2)
-        gdt += n[i]*I[i]*d**(I[i]-1)*J[i]*Tr**(J[i]-1)
+    for i, j, ni in zip(I, J, n):
+        g += ni * d**i * Tr**j
+        gd += ni*i * d**(i-1) * Tr**j
+        gdd += ni*i*(i-1) * d**(i-2) * Tr**j
+        gt += ni*j * d**i * Tr**(j-1)
+        gtt += ni*j*(j-1) * d**i * Tr**(j-2)
+        gdt += ni*i*j * d**(i-1) * Tr**(j-1)
 
     propiedades = {}
     propiedades["T"] = T
@@ -994,8 +1844,6 @@ def _Region3(rho, T):
                                       Tr**2/gtt))
     propiedades["alfav"] = (gd-Tr*gdt)/(2*gd+d*gdd)/T
     propiedades["kt"] = 1/(2*d*gd+d**2*gdd)/rho/R/T*1000
-    propiedades["alfap"] = (1-Tr*gdt/gd)/T
-    propiedades["betap"] = rho*(2+d*gdd/gd)
     propiedades["region"] = 3
     propiedades["x"] = 1
     return propiedades
@@ -1004,8 +1852,20 @@ def _Region3(rho, T):
 def _h_3ab(P):
     """Define the boundary between Region 3a-3b, h=f(P)
 
-    >>> "%.6f" % _h_3ab(25)
-    '2095.936454'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Examples
+    --------
+    >>> _h_3ab(25)
+    2095.936454
     """
     return 0.201464004206875e4 + 3.74696550136983*P - \
         0.0219921901054187*P**2+0.875131686009950e-4*P**3
@@ -1014,8 +1874,27 @@ def _h_3ab(P):
 def _tab_P(P):
     """Define the boundary between Region 3a-3b, T=f(P)
 
-    >>> "%.7f" % _tab_P(40)
-    '693.0341408'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Specific
+    Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water
+    and Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf, Eq. 2
+
+    Examples
+    --------
+    >>> _tab_P(40)
+    693.0341408
     """
     I = [0, 1, 2, -1, -2]
     n = [0.154793642129415e4, -0.187661219490113e3, 0.213144632222113e2,
@@ -1023,16 +1902,35 @@ def _tab_P(P):
 
     Pr = P/1
     T = 0
-    for i in range(5):
-        T += n[i]*log(Pr)**I[i]
+    for i, ni in zip(I, n):
+        T += ni * log(Pr)**i
     return T
 
 
 def _top_P(P):
     """Define the boundary between Region 3o-3p, T=f(P)
 
-    >>> "%.7f" % _top_P(22.8)
-    '650.0106943'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Specific
+    Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water
+    and Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf, Eq. 2
+
+    Examples
+    --------
+    >>> _top_P(22.8)
+    650.0106943
     """
     I = [0, 1, 2, -1, -2]
     n = [0.969461372400213e3, -0.332500170441278e3, 0.642859598466067e2,
@@ -1040,16 +1938,35 @@ def _top_P(P):
 
     Pr = P/1
     T = 0
-    for i in range(5):
-        T += n[i]*log(Pr)**I[i]
+    for i, ni in zip(I, n):
+        T += ni * log(Pr)**i
     return T
 
 
 def _twx_P(P):
     """Define the boundary between Region 3w-3x, T=f(P)
 
-    >>> "%.7f" % _twx_P(22.3)
-    '648.2049480'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Specific
+    Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water
+    and Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf, Eq. 2
+
+    Examples
+    --------
+    >>> _twx_P(22.3)
+    648.2049480
     """
     I = [0, 1, 2, -1, -2]
     n = [0.728052609145380e1, 0.973505869861952e2, 0.147370491183191e2,
@@ -1057,40 +1974,79 @@ def _twx_P(P):
 
     Pr = P/1
     T = 0
-    for i in range(5):
-        T += n[i]*log(Pr)**I[i]
+    for i, ni in zip(I, n):
+        T += ni * log(Pr)**i
     return T
 
 
 def _tef_P(P):
     """Define the boundary between Region 3e-3f, T=f(P)
 
-    >>> "%.7f" % _tef_P(40)
-    '713.9593992'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Specific
+    Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water
+    and Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf, Eq. 3
+
+    Examples
+    --------
+    >>> _tef_P(40)
+    713.9593992
     """
     return 3.727888004*(P-22.064)+647.096
 
 
-def _txx_P(P, xx):
+def _txx_P(P, xy):
     """Define the boundary between 3x-3y, T=f(P)
-    where xx represent the subregions options: cd, gh, ij, jk, mn, qu, rx, uv
-
-    >>> "%.7f" % _txx_P(25,"cd")
-    '649.3659208'
-    >>> "%.7f" % _txx_P(23,"gh")
-    '649.8873759'
-    >>> "%.7f" % _txx_P(23,"ij")
-    '651.5778091'
-    >>> "%.7f" % _txx_P(23,"jk")
-    '655.8338344'
-    >>> "%.7f" % _txx_P(22.8,"mn")
-    '649.6054133'
-    >>> "%.7f" % _txx_P(22,"qu")
-    '645.6355027'
-    >>> "%.7f" % _txx_P(22,"rx")
-    '648.2622754'
-    >>> "%.7f" % _txx_P(22.3,"uv")
-    '647.7996121'
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    xy: string
+        Subregions options: cd, gh, ij, jk, mn, qu, rx, uv
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Specific
+    Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water
+    and Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf, Eq. 1
+
+    Examples
+    --------
+    >>> _txx_P(25,"cd")
+    649.3659208
+    >>> _txx_P(23,"gh")
+    649.8873759
+    >>> _txx_P(23,"ij")
+    651.5778091
+    >>> _txx_P(23,"jk")
+    655.8338344
+    >>> _txx_P(22.8,"mn")
+    649.6054133
+    >>> _txx_P(22,"qu")
+    645.6355027
+    >>> _txx_P(22,"rx")
+    648.2622754
+    >>> _txx_P(22.3,"uv")
+    647.7996121
     """
     ng = {
         "cd": [0.585276966696349e3, 0.278233532206915e1, -0.127283549295878e-1,
@@ -1110,21 +2066,42 @@ def _txx_P(P, xx):
         "uv": [0.528199646263062e3, 0.890579602135307e1, -0.222814134903755,
                0.286791682263697e-2]}
 
-    n = ng[xx]
+    n = ng[xy]
     Pr = P/1
     T = 0
-    for i in range(len(n)):
-        T += n[i]*Pr**i
+    for i, ni in enumerate(n):
+        T += ni * Pr**i
     return T
 
 
 def _Backward3a_v_Ph(P, h):
     """Backward equation for region 3a, v=f(P,h)
 
-    >>> "%.12f" % _Backward3a_v_Ph(20,1700)
-    '0.001749903962'
-    >>> "%.12f" % _Backward3a_v_Ph(100,2100)
-    '0.001676229776'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 4
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+
+    Examples
+    --------
+    >>> _Backward3a_v_Ph(20,1700)
+    0.001749903962
+    >>> _Backward3a_v_Ph(100,2100)
+    0.001676229776
     """
     I = [-12, -12, -12, -12, -10, -10, -10, -8, -8, -6, -6, -6, -4, -4, -3, -2,
          -2, -1, -1, -1, -1, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 8]
@@ -1145,18 +2122,39 @@ def _Backward3a_v_Ph(P, h):
     Pr = P/100
     nu = h/2100
     suma = 0
-    for i in range(32):
-        suma += n[i]*(Pr+0.128)**I[i]*(nu-0.727)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (Pr+0.128)**i * (nu-0.727)**j
     return 0.0028*suma
 
 
 def _Backward3b_v_Ph(P, h):
     """Backward equation for region 3b, v=f(P,h)
 
-    >>> "%.12f" % _Backward3b_v_Ph(20,2500)
-    '0.006670547043'
-    >>> "%.12f" % _Backward3b_v_Ph(100,2700)
-    '0.002404234998'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 5
+
+    Examples
+    --------
+    >>> _Backward3b_v_Ph(20,2500)
+    0.006670547043
+    >>> _Backward3b_v_Ph(100,2700)
+    0.002404234998
     """
     I = [-12, -12, -8, -8, -8, -8, -8, -8, -6, -6, -6, -6, -6, -6, -4, -4, -4,
          -3, -3, -2, -2, -1, -1, -1, -1, 0, 1, 1, 2, 2]
@@ -1176,13 +2174,26 @@ def _Backward3b_v_Ph(P, h):
     Pr = P/100
     nu = h/2800
     suma = 0
-    for i in range(30):
-        suma += n[i]*(Pr+0.0661)**I[i]*(nu-0.72)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (Pr+0.0661)**i * (nu-0.72)**j
     return 0.0088*suma
 
 
 def _Backward3_v_Ph(P, h):
-    """Backward equation for region 3, v=f(P,h)"""
+    """Backward equation for region 3, v=f(P,h)
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+    """
     hf = _h_3ab(P)
     if h <= hf:
         return _Backward3a_v_Ph(P, h)
@@ -1193,10 +2204,31 @@ def _Backward3_v_Ph(P, h):
 def _Backward3a_T_Ph(P, h):
     """Backward equation for region 3a, T=f(P,h)
 
-    >>> "%.7f" % _Backward3a_T_Ph(20,1700)
-    '629.3083892'
-    >>> "%.7f" % _Backward3a_T_Ph(100,2100)
-    '733.6163014'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 2
+
+    Examples
+    --------
+    >>> _Backward3a_T_Ph(20,1700)
+    629.3083892
+    >>> _Backward3a_T_Ph(100,2100)
+    733.6163014
     """
     I = [-12, -12, -12, -12, -12, -12, -12, -12, -10, -10, -10, -8, -8, -8, -8,
          -5, -3, -2, -2, -2, -1, -1, 0, 0, 1, 3, 3, 4, 4, 10, 12]
@@ -1225,10 +2257,31 @@ def _Backward3a_T_Ph(P, h):
 def _Backward3b_T_Ph(P, h):
     """Backward equation for region 3b, T=f(P,h)
 
-    >>> "%.7f" % _Backward3b_T_Ph(20,2500)
-    '641.8418053'
-    >>> "%.7f" % _Backward3b_T_Ph(100,2700)
-    '842.0460876'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 3
+
+    Examples
+    --------
+    >>> _Backward3b_T_Ph(20,2500)
+    641.8418053
+    >>> _Backward3b_T_Ph(100,2700)
+    842.0460876
     """
     I = [-12, -12, -10, -10, -10, -10, -10, -8, -8, -8, -8, -8, -6, -6, -6, -4,
          -4, -3, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 1, 3, 5, 6, 8]
@@ -1255,7 +2308,20 @@ def _Backward3b_T_Ph(P, h):
 
 
 def _Backward3_T_Ph(P, h):
-    """Backward equation for region 3, T=f(P,h)"""
+    """Backward equation for region 3, T=f(P,h)
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+    """
     hf = _h_3ab(P)
     if h <= hf:
         T = _Backward3a_T_Ph(P, h)
@@ -1267,10 +2333,31 @@ def _Backward3_T_Ph(P, h):
 def _Backward3a_v_Ps(P, s):
     """Backward equation for region 3a, v=f(P,s)
 
-    >>> "%.12f" % _Backward3a_v_Ps(20,3.8)
-    '0.001733791463'
-    >>> "%.12f" % _Backward3a_v_Ps(100,4)
-    '0.001555893131'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 8
+
+    Examples
+    --------
+    >>> _Backward3a_v_Ps(20,3.8)
+    0.001733791463
+    >>> _Backward3a_v_Ps(100,4)
+    0.001555893131
     """
     I = [-12, -12, -12, -10, -10, -10, -10, -8, -8, -8, -8, -6, -5, -4, -3, -3,
          -2, -2, -1, -1, 0, 0, 0, 1, 2, 4, 5, 6]
@@ -1290,18 +2377,39 @@ def _Backward3a_v_Ps(P, s):
     Pr = P/100
     sigma = s/4.4
     suma = 0
-    for i in range(28):
-        suma += n[i]*(Pr+0.187)**I[i]*(sigma-0.755)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (Pr+0.187)**i * (sigma-0.755)**j
     return 0.0028*suma
 
 
 def _Backward3b_v_Ps(P, s):
     """Backward equation for region 3b, v=f(P,s)
 
-    >>> "%.12f" % _Backward3b_v_Ps(20,5)
-    '0.006262101987'
-    >>> "%.12f" % _Backward3b_v_Ps(100,5)
-    '0.002449610757'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 9
+
+    Examples
+    --------
+    >>> _Backward3b_v_Ps(20,5)
+    0.006262101987
+    >>> _Backward3b_v_Ps(100,5)
+    0.002449610757
     """
     I = [-12, -12, -12, -12, -12, -12, -10, -10, -10, -10, -8, -5, -5, -5, -4,
          -4, -4, -4, -3, -2, -2, -2, -2, -2, -2, 0, 0, 0, 1, 1, 2]
@@ -1322,13 +2430,26 @@ def _Backward3b_v_Ps(P, s):
     Pr = P/100
     sigma = s/5.3
     suma = 0
-    for i in range(31):
-        suma += n[i]*(Pr+0.298)**I[i]*(sigma-0.816)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (Pr+0.298)**i * (sigma-0.816)**j
     return 0.0088*suma
 
 
 def _Backward3_v_Ps(P, s):
-    """Backward equation for region 3, v=f(P,s)"""
+    """Backward equation for region 3, v=f(P,s)
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+    """
     if s <= sc:
         return _Backward3a_v_Ps(P, s)
     else:
@@ -1338,10 +2459,31 @@ def _Backward3_v_Ps(P, s):
 def _Backward3a_T_Ps(P, s):
     """Backward equation for region 3a, T=f(P,s)
 
-    >>> "%.7f" % _Backward3a_T_Ps(20,3.8)
-    '628.2959869'
-    >>> "%.7f" % _Backward3a_T_Ps(100,4)
-    '705.6880237'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 6
+
+    Examples
+    --------
+    >>> _Backward3a_T_Ps(20,3.8)
+    628.2959869
+    >>> _Backward3a_T_Ps(100,4)
+    705.6880237
     """
     I = [-12, -12, -10, -10, -10, -10, -8, -8, -8, -8, -6, -6, -6, -5, -5, -5,
          -4, -4, -4, -2, -2, -1, -1, 0, 0, 0, 1, 2, 2, 3, 8, 8, 10]
@@ -1362,18 +2504,39 @@ def _Backward3a_T_Ps(P, s):
     Pr = P/100
     sigma = s/4.4
     suma = 0
-    for i in range(33):
-        suma += n[i]*(Pr+0.240)**I[i]*(sigma-0.703)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (Pr+0.240)**i * (sigma-0.703)**j
     return 760*suma
 
 
 def _Backward3b_T_Ps(P, s):
     """Backward equation for region 3b, T=f(P,s)
 
-    >>> "%.7f" % _Backward3b_T_Ps(20,5)
-    '640.1176443'
-    >>> "%.7f" % _Backward3b_T_Ps(100,5)
-    '847.4332825'
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for the
+    Functions T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS
+    Industrial Formulation 1997 for the Thermodynamic Properties of Water and
+    Steam, http://www.iapws.org/relguide/Supp-Tv%28ph,ps%293-2014.pdf, Eq 7
+
+    Examples
+    --------
+    >>> _Backward3b_T_Ps(20,5)
+    640.1176443
+    >>> _Backward3b_T_Ps(100,5)
+    847.4332825
     """
     I = [-12, -12, -12, -12, -8, -8, -8, -6, -6, -6, -5, -5, -5, -5, -5, -4,
          -3, -3, -2, 0, 2, 3, 4, 5, 6, 8, 12, 14]
@@ -1393,13 +2556,26 @@ def _Backward3b_T_Ps(P, s):
     Pr = P/100
     sigma = s/5.3
     suma = 0
-    for i in range(28):
-        suma += n[i]*(Pr+0.760)**I[i]*(sigma-0.818)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (Pr+0.760)**i * (sigma-0.818)**j
     return 860*suma
 
 
 def _Backward3_T_Ps(P, s):
-    """Backward equation for region 3, T=f(P,s)"""
+    """Backward equation for region 3, T=f(P,s)
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+    """
     sc = 4.41202148223476
     if s <= sc:
         T = _Backward3a_T_Ps(P, s)
@@ -1411,12 +2587,34 @@ def _Backward3_T_Ps(P, s):
 def _Backward3a_P_hs(h, s):
     """Backward equation for region 3a, P=f(h,s)
 
-    >>> "%.8f" % _Backward3a_P_hs(1700,3.8)
-    '25.55703246'
-    >>> "%.8f" % _Backward3a_P_hs(2000,4.2)
-    '45.40873468'
-    >>> "%.8f" % _Backward3a_P_hs(2100,4.3)
-    '60.78123340'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 1
+
+    Examples
+    --------
+    >>> _Backward3a_P_hs(1700,3.8)
+    25.55703246
+    >>> _Backward3a_P_hs(2000,4.2)
+    45.40873468
+    >>> _Backward3a_P_hs(2100,4.3)
+    60.78123340
     """
     I = [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 6, 7, 8, 10, 10,
          14, 18, 20, 22, 22, 24, 28, 28, 32, 32]
@@ -1437,20 +2635,42 @@ def _Backward3a_P_hs(h, s):
     nu = h/2300
     sigma = s/4.4
     suma = 0
-    for i in range(33):
-        suma += n[i]*(nu-1.01)**I[i]*(sigma-0.75)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-1.01)**i * (sigma-0.75)**j
     return 99*suma
 
 
 def _Backward3b_P_hs(h, s):
     """Backward equation for region 3b, P=f(h,s)
 
-    >>> "%.8f" % _Backward3b_P_hs(2400,4.7)
-    '63.63924887'
-    >>> "%.8f" % _Backward3b_P_hs(2600,5.1)
-    '34.34999263'
-    >>> "%.8f" % _Backward3b_P_hs(2700,5.0)
-    '88.39043281'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 1
+
+    Examples
+    --------
+    >>> _Backward3b_P_hs(2400,4.7)
+    63.63924887
+    >>> _Backward3b_P_hs(2600,5.1)
+    34.34999263
+    >>> _Backward3b_P_hs(2700,5.0)
+    88.39043281
     """
     I = [-12, -12, -12, -12, -12, -10, -10, -10, -10, -8, -8, -6, -6, -6, -6,
          -5, -4, -4, -4, -3, -3, -3, -3, -2, -2, -1, 0, 2, 2, 5, 6, 8, 10, 14,
@@ -1473,13 +2693,26 @@ def _Backward3b_P_hs(h, s):
     nu = h/2800
     sigma = s/5.3
     suma = 0
-    for i in range(35):
-        suma += n[i]*(nu-0.681)**I[i]*(sigma-0.792)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-0.681)**i * (sigma-0.792)**j
     return 16.6/suma
 
 
 def _Backward3_P_hs(h, s):
-    """Backward equation for region 3, P=f(h,s)"""
+    """Backward equation for region 3, P=f(h,s)
+
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    P : float
+        Pressure [MPa]
+    """
     sc = 4.41202148223476
     if s <= sc:
         return _Backward3a_P_hs(h, s)
@@ -1489,7 +2722,25 @@ def _Backward3_P_hs(h, s):
 
 def _Backward3_sat_v_P(P, T, x):
     """Backward equation for region 3 for saturated state, vs=f(P,x)
-    x 0,1 vapor quality"""
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    x : integer
+        Vapor quality [-]
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+
+    Notes
+    -----
+    The vapor quality (x) can be 0 (saturated liquid) or 1 (saturated vapour)
+    """
     if x == 0:
         if P < 19.00881189:
             region = "c"
@@ -1513,7 +2764,27 @@ def _Backward3_sat_v_P(P, T, x):
 
 
 def _Backward3_v_PT(P, T):
-    """Backward equation for region 3, v=f(P,T)"""
+    """Backward equation for region 3, v=f(P,T)
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Specific
+    Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water
+    and Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf, Table 2 and 10
+    """
     if P > 40:
         if T <= _tab_P(P):
             region = "a"
@@ -1601,6 +2872,7 @@ def _Backward3_v_PT(P, T):
         elif tcd < T <= tqu:
             region = "q"
         elif tqu < T <= trx:
+            # Table 10
             tef = _tef_P(P)
             twx = _twx_P(P)
             tuv = _txx_P(P, "uv")
@@ -1654,7 +2926,7 @@ def _Backward3_v_PT(P, T):
             region = "r"
         else:
             region = "k"
-    elif 19.00881189 < P <= 20.5:
+    elif 19.00881189173929 < P <= 20.5:
         tcd = _txx_P(P, "cd")
         Ts = _TSat_P(P)
         if T <= tcd:
@@ -1663,7 +2935,7 @@ def _Backward3_v_PT(P, T):
             region = "s"
         else:
             region = "t"
-    elif Ps_623 < P <= 19.00881189:
+    elif Ps_623 < P <= 19.00881189173929:
         Ts = _TSat_P(P)
         if T <= Ts:
             region = "c"
@@ -1676,138 +2948,161 @@ def _Backward3_v_PT(P, T):
 def _Backward3x_v_PT(T, P, x):
     """Backward equation for region 3x, v=f(P,T)
 
-    >>> "%.12f" % _Backward3x_v_PT(630,50,"a")
-    '0.001470853100'
-    >>> "%.12f" % _Backward3x_v_PT(670,80,"a")
-    '0.001503831359'
-    >>> "%.12f" % _Backward3x_v_PT(710,50,"b")
-    '0.002204728587'
-    >>> "%.12f" % _Backward3x_v_PT(750,80,"b")
-    '0.001973692940'
-    >>> "%.12f" % _Backward3x_v_PT(630,20,"c")
-    '0.001761696406'
-    >>> "%.12f" % _Backward3x_v_PT(650,30,"c")
-    '0.001819560617'
-    >>> "%.12f" % _Backward3x_v_PT(656,26,"d")
-    '0.002245587720'
-    >>> "%.12f" % _Backward3x_v_PT(670,30,"d")
-    '0.002506897702'
-    >>> "%.12f" % _Backward3x_v_PT(661,26,"e")
-    '0.002970225962'
-    >>> "%.12f" % _Backward3x_v_PT(675,30,"e")
-    '0.003004627086'
-    >>> "%.12f" % _Backward3x_v_PT(671,26,"f")
-    '0.005019029401'
-    >>> "%.12f" % _Backward3x_v_PT(690,30,"f")
-    '0.004656470142'
-    >>> "%.12f" % _Backward3x_v_PT(649,23.6,"g")
-    '0.002163198378'
-    >>> "%.12f" % _Backward3x_v_PT(650,24,"g")
-    '0.002166044161'
-    >>> "%.12f" % _Backward3x_v_PT(652,23.6,"h")
-    '0.002651081407'
-    >>> "%.12f" % _Backward3x_v_PT(654,24,"h")
-    '0.002967802335'
-    >>> "%.12f" % _Backward3x_v_PT(653,23.6,"i")
-    '0.003273916816'
-    >>> "%.12f" % _Backward3x_v_PT(655,24,"i")
-    '0.003550329864'
-    >>> "%.12f" % _Backward3x_v_PT(655,23.5,"j")
-    '0.004545001142'
-    >>> "%.12f" % _Backward3x_v_PT(660,24,"j")
-    '0.005100267704'
-    >>> "%.12f" % _Backward3x_v_PT(660,23,"k")
-    '0.006109525997'
-    >>> "%.12f" % _Backward3x_v_PT(670,24,"k")
-    '0.006427325645'
-    >>> "%.12f" % _Backward3x_v_PT(646,22.6,"l")
-    '0.002117860851'
-    >>> "%.12f" % _Backward3x_v_PT(646,23,"l")
-    '0.002062374674'
-    >>> "%.12f" % _Backward3x_v_PT(648.6,22.6,"m")
-    '0.002533063780'
-    >>> "%.12f" % _Backward3x_v_PT(649.3,22.8,"m")
-    '0.002572971781'
-    >>> "%.12f" % _Backward3x_v_PT(649,22.6,"n")
-    '0.002923432711'
-    >>> "%.12f" % _Backward3x_v_PT(649.7,22.8,"n")
-    '0.002913311494'
-    >>> "%.12f" % _Backward3x_v_PT(649.1,22.6,"o")
-    '0.003131208996'
-    >>> "%.12f" % _Backward3x_v_PT(649.9,22.8,"o")
-    '0.003221160278'
-    >>> "%.12f" % _Backward3x_v_PT(649.4,22.6,"p")
-    '0.003715596186'
-    >>> "%.12f" % _Backward3x_v_PT(650.2,22.8,"p")
-    '0.003664754790'
-    >>> "%.12f" % _Backward3x_v_PT(640,21.1,"q")
-    '0.001970999272'
-    >>> "%.12f" % _Backward3x_v_PT(643,21.8,"q")
-    '0.002043919161'
-    >>> "%.12f" % _Backward3x_v_PT(644,21.1,"r")
-    '0.005251009921'
-    >>> "%.12f" % _Backward3x_v_PT(648,21.8,"r")
-    '0.005256844741'
-    >>> "%.12f" % _Backward3x_v_PT(635,19.1,"s")
-    '0.001932829079'
-    >>> "%.12f" % _Backward3x_v_PT(638,20,"s")
-    '0.001985387227'
-    >>> "%.12f" % _Backward3x_v_PT(626,17,"t")
-    '0.008483262001'
-    >>> "%.12f" % _Backward3x_v_PT(640,20,"t")
-    '0.006227528101'
-    >>> "%.12f" % _Backward3x_v_PT(644.6,21.5,"u")
-    '0.002268366647'
-    >>> "%.12f" % _Backward3x_v_PT(646.1,22,"u")
-    '0.002296350553'
-    >>> "%.12f" % _Backward3x_v_PT(648.6,22.5,"v")
-    '0.002832373260'
-    >>> "%.12f" % _Backward3x_v_PT(647.9,22.3,"v")
-    '0.002811424405'
-    >>> "%.12f" % _Backward3x_v_PT(647.5,22.15,"w")
-    '0.003694032281'
-    >>> "%.12f" % _Backward3x_v_PT(648.1,22.3,"w")
-    '0.003622226305'
-    >>> "%.12f" % _Backward3x_v_PT(648,22.11,"x")
-    '0.004528072649'
-    >>> "%.12f" % _Backward3x_v_PT(649,22.3,"x")
-    '0.004556905799'
-    >>> "%.12f" % _Backward3x_v_PT(646.84,22,"y")
-    '0.002698354719'
-    >>> "%.12f" % _Backward3x_v_PT(647.05,22.064,"y")
-    '0.002717655648'
-    >>> "%.12f" % _Backward3x_v_PT(646.89,22,"z")
-    '0.003798732962'
-    >>> "%.12f" % _Backward3x_v_PT(647.15,22.064,"z")
-    '0.003701940009'
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    x : char
+        Region 3 subregion code
+
+    Returns
+    -------
+    v : float
+        Specific volume [m³/kg]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations for Specific
+    Volume as a Function of Pressure and Temperature v(p,T) for Region 3 of the
+    IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water
+    and Steam, http://www.iapws.org/relguide/Supp-VPT3-2016.pdf, Eq. 4-5
+
+    Examples
+    --------
+    >>> _Backward3x_v_PT(630,50,"a")
+    0.001470853100
+    >>> _Backward3x_v_PT(670,80,"a")
+    0.001503831359
+    >>> _Backward3x_v_PT(710,50,"b")
+    0.002204728587
+    >>> _Backward3x_v_PT(750,80,"b")
+    0.001973692940
+    >>> _Backward3x_v_PT(630,20,"c")
+    0.001761696406
+    >>> _Backward3x_v_PT(650,30,"c")
+    0.001819560617
+    >>> _Backward3x_v_PT(656,26,"d")
+    0.002245587720
+    >>> _Backward3x_v_PT(670,30,"d")
+    0.002506897702
+    >>> _Backward3x_v_PT(661,26,"e")
+    0.002970225962
+    >>> _Backward3x_v_PT(675,30,"e")
+    0.003004627086
+    >>> _Backward3x_v_PT(671,26,"f")
+    0.005019029401
+    >>> _Backward3x_v_PT(690,30,"f")
+    0.004656470142
+    >>> _Backward3x_v_PT(649,23.6,"g")
+    0.002163198378
+    >>> _Backward3x_v_PT(650,24,"g")
+    0.002166044161
+    >>> _Backward3x_v_PT(652,23.6,"h")
+    0.002651081407
+    >>> _Backward3x_v_PT(654,24,"h")
+    0.002967802335
+    >>> _Backward3x_v_PT(653,23.6,"i")
+    0.003273916816
+    >>> _Backward3x_v_PT(655,24,"i")
+    0.003550329864
+    >>> _Backward3x_v_PT(655,23.5,"j")
+    0.004545001142
+    >>> _Backward3x_v_PT(660,24,"j")
+    0.005100267704
+    >>> _Backward3x_v_PT(660,23,"k")
+    0.006109525997
+    >>> _Backward3x_v_PT(670,24,"k")
+    0.006427325645
+    >>> _Backward3x_v_PT(646,22.6,"l")
+    0.002117860851
+    >>> _Backward3x_v_PT(646,23,"l")
+    0.002062374674
+    >>> _Backward3x_v_PT(648.6,22.6,"m")
+    0.002533063780
+    >>> _Backward3x_v_PT(649.3,22.8,"m")
+    0.002572971781
+    >>> _Backward3x_v_PT(649,22.6,"n")
+    0.002923432711
+    >>> _Backward3x_v_PT(649.7,22.8,"n")
+    0.002913311494
+    >>> _Backward3x_v_PT(649.1,22.6,"o")
+    0.003131208996
+    >>> _Backward3x_v_PT(649.9,22.8,"o")
+    0.003221160278
+    >>> _Backward3x_v_PT(649.4,22.6,"p")
+    0.003715596186
+    >>> _Backward3x_v_PT(650.2,22.8,"p")
+    0.003664754790
+    >>> _Backward3x_v_PT(640,21.1,"q")
+    0.001970999272
+    >>> _Backward3x_v_PT(643,21.8,"q")
+    0.002043919161
+    >>> _Backward3x_v_PT(644,21.1,"r")
+    0.005251009921
+    >>> _Backward3x_v_PT(648,21.8,"r")
+    0.005256844741
+    >>> _Backward3x_v_PT(635,19.1,"s")
+    0.001932829079
+    >>> _Backward3x_v_PT(638,20,"s")
+    0.001985387227
+    >>> _Backward3x_v_PT(626,17,"t")
+    0.008483262001
+    >>> _Backward3x_v_PT(640,20,"t")
+    0.006227528101
+    >>> _Backward3x_v_PT(644.6,21.5,"u")
+    0.002268366647
+    >>> _Backward3x_v_PT(646.1,22,"u")
+    0.002296350553
+    >>> _Backward3x_v_PT(648.6,22.5,"v")
+    0.002832373260
+    >>> _Backward3x_v_PT(647.9,22.3,"v")
+    0.002811424405
+    >>> _Backward3x_v_PT(647.5,22.15,"w")
+    0.003694032281
+    >>> _Backward3x_v_PT(648.1,22.3,"w")
+    0.003622226305
+    >>> _Backward3x_v_PT(648,22.11,"x")
+    0.004528072649
+    >>> _Backward3x_v_PT(649,22.3,"x")
+    0.004556905799
+    >>> _Backward3x_v_PT(646.84,22,"y")
+    0.002698354719
+    >>> _Backward3x_v_PT(647.05,22.064,"y")
+    0.002717655648
+    >>> _Backward3x_v_PT(646.89,22,"z")
+    0.003798732962
+    >>> _Backward3x_v_PT(647.15,22.064,"z")
+    0.003701940009
     """
     par = {
-        "a": [0.0024, 100, 760, 30, 0.085, 0.817, 1, 1, 1],
-        "b": [0.0041, 100, 860, 32, 0.280, 0.779, 1, 1, 1],
-        "c": [0.0022, 40, 690, 35, 0.259, 0.903, 1, 1, 1],
-        "d": [0.0029, 40, 690, 38, 0.559, 0.939, 1, 1, 4],
-        "e": [0.0032, 40, 710, 29, 0.587, 0.918, 1, 1, 1],
-        "f": [0.0064, 40, 730, 42, 0.587, 0.891, 0.5, 1, 4],
-        "g": [0.0027, 25, 660, 38, 0.872, 0.971, 1, 1, 4],
-        "h": [0.0032, 25, 660, 29, 0.898, 0.983, 1, 1, 4],
-        "i": [0.0041, 25, 660, 42, 0.910, 0.984, 0.5, 1, 4],
-        "j": [0.0054, 25, 670, 29, 0.875, 0.964, 0.5, 1, 4],
-        "k": [0.0077, 25, 680, 34, 0.802, 0.935, 1, 1, 1],
-        "l": [0.0026, 24, 650, 43, 0.908, 0.989, 1, 1, 4],
-        "m": [0.0028, 23, 650, 40, 1.000, 0.997, 1, 0.25, 1],
-        "n": [0.0031, 23, 650, 39, 0.976, 0.997, None, None, None],
-        "o": [0.0034, 23, 650, 24, 0.974, 0.996, 0.5, 1, 1],
-        "p": [0.0041, 23, 650, 27, 0.972, 0.997, 0.5, 1, 1],
-        "q": [0.0022, 23, 650, 24, 0.848, 0.983, 1, 1, 4],
-        "r": [0.0054, 23, 650, 27, 0.874, 0.982, 1, 1, 1],
-        "s": [0.0022, 21, 640, 29, 0.886, 0.990, 1, 1, 4],
-        "t": [0.0088, 20, 650, 33, 0.803, 1.020, 1, 1, 1],
-        "u": [0.0026, 23, 650, 38, 0.902, 0.988, 1, 1, 1],
-        "v": [0.0031, 23, 650, 39, 0.960, 0.995, 1, 1, 1],
-        "w": [0.0039, 23, 650, 35, 0.959, 0.995, 1, 1, 4],
-        "x": [0.0049, 23, 650, 36, 0.910, 0.988, 1, 1, 1],
-        "y": [0.0031, 22, 650, 20, 0.996, 0.994, 1, 1, 4],
-        "z": [0.0038, 22, 650, 23, 0.993, 0.994, 1, 1, 4],
+        "a": [0.0024, 100, 760, 0.085, 0.817, 1, 1, 1],
+        "b": [0.0041, 100, 860, 0.280, 0.779, 1, 1, 1],
+        "c": [0.0022, 40, 690, 0.259, 0.903, 1, 1, 1],
+        "d": [0.0029, 40, 690, 0.559, 0.939, 1, 1, 4],
+        "e": [0.0032, 40, 710, 0.587, 0.918, 1, 1, 1],
+        "f": [0.0064, 40, 730, 0.587, 0.891, 0.5, 1, 4],
+        "g": [0.0027, 25, 660, 0.872, 0.971, 1, 1, 4],
+        "h": [0.0032, 25, 660, 0.898, 0.983, 1, 1, 4],
+        "i": [0.0041, 25, 660, 0.910, 0.984, 0.5, 1, 4],
+        "j": [0.0054, 25, 670, 0.875, 0.964, 0.5, 1, 4],
+        "k": [0.0077, 25, 680, 0.802, 0.935, 1, 1, 1],
+        "l": [0.0026, 24, 650, 0.908, 0.989, 1, 1, 4],
+        "m": [0.0028, 23, 650, 1.000, 0.997, 1, 0.25, 1],
+        "n": [0.0031, 23, 650, 0.976, 0.997, None, None, None],
+        "o": [0.0034, 23, 650, 0.974, 0.996, 0.5, 1, 1],
+        "p": [0.0041, 23, 650, 0.972, 0.997, 0.5, 1, 1],
+        "q": [0.0022, 23, 650, 0.848, 0.983, 1, 1, 4],
+        "r": [0.0054, 23, 650, 0.874, 0.982, 1, 1, 1],
+        "s": [0.0022, 21, 640, 0.886, 0.990, 1, 1, 4],
+        "t": [0.0088, 20, 650, 0.803, 1.020, 1, 1, 1],
+        "u": [0.0026, 23, 650, 0.902, 0.988, 1, 1, 1],
+        "v": [0.0031, 23, 650, 0.960, 0.995, 1, 1, 1],
+        "w": [0.0039, 23, 650, 0.959, 0.995, 1, 1, 4],
+        "x": [0.0049, 23, 650, 0.910, 0.988, 1, 1, 1],
+        "y": [0.0031, 22, 650, 0.996, 0.994, 1, 1, 4],
+        "z": [0.0038, 22, 650, 0.993, 0.994, 1, 1, 4],
         }
 
     I = {
@@ -2243,24 +3538,44 @@ def _Backward3x_v_PT(T, P, x):
     I = I[x]
     J = J[x]
     n = n[x]
-    v_, P_, T_, N, a, b, c, d, e = par[x]
+    v_, P_, T_, a, b, c, d, e = par[x]
 
     Pr = P/P_
     Tr = T/T_
     suma = 0
     if x == "n":
-        for i in range(N):
-            suma += n[i]*(Pr-a)**I[i]*(Tr-b)**J[i]
+        for i, j, ni in zip(I, J, n):
+            suma += ni * (Pr-a)**i * (Tr-b)**j
         return v_*exp(suma)
     else:
-        for i in range(N):
-            suma += n[i]*(Pr-a)**(c*I[i])*(Tr-b)**(J[i]*d)
+        for i, j, ni in zip(I, J, n):
+            suma += ni * (Pr-a)**(c*i) * (Tr-b)**(j*d)
         return v_*suma**e
 
 
 # Region 4
 def _Region4(P, x):
-    """Basic equation for region 4"""
+    """Basic equation for region 4
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    x : float
+        Vapor quality [-]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties. The available properties are:
+
+            * T: Saturated temperature [K]
+            * P: Saturated pressure [MPa]
+            * x: Vapor quality [-]
+            * v: Specific volume [m³/kg]
+            * h: Specific enthalpy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+    """
     T = _TSat_P(P)
     if T > 623.15:
         rhol = 1./_Backward3_sat_v_P(P, T, 0)
@@ -2282,8 +3597,6 @@ def _Region4(P, x):
     propiedades["w"] = None
     propiedades["alfav"] = None
     propiedades["kt"] = None
-    propiedades["alfap"] = None
-    propiedades["betap"] = None
     propiedades["region"] = 4
     propiedades["x"] = x
     return propiedades
@@ -2292,12 +3605,34 @@ def _Region4(P, x):
 def _Backward4_T_hs(h, s):
     """Backward equation for region 4, T=f(h,s)
 
-    >>> "%.7f" % _Backward4_T_hs(1800,5.3)
-    '346.8475498'
-    >>> "%.7f" % _Backward4_T_hs(2400,6.0)
-    '425.1373305'
-    >>> "%.7f" % _Backward4_T_hs(2500,5.5)
-    '522.5579013'
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    T : float
+        Temperature [K]
+
+    References
+    ----------
+    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
+    Region 3, Equations as a Function of h and s for the Region Boundaries, and
+    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
+    for the Thermodynamic Properties of Water and Steam,
+    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 9
+
+    Examples
+    --------
+    >>> _Backward4_T_hs(1800,5.3)
+    346.8475498
+    >>> _Backward4_T_hs(2400,6.0)
+    425.1373305
+    >>> _Backward4_T_hs(2500,5.5)
+    522.5579013
     """
     I = [0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6,
          8, 10, 10, 12, 14, 14, 16, 16, 18, 18, 18, 20, 28]
@@ -2319,8 +3654,8 @@ def _Backward4_T_hs(h, s):
     nu = h/2800
     sigma = s/9.2
     suma = 0
-    for i in range(36):
-        suma += n[i]*(nu-0.119)**I[i]*(sigma-1.07)**J[i]
+    for i, j, ni in zip(I, J, n):
+        suma += ni * (nu-0.119)**i * (sigma-1.07)**j
     return 550*suma
 
 
@@ -2328,24 +3663,53 @@ def _Backward4_T_hs(h, s):
 def _Region5(T, P):
     """Basic equation for region 5
 
-    >>> "%.8f" % _Region5(1500,0.5)["v"]
-    '1.38455090'
-    >>> "%.5f" % _Region5(1500,0.5)["h"]
-    '5219.76855'
-    >>> "%.5f" % (_Region5(1500,0.5)["h"]-500*_Region5(1500,0.5)["v"], )
-    '4527.49310'
-    >>> "%.8f" % _Region5(1500,30)["s"]
-    '7.72970133'
-    >>> "%.8f" % _Region5(1500,30)["cp"]
-    '2.72724317'
-    >>> "%.8f" % _Region5(1500,30)["cv"]
-    '2.19274829'
-    >>> "%.5f" % _Region5(2000,30)["w"]
-    '1067.36948'
-    >>> "%.12f" % _Region5(2000,30)["alfav"]
-    '0.000508830641'
-    >>> "%.10f" % _Region5(2000,30)["kt"]
-    '0.0329193892'
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties. The available properties are:
+
+            * v: Specific volume [m³/kg]
+            * h: Specific enthalpy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * cv: Specific isocoric heat capacity [kJ/kgK]
+            * w: Speed of sound [m/s]
+            * alfav: Cubic expansion coefficient [1/K]
+            * kt: Isothermal compressibility [1/MPa]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 32-34
+
+    Examples
+    --------
+    >>> _Region5(1500,0.5)["v"]
+    1.38455090
+    >>> _Region5(1500,0.5)["h"]
+    5219.76855
+    >>> _Region5(1500,0.5)["h"]-500*_Region5(1500,0.5)["v"]
+    4527.49310
+    >>> _Region5(1500,30)["s"]
+    7.72970133
+    >>> _Region5(1500,30)["cp"]
+    2.72724317
+    >>> _Region5(1500,30)["cv"]
+    2.19274829
+    >>> _Region5(2000,30)["w"]
+    1067.36948
+    >>> _Region5(2000,30)["alfav"]
+    0.000508830641
+    >>> _Region5(2000,30)["kt"]
+    0.0329193892
     """
     Tr = 1000/T
     Pr = P/1
@@ -2357,13 +3721,13 @@ def _Region5(T, P):
     nr = [0.15736404855259e-2, 0.90153761673944e-3, -0.50270077677648e-2,
           0.22440037409485e-5, -0.41163275453471e-5, 0.37919454822955e-7]
     gr = grp = grpp = grt = grtt = grpt = 0
-    for i in range(6):
-        gr += nr[i]*Pr**Ir[i]*Tr**Jr[i]
-        grp += nr[i]*Ir[i]*Pr**(Ir[i]-1)*Tr**Jr[i]
-        grpp += nr[i]*Ir[i]*(Ir[i]-1)*Pr**(Ir[i]-2)*Tr**Jr[i]
-        grt += nr[i]*Pr**Ir[i]*Jr[i]*Tr**(Jr[i]-1)
-        grtt += nr[i]*Pr**Ir[i]*Jr[i]*(Jr[i]-1)*Tr**(Jr[i]-2)
-        grpt += nr[i]*Ir[i]*Pr**(Ir[i]-1)*Jr[i]*Tr**(Jr[i]-1)
+    for i, j, ni in zip(Ir, Jr, nr):
+        gr += ni * Pr**i * Tr**j
+        grp += ni*i * Pr**(i-1) * Tr**j
+        grpp += ni*i*(i-1) * Pr**(i-2) * Tr**j
+        grt += ni*j * Pr**i * Tr**(j-1)
+        grtt += ni*j*(j-1) * Pr**i * Tr**(j-2)
+        grpt += ni*i*j * Pr**(i-1) * Tr**(j-1)
 
     propiedades = {}
     propiedades["T"] = T
@@ -2384,7 +3748,33 @@ def _Region5(T, P):
 
 
 def Region5_cp0(Tr, Pr):
-    """Ideal properties for Region 5"""
+    """Ideal properties for Region 5
+
+    Parameters
+    ----------
+    Tr : float
+        Reduced temperature [-]
+    Pr : float
+        Reduced pressure [-]
+
+    Returns
+    -------
+    prop : array
+        Array with ideal Gibbs energy partial derivatives:
+
+            * g: Ideal Specific Gibbs energy [kJ/kg]
+            * gp: [∂g/∂P]T
+            * gpp: [∂²g/∂P²]T
+            * gt: [∂g/∂T]P
+            * gtt: [∂²g/∂T²]P
+            * gpt: [∂²g/∂T∂P]
+
+    References
+    ----------
+    IAPWS, Revised Release on the IAPWS Industrial Formulation 1997 for the
+    Thermodynamic Properties of Water and Steam August 2007,
+    http://www.iapws.org/relguide/IF97-Rev.html, Eq 33
+    """
     Jo = [0, 1, -3, -2, -1, 2]
     no = [-0.13179983674201e2, 0.68540841634434e1, -0.24805148933466e-1,
           0.36901534980333, -0.31161318213925e1, -0.32961626538917]
@@ -2392,17 +3782,36 @@ def Region5_cp0(Tr, Pr):
     gop = Pr**-1
     gopp = -Pr**-2
     got = gott = gopt = 0
-    for i in range(6):
-        go += no[i]*Tr**Jo[i]
-        got += no[i]*Jo[i]*Tr**(Jo[i]-1)
-        gott += no[i]*Jo[i]*(Jo[i]-1)*Tr**(Jo[i]-2)
+    for j, ni in zip(Jo, no):
+        go += ni * Tr**j
+        got += ni*j * Tr**(j-1)
+        gott += ni*j*(j-1) * Tr**(j-2)
 
     return go, gop, gopp, got, gott, gopt
 
 
 # Region definitions
 def _Bound_TP(T, P):
-    """Region definition for input T and P"""
+    """Region definition for input T and P
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    region : float
+        IAPWS-97 region code
+
+    References
+    ----------
+    Wagner, W; Kretzschmar, H-J: International Steam Tables: Properties of
+    Water and Steam Based on the Industrial Formulation IAPWS-IF97; Springer,
+    2008; doi: 10.1007/978-3-540-74234-0. Fig. 2.3
+    """
     region = None
     if 1073.15 < T <= 2273.15 and Pmin <= P <= 50:
         region = 5
@@ -2416,15 +3825,34 @@ def _Bound_TP(T, P):
         T_b23 = _t_P(P)
         if 273.15 <= T <= 623.15:
             region = 1
-        elif T_b23 <= T <= 1073.15:
-            region = 2
         elif 623.15 < T < T_b23:
             region = 3
+        elif T_b23 <= T <= 1073.15:
+            region = 2
     return region
 
 
 def _Bound_Ph(P, h):
-    """Region definition for input P y h"""
+    """Region definition for input P y h
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+
+    Returns
+    -------
+    region : float
+        IAPWS-97 region code
+
+    References
+    ----------
+    Wagner, W; Kretzschmar, H-J: International Steam Tables: Properties of
+    Water and Steam Based on the Industrial Formulation IAPWS-IF97; Springer,
+    2008; doi: 10.1007/978-3-540-74234-0. Fig. 2.5
+    """
     region = None
     if Pmin <= P <= Ps_623:
         h14 = _Region1(_TSat_P(P), P)["h"]
@@ -2449,7 +3877,10 @@ def _Bound_Ph(P, h):
         if hmin <= h <= h13:
             region = 1
         elif h13 < h < h32:
-            p34 = _PSat_h(h)
+            try:
+                p34 = _PSat_h(h)
+            except NotImplementedError:
+                p34 = Pc
             if P < p34:
                 region = 4
             else:
@@ -2476,7 +3907,26 @@ def _Bound_Ph(P, h):
 
 
 def _Bound_Ps(P, s):
-    """Region definition for input P and s"""
+    """Region definition for input P and s
+
+    Parameters
+    ----------
+    P : float
+        Pressure [MPa]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    region : float
+        IAPWS-97 region code
+
+    References
+    ----------
+    Wagner, W; Kretzschmar, H-J: International Steam Tables: Properties of
+    Water and Steam Based on the Industrial Formulation IAPWS-IF97; Springer,
+    2008; doi: 10.1007/978-3-540-74234-0. Fig. 2.9
+    """
     region = None
     if Pmin <= P <= Ps_623:
         smin = _Region1(273.15, P)["s"]
@@ -2501,7 +3951,10 @@ def _Bound_Ps(P, s):
         if smin <= s <= s13:
             region = 1
         elif s13 < s < s32:
-            p34 = _PSat_s(s)
+            try:
+                p34 = _PSat_s(s)
+            except NotImplementedError:
+                p34 = Pc
             if P < p34:
                 region = 4
             else:
@@ -2528,95 +3981,164 @@ def _Bound_Ps(P, s):
 
 
 def _Bound_hs(h, s):
-    """Region definition for input h and s"""
+    """Region definition for input h and s
+
+    Parameters
+    ----------
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+
+    Returns
+    -------
+    region : float
+        IAPWS-97 region code
+
+    References
+    ----------
+    Wagner, W; Kretzschmar, H-J: International Steam Tables: Properties of
+    Water and Steam Based on the Industrial Formulation IAPWS-IF97; Springer,
+    2008; doi: 10.1007/978-3-540-74234-0. Fig. 2.14
+    """
     region = None
-    smin = _Region1(273.15, 100)["s"]
-    hmin = _Region1(273.15, 100)["h"]
     s13 = _Region1(623.15, 100)["s"]
     s13s = _Region1(623.15,  Ps_623)["s"]
-    smax = _Region2(1073.15, _PSat_T(273.15))["s"]
-    hmax = _Region2(1073.15, _PSat_T(273.15))["h"]
+    sTPmax = _Region2(1073.15, 100)["s"]
+    s2ab = _Region2(1073.15, 4)["s"]
 
-    s4l = _Region1(273.15, Pmin)["s"]
-    h4l = _Region1(273.15, Pmin)["h"]
-    s4v = _Region2(273.15, Pmin)["s"]
-    h4v = _Region2(273.15, Pmin)["h"]
+    # Left point in h-s plot
+    smin = _Region1(273.15, 100)["s"]
+    hmin = _Region1(273.15, Pmin)["h"]
+
+    # Right point in h-s plot
+    _Pmax = _Region2(1073.15, Pmin)
+    hmax = _Pmax["h"]
+    smax = _Pmax["s"]
+
+    # Region 4 left and right point
+    _sL = _Region1(273.15, Pmin)
+    h4l = _sL["h"]
+    s4l = _sL["s"]
+    _sV = _Region2(273.15, Pmin)
+    h4v = _sV["h"]
+    s4v = _sV["s"]
+
+    if smin <= s <= s13:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h1_s(s)
+        T = _Backward1_T_Ps(100, s)-0.0218
+        hmax = _Region1(T, 100)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h <= hmax:
+            region = 1
 
-    h23max = _Region2(863.15, 100)["h"]
-    h23min = _Region2(623.15, Ps_623)["h"]
+    elif s13 < s <= s13s:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h1_s(s)
+        h13 = _h13_s(s)
+        v = _Backward3_v_Ps(100, s)*(1+9.6e-5)
+        T = _Backward3_T_Ps(100, s)-0.0248
+        hmax = _Region3(1/v, T)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h < h13:
+            region = 1
+        elif h13 <= h <= hmax:
+            region = 3
 
-    if h <= hmax:
-        if smin <= s <= s13:
-            P = _Backward1_P_hs(h, s)
-            T = _Backward1_T_Ph(P, h)
-            if T-0.0218 >= 273.15 and Pt <= P <= 100:
-                hs = _h1_s(s)
-                if h >= hs:
-                    region = 1
-                elif hmin <= h < hs:
-                    region = 4
-        elif s13 < s <= s13s:
-            hs = _h1_s(s)
-            h13 = _h13_s(s)
-            hmin4 = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
-            if h > h13 and _Backward3_P_hs(h, s) <= 100:
-                region = 3
-            elif hs <= h <= h13:
-                region = 1
-            elif hmin4 <= h < hs:
-                region = 4
-        elif s13s < s <= sc:
-            hs = _h3a_s(s)
-            hmin4 = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
-            if h >= hs and _Backward3_P_hs(h, s) <= 100:
-                region = 3
-            elif hmin4 <= h < hs:
-                region = 4
-        elif sc < s < 5.049096828:
-            hs = _h2c3b_s(s)
-            hmin4 = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
-            if h >= hs and _Backward3_P_hs(h, s) <= 100:
-                region = 3
-            elif hmin4 <= h < hs:
-                region = 4
-        elif 5.049096828 <= s < 5.260578707:
-            hs = _h2c3b_s(s)
-            hmin4 = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
-            if h23max <= h and _Backward2_P_hs(h, s) <= 100:
+    elif s13s < s <= sc:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h3a_s(s)
+        v = _Backward3_v_Ps(100, s)*(1+9.6e-5)
+        T = _Backward3_T_Ps(100, s)-0.0248
+        hmax = _Region3(1/v, T)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h <= hmax:
+            region = 3
+
+    elif sc < s < 5.049096828:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h2c3b_s(s)
+        v = _Backward3_v_Ps(100, s)*(1+9.6e-5)
+        T = _Backward3_T_Ps(100, s)-0.0248
+        hmax = _Region3(1/v, T)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h <= hmax:
+            region = 3
+
+    elif 5.049096828 <= s < 5.260578707:
+        # Specific zone with 2-3 boundary in s shape
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h2c3b_s(s)
+        h23max = _Region2(863.15, 100)["h"]
+        h23min = _Region2(623.15, Ps_623)["h"]
+        T = _Backward2_T_Ps(100, s)-0.019
+        hmax = _Region2(T, 100)["h"]
+
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h < h23min:
+            region = 3
+        elif h23min <= h < h23max:
+            if _Backward2c_P_hs(h, s) <= _P23_T(_t_hs(h, s)):
                 region = 2
-            elif h23min <= h < h23max:
-                if _Backward2c_P_hs(h, s) <= _P23_T(_t_hs(h, s)):
-                    region = 2
-                else:
-                    region = 3
-            elif hs <= h < h23min:
+            else:
                 region = 3
-            elif hmin4 <= h < hs:
-                region = 4
-        elif 5.260578707 <= s < 5.85:
-            hs = _h2c3b_s(s)
-            hmin4 = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
-            if hs <= h and _Backward2_P_hs(h, s) <= 100:
-                region = 2
-            elif hmin4 <= h < hs:
-                region = 4
-        elif 5.85 <= s < s4v:
-            hs = _h2ab_s(s)
-            hmin4 = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
-            P = _Backward2_P_hs(h, s)
-            if P <= 100:
-                T = _Backward2_T_Ph(P, h)
-                h2max = _Region2(1073.15, P)["h"]
-                if hs <= h <= h2max and Pmin <= P <= 100 and T <= 1073.15:
-                    region = 2
-                elif hmin4 <= h < hs:
-                    region = 4
-        elif s4v <= s <= smax:
-            P = _Backward2a_P_hs(h, s)
-            T = _Backward2a_T_Ph(P, h)
-            if P >= Pmin and T <= 1073.15:
-                region = 2
+        elif h23max <= h <= hmax:
+            region = 2
+
+    elif 5.260578707 <= s < 5.85:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h2c3b_s(s)
+        T = _Backward2_T_Ps(100, s)-0.019
+        hmax = _Region2(T, 100)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h <= hmax:
+            region = 2
+
+    elif 5.85 <= s < sTPmax:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h2ab_s(s)
+        T = _Backward2_T_Ps(100, s)-0.019
+        hmax = _Region2(T, 100)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h <= hmax:
+            region = 2
 
+    elif sTPmax <= s < s2ab:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h2ab_s(s)
+        P = _Backward2_P_hs(h, s)
+        hmax = _Region2(1073.15, P)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h <= hmax:
+            region = 2
+
+    elif s2ab <= s < s4v:
+        hmin = h4l+(s-s4l)/(s4v-s4l)*(h4v-h4l)
+        hs = _h2ab_s(s)
+        P = _Backward2_P_hs(h, s)
+        hmax = _Region2(1073.15, P)["h"]
+        if hmin <= h < hs:
+            region = 4
+        elif hs <= h <= hmax:
+            region = 2
+
+    elif s4v <= s <= smax:
+        hmin = _Region2(273.15, Pmin)["h"]
+        P = _Backward2a_P_hs(h, s)
+        hmax = _Region2(1073.15, P)["h"]
+        if Pmin <= P <= 100 and hmin <= h <= hmax:
+            region = 2
+
+    # Check region 5
     if not region and \
             _Region5(1073.15, 50)["s"] < s <= _Region5(2273.15, Pmin)["s"] \
             and _Region5(1073.15, 50)["h"] < h <= _Region5(2273.15, Pmin)["h"]:
@@ -2631,7 +4153,29 @@ def _Bound_hs(h, s):
 
 
 def prop0(T, P):
-    """Ideal gas properties"""
+    """Ideal gas properties
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+
+    Returns
+    -------
+    prop : dict
+        Dict with calculated properties. The available properties are:
+
+            * v: Specific volume [m³/kg]
+            * h: Specific enthalpy [kJ/kg]
+            * s: Specific entropy [kJ/kgK]
+            * cp: Specific isobaric heat capacity [kJ/kgK]
+            * cv: Specific isocoric heat capacity [kJ/kgK]
+            * w: Speed of sound [m/s]
+            * alfav: Cubic expansion coefficient [1/K]
+            * kt: Isothermal compressibility [1/MPa]
+    """
     if T <= 1073.15:
         Tr = 540/T
         Pr = P/1.
@@ -2655,91 +4199,97 @@ def prop0(T, P):
 
 
 class IAPWS97(object):
-    """Class to model a state for liquid water or steam with the IAPWS-IF97
-
-    Incoming properties::
-    T   -   Temperature, K
-    P   -   Pressure, MPa
-    h   -   Specific enthalpy, kJ/kg
-    s   -   Specific entropy, kJ/kg·K
-    x   -   Quality
-
-    Optional:
-    l   -   Wavelength of light, for refractive index
-
+    """Class to model a state of liquid water or steam with the IAPWS-IF97
+
+    Parameters
+    ----------
+    T : float
+        Temperature [K]
+    P : float
+        Pressure [MPa]
+    h : float
+        Specific enthalpy [kJ/kg]
+    s : float
+        Specific entropy [kJ/kgK]
+    x : float
+        Vapor quality [-]
+    l : float, optional
+        Wavelength of light, for refractive index [nm]
+
+    Notes
+    -----
     Definitions options:
-    T, P    Not valid for two-phases region
-    P, h
-    P, s
-    h, s
-    T, x    Only for two-phases region
-    P, x    Only for two-phases region
-
-
-    Properties:
-    P        -   Pressure, MPa
-    T        -   Temperature, K
-    g        -   Specific Gibbs free energy, kJ/kg
-    a        -   Specific Helmholtz free energy, kJ/kg
-    v        -   Specific volume, m³/kg
-    r        -   Density, kg/m³
-    h        -   Specific enthalpy, kJ/kg
-    u        -   Specific internal energy, kJ/kg
-    s        -   Specific entropy, kJ/kg·K
-    cp       -   Specific isobaric heat capacity, kJ/kg·K
-    cv       -   Specific isochoric heat capacity, kJ/kg·K
-    Z        -   Compression factor
-    fi       -   Fugacity coefficient
-    f        -   Fugacity, MPa
-
-    gamma    -   Isoentropic exponent
-    alfav    -   Isobaric cubic expansion coefficient, 1/K
-    xkappa   -   Isothermal compressibility, 1/MPa
-    kappas   -   Adiabatic compresibility, 1/MPa
-    alfap    -   Relative pressure coefficient, 1/K
-    betap    -   Isothermal stress coefficient, kg/m³
-    joule    -   Joule-Thomson coefficient, K/MPa
-    deltat   -   Isothermal throttling coefficient, kJ/kg·MPa
-    region   -   Region
-
-    v0       -   Ideal specific volume, m³/kg
-    u0       -   Ideal specific internal energy, kJ/kg
-    h0       -   Ideal specific enthalpy, kJ/kg
-    s0       -   Ideal specific entropy, kJ/kg·K
-    a0       -   Ideal specific Helmholtz free energy, kJ/kg
-    g0       -   Ideal specific Gibbs free energy, kJ/kg
-    cp0      -   Ideal specific isobaric heat capacity, kJ/kg·K
-    cv0      -   Ideal specific isochoric heat capacity, kJ/kg·K
-    w0       -   Ideal speed of sound, m/s
-    gamma0   -   Ideal isoentropic exponent
-
-    w        -   Speed of sound, m/s
-    mu       -   Dynamic viscosity, Pa·s
-    nu       -   Kinematic viscosity, m²/s
-    k        -   Thermal conductivity, W/m·K
-    alfa     -   Thermal diffusivity, m²/s
-    sigma    -   Surface tension, N/m
-    epsilon  -   Dielectric constant
-    n        -   Refractive index
-    Prandt   -   Prandtl number
-    Pr       -   Reduced Pressure
-    Tr       -   Reduced Temperature
-    Hvap     -   Vaporization heat, kJ/kg
-    Svap     -   Vaporization entropy, kJ/kg·K
-
-    Usage:
+        * T, P: Not valid for two-phases region
+        * P, h
+        * P, s
+        * h, s
+        * T, x: Only for two-phases region
+        * P, x: Only for two-phases region
+
+    Returns
+    -------
+    The calculated instance has the following properties:
+        * P: Pressure [MPa]
+        * T: Temperature [K]
+        * g: Specific Gibbs free energy [kJ/kg]
+        * a: Specific Helmholtz free energy [kJ/kg]
+        * v: Specific volume [m³/kg]
+        * r: Density [kg/m³]
+        * h: Specific enthalpy [kJ/kg]
+        * u: Specific internal energy [kJ/kg]
+        * s: Specific entropy [kJ/kg·K]
+        * cp: Specific isobaric heat capacity [kJ/kg·K]
+        * cv: Specific isochoric heat capacity [kJ/kg·K]
+        * Z: Compression factor [-]
+        * fi: Fugacity coefficient [-]
+        * f: Fugacity [MPa]
+
+        * gamma: Isoentropic exponent [-]
+        * alfav: Isobaric cubic expansion coefficient [1/K]
+        * xkappa: Isothermal compressibility [1/MPa]
+        * kappas: Adiabatic compresibility [1/MPa]
+        * alfap: Relative pressure coefficient [1/K]
+        * betap: Isothermal stress coefficient [kg/m³]
+        * joule: Joule-Thomson coefficient [K/MPa]
+        * deltat: Isothermal throttling coefficient [kJ/kg·MPa]
+        * region: Region
+
+        * v0: Ideal specific volume [m³/kg]
+        * u0: Ideal specific internal energy [kJ/kg]
+        * h0: Ideal specific enthalpy [kJ/kg]
+        * s0: Ideal specific entropy [kJ/kg·K]
+        * a0: Ideal specific Helmholtz free energy [kJ/kg]
+        * g0: Ideal specific Gibbs free energy [kJ/kg]
+        * cp0: Ideal specific isobaric heat capacity [kJ/kg·K]
+        * cv0: Ideal specific isochoric heat capacity [kJ/kg·K]
+        * w0: Ideal speed of sound [m/s]
+        * gamma0: Ideal isoentropic exponent [-]
+
+        * w: Speed of sound [m/s]
+        * mu: Dynamic viscosity [Pa·s]
+        * nu: Kinematic viscosity [m²/s]
+        * k: Thermal conductivity [W/m·K]
+        * alfa: Thermal diffusivity [m²/s]
+        * sigma: Surface tension [N/m]
+        * epsilon: Dielectric constant [-]
+        * n: Refractive index [-]
+        * Prandt: Prandtl number [-]
+        * Pr: Reduced Pressure [-]
+        * Tr: Reduced Temperature [-]
+        * Hvap: Vaporization heat [kJ/kg]
+        * Svap: Vaporization entropy [kJ/kg·K]
+
+    Examples
+    --------
     >>> water=IAPWS97(T=170+273.15,x=0.5)
-    >>> "%0.4f %0.4f %0.1f %0.2f" %(water.Liquid.cp, water.Vapor.cp, \
-        water.Liquid.w, water.Vapor.w)
-    '4.3695 2.5985 1418.3 498.78'
+    >>> water.Liquid.cp, water.Vapor.cp, water.Liquid.w, water.Vapor.w
+    4.3695 2.5985 1418.3 498.78
     >>> water=IAPWS97(T=325+273.15,x=0.5)
-    >>> "%0.4f %0.8f %0.7f %0.2f %0.2f" %(water.P, water.Liquid.v, \
-        water.Vapor.v, water.Liquid.h, water.Vapor.h)
-    '12.0505 0.00152830 0.0141887 1493.37 2684.48'
+    >>> water.P, water.Liquid.v, water.Vapor.v, water.Liquid.h, water.Vapor.h
+    12.0505 0.00152830 0.0141887 1493.37 2684.48
     >>> water=IAPWS97(T=50+273.15,P=0.0006112127)
-    >>> "%0.4f %0.4f %0.2f %0.3f %0.2f" %(water.cp0, water.cv0, water.h0, \
-        water.s0, water.w0)
-    '1.8714 1.4098 2594.66 9.471 444.93'
+    >>> water.cp0, water.cv0, water.h0, water.s0, water.w0
+    1.8714 1.4098 2594.66 9.471 444.93
     """
     kwargs = {"T": 0.0,
               "P": 0.0,
@@ -2797,11 +4347,14 @@ class IAPWS97(object):
             elif region == 2:
                 propiedades = _Region2(T, P)
             elif region == 3:
-                vo = _Backward3_v_PT(P, T)
+                if T == Tc and P == Pc:
+                    rho = rhoc
+                else:
+                    vo = _Backward3_v_PT(P, T)
 
-                def funcion(rho):
-                    return _Region3(rho, self.kwargs["T"])["P"]-P
-                rho = newton(funcion, 1/vo)
+                    def funcion(rho):
+                        return _Region3(rho, self.kwargs["T"])["P"]-P
+                    rho = newton(funcion, 1/vo)
                 propiedades = _Region3(rho, T)
             elif region == 5:
                 propiedades = _Region5(T, P)
@@ -2915,8 +4468,8 @@ class IAPWS97(object):
                 propiedades = _Region2(T, P)
             elif region == 3:
                 P = _Backward3_P_hs(h, s)
-                vo = _Backward3_v_Ps(P, s)
-                To = _Backward3_T_Ps(P, s)
+                vo = _Backward3_v_Ph(P, h)
+                To = _Backward3_T_Ph(P, h)
 
                 def funcion(par):
                     return (_Region3(par[0], par[1])["h"]-h,
@@ -2924,12 +4477,40 @@ class IAPWS97(object):
                 rho, T = fsolve(funcion, [1/vo, To])
                 propiedades = _Region3(rho, T)
             elif region == 4:
-                T = _Backward4_T_hs(h, s)
-                P = _PSat_T(T)
-                h1 = _Region1(T, P)["h"]
-                h2 = _Region2(T, P)["h"]
-                x = (h-h1)/(h2-h1)
-                propiedades = _Region4(P, x)
+                if round(s-sc, 6) == 0 and round(h-hc, 6) == 0:
+                    propiedades = _Region3(rhoc, Tc)
+
+                else:
+                    To = _Backward4_T_hs(h, s)
+                    if To < 273.15 or To > Tc:
+                        To = 300
+
+                    def funcion(par):
+                        if par[1] < 0:
+                            par[1] = 0
+                        elif par[1] > 1:
+                            par[1] = 1
+                        if par[0] < 273.15:
+                            par[0] = 273.15
+                        elif par[0] > Tc:
+                            par[0] = Tc
+
+                        Po = _PSat_T(par[0])
+                        liquid = _Region1(par[0], Po)
+                        vapor = _Region2(par[0], Po)
+                        hl = liquid["h"]
+                        sl = liquid["s"]
+                        hv = vapor["h"]
+                        sv = vapor["s"]
+                        return (hv*par[1]+hl*(1-par[1])-h,
+                                sv*par[1]+sl*(1-par[1])-s)
+                    T, x = fsolve(funcion, [To, 0.5])
+                    P = _PSat_T(T)
+
+                    if Pt <= P < Pc and 0 < x < 1:
+                        propiedades = _Region4(P, x)
+                    elif Pt <= P <= Ps_623 and x == 0:
+                        propiedades = _Region1(T, P)
             elif region == 5:
                 def funcion(par):
                     return (_Region5(par[0], par[1])["h"]-h,
@@ -2942,42 +4523,45 @@ class IAPWS97(object):
         elif self._thermo == "Px":
             P, x = args
             T = _TSat_P(P)
-            if Pt <= P <= Pc and 0 < x < 1:
+            if Pt <= P < Pc and 0 < x < 1:
                 propiedades = _Region4(P, x)
-            elif P > Ps_623 and x in (0, 1):
-                rho = 1./_Backward3_sat_v_P(P, T, x)
-                propiedades = _Region3(rho, T)
-            elif x == 0:
+            elif Pt <= P <= Ps_623 and x == 0:
                 propiedades = _Region1(T, P)
-            elif x == 1:
+            elif Pt <= P <= Ps_623 and x == 1:
                 propiedades = _Region2(T, P)
+            elif Ps_623 < P < Pc and x in (0, 1):
+                def funcion(rho):
+                    return _Region3(rho, T)["P"]-P
+                rhoo = 1./_Backward3_sat_v_P(P, T, x)
+                rho = fsolve(funcion, rhoo)[0]
+                propiedades = _Region3(rho, T)
+            elif P == Pc and 0 <= x <= 1:
+                propiedades = _Region3(rhoc, Tc)
             else:
                 raise NotImplementedError("Incoming out of bound")
             self.sigma = _Tension(T)
+            propiedades["x"] = x
 
         elif self._thermo == "Tx":
             T, x = args
             P = _PSat_T(T)
-            if 273.15 <= T <= Tc and 0 < x < 1:
+            if 273.15 <= T < Tc and 0 < x < 1:
                 propiedades = _Region4(P, x)
-            elif T > 623.15 and x in (0, 1):
-                rho = 1./_Backward3_sat_v_P(P, T, x)
-                propiedades = _Region3(rho, T)
             elif 273.15 <= T <= 623.15 and x == 0:
                 propiedades = _Region1(T, P)
             elif 273.15 <= T <= 623.15 and x == 1:
                 propiedades = _Region2(T, P)
-            elif P > Ps_623:
-                rho = 1./_Backward3_v_PT(P, T)
+            elif 623.15 < T < Tc and x in (0, 1):
+                rho = 1./_Backward3_sat_v_P(P, T, x)
                 propiedades = _Region3(rho, T)
+            elif T == Tc and 0 <= x <= 1:
+                propiedades = _Region3(rhoc, Tc)
             else:
                 raise NotImplementedError("Incoming out of bound")
             self.sigma = _Tension(T)
+            propiedades["x"] = x
 
-        else:
-            raise NotImplementedError("Bad incoming variables")
-
-        self.M = M
+        self.M = 18.015257  # kg/kmol
         self.Pc = Pc
         self.Tc = Tc
         self.rhoc = rhoc
@@ -3064,48 +4648,35 @@ class IAPWS97(object):
         fase.xkappa = estado["kt"]
         fase.kappas = -1/fase.v*self.derivative("v", "P", "s", fase)
 
-        fase.mu = _Viscosity(fase.rho, self.T)
-        fase.k = _ThCond(fase.rho, self.T)
-        fase.nu = fase.mu/fase.rho
-        fase.epsilon = _Dielectric(fase.rho, self.T)
-        fase.Prandt = fase.mu*fase.cp*1000/fase.k
-        fase.n = _Refractive(fase.rho, self.T, self.kwargs["l"])
-
-        fase.alfa = fase.k/1000/fase.rho/fase.cp
         fase.joule = self.derivative("T", "P", "h", fase)
         fase.deltat = self.derivative("h", "P", "T", fase)
         fase.gamma = -self.v/self.P/1000*self.derivative("P", "v", "s", fase)
 
-        if self.region == 3:
-            fase.alfap = estado["alfap"]
-            fase.betap = estado["betap"]
-        else:
-            fase.alfap = fase.alfav/self.P/fase.xkappa
-            fase.betap = -1/self.P*self.derivative("P", "v", "T", fase)
+        fase.alfap = fase.alfav/self.P/fase.xkappa
+        fase.betap = -1/self.P*self.derivative("P", "v", "T", fase)
 
         fase.fi = exp((fase.g-self.g0)/R/self.T)
         fase.f = self.P*fase.fi
 
+        fase.mu = _Viscosity(fase.rho, self.T)
+        # Use industrial formulation for critical enhancement in thermal
+        # conductivity calculation
+        fase.drhodP_T = self.derivative("rho", "P", "T", fase)
+        fase.k = _ThCond(fase.rho, self.T, fase)
+
+        fase.nu = fase.mu/fase.rho
+        fase.alfa = fase.k/1000/fase.rho/fase.cp
+        fase.epsilon = _Dielectric(fase.rho, self.T)
+        fase.Prandt = fase.mu*fase.cp*1000/fase.k
+        try:
+            fase.n = _Refractive(fase.rho, self.T, self.kwargs["l"])
+        except NotImplementedError:
+            fase.n = None
+
     def derivative(self, z, x, y, fase):
-        """Calculate generic partial derivative: (δz/δx)y
+        """Wrapper derivative for custom derived properties
         where x, y, z can be: P, T, v, u, h, s, g, a"""
-        dT = {"P": 0,
-              "T": 1,
-              "v": fase.v*fase.alfav,
-              "u": fase.cp-self.P*1000*fase.v*fase.alfav,
-              "h": fase.cp,
-              "s": fase.cp/self.T,
-              "g": -fase.s,
-              "a": -self.P*1000*fase.v*fase.alfav-fase.s}
-        dP = {"P": 1,
-              "T": 0,
-              "v": -fase.v*fase.xkappa,
-              "u": fase.v*(self.P*1000*fase.xkappa-self.T*fase.alfav),
-              "h": fase.v*(1-self.T*fase.alfav),
-              "s": -fase.v*fase.alfav,
-              "g": fase.v,
-              "a": self.P*1000*fase.v*fase.xkappa}
-        return (dP[z]*dT[y]-dT[z]*dP[y])/(dP[x]*dT[y]-dT[x]*dP[y])
+        return deriv_G(self, z, x, y, fase)
 
 
 class IAPWS97_PT(IAPWS97):
@@ -3136,13 +4707,3 @@ class IAPWS97_Tx(IAPWS97):
     """Derivated class for direct T and x input"""
     def __init__(self, T, x):
         IAPWS97.__init__(self, T=T, x=x)
-
-
-if __name__ == "__main__":
-    # import doctest
-    # doctest.testmod()
-
-    liquido = IAPWS97(P=18, T=626)
-    print(liquido.h, liquido.T, liquido.region, liquido.x)
-    vapor = IAPWS97(P=17, x=1)
-    print(vapor.h)
diff --git a/setup.cfg b/setup.cfg
index a669c45..8bfd5a1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,4 @@
 [egg_info]
-tag_svn_revision = 0
 tag_build = 
 tag_date = 0
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/iapws.git



More information about the debian-science-commits mailing list