ENKI

SWIM

Standard Water Intergrated Model

The SWIM model is described in a notebook located in the Pure-Phases folder with the title “Water.ipynb.” In that folder the model is accessed using server code written in Ovjective-C and bridged to Python utilizing the Rubicon Python to Objective-C wrappper.

SWIM may also be accessed using Cython wrappers to C/C++ code. That method of access is illustrated in this notebook. The Cython access method is faster because it avoids the Rubicon bridge and is more easily ported to hardware platforms not normally configured to compile and execute Objective-C. The method of access to SWIM demonstrated here should be used in preference to the default method, which will soon be deprecated.

from thermoengine import model

The Cython-SWIM module is accessed as …

modelDB = model.Database(database="CoderModule", calib=True, phase_tuple=('thermoengine.aqueous', {'SWIM':['SWIM','pure']}))

… the objective-C/Rubicon code is accessed using the default call, modelDB = model.Database()

The phase is accessed in the standard way once the model database has been instantiated.

SWIM = modelDB.get_phase('SWIM')

Generic Properties of the SWIM phase

print (SWIM.props['phase_name'])
print (SWIM.props['formula'][0])
print (SWIM.props['molwt'][0])
SWIM
H2O
18.01528

Thermodynamic properties of the SWIM phase

By default, interpolative smooothing of the integrated model properties is implemented.

t = 1000.0 # K
p = 1000.0 # bars
import numpy as np
def test_func(name, func, t, p, units, deriv=None, const=None, endmember=None):
    try:
        if deriv:
            result = func(t, p, deriv=deriv)
            if type(result) is np.ndarray:
                if len(result.shape) == 2:
                    print ("{0:>10s}".format(name), end=' ')
                    for x in result[0]:
                        print ("{0:15.6e}".format(x), end=' ')
                    print (" {0:<20s}".format(units))
                elif len(result.shape) == 3:
                    for i in range(0,result.shape[1]):
                        print ("{0:>10s}".format(name), end=' ')
                        for x in result[0][i]:
                            print ("{0:15.6e}".format(x), end=' ')
                        print (" {0:<20s}".format(units))
                elif len(result.shape) == 4:
                    for i in range(0,result.shape[1]):
                        for j in range(0,result.shape[2]):
                            print ("{0:>10s}".format(name), end=' ')
                            for x in result[0][i][j]:
                                print ("{0:15.6e}".format(x), end=' ')
                            print (" {0:<20s}".format(units))
                elif len(result.shape) == 1:
                    print ("{0:>10s}".format(name), end=' ')
                    for x in result:
                        print ("{0:15.6e}".format(x), end=' ')
                    print (" {0:<20s}".format(units))
                else:
                    print ('A', result.shape)
            else:
                print ("{0:>10s}{1:15.6e} {2:<20s}".format(name, result, units))
        elif const:
            print ("{0:>10s}{1:15.6e} {2:<20s}".format(name, func(t, p, const=const), units))
        else:
            result = func(t, p)
            if type(result) is np.ndarray:
                if len(result.shape) == 2:
                    print ("{0:>10s}".format(name), end=' ')
                    for x in result[0]:
                        print ("{0:15.6e}".format(x), end=' ')
                    print (" {0:<20s}".format(units))
                elif len(result.shape) == 1:
                    print ("{0:>10s}".format(name), end=' ')
                    for x in result:
                        print ("{0:15.6e}".format(x), end=' ')
                    print (" {0:<20s}".format(units))
                else:
                    print ('B', len(result.shape))
            else:
                print ("{0:>10s}{1:15.6e} {2:<20s}".format(name, result, units))
    except AttributeError:
        print ("{0:>10s} is not implemented".format(name))

test_func('G',  SWIM.gibbs_energy, t, p, 'J/mol')
test_func('dG/dT', SWIM.gibbs_energy, t, p, 'J/K-mol', deriv={'dT':1})
test_func('dG/dP', SWIM.gibbs_energy, t, p, 'J/bar-mol', deriv={'dP':1})

test_func('d2G/dT2', SWIM.gibbs_energy, t, p, 'J/K^2-mol', deriv={'dT':2})
test_func('d2G/dTdP', SWIM.gibbs_energy, t, p, 'J/K-bar-mol', deriv={'dT':1, 'dP':1})
test_func('d2G/dP2', SWIM.gibbs_energy, t, p, 'J/bar^2-mol', deriv={'dP':2})

test_func('d3G/dT3', SWIM.gibbs_energy, t, p, 'J/K^3-mol', deriv={'dT':3})
test_func('d3G/dT2dP', SWIM.gibbs_energy, t, p, 'J/K^2-bar-mol', deriv={'dT':2, 'dP':1})
test_func('d3G/dTdP2', SWIM.gibbs_energy, t, p, 'J/K-bar^2-mol', deriv={'dT':1, 'dP':2})
test_func('d3G/dP3', SWIM.gibbs_energy, t, p, 'J/bar^3-mol', deriv={'dP':3})

test_func('H', SWIM.enthalpy, t, p, 'J/mol')
test_func('S', SWIM.entropy, t, p, 'J/K-mol')

test_func('Cv', SWIM.heat_capacity, t, p, 'J/K-mol', const='V')
test_func('Cp', SWIM.heat_capacity, t, p, 'J/K-mol')
test_func('dCp/dT', SWIM.heat_capacity, t, p, 'J/-K^2-mol', deriv={'dT':1})

test_func('rho', SWIM.density, t, p, 'gm/cc')
test_func('alpha', SWIM.thermal_exp, t, p, '1/K')
test_func('beta', SWIM.compressibility, t, p, '1/bar')
test_func('K', SWIM.bulk_mod, t, p, '')
test_func('Kp', SWIM.bulk_mod, t, p, '1/bar', deriv={'dP':1})

test_func("V", SWIM.volume, t, p, 'J/bar-mol')
test_func("dV/dT", SWIM.volume, t, p, 'J/bar-K-mol', deriv={'dT':1})
test_func("dv/dP", SWIM.volume, t, p, 'J/bar^2-mol', deriv={'dP':1})
test_func("d2V/dT2", SWIM.volume, t, p, 'J/bar-K^2-mol', deriv={'dT':2})
test_func("d2V/dTdP", SWIM.volume, t, p, 'J/bar^2-K-mol', deriv={'dT':1, 'dP':1})
test_func("d2V/dP2", SWIM.volume, t, p, 'J/bar^3-mol', deriv={'dP':2})

test_func('mu0', SWIM.chem_potential, t, p, 'J/mol')
        G  -3.234830e+05 J/mol
    dG/dT  -1.671547e+02 J/K-mol
    dG/dP   6.838333e+00 J/bar-mol
  d2G/dT2  -7.291385e-02 J/K^2-mol
 d2G/dTdP   1.431826e-02 J/K-bar-mol
  d2G/dP2  -7.243395e-03 J/bar^2-mol
  d3G/dT3   1.971884e-04 J/K^3-mol
d3G/dT2dP  -1.818046e-05 J/K^2-bar-mol
d3G/dTdP2  -1.299463e-05 J/K-bar^2-mol
  d3G/dP3   1.744388e-05 J/bar^3-mol
        H is not implemented
        S   1.671547e+02 J/K-mol
       Cv   4.461045e+01 J/K-mol
       Cp   7.291385e+01 J/K-mol
   dCp/dT  -1.242746e-01 J/-K^2-mol
      rho is not implemented
    alpha   2.093823e-03 1/K
     beta   1.059234e-03 1/bar
        K   9.440785e+02
       Kp  -1.428920e-06 1/bar
        V   6.838333e+00 J/bar-mol
    dV/dT   1.431826e-02 J/bar-K-mol
    dv/dP  -7.243395e-03 J/bar^2-mol
  d2V/dT2  -1.818046e-05 J/bar-K^2-mol
 d2V/dTdP  -1.299463e-05 J/bar^2-K-mol
  d2V/dP2   1.744388e-05 J/bar^3-mol
      mu0  -3.234830e+05 J/mol

Smoothing can be turned off using calibration mode

There is only one calibration parameter for SWIM. It is an integer, which if non-zero turns off smoothing and forces the use of one of the four integrated thermodynamic models, even if that model is not applicable at the T,P conditions specified. See further explanation in the Pure-Phase notebook mentioned above.

try:
    param_props = SWIM.param_props
    supports_calib = param_props['supports_calib']
    print ('This phase supports the Calibration protocol')
    nparam = param_props['param_num']
    print ('... there are', nparam, 'parameters')
    names = param_props['param_names']
    units = param_props['param_units']
    values = param_props['param0']
    t = 1000.0
    p = 1000.0
    for i in range (0, nparam):
        print ("Parameter {0:<15s} has value {1:15.6e}  {2:<20s}".format(names[i], values[i], units[i]))
except AttributeError:
    print ('This phase does not implement the parameter calibration protocol')
This phase supports the Calibration protocol
... there are 1 parameters
Parameter EOS/0-auto/1-DZ2006/2-ZD2005/3-Holten/4-Wagner has value    0.000000e+00  None

Use the model of Duan and Zhang (2006)

This is the model adopted in MELTS

SWIM.module.cy_SWIM_aqueous_set_param_value(0,1)
SWIM.gibbs_energy(t, p)
-323482.90090449614

Use the model of Zhang and Duan (2005)

This is the model adopted in DEW

SWIM.module.cy_SWIM_aqueous_set_param_value(0,2)
SWIM.gibbs_energy(1000,1000)
-323483.03766402684

Use the model of Holten (2014)

This is a model applicable to supercoooled water

SWIM.module.cy_SWIM_aqueous_set_param_value(0,3)
SWIM.gibbs_energy(1000,1000)
-293932.509702217

Use the model of Wagner (2002)

This is the standard water model for properties in the liquid and steam region up to the critical point

SWIM.module.cy_SWIM_aqueous_set_param_value(0,4)
SWIM.gibbs_energy(1000,1000)
-323607.85259968095