gsw-3.0.2/0000755000175000017500000000000012172027075013451 5ustar amckinstryamckinstrygsw-3.0.2/setup.py0000644000175000017500000000330512172027023015155 0ustar amckinstryamckinstry#!/usr/bin/env python # -*- coding: utf-8 -*- import codecs from gsw import __version__ from distutils.core import setup try: # Python 3 from distutils.command.build_py import build_py_2to3 as build_py except ImportError: # Python 2 from distutils.command.build_py import build_py classifiers = """\ Development Status :: 5 - Production/Stable Environment :: Console Intended Audience :: Science/Research Intended Audience :: Developers Intended Audience :: Education License :: OSI Approved :: MIT License Operating System :: OS Independent Programming Language :: Python Topic :: Scientific/Engineering Topic :: Education Topic :: Software Development :: Libraries :: Python Modules """ readme = codecs.open('README.rst', encoding='utf-8') config = dict(name='gsw', version=__version__, packages=['gsw', 'gsw/gibbs', 'gsw/utilities'], package_data={'gsw': ['utilities/data/*.npz']}, license=open('LICENSE.txt').read(), description='Gibbs SeaWater Oceanographic Package of TEOS-10', long_description=readme.read(), author=u'Filipe Fernandes, Eric Firing, Ådlandsvik Bjørn', author_email='ocefpaf@gmail.com', maintainer='Filipe Fernandes', maintainer_email='ocefpaf@gmail.com', url='http://pypi.python.org/pypi/seawater/', download_url='https://pypi.python.org/pypi/gsw/', classifiers=filter(None, classifiers.split("\n")), platforms='any', cmdclass={'build_py': build_py}, keywords=['oceanography', 'seawater'], install_requires=['numpy', 'nose'] ) setup(**config) gsw-3.0.2/gsw/0000755000175000017500000000000012172027023014242 5ustar amckinstryamckinstrygsw-3.0.2/gsw/__init__.py0000644000175000017500000000055612172027023016361 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- __authors__ = 'Eric Firing', u'Bjørn Ådlandsvik', 'Filipe Fernandes' __license__ = "MIT" __version__ = "3.0.2" __maintainer__ = "Filipe Fernandes" __email__ = "ocefpaf@gmail.com" __status__ = "Production" __created_ = "14-Jan-2010" __modified__ = "07-March-2013" __all__ = 'gibbs', 'utilities' from gibbs import * from utilities import * gsw-3.0.2/gsw/utilities/0000755000175000017500000000000012172027023016255 5ustar amckinstryamckinstrygsw-3.0.2/gsw/utilities/mat2npz.py0000644000175000017500000000365412172027023020232 0ustar amckinstryamckinstry#!/usr/bin/env python # -*- coding: utf-8 -*- # # mat2npz.py # # purpose: Convert matlab file from TEOS-10 group to a npz file # author: Filipe P. A. Fernandes # e-mail: ocefpaf@gmail # web: http://ocefpaf.tiddlyspot.com/ # created: 06-Jun-2011 # modified: Thu 07 Feb 2013 03:46:02 PM BRST # # obs: # import h5py import numpy as np def get_data(data): return np.atleast_1d(np.squeeze(data)).T data_ver = 'v3_0' gsw_data = h5py.File('gsw_data_%s.mat' % data_ver, mode='r') # Delta SA Atlas. ref_table = dict() for k in gsw_data: if k == u'gsw_cv' or k == u'#refs#' or k == 'gsw_demo_data': pass else: if k == 'deltaSA_ref': name = 'delta_SA_ref' else: name = k if name == 'version_number' or name == 'version_date': var = ''.join([unichr(c) for c in gsw_data[k][:]]) else: var = get_data(gsw_data[k][:]) ref_table.update({name: var}) np.savez("gsw_data_%s" % data_ver, **ref_table) # Save demo data values gsw_demo_data` in a separate file. gsw_demo_data = gsw_data['gsw_demo_data'] demo_vars = dict() for name in gsw_demo_data: var = get_data(gsw_demo_data[name][:]) demo_vars.update({name: var}) np.savez("gsw_demo_data_%s" % data_ver, **demo_vars) # Save compare values `gsw_cv` in a separate file. gsw_cv = gsw_data['gsw_cv'] cv_vars = dict() for name in gsw_cv: var = get_data(gsw_cv[name][:]) cv_vars.update({name: var}) np.savez("gsw_cv_%s" % data_ver, **cv_vars) gsw_data.close() # NOTE: This is a saved result of a modified version of `gsw_check_functions.m` # where the structure variable gsw_cf was saved. The matlab version relies # on the result of some of its functions to test others, so we need this file. gsw_cf = h5py.File('gsw_cf.mat', mode='r') gsw_cf['gsw_cf'] cf_vars = dict() for name in gsw_cf: var = get_data(gsw_cf[name][:]) cf_vars.update({name: var}) np.savez("gsw_cf", **cf_vars) gsw-3.0.2/gsw/utilities/__init__.py0000644000175000017500000000005712172027023020370 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from utilities import *gsw-3.0.2/gsw/utilities/data/0000755000175000017500000000000012172027023017166 5ustar amckinstryamckinstrygsw-3.0.2/gsw/utilities/data/gsw_cv_v3_0.npz0000644000175000017500000040235412172027023022046 0ustar amckinstryamckinstryPKXA  specvol.npyNUMPYF{'descr': 'xP?vvP?gꗯ'P? A P?d P?:\O?^UO?t&O?GJO?y2O?2"O?%'O?o O?4sTO?'XO?kg8O?YF_O?vd#tO?`zJO?/],O?]O?p!O?UO?&(6O?kO?Ф>O?G O?MO?C}O? vuO?z$LlO?]%cO?hKZO?7MCJRO?cIO?Y汞UAO?P*8O?S0O?Iwq(O?x< O?H-DJ$O?WO?PKXA:>XXSstar_from_SA_ca.npyNUMPYF{'descr': '@|@&@ds|79@1K@a}^@PKXA 5XX alpha_ca.npyNUMPYF{'descr': '@D@I@S@@Y@_@b@f@@i@o@r@v@@y@@@@@@h@@\@@@ @@@@Ρ@̣@ʥ@ʧ@ȩ@ȫ@ȭ@ʯ@@@@@@@@@PKXAԸcp_t_exact.npyNUMPYF{'descr': 'yD@v@@;@6@ X2@ .A/@Mt,@r&@Ÿ"@:o+@V)OS@3@ $@ @z5.@LG#y@_g@֝:@zr@K_<@&Eܮ@Kծ@39oϮ@ 6u@m@2x@VD帔@D@.z@km@Gی0a@>Z?U@jJI@P7F>@Nxc3@`w(@>_k0v@諆@>{ @ӈIС@bzI@PKXA/T-geo_strf_dyn_height_pc.npyNUMPYF{'descr': 'Tҿ@LH쿠X o${`f(vH$ PLtN B^@Hs! E"Hb$0 4%ګP'`<;M)`F{=/O+YR-M20/6w00:.G10 24Ɯ20.zo3 ] 4 (`4/(5(6@7z8F@9g X:Gsej;sw<@(b9?=!k>]?cH&B@t{@ki#AA:A;ABT/B`!{FC#CPKXAv:SP_from_SA.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@n)DA@7}vuEA@7FA@[[x^*HA@)&oIA@x$^JA@߽KA@̘5NA@hN4?zO]x4?jg4?^b'4?I4?x}4?Z=3?>; 2?*E[1?Q0?\6n-?\@#(?T _&?C%?`c$?M쮮g#?`g"?KA!"?|3h!?pLa!?_!?Z ?if% ?<}Gʆ ?5Vs ?s ?oG ?!?F8^!?`j="?g["?VA#?_ -^$?#ct)%?^Jۼ%?^&?= ZQ'?-d{(?bq(?-5)?%vN*?8 +?qL+?,>X0{,?PKXAxd̸SP_from_SR.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@q)DA@9}vuEA@7FA@][x^*HA@,&oIA@x$^JA@߽KA@̘5NA@PKXA,/entropy_t_exact.npyNUMPYF{'descr': 'nXnOx@GPx@ںkBx@7j]/x@zw@Wl=v@mvx}t@E,r@h&- p@\^n+l@$oze@:lb@ګG`@4(ϓ8^@D=5Z@maW@ok'U@+gGS@_ՏQ@O@lRL@%12J@aG@E@~D@3@@ڪ<@դP:y9@ ìF7@Ϭ5@Em-/4@L/)3@2@=uiZ1@ F~V0@p&/@'*/@2Mr.@*ϑk(.@;r.@]!ę-@M9_-@u&-@PKXAOXX CT_SA_ca.npyNUMPYF{'descr': 'PKXAbXXrho_rab_ca.npyNUMPYF{'descr': 'PKXA{s%pot_rho_t_exact.npyNUMPYF{'descr': 'h @~ @)] @`R @ @.@ @_y @JX@mA@PX_@mգ@=ZI@K@6(@A@ Z@M5f@Pg "@ +t(@.@l4@66@B7:@+<@s;@ <@c<@<@PKXA eta_SA_CT.npyNUMPYF{'descr': 'PKXA(XXinternal_energy_t_exact_ca.npyNUMPYF{'descr': 'PKXA@Y"XXSA_from_rho_CT_exact_ca.npyNUMPYF{'descr': '%V?>aW? QMY?kehTZ?*]?L_?Aa?C.%c?5+:d?Gbe?e?C\Åf?sYg?$$g?T h?dEH%h?!*hh?h?Bhh?_rph?3X>ph?Ugrh?PKXA9_pt_from_CT.npyNUMPYF{'descr': 'D?PPy?PװO?s?t`{?o1?n9ҍ?Ș?2:z-r? Eِ?oh?HO R)?ʻ{*?o?v ?7 Ԑ? 1Q%!? P_?j>??&?F?Ov?l~}G? + H?PKXAϜXXentropy_t_exact_ca.npyNUMPYF{'descr': 'PKXAgXXSA_SA_Sstar_from_SP_ca.npyNUMPYF{'descr': '+7@︖A@ڢM@7cZ@YA4i@Xx@'D:爗@3ez@=J)@T0\P@sX̗@D׼mޗ@v9@=%@6G`@GPr)&@8Ar9@ Q$L@h|2I^@PKXA3$ h_SA_SA.npyNUMPYF{'descr': '(YFZZ?TX^?kd?;%h?Axml?U "p?.^<u?3?}^y?i%}?<= ?A?]v?TZ? ?0?@`W?~C?nwv?=[l?K?w'?=6p?L~?va3?Ii?{3?T/ "Ĥ?"o~ڕ?xE?~? ,?t3?' 87?,ψ1?kw%?PKXA2internal_energy_t_exact.npyNUMPYF{'descr': '|8@4` %@$t@Pml@8://F@~k/ƣ@9& %@8Lف@Zϱ@u@6O@W@uM!@!PX@PKXA]XXspecvol_anom_CT_exact_ca.npyNUMPYF{'descr': 'PKXArXX sigma1_ca.npyNUMPYF{'descr': '6.MꤿsܤOaZTs$X*LxSp-|%+cf%ӻaca+ >(ƑmkᖐX,T썿ŀ Nj&';ov烈,n$KMׅFH{LiEānp%#;4T-}!J|蓕zD{fߎzөaz2H0y[ @'y:j4W=xI‹x-/KxWS2xoh2x&ZwyXfw;9wwY@wPKXAsK4XX grav_ca.npyNUMPYF{'descr': 'N~A@jA@!MA@8.1DLA@WHOA@#RA@dfk_TA@\݌UA@;+_QWA@^XA@9>EZA@P[A@Ή@]A@+^A@7/`A@ח JaA@QM{bA@ZeA@6vgA@7[=CsnA@$nA@y>nA@G#oA@/ vZoA@dRSsoA@X[yZoA@caoA@aoA@6coA@PKXAOfCT_chck_cast.npyNUMPYF{'descr': 'wv9@;a7@"s4@i$2@G/@ȸݜ(@{x$@4u~"@;D @_L5h@y@L`@O(sH@6+^@f@*@QVA4 @ҴN @A&ft@I2 @y<6@Lg?8?x?B从??]?jD?{7?{`I&?#{+@x?[L6?bָ?iv?9Aqn?yuF?)??ICJ=?PKXA<0alpha_CT_exact.npyNUMPYF{'descr': '4?\4?L4?BP+4?ږ4?.f4?Lp4? J3?T2?U1?3/?/a!h-?YJ(?#\&?K%?婿Ω$?axg#?MNʭ"?+IF#"?ڋN%!?Dc!? !?dN ?>Is; ?t ?޶v ?qv ?*eN ?Pˠ5u!? !?5+A"?T؟"?qi#?~b$?(̞~%?/a%?OPsÙ&?8&W'?< (?I~2(?$)?n:T*?#4t.+?\!+?́,?PKXA%7t90_from_t68.npyNUMPYF{'descr': '@߁@/6@R?uU?na_?+]ٸ?m?Fm1!?[ƻ?*\u"[?}@ ?pPZ?Fb?7?`?I?հuT{? m?ј`5?PKXArXX beta_ca.npyNUMPYF{'descr': 'F~q=Y>PDZ6Y>*>+9Y>` 0Y>brQf#Y>X>}W>)+EV>>@cT>IRR>lSP>ԯ,SL>6HBI>4͓ԻcH>8d6G>/$E>~CD>l'D>c)C>C暶;C>QLB>'܃B>h2LB>i9;'B>.^ B>"uB>WLV:B>ȓUB>2,C>)tC>p6D>C+AE>:DuF>_yF>40bG>;QH>2 I>_7I>*J>K{%hK>k~S,L>$8mL>8LFM>hN>PKXA^7XXenthalpy_ca.npyNUMPYF{'descr': 'PKXAԶXXalpha_wrt_t_exact_ca.npyNUMPYF{'descr': 'nXnOx@HPx@ۺkBx@7j]/x@zw@Wl=v@mvx}t@E,r@h&- p@\^n+l@$oze@7lb@ګG`@5(ϓ8^@B=5Z@maW@ok'U@+gGS@\ՏQ@O@lRL@$12J@aG@E@~D@3@@ܪ<@פP:y9@ ìF7@Ϭ5@Em-/4@L/)3@2@=uiZ1@ F~V0@p&/@%*/@2Mr.@*ϑk(.@;r.@_!ę-@M9_-@t&-@PKXAngXXSP_from_C_ca.npyNUMPYF{'descr': 'W?oo?K{/L?Ӛ?9#?46"-7PKXAĸSstar_SA_Sstar_from_SP.npyNUMPYF{'descr': 'XA@I)A@n &~A@DxjA@jYZMA@KA@f=NA@G"RA@q@]SA@"c_YTA@}:UA@5NcLWA@hgXA@i+P@YA@x>2[A@/ҽu\A@h]A@y^A@)u"_A@$~hbA@dA@г\LdfA@ e¨gA@hA@GsiA@cTjA@jA@ >kA@xկkA@~LNy8lA@<_lA@6lA@kZblA@бlA@s$elA@^LlA@1 lA@PKXAr9 C_from_SP.npyNUMPYF{'descr': 'PKXAzXXSP_from_R_ca.npyNUMPYF{'descr': '@D@I@S@@Y@_@b@f@@i@o@r@v@@y@@@@@@h@@\@@@ @@@@Ρ@̣@ʥ@ʧ@ȩ@ȫ@ȭ@ʯ@@@@@@@@@PKXA8^XX C3515.npyNUMPYF{'descr': '^W@Vdg/W@4ۂW@OW@ɳXXW@َW@hW@-PW@X~W@Ж^lW@p)W@&W@2ֲW@PKXAxMXX eta_SA_ca.npyNUMPYF{'descr': 'PKXAXXf.npyNUMPYF{'descr': 'PKXAǥAbs_Pressure_from_p.npyNUMPYF{'descr': '=PKXAx.|XXCT_from_pt_ca.npyNUMPYF{'descr': 'PKXAtXXdelta_sa_ref_ca.npyNUMPYF{'descr': 'N~A@jA@!MA@8.1DLA@WHOA@#RA@dfk_TA@\݌UA@;+_QWA@^XA@9>EZA@P[A@Ή@]A@+^A@7/`A@ח JaA@QM{bA@ZeA@6vgA@7[=CsnA@$nA@y>nA@G#oA@/ vZoA@dRSsoA@X[yZoA@caoA@aoA@6coA@PKXA XXlatentheat_melting_ca.npyNUMPYF{'descr': 'PKXA-specvol_anom_t_exact.npyNUMPYF{'descr': '"nN>'Ǵ>NG>r  >iv>>=BE>wk>\K~Q>R0zrp>ph >hJ*H>bJ@>D6L>3.>b(>P>L*>jw$>{-/>㬂X>D>F>ͥ>>~}>$ڡ>|@f>^>>_>( >8~>\>c>`01`>&!>.*5>2(^>X1*>䆮z> i>p@>p/>PKXAJ״XX eta_CT_ca.npyNUMPYF{'descr': '6@6@7@n8@܋99@)ۉ. :@1,ԯ:@am,;@.S<@k=@+>@o?@@@PKXA@J/sigma0_CT_exact.npyNUMPYF{'descr': 'i1;@@Jw0D;@?زT;@6zc;@ vq;@ge};@;@[o;@>֗;@@[c;@@V~;@@풷;@ JA;@@`;@jC;@@SM;@Y;@@Ê1;@:;@#0;@%;@gЍ;@1 ;@]n;@7;@%;@l+;@PKXAtLXXalpha_CT_exact_rab_ca.npyNUMPYF{'descr': 'wv9@;a7@"s4@i$2@G/@ʸݜ(@yx$@4u~"@;D @`L5h@y@M`@O(sH@4+^@f@(@NVA4 @ҴN @@&ft@I2 @y<6@Lg?8?x?B从??\?kD?{7?y`I&?${+@x?ZL6?bָ?iv?9Aqn?yuF?)??HCJ=?PKXA4sXX!geo_strf_velocity_mid_long_ca.npyNUMPYF{'descr': '@|D@H@S@i?Y@_@b@ef@z?i@o@6r@v@?y@@@@?@.h@@[@@@@@@@Ρ@̣@ɥ@ɧ@ǩ@ǫ@ȭ@ɯ@@@ @@@@@@PKXA^1XXSA_from_rho_t_exact_ca.npyNUMPYF{'descr': '_ײW@PKXAzҸ CT_SA_pt.npyNUMPYF{'descr': 'lW/W2=WѵWJo|X:̫ X"jPXbX2kJmXXXJ{XF3 X[c X2,"!X:K!XPKXAOf CT_from_t.npyNUMPYF{'descr': 'wv9@;a7@"s4@i$2@G/@ȸݜ(@{x$@4u~"@;D @_L5h@y@L`@O(sH@6+^@f@*@QVA4 @ҴN @A&ft@I2 @y<6@Lg?8?x?B从??]?jD?{7?{`I&?#{+@x?[L6?bָ?iv?9Aqn?yuF?)??ICJ=?PKXAϜXXentropy_from_pt_ca.npyNUMPYF{'descr': 'PKXA3= chem_potential_water_t_exact.npyNUMPYF{'descr': 'nXXpt_SA_SA_ca.npyNUMPYF{'descr': 'N~A@jA@MA@!.1DLA@WHOA@RA@xfk_TA@[݌UA@)+_QWA@kXA@^9>EZA@P[A@ʉ@]A@*^A@`/`A@Jؗ JaA@M{bA@ZeA@.6vgA@C[=CnA@L#oA@@ vZoA@dRSsoA@[yZoA@caoA@UaoA@ZcoA@PKXAaXXchem_potential_t_exact_ca.npyNUMPYF{'descr': 'PKXAfr IPVfN2.npyNUMPYF{'descr': '? F??: 8?PE_?mx( ?U-I @2?8I C:s?vvd?PKXA6,S$SA_SA_Sstar_from_SP.npyNUMPYF{'descr': 'N~A@jA@#MA@:.1DLA@WHOA@%RA@gfk_TA@^݌UA@=+_QWA@aXA@9>EZA@P[A@щ@]A@+^A@:/`A@ח JaA@SM{bA@ZeA@6vgA@9[=CnA@J#oA@1 vZoA@dRSsoA@Z[yZoA@caoA@aoA@9coA@PKXAMK-XXdepth_from_z_ca.npyNUMPYF{'descr': 'PKXAdFXXR_from_SP_ca.npyNUMPYF{'descr': 'OaBLf/w*'vr@{/7\r)~NjR1ZX[Kw\?c3 s)mj 0z&sDjS̩쾮 O͎hmi> !YahT" ^mm.#<$NE&J'm(?ZwS*)V+v-]R4J{..zM/*4Z0ݚW1à 2 2:t3PKXAyTp_chck_cast_shallow.npyNUMPYF{'descr': '@D@I@S@@Y@_@b@f@@i@o@r@v@@y@@@@@@h@@\@@@ @@@@Ρ@̣@ʥ@ʧ@ȩ@ȫ@ȭ@ʯ@@@@@@@@@PKXA-  fdelta.npyNUMPYF{'descr': 'y/V>0>>\~K>N _J>tΆ>ߺyc>6q>˔>"OP> 2b?Y ?59A?!?:Tu$?웳'?EC4?dJ6?ɭY=9?̋;?r+ZB>?{Eϵ7@?ERA?zA?n?FB?)=m&C?ΞN}lD?Vh&D?hg5E?WJE?MKE?`9z*:E?\G8E?%f-D?K/D?k$MD?22x#D??PCC?7"R2C?:C?C? SbC?eI(cC?PKXA= geo_strf_dyn_height_pc_p_mid.npyNUMPYF{'descr': 'PKXA63chem_potential_salt_t_exact.npyNUMPYF{'descr': 'PKXA2entropy_from_pt.npyNUMPYF{'descr': 'nXnOx@HPx@ںkBx@7j]/x@zw@Wl=v@mvx}t@E,r@h&- p@\^n+l@$oze@9lb@ګG`@7(ϓ8^@B=5Z@maW@ok'U@+gGS@\ՏQ@O@lRL@%12J@ aG@E@~D@3@@ݪ<@פP:y9@ ìF7@Ϭ5@Em-/4@L/)3@2@=uiZ1@ F~V0@p&/@(*/@2Mr.@*ϑk(.@;r.@_!ę-@M9_-@w&-@PKXAnXX#chem_potential_water_t_exact_ca.npyNUMPYF{'descr': 'PKXAJPa XXdistance_ca.npyNUMPYF{'descr': 'PKXAhVUtXXsigma0_CT_exact_ca.npyNUMPYF{'descr': 'PKXAհp_mid_TuRsr.npyNUMPYF{'descr': 'PKXA,'Jinternal_energy_CT_exact.npyNUMPYF{'descr': '|8@4` %@$t@Pml@8://F@~k/ƣ@9& %@0Lف@Zϱ@u@6O@W@uM!@!PX@PKXA6xXXspecvol_anom_ca.npyNUMPYF{'descr': 'PKXAU]XXCT_pt_pt_ca.npyNUMPYF{'descr': '"?*"?`}Rx#?dHX_$?=c%?wx%?lɖ&?2iT'?yk(?=(?1$z)?S*?3 +?DF+?O,?PKXA.FXXbeta_CT_exact_rab_ca.npyNUMPYF{'descr': 'A@)>A@z &~>A@;j>A@d'AA@*PBA@b\A@ v|A@,_EA@ A@>)|A@jbhA@ KA@2Y+0JA@)sMA@urPA@K%]8RA@Gd1eSA@Dgl)UA@'VA@XA@-TYA@&[A@d;_\A@ܲ^A@R _A@TEحR`A@ CbA@ ," LeA@wgA@Vۻ`hA@uJ~\iA@-jA@ejA@FykA@{kA@7q]lA@! lA@lA@MZ+mA@6DmA@(+mA@XT,2mA@JFn1mA@eL3mA@PKXA 1~ pt_from_t.npyNUMPYF{'descr': ''?Q׆7'?̪F-I)?^)?l*?m*?([+? 5+?V,7 ,?Ԙ*@O,?04,?V?,?bw.-?NS;-?]y^h-?#1B-?#%d-?Jx-?]b*.?ҕ/J.?c8e.? hw.?9ֹ.?z.?%.?cݣ.?zū.?`.?0.?;X[R.?6.?@H߈.?9.??HP.?,i.?PKXA }7XX!isochoric_heat_cap_t_exact_ca.npyNUMPYF{'descr': 'PKXADXXeta_CT_CT_ca.npyNUMPYF{'descr': 'PKXA. z_from_p.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@n)DA@6}vuEA@7FA@[[x^*HA@)&oIA@x$^JA@߽KA@̘5NA@|1|,@rR,@,@,>[,@Sw,@?r,@?~'Y,@i,@,@ET2-@g-u -@sg-@CF[-@rR@-@{N-@v-@-&-@z@!-@ծ-@ -@,,5V-@ 6e-@0s-@L-@?|-@xC-@PKXAPKXAGg@ distance.npyNUMPYF{'descr': 'QA.!,QApOQA QAbhQAu>QA^OQAf\QA|QA=PQAz_$QAoKQA @QAȘQAtQAp{GQA QAm(QAQAKQA(+ikQA!({?QAOAQA׭@QAQAPKXA}XXsteric_height_ca.npyNUMPYF{'descr': 'PKXAJDgXX n2_ca.npyNUMPYF{'descr': 'ձp?U?;@㷽@ж=AjA#>Bl+8#B8+@C,_C8S"GD@DPKXAXXp_mid_IPVfN2_ca.npyNUMPYF{'descr': 'PKXA^SXXh_SA_CT_ca.npyNUMPYF{'descr': 'E=dsC=ӕz=18==>'/=EpY 8=M;=C̍-<= y:= 8=d804=$Q"/=o'=RR=Mچ=[=c>m=R$=s=@̡uD=[=c9=톌=*eME=W P= =Z=@j=Z+=ObHY=j'B(=Hƃ=Դ>=PKXAAd@XXionic_strength_from_SA_ca.npyNUMPYF{'descr': '?)LFl?Gzє?/|?<#V?\ ?b46?1VzT?}]j?xz?}1ч?ʴh?u?O?Xf?E@?9? O?",?a ?Fפ?9?&Ƕ?PKXACZh_SA.npyNUMPYF{'descr': 'N~A@jA@5MA@5.1DLA@WHOA@$RA@fk_TA@g݌UA@M+_QWA@]XA@9>EZA@Q[A@@]A@+^A@9/`A@ח JaA@DM{bA@ZeA@,6vgA@&[=CnA@#oA@ vZoA@dRSsoA@_[yZoA@caoA@yaoA@XcoA@PKXA}L!XXgeo_strf_Cunningham_ca.npyNUMPYF{'descr': 'PKXA#CT_from_rho.npyNUMPYF{'descr': '';PKXA@0cXXgeo_strf_isopycnal_pc.npyNUMPYF{'descr': 'PKXA%beta.npyNUMPYF{'descr': 'T@dXX@a-]@c$a@`*e@Y`+`j@(n@s s@2KNw@`T{@PKXAc2%u alpha.npyNUMPYF{'descr': '"?*"?`}Rx#?dHX_$?=c%?wx%?lɖ&?2iT'?yk(?=(?1$z)?S*?3 +?DF+?O,?PKXAZʝXX h_CT_ca.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@o)DA@6}vuEA@7FA@[[x^*HA@)&oIA@x$^JA@߽KA@̘5NA@T@dXX@a-]@c$a@`*e@Y`+`j@(n@s s@2KNw@`T{@PKXAҸSA_from_Sstar.npyNUMPYF{'descr': 'N~A@jA@!MA@8.1DLA@WHOA@#RA@dfk_TA@[݌UA@;+_QWA@^XA@9>EZA@P[A@Ή@]A@+^A@7/`A@ח JaA@RM{bA@ZeA@6vgA@6[=CsnA@$nA@y>nA@G#oA@/ vZoA@dRSsoA@X[yZoA@caoA@aoA@5coA@PKXA]XXspecvol_anom_t_exact_ca.npyNUMPYF{'descr': 'PKXA'θt_freezing.npyNUMPYF{'descr': '?Mܫt|?WW ?:?q|a?ff?Ik?|Dj??nʃ?뫿9?LIM??3,]?*?m?H;?Mİ9? 3/?͓B:??!'?W?.͌w ?PKXA`Ҹ CT_SA_SA.npyNUMPYF{'descr': 'W?mo?K{/L?Ӛ?9#?46@HTj>@u!?@@N?@@uU?@+B?@s*^?@ߒs?@@NO[?@@/= ?@Ɓ@@ V+ @@@@@@@@@0x%@@b,@@ e[0@@3@@ s%6@@  7@@<9@@ Y:@@;;@@u"?<@@&=@@Z=@@`g>@@@>@@`ix>@@[a>@@>@@s>@@PKXAcw  sigma0.npyNUMPYF{'descr': 'A@`i9A@ Q#A@@F-sA@ CJXA@A@tIB@"S:B@#+B@IDt#C@ÏC@3dC@C@@2`[C@@w D@lj5D@9AFD@r4UD@4aD@rΩmD@`}xD@~7D@qKD@)D@խD@ MUD@{@Ͼcs)>@@ݻ,>@>RL,>@5ґ7>@s@>@6He>@aL'_?@^@@ ;OK@@`:)@@ quA@'rA@@A@@yw4$A@,A@yq{A@  < B@B@ P&B@Ș1B@@:U@-N@y`@6򃶮@Slx@=-@S@yqQƮ@ _ցӮ@@3Մ@ZL&@NMp@#@):@uA@CB>@vԅ@a@+Z@ř@LSۮ@|\ծ@|uZϮ@iIRɮ@î@Ê@_Cͬ@hu9@zH@V~}@ߗn@g_@)P@]YB@44@Gѕ&@Wo{X@A @@Mo@A~,@dv=׭@z|ʭ@4tܾ@PKXANn%specvol_anom.npyNUMPYF{'descr': '/>(j>ߵY>g^ʩ>1v>b2>L+E>đi?k>h%>-o>Q >j.=> >>T I>X>|&>>C(>?!>0@,>U>;> >˥>(C>xpB맣>z١>+jie>~>p.>簜>GX>]E폛>>؜>z^>>4>xFy>6u)>oz>V%>XV>/>PKXASuXXpt_from_t_ca.npyNUMPYF{'descr': 'PKXALXXt_maxdensity_exact_ca.npyNUMPYF{'descr': 'wv9@;a7@"s4@i$2@G/@ȸݜ(@{x$@4u~"@;D @_L5h@y@L`@O(sH@6+^@f@*@QVA4 @ҴN @A&ft@I2 @y<6@Lg?8?x?B从??]?jD?{7?{`I&?#{+@x?[L6?bָ?iv?9Aqn?yuF?)??ICJ=?PKXAϜXXentropy_from_CT_ca.npyNUMPYF{'descr': 'PKXAjM~XX"osmotic_coefficient_t_exact_ca.npyNUMPYF{'descr': 'PKXAY:XXt_from_rho_exact_ca.npyNUMPYF{'descr': 'PKXA`XdeltaSA_from_SP.npyNUMPYF{'descr': 'S>???=?v?V5G?G?PKXA؆grav.npyNUMPYF{'descr': 'PKXAY]۸t90_from_t48.npyNUMPYF{'descr': '4?\4?L4?BP+4?ږ4?.f4?Lp4? J3?T2?U1?3/?/a!h-?YJ(?#\&?K%?婿Ω$?axg#?MNʭ"?+IF#"?ڋN%!?Dc!? !?dN ?>Is; ?t ?޶v ?qv ?*eN ?Pˠ5u!? !?5+A"?T؟"?qi#?~b$?(̞~%?/a%?OPsÙ&?8&W'?< (?I~2(?$)?n:T*?#4t.+?\!+?́,?PKXAĻ)XXp_from_Abs_Pressure_ca.npyNUMPYF{'descr': 'PKXA8'XXP0.npyNUMPYF{'descr': '[6JA`+ A>AFbA3!A78LiA{AI^A3AFAM_OHA -cCA AV2AmcR#A}AmsAѕ&iAcet^ACSAHAPKXAXXp_mid_n2_ca.npyNUMPYF{'descr': 'PKXAXXp_mid_G_CT_ca.npyNUMPYF{'descr': 'PKXAvXX sigma3_ca.npyNUMPYF{'descr': 'PKXAS h_SA_CT.npyNUMPYF{'descr': 'PKXA(XXinternal_energy_CT_exact_ca.npyNUMPYF{'descr': 'PKXA1XXpt_SA_CT_ca.npyNUMPYF{'descr': 'u=]x= 3+2=kw,r&=|6?V=ÁD|=sNX=u_dh=d/܇=Z=c=.և=~k=| =~Ms=,K=)͵=Yϐ=(Lռ=[U=z#N=BZY=>^%ׅ=Uhvř=b|Z=oF=PKXAspecvol_t_exact.npyNUMPYF{'descr': 'I^O?*=O?c O?HVO?kX}O?'o#uO?9ZKlO?cO?pT(ZO?zZJRO?VkIO? jbUAO?y8O?Jݿ0O?۾q(O?= O?PKXAgeo_strf_Montgomery.npyNUMPYF{'descr': '.,&D\--r.|ΰ/z)[V0J!0xᒺ0:N"1n:K12^ ,~1m1Ô1݃ 1y18i_1 =1H1q0PKXAgxQ@qFQ@U|ՂP@aTf/P@hO@`/O@_EN@{ .pN@O\M@*czM@ĉM@DL@d;F L@sf9/K@rzDK@J@|ήqJ@lɸsI@,41|H@G@y F@tE@e)D@? }C@NB@vB@@ #<@W*8;@V9@3E7@GR5@[^4@PKXAxZsteric_height.npyNUMPYF{'descr': 'j6ӿ ܿ3]!$SJ-pi}R<뿛G3Cνnh_z6DVH2¢RZP5`CɺT,h8wP{*r;y :h"@ ˠdb3eAZq:=ͺQ-X棺69jih m&9 ~߻W a( 7ig 37Io[q:/S# BbPKXAyXX sigma0_ca.npyNUMPYF{'descr': '&~<#~>T!~~os~=O~`]~0J~cm~~èW~UW9~U~~?Qy~PKXAӰPXXosmotic_pressure_t_exact_ca.npyNUMPYF{'descr': 'PKXAvɭsigma2_CT_exact.npyNUMPYF{'descr': '@)>@,>@@F,>@4q7>@A>@@v>@@Ř_?@@@`d@@ @@`{\A@ rA@ 6FA@qv*A@ҽA@`IA@˄"G B@ h+B@ ~^&B@1B@*B@`fB@@B@GB@`)ƈB@@ʈB@PKXA׸t_from_rho_exact.npyNUMPYF{'descr': 'W?o?N/L?D?49#?-6O@0 @a2"@H$@RP&@?XX(@cZ_T*@7/@_4@Ta{8@Φo=@<B@>F@g^J5K@)u:ۿO@ձD?T@zX@ .]@~ޚa@^e@F`j@ܥn@ris@*rMw@ {@PKXA~a enthalpy.npyNUMPYF{'descr': '5z ?C[ ? ʎE ?~nB ?Yu ?7K ?.SQ!?eT!?V4)"?,z0#?Kjb/5#?#݋$?F<%?b>I%?lc&?٠O'?Kh'?(?\=qZ)?xMǮ*?_l*?epV+?PKXANXX G_CT_ca.npyNUMPYF{'descr': 'PKXA1q0XXNeutral_Density.npyNUMPYF{'descr': '.wF@ =F@w|F@&F@`I#BF@`vF@ 3F@@%F@+F@Zh9F@`kF@PKXAbXXrho_t_exact_ca.npyNUMPYF{'descr': '-?PKXA-paXXCT_SA_SA_ca.npyNUMPYF{'descr': 'I^O?*=O?c O?HVO?kX}O?'o#uO?9ZKlO?cO?pT(ZO?zZJRO?VkIO? jbUAO?y8O?Jݿ0O?۾q(O?= O?U%_>+nG`>\M]>oR\^>v}a>=1Q>oC>nD>Y >Πۂ>-f>$;B>X>Eˆ>2Y>KkH>m}>v/)4>K- >5+x>fĒ_)>TT{3>zA7>Ū5>hG0>0~%>鍽>J>%|h>M>$!>1=*\>^J.>)Z>Rss:>ي>Dơv>w> e> vNL>l> n(?>|8ǟ'$>47W>PKXAJXXsigma3_CT_exact_ca.npyNUMPYF{'descr': 'PKXA8XXSP_from_SR_ca.npyNUMPYF{'descr': '?s\' >?)=?0>@=?<=?'=?i;?Huo8?g2?NY_*?G?#??e?+A_?^F?ZA ?ZlD ?1Di ?i ?ԌU ?0 ?ڋ ?#gɥ? ?/$?> ?ɜ?|u?^?`U?Vvh?:A43?2l?+?ո+?w ?LVG ?\r ?B ?r4 ?t\S ?ljW0 ? d ?&ǖ ?d^ ?v[i  ?PKXA4sXX geo_strf_velocity_mid_lat_ca.npyNUMPYF{'descr': 'XA@ I)A@k &~A@BxjA@jYZMA@KA@d=NA@G"RA@n@]SA@!c_YTA@{:UA@5NcLWA@egXA@g+P@YA@u>2[A@.ҽu\A@h]A@y^A@&u"_A@$~hbA@dA@ϳ\LdfA@e¨gA@hA@GsiA@aTjA@jA@ >kA@vկkA@{LNy8lA@<_lA@6lA@iZblA@бlA@p$elA@^LlA@1 lA@PKXAtLXXalpha_CT_exact_ca.npyNUMPYF{'descr': 'XA@ I)A@l &~A@BxjA@jYZMA@KA@d=NA@G"RA@n@]SA@ c_YTA@{:UA@5NcLWA@egXA@g+P@YA@u>2[A@-ҽu\A@h]A@y^A@'u"_A@$~hbA@dA@γ\LdfA@e¨gA@hA@GsiA@aTjA@jA@ >kA@vկkA@{LNy8lA@<_lA@6lA@iZblA@бlA@p$elA@^LlA@1 lA@PKXA~XXC_from_SP_ca.npyNUMPYF{'descr': 'PKXAXXp_mid_TuRsr_ca.npyNUMPYF{'descr': 'PKXA0,HXXkappa_t_exact_ca.npyNUMPYF{'descr': '4?\4?L4?BP+4?ږ4?.f4?Lp4? J3?T2?U1?3/?/a!h-?YJ(?#\&?K%?婿Ω$?axg#?MNʭ"?*IF#"?ۋN%!?Dc!? !?dN ?>Is; ?t ?޶v ?qv ?+eN ?Pˠ5u!? !?5+A"?T؟"?qi#?~b$?(̞~%?/a%?OPsÙ&?8&W'?< (?I~2(?$)?n:T*?#4t.+?\!+?!́,?PKXABXbeta_const_CT_t_exact.npyNUMPYF{'descr': 'PKXA {XXpt_CT_CT_ca.npyNUMPYF{'descr': 'PKXAŕ^XX h_P_ca.npyNUMPYF{'descr': 'H?9H?{H?PMH?f>H?.? H?;EtH? R?_H?a4 KH?6H?k"H?J H?)V cG?r)G??ղG?rJkrG? [G?hIwG?TÀG?U 6mG?PKXAHXXgeo_strf_velocity_ca.npyNUMPYF{'descr': 'PKXASuXXpt_from_CT_ca.npyNUMPYF{'descr': 'PKXAe R_from_SP.npyNUMPYF{'descr': 'v?k3?_? nt?vi?RHe?)h?/p?.6{?L%?j?֐.?u:߽t?'vXY? B?&9?9r? ?!?s&96?PKXAZXXgeo_strf_dyn_height_pc_ca.npyNUMPYF{'descr': 'PKXAIgeo_strf_Cunningham.npyNUMPYF{'descr': 'PKXA 'ɸlatentheat_evap_t.npyNUMPYF{'descr': ' CAҧ?# CAX4 CAH.l# CA7 CA  CAJCA|YCA"hCA.Gf}CAPKXA:>XXSstar_from_SP_ca.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@n)DA@7}vuEA@7FA@[[x^*HA@(&oIA@x$^JA@߽KA@̘5NA@S@@ G@Ii@PKXAHn X SP_from_C.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@p)DA@7}vuEA@7FA@[[x^*HA@*&oIA@x$^JA@߽KA@̘5NA@PKXA'adynamic_enthalpy.npyNUMPYF{'descr': 'H'@ غ@gd]@nWa?@EE(@Z&-@b{G@BU#@% 1@/l2@wμC@AڊR'@h"@v@6;V@ @?7 @T@p@2u^F(@mPY@w>G@c72@j_% @`ϫ$@ nXX@ScV놊@ͯO@PKXA-U CT_pt_pt.npyNUMPYF{'descr': 'D ?4|G ?4ުG ?2yP ?1}x}Y ?}' ?=p!?|;O"?YH#?ۄ#?x #?r#?l]Y"?h@>L U!?cDk ?@KK?@9?,5??k??y6(?p@?h>CK?O+? ? ?m E? ?9:S?b?f<?p>n8>@>O(h>>d82>38>>~q>I# 7>w->P*>PKXA%G_CT.npyNUMPYF{'descr': 'PKXA4!> pt_SA_CT.npyNUMPYF{'descr': 'A@W>A@@">A@2yw>A@+AA@+YnܲBA@> \A@||A@7_ATA@P/A@9\8|A@*hA@/x6KA@p,JA@BMA@PPA@YIRA@ZB wSA@aL/R%@Kb-@`(Yf@3-IBZ@AsOB@]TZ@mK+@>±T5@>@ј@Õk @07:h@Á頯@"@AK@sٙV@ WCkg{@8Da; @[4؄Ծ@LO@FӸ@Yj@0債@ƌbHj@J1xF@njz@*@Ջ@aJư@ҸU@D @Ϡ@4CY@' @ /p$3@PKXAx!XXlong_chck_cast.npyNUMPYF{'descr': 'sivh@PKXA/u|specvol_anom_CT_exact.npyNUMPYF{'descr': '"nN>'Ǵ>NG>r  >jv>>=BE>wk>\K~Q>R0zrp>ph >hJ*H>bJ@>D6L>3.>b(>P>L*>jw$>{-/>㬂X>D>F>ͥ>>~}>$ڡ>|@f>^>>_>( >8~>\>c>`01`>&!>.*5>2(^>X1*>䆮z> i>p@>p/>PKXA*ubeta_const_pt_t_exact.npyNUMPYF{'descr': '\H?0H?2wŧJH?'dH?DjH?OsH?ē¢H? MH?-ŷH?H?*AsH?F2@H?4tH?=VH?O+H?(dgH?_H?e|T@H?CdH?\Yr.H?H?H?kH?yp`nH?j@YH?'CH?e.H?cYH? ?BH?7h&G?r䍥G? G?{*$G?EG?K7Q˅G?e)qG?lH\G?PKXAᡸSP_salinometer.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@n)DA@7}vuEA@7FA@[[x^*HA@(&oIA@x$^JA@߽KA@̘5NA@$۸ e;Ze {"WSwg#%)tUj% \ $!-0 Sbb %x1Nh1w'ğI?XU@re#Z ZI)P?F-?%/?N83"5 !J1-70cO. ;<Xp!g"5 b`#4%@KZ&{'. )G/p*Yi+<-6ȩ.h 0_e (0"1KB>2_ 2̗3PKXA;XXalpha_wrt_CT_t_exact_ca.npyNUMPYF{'descr': ' 7^A@ 9~A@" MiA@ZCA@_W>N~A@jA@5MA@>.1DLA@WHOA@%RA@gfk_TA@`݌UA@M+_QWA@PXA@9>EZA@P[A@㉈@]A@+^A@/`A@ח JaA@MM{bA@ZeA@66vgA@*[=CnA@0#oA@ vZoA@dRSsoA@w[yZoA@caoA@uaoA@8coA@PKXA:>XXSstar_SA_Sstar_from_SP_ca.npyNUMPYF{'descr': 'PKXAUUKXXgeo_strf_isopycnal.npyNUMPYF{'descr': '@@a>@=u!?@øN?@y]?@@ L?@#l?@E8?@l?@?@k@@ @@ !Q)@@a\G@@@@)%@@",@@z:Wm0@@3@@G6@@ 6v7@@(O9@@ G/:@@j ;@@`4<@@@ϣ=@@e =@@`}{>@@@)j>@@6I>@@8>@@̹>@@>vY>@@PKXAhVUtXXsigma0_pt0_exact_ca.npyNUMPYF{'descr': 'O@0 @a2"@H$@RP&@?XX(@cZ_T*@7/@_4@Ta{8@Φo=@<B@>F@g^J5K@)u:ۿO@ձD?T@zX@ .]@~ޚa@^e@F`j@ܥn@ris@*rMw@ {@PKXA7cXXmolality_from_SA_ca.npyNUMPYF{'descr': 'PKXA,CT_maxdensity_exact.npyNUMPYF{'descr': 'ۃ2Glr)( zcJShBQ%?4znY9d'yoR#-/OFZE'̘e ްEs}bQ$] {!0"K]u#jh`E6$b &uQ'PKXA=WXXspecvol_ca.npyNUMPYF{'descr': 'PKXAXXX sigma2_ca.npyNUMPYF{'descr': '>Ϳ3KEͿXͿBvv[ͿDͿ%ӿͿͿͿ:ƿͿ>.Ϳ&`ͿA#߸ͿPKXAQXXAbs_Pressure_from_p_ca.npyNUMPYF{'descr': 'i1;@@Jw0D;@?زT;@6zc;@ vq;@ge};@;@[o;@>֗;@@[c;@@V~;@@풷;@ JA;@@`;@jC;@@SM;@Y;@@Ê1;@:;@#0;@%;@gЍ;@1 ;@]n;@7;@%;@l+;@PKXAyڰTu.npyNUMPYF{'descr': '0@f$7@Q7B@ F@vJ@МeL@T<wL@y2JG@.jCC@K!vB@ü$E@^*kԲD@XC@`?B@LsTB@xх.fB@Uc妱A@OnA@` @@GA@ el"?@z?6=@:;@|8@ 5at|:@H|A:@]9@kH\:@,5 :@6xw<@վ;@S} E:@,B>@ Xq>@`$B@2X@f)D@`? UG@pX +9@PKXAR,XXsound_speed_ca.npyNUMPYF{'descr': 'PKXAx.|XXCT_from_entropy_ca.npyNUMPYF{'descr': 'PKXAXdynamic_enthalpy_CT_exact.npyNUMPYF{'descr': 'sivh@@D@I@N@U@[@a@ d@@g@j@`p@s@v@y@@@@h@@@@@@@H@ܗ@ԛ@̟@@@ޥ@ާ@ܩ@ܫ@ܭ@ޯ@@@@@@@@@PKXAU XX fdelta_ca.npyNUMPYF{'descr': '+@qկ@I@jIZ,@[=7E@r4e@7P@ܫ$@\~@5]k@T=#%@P' @_@eGNd@y$+@ΧnD@2r?"K^@pGz@CKď@#4A@9׃@: %@ ;>S@@ G@Ii@PKXAհ p_mid_n2.npyNUMPYF{'descr': 'O@0 @a2"@H$@RP&@?XX(@cZ_T*@7/@_4@Ta{8@Φo=@<B@>F@g^J5K@)u:ۿO@ձD?T@zX@ .]@~ޚa@^e@F`j@ܥn@ris@*rMw@ {@PKXAH*XXCT_maxdensity_ca.npyNUMPYF{'descr': 'L??(XC)?_ő?3Ɩ?U?=ɋ?;k2?OzN?N[:&?/ څ?Svm?+ e^?!ÄAN?j#ǁ?C5W?J1?imZ}?4P|??cJ{?Qz?2qXz?4y?Yv,y?0ﷅx?6W`x?+$Px?Gy(8x?Ye x? gUw?w?w?k`w?dPksw?PKXA8oXXp_from_z_ca.npyNUMPYF{'descr': 'PKXA%!N\Rt_chck_cast.npyNUMPYF{'descr': '? ?#<?F? ?ȡƦ???PKXAcuEbeta_CT_exact.npyNUMPYF{'descr': 'I^O?*=O?c O?HVO?kX}O?'o#uO?9ZKlO?cO?pT(ZO?zZJRO?VkIO? jbUAO?y8O?Jݿ0O?۾q(O?= O?+7@︖A@ڢM@7cZ@YA4i@Xx@'D:爗@3ez@=J)@T0\P@sX̗@D׼mޗ@v9@=%@6G`@GPr)&@8Ar9@ Q$L@h|2I^@PKXA@LXXisopycnal_slope_ratio_ca.npyNUMPYF{'descr': '4hw>hLKޡ~w>vt\?x=S?G,$?![Z0?3/*2?rHa3?o_Ҧ+?b$?K|8 ?:`g?ȃI?[{>L >,܎>qq [> 5>}Oz,>>;l>ve?= >PA>zp>Ͻb>s7>R>pF[> $h>}ʭ>y;>$(â>kcV>T>>۟ qn>/r">%>J}>-!A݀>Ah6B޴v>[KPJ>8<=>PKXA*FXXuPS.npyNUMPYF{'descr': 'XXSstar_from_SA_ca.npyPKXA~DXXkatomic_weight.npyPKXAsXXSA_from_Sstar_ca.npyPKXAv([|sound_speed.npyPKXA 5XX aalpha_ca.npyPKXA[eXX CT_pt_ca.npyPKXAyTep_chck_cast.npyPKXAԸJcp_t_exact.npyPKXA/T-. geo_strf_dyn_height_pc.npyPKXAv: SP_from_SA.npyPKXAnXXkpt_SA_SA_ca.npyPKXAkFkSA_from_rho.npyPKXAaXXxmchem_potential_t_exact_ca.npyPKXAfr nIPVfN2.npyPKXA6,S$oSA_SA_Sstar_from_SP.npyPKXAMK-XXqdepth_from_z_ca.npyPKXAdFXXYrR_from_SP_ca.npyPKXA ! rCT_pt.npyPKXAxtt_maxdensity_exact.npyPKXAyTvp_chck_cast_shallow.npyPKXA-  xfdelta.npyPKXA= wzgeo_strf_dyn_height_pc_p_mid.npyPKXAKkXXm|geo_strf_dyn_height_ca.npyPKXA63|chem_potential_salt_t_exact.npyPKXAXX~dynamic_enthalpy_ca.npyPKXA2entropy_from_pt.npyPKXAnXX#hchem_potential_water_t_exact_ca.npyPKXAJPa XXdistance_ca.npyPKXAhVUtXXsigma0_CT_exact_ca.npyPKXA 5XXalpha_rab_ca.npyPKXA0XXRsubrho_ca.npyPKXAհp_mid_TuRsr.npyPKXA!XXSP_salinometer_ca.npyPKXA!hXXinternal_energy_ca.npyPKXA,'Jinternal_energy_CT_exact.npyPKXA6xXXspecvol_anom_ca.npyPKXAjɵXXthermobaric_ca.npyPKXAXXt90_from_t68_ca.npyPKXAU]XXCT_pt_pt_ca.npyPKXA32!latentheat_evap_CT.npyPKXA (XX t_freezing_ca.npyPKXAhJ3XXCT_SA_pt_ca.npyPKXAVp alpha_rab.npyPKXA.FXXbeta_CT_exact_rab_ca.npyPKXA,y brineSA_t.npyPKXA 1~ mpt_from_t.npyPKXA4sXX"Pgeo_strf_isopycnal_pc_p_mid_ca.npyPKXAXXSSO.npyPKXAᜈ ept_SA_SA.npyPKXA }7XX!Gisochoric_heat_cap_t_exact_ca.npyPKXADXXޗeta_CT_CT_ca.npyPKXAVXXdsigma2_CT_exact_ca.npyPKXA^7XXpot_enthalpy_from_pt_ca.npyPKXA. z_from_p.npyPKXAXXcSP_from_SA_ca.npyPKXAaGnosmotic_pressure_t_exact.npyPKXA* XXܝbeta_const_t_exact_ca.npyPKXALXXkntpptCT_ca.npyPKXA})XXSA_from_rho_ca.npyPKXA0=ǥXXwp_Neutral_Density.npyPKXAUXSP_chck_cast.npyPKXAXXSR_from_SP_ca.npyPKXA4sXXof_ca.npyPKXAo eta_CT.npyPKXAh_SA_CT_ca.npyPKXAp]sXX«deltaSA_from_SP_ca.npyPKXA{ Nbeta_rab.npyPKXAhVUtXX0pot_rho_t_exact_ca.npyPKXAFkappa_t_exact.npyPKXAAd@XXionic_strength_from_SA_ca.npyPKXA.6z_from_depth.npyPKXA9r pt_CT.npyPKXACZh_SA.npyPKXA4&޸ٶSA_from_rho_CT_exact.npyPKXA}L!XXǸgeo_strf_Cunningham_ca.npyPKXA#WCT_from_rho.npyPKXA1CXX<h_CT_CT_ca.npyPKXA9XXvalence_factor.npyPKXA;sXXHkappa_const_t_exact_ca.npyPKXAc ؼpt_CT_CT.npyPKXA@0cXXgeo_strf_isopycnal_pc.npyPKXAXXIlatentheat_evap_CT_ca.npyPKXA%ؿbeta.npyPKXA=j"rho.npyPKXAc2%u alpha.npyPKXAZʝXX rh_CT_ca.npyPKXAHYuSP_from_Sstar.npyPKXA i rho_rab.npyPKXAҸSA_from_Sstar.npyPKXA]XXspecvol_anom_t_exact_ca.npyPKXAMK-XX3z_from_depth_ca.npyPKXA'θt_freezing.npyPKXA"osmotic_coefficient_t_exact.npyPKXA`Ҹ CT_SA_SA.npyPKXA.FXXwbeta_const_CT_t_exact_ca.npyPKXAP݅\XX eta_SA_SA_ca.npyPKXA-lt_chck_cast.npyPKXANl tsigma4.npyPKXA  Tsigma1.npyPKXAcw  4sigma0.npyPKXA~ sigma3.npyPKXAe{ sigma2.npyPKXAuisochoric_heat_cap_t_exact.npyPKXANn%specvol_anom.npyPKXASuXXpt_from_t_ca.npyPKXALXX4t_maxdensity_exact_ca.npyPKXAڸ h_CT_CT.npyPKXAOfCT_from_pt.npyPKXAϜXXentropy_from_CT_ca.npyPKXAjM~XX"osmotic_coefficient_t_exact_ca.npyPKXAXXsound_speed_t_exact_ca.npyPKXAY:XX<t_from_rho_exact_ca.npyPKXA`XdeltaSA_from_SP.npyPKXA؆grav.npyPKXAx.|XXCT_from_t_ca.npyPKXAY]۸t90_from_t48.npyPKXA8XXSP_from_Sstar_ca.npyPKXArXXbeta_rab_ca.npyPKXA Rsubrho.npyPKXADXXenthalpy_diff_CT_exact_ca.npyPKXA<0walpha_CTrab_exact.npyPKXAĻ)XXbp_from_Abs_Pressure_ca.npyPKXA8'XXP0.npyPKXA9XX nsigma4_ca.npyPKXAn&XXlat_chck_cast.npyPKXA׸xlatentheat_melting.npyPKXAXXdp_mid_n2_ca.npyPKXAXXp_mid_G_CT_ca.npyPKXAvXX psigma3_ca.npyPKXAհp_mid_G_CT.npyPKXASXX dynamic_enthalpy_CT_exact_ca.npyPKXAS eh_SA_CT.npyPKXAxaXX FTu_ca.npyPKXA(XXinternal_energy_CT_exact_ca.npyPKXA1XXZpt_SA_CT_ca.npyPKXAyyȸthermobaric.npyPKXAspecvol_t_exact.npyPKXAnXXpt_from_entropy_ca.npyPKXA9geo_strf_Montgomery.npyPKXAgbeta_const_t_exact.npyPKXAHXXT@geo_strf_velocity_ca.npyPKXASuXX@pt_from_CT_ca.npyPKXAe iAR_from_SP.npyPKXAZXXLCgeo_strf_dyn_height_pc_ca.npyPKXAICgeo_strf_Cunningham.npyPKXAcHXX"Echem_potential_salt_t_exact_ca.npyPKXA 'ɸdFlatentheat_evap_t.npyPKXA:>XXOHSstar_from_SP_ca.npyPKXAZTHionic_strength_from_SA.npyPKXAbXXJrho_CT_exact_rab_ca.npyPKXAy~VKSR_from_SP.npyPKXAXX :Mpt_SA_ca.npyPKXAXXMCT_freezing_ca.npyPKXAG; DNSP_from_R.npyPKXA^}¸'Penthalpy_CT_exact.npyPKXAHn X RSP_from_C.npyPKXAMK-XXSz_from_p_ca.npyPKXA'azTdynamic_enthalpy.npyPKXA-U dVCT_pt_pt.npyPKXA%FXG_CT.npyPKXAXXZt_from_CT_ca.npyPKXA4!> Zpt_SA_CT.npyPKXAo\brineSA_CT.npyPKXAh"h^pot_enthalpy_from_pt.npyPKXAx!XXV`long_chck_cast.npyPKXAZ`dynamic_enthalpy_t_exact.npyPKXA1XXbalpha_wrt_pt_t_exact_ca.npyPKXAIXXact90_from_t48_ca.npyPKXA/u|cspecvol_anom_CT_exact.npyPKXA*uebeta_const_pt_t_exact.npyPKXAᡸgSP_salinometer.npyPKXAڄ XXieta_SA_CT_ca.npyPKXA?eָ6jpt_from_entropy.npyPKXA lCT_maxdensity.npyPKXA;XXnalpha_wrt_CT_t_exact_ca.npyPKXAcuEnbeta_CTrab_exact.npyPKXA}KѸpSA_from_rho_t_exact.npyPKXA:>XXnrSstar_SA_Sstar_from_SP_ca.npyPKXA~(XXsenthalpy_diff_ca.npyPKXAŕ^XXsspecvol_t_exact_ca.npyPKXA.FXXtbeta_CT_exact_ca.npyPKXAEEXXtdynamic_enthalpy_t_exact_ca.npyPKXAUUKXX6ugeo_strf_isopycnal.npyPKXAYwugeo_strf_velocity_mid_long.npyPKXAWָwsigma1_CT_exact.npyPKXAhVUtXXysigma0_pt0_exact_ca.npyPKXA9,zgeo_strf_velocity_mid_lat.npyPKXA0^|rho_CT_exact.npyPKXA7cXX~molality_from_SA_ca.npyPKXA laXX~h_SA_SA_ca.npyPKXAˠOXXcp_t_exact_ca.npyPKXA,CT_maxdensity_exact.npyPKXA=WXXspecvol_ca.npyPKXAXXcabbeling_ca.npyPKXAsigma3_CT_exact.npyPKXAc}XX}CT_from_rho_exact_ca.npyPKXAXXX sigma2_ca.npyPKXAdepth_from_z.npyPKXAb*dXXtSA_from_SP_ca.npyPKXA ayH eta_SA.npyPKXAQXXۉAbs_Pressure_from_p_ca.npyPKXA@J/ksigma0_pt0_exact.npyPKXAyڰUTu.npyPKXAR,XX)sound_speed_ca.npyPKXAx.|XXCT_from_entropy_ca.npyPKXAX=dynamic_enthalpy_CT_exact.npyPKXA"0internal_energy.npyPKXAh/p_chck_cast_deep.npyPKXAU XX fdelta_ca.npyPKXAXXgeo_strf_isopycnal_pc_p_mid.npyPKXA1pXXcp0.npyPKXA|enthalpy_t_exact.npyPKXAհ p_mid_n2.npyPKXAbXX\rho_CT_exact_ca.npyPKXA%`Crho_t_exact.npyPKXAH*XXʜCT_maxdensity_ca.npyPKXAXXTT0.npyPKXA+ Нpt_SA.npyPKXA8oXXp_from_z_ca.npyPKXA%!N\4Rt_chck_cast.npyPKXAcuEbeta_CT_exact.npyPKXAsV. specvol_CT_exact.npyPKXA Îsound_speed_t_exact.npyPKXA@LXXاisopycnal_slope_ratio_ca.npyPKXAmjn2.npyPKXA*FXX>uPS.npyPKeeZgsw-3.0.2/gsw/utilities/data/gsw_cf.npz0000644000175000017500000072202012172027023021172 0ustar amckinstryamckinstryPKXARr specvol.npyNUMPYF{'descr': 'xP?vvP?gꗯ'P? A P?d P?:\O?^UO?t&O?GJO?y2O?2"O?%'O?o O?4sTO?'XO?kg8O?YF_O?vd#tO?`zJO?/],O?]O?p!O?UO?&(6O?kO?Ф>O?G O?MO?C}O? vuO?z$LlO?]%cO?hKZO?7MCJRO?cIO?Y汞UAO?P*8O?S0O?Iwq(O?x< O?H-DJ$O?WO?/P? P?DP?BP?uP?2P?ߵ-P?I5̲O?q`G2O?y]0O?܏`O?-O?E4O?#+O?]m/O?\?O?OEO?o O?M*1O?QO?;FO?qyO?wsO?ϹfO?W =dO?`D^O?7fO?AТO?]IO?8'O?T5O?aAW ~O?kuO?_ KlO?KWcO?cZO?!RO?$ IO?P AO?쑷68O?ƣMO0O?Ջ(O?{BO?*nO?L-O?:7MP?EMP?0 KP?HGJP?+,IP?hWp3HP?&<0sBP?#0->P?PKXA kalpha_wrt_CT_t_exact.npyNUMPYF{'descr': '4?\4?L4?BP+4?ږ4?.f4?Lp4? J3?T2?U1?3/?/a!h-?YJ(?#\&?K%?婿Ω$?axg#?MNʭ"?*IF#"?ۋN%!?Dc!? !?dN ?>Is; ?t ?޶v ?qv ?+eN ?Pˠ5u!? !?5+A"?T؟"?qi#?~b$?(̞~%?/a%?OPsÙ&?8&W'?< (?I~2(?$)?n:T*?#4t.+?\!+?!́,?Yr224?OQΆ4?%+4?)ez4?,Ғ4?m4?k[l3?*1?K0?kQH,?J@)?/"(?lv&?N>&W&?5%?lkx%?aD%{$? cr#??"&@"?,'"?7!?w0c!?X>!? dq!?C?  ?f~u ?9@i ?6I ?h~PP0!?f=t1*?ɖ+?y#X,?wRt?%?=?gpl?7Q">mkg>[]w >6<?PKXAސPPIgeo_strf_Montgomery.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@n)DA@7}vuEA@7FA@[[x^*HA@)&oIA@x$^JA@߽KA@̘5NA@Y}A@>rgA@$"JA@NNA@O@QA@KFžRA@ơ~TA@A>UA@UA@m4VA@?QWA@<WA@o-xXA@7YA@|yYA@YA@YA@mV^YA@+/YA@rZ| ZA@G@JZA@uE@UD@BV9>@OGɫ#@8 @p-@"@ S[ $@PKXAސPPIthermobaric.npyNUMPYF{'descr': 'N~A@jA@MA@!.1DLA@WHOA@RA@xfk_TA@[݌UA@)+_QWA@kXA@^9>EZA@P[A@ʉ@]A@*^A@`/`A@Jؗ JaA@M{bA@ZeA@.6vgA@C[=CnA@L#oA@@ vZoA@dRSsoA@[yZoA@caoA@UaoA@ZcoA@6KMA@"KA@A CzOA@eqMA@֙ NA@ TA@rǦ#xA@ha@A@ok|A@ֺ*_A@BƒzZA@p_A@*tgA@$iA@(ŞhA@P3fA@$8#aA@*zea]A@:_^q[A@IA][A@N[A@gE|\A@T) ]A@c_A@8d`A@FȘaA@˛bA@8jeA@F %>hA@3NEiA@&1kA@?X "lA@@mA@mA@$hnA@^woA@{t1toA@GMNoA@dWpA@!8pA@+'9pA@pA@1vrpA@u;pA@oAMqA@;Ng@)Z@ +ݦ@8Ҍ@-Iv@{`KJX@>8U"@-Shh$@PKXAސPPIP0.npyNUMPYF{'descr': ',N,rܐD,,tEC,xJ)d,N/d/RP6 @!b"!8z\U#ɫ%qAZ&f.g&PKXA6? pt_CT_CT.npyNUMPYF{'descr': '';.ݽh -}ak .̰j -Wl -=`k '=l͎ /!"\?#w 9#uvr#rCo"o\{"md#"kX!h.d!bs` (|ݬ>T/7~faEfxR-~pshJP}x p 0cnoOI~ zw SB(|3k-a2VZyݨC0fyZ?TAc @xv0?k4,1?P05?H9?PS};?p0C@`K1C@`\1C@`"2C@1C@6kDC@@9A}C@@uTD@Ђ]D@`1l$CE@-SݣE@Ġ@HTj>@u!?@@N?@@uU?@+B?@s*^?@ߒs?@@NO[?@@/= ?@Ɓ@@ V+ @@@@@@@@@0x%@@b,@@ e[0@@3@@ s%6@@  7@@<9@@ Y:@@;;@@u"?<@@&=@@Z=@@`g>@@@>@@`ix>@@[a>@@>@@s>@@xXfa:@ ~d:@@:d:@@.3e:@e:@:@'pm;@Ŋ!]y<@@NU9=@E >@*s>@?ј>@@j?@NxRX-?@M@?@@t8R?@m0cu?@@0ߌ:?@mq?@@iS?@^D?@j!?@όW@@]@@/de@@O,@@@M*M@@A#@@`+@@c@6/@@2@@ vf[b5@@ Xb7@@"y9@@6D;@@9e=@@Tz>@@@(?@@`Ѹ@@@@ NA@@ iA@@A@@9fPB@@`#0B@@ YPB@@g̷#@@\j|#@2%$@ $@U%@Zd%@@fe|%(@x[)@PKXA7 sigma0.npyNUMPYF{'descr': ';@saO;@r8[_;@@j;@@yǝu;@@W;@ ];@S˓;@&d;@".;@%Z;@>;@@b#-;@4-;@;@@;@pi;@H*;@v;@ƺ>;@ФS*;@";@)+;@@[B;@?[;@X?;@#Ƹ@d 7@Ss Q@Av@5S@m @2!%@@Ѻ:-f @PKXAb sigma3.npyNUMPYF{'descr': 'A@`i9A@ Q#A@@F-sA@ CJXA@A@tIB@"S:B@#+B@IDt#C@ÏC@3dC@C@@2`[C@@w D@lj5D@9AFD@r4UD@4aD@rΩmD@`}xD@~7D@qKD@)D@խD@ MUD@{3@3@/YE4@ V3@4@b5@=?6@PKXAy sigma2.npyNUMPYF{'descr': '@Ͼcs)>@@ݻ,>@>RL,>@5ґ7>@s@>@6He>@aL'_?@^@@ ;OK@@`:)@@ quA@'rA@@A@@yw4$A@,A@yq{A@  < B@B@ P&B@Ș1B@@( cz>@@Sy>@{>@F?z>@{5ɂ>@뀊?@` / P@@@@ &|7#A@ Yվw`A@`(l{A@0_A@ A@@]"A@A@`1A@=B@B@h= !B@:f-B@q>\8B@`9N:@B@AjGB@@;wOB@ VB@m#}]B@@2bgB@qB@bPvB@`#wzB@0T}B@B@LB@-?SB@kB@t5B@ YmމB@ox B@@ɟB@ |.B@yhB@@.wB@`hB@`TʌB@8,@,@npk-@%8.@@G.@$ae:/@~q~0@[K1@PKXApp IPVfN2.npyNUMPYF{'descr': '? F??: 8?PE_?mx( ?U-I @2?8I C:s?vvd?ݾa?*C3P?m7g?<~5h?B?X?šjߵ?&J?D,?ힰG?X<5x?2_?{]?w5?&%?Ӵ3}?wY?!"P? ?U?zT? @|@&@ds|79@1K@a}^@_5 @@ @ӳA @Kz @s@@s @@^@W@;^2:@5y@WFh@^(v\@W@ѕT@~zQQ@^I@!JELB@ma;@GIs8@ad,6@)MX5@Sr6@>l7@xǕ8@I(:@}mV;@p($+D@lN@t"i\@+j@N$'z@6W Љ@9 ș@l@)\=@=ʗ@@Yۗ@6@;@@P@t#@.K56@bH@R[@zo@ @L u@6qqn@1^j;Z@X%TP@Wg@:K|y@PKXA0@ geo_strf_dyn_height_pc_p_mid.npyNUMPYF{'descr': '@:U@-N@y`@6򃶮@Slx@=-@S@yqQƮ@ _ցӮ@@3Մ@ZL&@NMp@#@):@uA@CB>@vԅ@a@+Z@ř@LSۮ@|\ծ@|uZϮ@iIRɮ@î@Ê@_Cͬ@hu9@zH@V~}@ߗn@g_@)P@]YB@44@Gѕ&@Wo{X@A @@Mo@A~,@dv=׭@z|ʭ@4tܾ@hO=l@N[Ƨm@;8%@[¾ @ 6@r:@`N®@P}Ϯ@: @Y-@hGG@;Dy@?}wG@B{@@[3y*@Qb@8-@~7@](B@R@`pNۮ@ (Bծ@Ϯ@Ȯ@*!x®@Lקp@u)+@6@]>iIE@0}@n@0_@Ow.P@&IB@vg3@ "N%@oz@1h|` @w@&ip@6@\ઞ֭@`Oʭ@.(@Hw2@3@B^8@<;@U#<@V;@c.@RҾ $@PKXAސPPISA_from_SP.npyNUMPYF{'descr': 'nXnOx@HPx@ۺkBx@7j]/x@zw@Wl=v@mvx}t@E,r@h&- p@\^n+l@$oze@7lb@ګG`@5(ϓ8^@B=5Z@maW@ok'U@+gGS@\ՏQ@O@lRL@$12J@aG@E@~D@3@@ܪ<@פP:y9@ ìF7@Ϭ5@Em-/4@L/)3@2@=uiZ1@ F~V0@p&/@%*/@2Mr.@*ϑk(.@;r.@_!ę-@M9_-@t&-@hw@nu@H:?s@kp@j@og@%d@gN[b@_sĮa@[qC`@wIX!`@uT\@D$ UE@iqy4B@Zhy8=@P`JYa;@=`w8@ n6@ds`<\ 5@eK3@]7#2@'0@jo.@21a,@V+@e r*@p*T')@P(@n (@AX6c(@Ϩ(@U#c@Cisa@3H?[@@LnS@v,M@¥O'I@`} kN@XxjQ@PKXA4beta_const_CT_t_exact.npyNUMPYF{'descr': 'oG?vYOG?3G?=X~ G? ~G?‡iG?\*UG?Oj^/I?[HHCI?~rI?ك}I?GLfI?[I?_ʿI?Ae I?PKXA6 p_from_z.npyNUMPYF{'descr': '@|D@H@S@i?Y@_@b@ef@z?i@o@6r@v@?y@@@@?@.h@@[@@@@@@@Ρ@̣@ɥ@ɧ@ǩ@ǫ@ȭ@ɯ@@@ @@@@@@~ $@c4@>@D@I@R@t?Y@_@b@f@H@i@o@r@v@@y@@.@@?@h@@[@@@@@@ @Ρ@̣@ɥ@ʧ@ȩ@ȫ@ǭ@ɯ@@@@ @@@@@$@4@ >@D@)I@R@i?Y@PKXAސPPISP_from_SR.npyNUMPYF{'descr': '/>(j>ߵY>g^ʩ>1v>b2>L+E>đi?k>h%>-o>Q >j.=> >>T I>X>|&>>C(>?!>0@,>U>;> >˥>(C>xpB맣>z١>+jie>~>p.>簜>GX>]E폛>>؜>z^>>4>xFy>6u)>oz>V%>XV>/>塡W>Ň>JЌ>-U>@ʓ>7>!5>^<>|O>#E><]> 4>S[ո>А>>hYZ>g>P ݳ>I7>Xs>yj>g >dC>X0kM> f>@m>Df>=>$E>hc˟>X0>҄A>(K>$e> Ͽ>0saVޙ>W>GjT>H2>XA&> >> sޗ>v'v>X '>#>`B]d>`2e>8> ַ>*۞`> Z>RSt>PKXAސPP Ispecvol.npyNUMPYF{'descr': 'N~A@jA@#MA@:.1DLA@WHOA@%RA@gfk_TA@^݌UA@=+_QWA@aXA@9>EZA@P[A@щ@]A@+^A@:/`A@ח JaA@SM{bA@ZeA@6vgA@9[=CnA@J#oA@1 vZoA@dRSsoA@Z[yZoA@caoA@aoA@9coA@>KMA@"KA@I CzOA@eqMA@֙ NA@ TA@rǦ#xA@Fa@A@nk|A@ֺ*_A@BƒzZA@p_A@*tgA@1%iA@ŞhA@Q3fA@8#aA@-zea]A@:_^q[A@IA][A@N[A@EE|\A@$) ]A@c_A@8d`A@FȘaA@r˛bA@0jeA@N %>hA@`NEiA@!1kA@~?X "lA@@mA@mA@%hnA@^woA@ct1toA@GMNoA@dWpA@88pA@+'9pA@LpA@vrpA@u;pA@AMqA@Ng@)Z@ +ݦ@8Ҍ@I-Iv@`KJX@l8U"@Rhh$@PKXAސPPIR_from_SP.npyNUMPYF{'descr': 'yD@v@@;@6@ X2@ .A/@Mt,@r&@Ÿ"@:o+@V)OS@3@ $@ @z5.@LG#y@_g@֝:@zr@K_<@&Eܮ@Kծ@39oϮ@ 6u@m@2x@VD帔@D@.z@km@Gی0a@>Z?U@jJI@P7F>@Nxc3@`w(@>_k0v@諆@>{ @ӈIС@bzI@ғcE@}B"_E@ +hD@s aD@6}C@ƲB@ֱ<@N5@eM2@;hD.@7M-+@M uv'@-ӱ"@'ҩJ@B@(/@eQ @( W @30@;X"@Ac,@x@M@ @ ߄*ܮ@p֮@JϮ@ɫ37@6@Ғ@d @d=@0xez@?vm@u %a@~& T@cRH@> p=@9Q2@'@V01@[S>@k5% @:>@CM*@9@if$9@LD:@"<@IS<@l&;@.@2]%@PKXA?[SCT_maxdensity_exact.npyNUMPYF{'descr': 'ۃ2Glr)( zcJShBQ%?4znY9d'yoR#-/OFZE'̘e ްEs}bQ$] {!0"K]u#jh`E6$b &uQ'g 0y 2W( _ M* #Eci!WQwD3Zl!&M9-^cߣ% %Yz<ghIfU1hԀ.,&D\--r.|ΰ/z)[V0J!0xᒺ0:N"1n:K12^ ,~1m1Ô1݃ 1y18i_1 =1H1q0p`)Z+M??L?P$^d?@p&T -݆[DCkd:d! <, F6'\!;E<'(Wd!ke&6z}14cP c-!9"iҁ""qH#/ %w٫JU/&IUe? (H/HP=*:+:igB,ԅ,!RT-}.Kt#Z/N9(0 cڀ0ER1Gm U1EtT}14Q1J\r1h_15U31V[ 1#| ܟ@Հ5 CɿNdѿzPKXA!geo_strf_Cunningham.npyNUMPYF{'descr': '. AcIGJFClWM(pP (M !_/OK"7F#TU Q$eHr%P&x'Ѿ).,.S-K.Xz*/g`0ռ0,?V11A(sc2l2c_<3 U~3(430Pw3 ]ek3}3I43@J`8ƾ?ȿ,ѿ ӉVPKXA<CT_from_pt.npyNUMPYF{'descr': 'wv9@;a7@"s4@i$2@G/@ȸݜ(@yx$@4u~"@;D @`L5h@y@M`@O(sH@6+^@f@*@OVA4 @ҴN @A&ft@I2 @y<6@Lg?8?x?B从??]?kD?{7?{`I&?#{+@x?ZL6?bָ?iv?9Aqn?yuF?(??HCJ=?1&R;@Bk B;@Ak S;@%GgG;@ncN;@I΋ :@tlA8@w!35@q: 2@$PN.@y)@k&@'8Xc$@Y} #@e"@H?!@6w @+E[@k @0Oo@ઐw@+(n@Fs@ +v@}c @,*' @AZa@|q@vm@} ?מ?ڎ? ?5 ?Y`?t5?7F?8?/?~%?I*І?\b?$"o?ٌͭ?\ݏ?틥?D?6j%@E#@,y@2@b)~@;6'ZO @@Pr@PKXAݚalpha_wrt_pt_t_exact.npyNUMPYF{'descr': 'hN4?zO]x4?jg4?^b'4?I4?x}4?Z=3?>; 2?*E[1?Q0?\6n-?\@#(?T _&?C%?`c$?M쮮g#?`g"?KA!"?|3h!?pLa!?_!?Z ?if% ?<}Gʆ ?5Vs ?s ?oG ?!?F8^!?`j="?g["?VA#?_ -^$?#ct)%?^Jۼ%?^&?= ZQ'?-d{(?bq(?-5)?%vN*?8 +?qL+?,>X0{,? 螱4?`I8V4?;4?U!4?'?PC4?{4?ov3?Ș|1?AN1DP0?`XkN,?)-,)?6($(?&?;D-W&?al%?vw%?o=z$?X3Έ#?x"?)%"?6o{_!?$a!?&z;!?!O!?}i ?V>X ?Lx~ ?zRV ?ka2-!? 'n!?>,]"?LQ#?É޳#?.#g$?+y%?hi%?NK{&?DA=w.'?k'? (?c8b)?t; *?4*? D{+?s|eQ,???X?z,y:?$>XS|ݽ>3û5>#zW?PKXAwg CT_SA_pt.npyNUMPYF{'descr': 'lW/W2=WѵWJo|X:̫ X"jPXbX2kJmXX"Xj{XF3 X[c X2,"!X=K!X\SSSJS\iS6ⷻS'sVSyqdS&Y,TO&T*3UYHUhU`UU]1MUD)#UD*R' V$V~ZVBVVpcVI5&,VoW.a(WkV?_=WB;cWb6W7{ΗWRYWj|W:m:WXB3X XjV#XXJ]XRm$X(XR4*X݁-Xzܱ-Xjɢ.X2.XJa.Xhi@Y9`/^YtB 'Z9RLZ E~6F[({[[$Z}gZPKXAސPPIsigma0_pt0_exact.npyNUMPYF{'descr': 'y/V>0>>\~K>N _J>tΆ>ߺyc>6q>˔>"OP> 2b?Y ?59A?!?:Tu$?웳'?EC4?dJ6?ɭY=9?̋;?r+ZB>?{Eϵ7@?ERA?zA?n?FB?)=m&C?ΞN}lD?Vh&D?hg5E?WJE?MKE?`9z*:E?\G8E?%f-D?K/D?k$MD?22x#D??PCC?7"R2C?:C?C? SbC?eI(cC?#'G[> Y \i>9~>ڲY>"BZҮ>ǃ>B>+g>k u9H>)`-?H5[k?v+F$m?* ?)@?#? a$?s+nd&?Wp+?ƥ-0?r.T3?|T&5?M/'8?.:?~f?ip@?1SA?o<"B?t'ԆC?zG&D? 1HE?ގN"E?l=E?-qgE?{ E?ie.gE?GD?fID?4۔C?'ₕC?ZǗB?FiMz}B?tH_B?sMB?'XBB?e8B?PKXAސPPIchem_potential_t_exact.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@q)DA@9}vuEA@7FA@][x^*HA@,&oIA@x$^JA@߽KA@̘5NA@Y}A@!>rgA@$"JA@QUA@UA@m4VA@?QWA@<WA@r-xXA@9YA@|yYA@YA@YA@pV^YA@./YA@tZ| ZA@I@JZA@xE@YD@FV9>@SGɫ#@8 @p-@"@S[ $@PKXAσisopycnal_slope_ratio.npyNUMPYF{'descr': ' CAҧ?# CAX4 CAH.l# CA7 CA  CAJCA|YCA"hCA.Gf}CA=ސBAQ-(BA ӐBASBABA/@naBAi;NBA[7IBAlA?BA(a!BAPGBAàxBA=]{BA0PBA;BAiBAzBA2BA!iBACݠ{BA6d\BA%BAJUBAVQC9BAdBA @CA/@CAx@CA&}CAe@wCAv9fACA&cCAv1CA,W|CAEH CA$&? CA$ٖ CA CApw CAӁ8 CA@ l CAX CAh CA&h| CAJZľW CAzCBAJ.BA^#BAxϓBA[BAYFDCAsBA"5BAPKXAސPPIosmotic_pressure_t_exact.npyNUMPYF{'descr': 'nXnOx@HPx@ںkBx@7j]/x@zw@Wl=v@mvx}t@E,r@h&- p@\^n+l@$oze@9lb@ګG`@7(ϓ8^@B=5Z@maW@ok'U@+gGS@\ՏQ@O@lRL@%12J@ aG@E@~D@3@@ݪ<@פP:y9@ ìF7@Ϭ5@Em-/4@L/)3@2@=uiZ1@ F~V0@p&/@(*/@2Mr.@*ϑk(.@;r.@_!ę-@M9_-@w&-@hw@nu@I:?s@kp@j@og@%d@gN[b@_sĮa@[qC`@wIX!`@uT\@D$ UE@hqy4B@Why8=@P`JYa;@=`w8@ n6@ds`<\ 5@eK3@]7#2@'0@jo.@21a,@V+@d r*@o*T')@P(@n (@AX6c(@Ϩ(@U#c@Cisa@3H?[@@LnS@v,M@O'I@`} kN@XxjQ@PKXAސPPICT_from_rho.npyNUMPYF{'descr': '"nN>'Ǵ>NG>r  >iv>>=BE>wk>\K~Q>R0zrp>ph >hJ*H>bJ@>D6L>3.>b(>P>L*>jw$>{-/>㬂X>D>F>ͥ>>~}>$ڡ>|@f>^>>_>( >8~>\>c>`01`>&!>.*5>2(^>X1*>䆮z> i>p@>p/>b>䣮>&>?>W'&>a>Vx><>]J >_@R >U>#͑>׸>@>:q%]>ӹ>ewE߳> ~9>R> >L: >x>B㽩>UJi>' >,ﶥ>kKk>Hd>v>@͟>k?f2>,#tC>L>b$V>@VU>nߙ> و>UjU>~>td⽗>繖>kx>Hߗ>> '>18u>@`M_d>:p>`wN>`Ւ>@İ`> I>@r>PKXAZXDionic_strength_from_SA.npyNUMPYF{'descr': '??TEG??2 ?P1?6Swm?fi?M?F% ?]2?x¶"?Nb?t2B?:IE?^?ℏ?x ?GSK?1 E?G&=?w?f(6?Ot?{ ?AX,?]?Ȼ7?Nm5?ėA?c~nR? ?HX{ ?%N?D?? >? '7?HFcf?->{?OӤ?PKXAt90_from_t48.npyNUMPYF{'descr': ';@bF;@0&:@v 8@X5@{2@& .@zF)@w^9t{'@vB$@#@i-"@ꍠ<"@o"  @]꥔@麺=@/se@ì_/@@!p#\l@f. @)^ @O0oQg @z҄=6@"@ݣǍ@|"@v.q92@M-@"3x @ MJª@.<@,@9@PKXAސPP Ibeta.npyNUMPYF{'descr': 'S>???=?v?V5G?G?.+? O+?` ,?e-?p--?n,?M63?Td:?'wD?PQ?W[?sd?#Zk?@0o?>H1p?@9xr?|Wv?gz?N?^?_7pg? U?2?54?`?]p?@gދ? V^ -?zjco?E?2%?y?XNC?C?ISz?8yB?0ِ?\8]? %b?p4Ȏ?D6?`rp׍?}V?%݊?xÛx?h?$LI?u8?!?m2˱?y?Ѳ?Y?v?PKXAސPPIt_maxdensity_exact.npyNUMPYF{'descr': '7 ]]] jN3]E\+Y _[mCYܺJJV;=S:_LQ:epPu:N{*M,dLb .PK(vI HVEC=FPDݥiCK8BQ:A+A=UӁM@m?q*=n\s;o2T9rx8X7 gW6eNZ6GF45#4\`5b4,3wJo4f 4*+`3e 33%@}3ΩG"o3d ]l3(j3ՕWe3CS> F|`DPd?|u 45*R-6"&G} 0S3PKXAސPPIlatentheat_melting.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@n)DA@7}vuEA@7FA@[[x^*HA@(&oIA@x$^JA@߽KA@̘5NA@Y}A@>rgA@$"JA@NUA@UA@m4VA@?QWA@<WA@p-xXA@7YA@|yYA@YA@YA@nV^YA@)/YA@sZ| ZA@E@JZA@rE@XD@AV9>@WGɫ#@8 @p-@"@S[ $@PKXAnXXP0.npyNUMPYF{'descr': 'D@BD@D@6D@D@^D@ z%jD@8D@>MD@73D@@xD@$Y2@62@>3@`6:3@Mc4@@e?4@ ]]b5@ >o?6@PKXAٗڪentropy_t_exact.npyNUMPYF{'descr': 'nXnOx@GPx@ںkBx@7j]/x@zw@Wl=v@mvx}t@E,r@h&- p@\^n+l@$oze@:lb@ګG`@4(ϓ8^@D=5Z@maW@ok'U@+gGS@_ՏQ@O@lRL@%12J@aG@E@~D@3@@ڪ<@դP:y9@ ìF7@Ϭ5@Em-/4@L/)3@2@=uiZ1@ F~V0@p&/@'*/@2Mr.@*ϑk(.@;r.@]!ę-@M9_-@u&-@hw@nu@I:?s@kp@j@og@&d@gN[b@_sĮa@XqC`@wIX!`@uT\@D$ UE@hqy4B@Why8=@P`JYa;@<`w8@ n6@ds`<\ 5@eK3@]7#2@'0@jo.@21a,@V+@b r*@o*T')@P(@n (@?X6c(@Ϩ(@U#c@Bisa@3H?[@CLnS@v,M@O'I@b} kN@XxjQ@PKXA>&Ljmolality_from_SA.npyNUMPYF{'descr': '%V?>aW? QMY?kehTZ?*]?L_?Aa?C.%c?5+:d?Gbe?e?C\Åf?sYg?$$g?T h?dEH%h?!*hh?h?Bhh?_rph?3X>ph?Ugrh?#C?75M~A?8͋E?3jC?]p(D?*`J?B(-r??x?v?% !W?UQ?Y0W?^_?WLb?co`?LWP^?x 8BX?R}G: % Yr je17ܟQ/pM (}jTޯv=d骲Mp/8? 0,+@8kVL>ғ\ 翮M/͛Y]JBʿFw@ֈ?R"?PKXA6oalpha_CTrab_exact.npyNUMPYF{'descr': '4?\4?L4?BP+4?ږ4?.f4?Lp4? J3?T2?U1?3/?/a!h-?YJ(?#\&?K%?婿Ω$?axg#?MNʭ"?+IF#"?ڋN%!?Dc!? !?dN ?>Is; ?t ?޶v ?qv ?*eN ?Pˠ5u!? !?5+A"?T؟"?qi#?~b$?(̞~%?/a%?OPsÙ&?8&W'?< (?I~2(?$)?n:T*?#4t.+?\!+?́,?Yr224?OQΆ4?%+4?,ez4?,Ғ4?m4?k[l3?*1?K0?kQH,?K@)?/"(?lv&?N>&W&? 5%?lkx%?aD%{$?cr#??"&@"?,'"?7!?w0c!?X>!? dq!?C?  ?f~u ?9@i ?6I ?h~PP0!?f=t1*?ɖ+?y#X,?vRt? %?=?gpl?7Q">mkg>U]w >6<?PKXAސPPIt90_from_t68.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@p)DA@7}vuEA@7FA@[[x^*HA@*&oIA@x$^JA@߽KA@̘5NA@Y}A@>rgA@$"JA@NUA@UA@m4VA@?QWA@<WA@p-xXA@7YA@|yYA@YA@YA@oV^YA@)/YA@sZ| ZA@E@JZA@uE@XD@CV9>@WGɫ#@8 @p-@"@S[ $@PKXAH8pt0_from_t.npyNUMPYF{'descr': 'H'@ غ@gd]@nWa?@EE(@Z&-@b{G@BU#@% 1@/l2@wμC@AڊR'@h"@v@6;V@ @?7 @T@p@2u^F(@mPY@w>G@c72@j_% @`ϫ$@ nXX@ScV놊@ͯO@'o4tX@~O1th@`Wr@-{_tx@PLJ~@f"5@LJc$/ώ@Y~4@@8$;ʚ@دe}@^*@e @ň֪@aDϵ@~2/@e Fb@qW3غ@o@^(6?@ ](@:DW@!C@X@"5b@V@0U@/R'@ w陋@\ L$@Ni V@/F@&q2 @>ļ@m@E2(@yPY@z>R@@2_ƿ@$A@s Pv$@):!X@OK@\1S@U]X@!h@۱f٤r@|8Fx@hbm/@1@WL@PKXAސPPISR_from_SP.npyNUMPYF{'descr': '|8@4` %@$t@Pml@8://F@~k/ƣ@9& %@0Lف@Zϱ@u@6O@W@uM!@!PX@Nc$@ds@K9@ q@j_{@tl29F@F=a0@q-T@$>ʓJ@l5@p:.@U%5-h@\$@shG@Ei@ቸ@lKtζ@0LW@P!@W|録@!L@pz6@4\@`Y,@@=!@@r{@%w@p/@l@}mo\l@#@6f4i)@h}@--q@ĉP^w@nuet@PKXAސPP INsquared.npyNUMPYF{'descr': 'T@dXX@a-]@c$a@`*e@Y`+`j@(n@s s@2KNw@`T{@s'}O@-LT@q 5X@wiOK]@C^a@(I'f@Xj@٤En@f[4s@R+i~w@O'{@Gq g@`s 8h@cfk@Y]Wn@Ϣ98p@w.lr@ }@S@PKXAx*XX gsw_chks.npyNUMPYF{'descr': 'D ?4|G ?4ުG ?2yP ?1}x}Y ?}' ?=p!?|;O"?YH#?ۄ#?x #?r#?l]Y"?h@>L U!?cDk ?@KK?@9?,5??k??y6(?p@?h>CK?O+? ? ?m E? ?9:S?b?f<?p>n8>@>O(h>>d82>38>>~q>I# 7>w->P*>(=aȋ ?'= ?(}$/ ?'=! % ?'J ?"=} ?!?<r"?#?w~a #?u}*q{#?rA"?o}"?mv#"?k !?h`b!?bEj^ ?؂%w?0X?@$W'?Iv?@q?@ ]?x/ ?pW?h@)lA??(x ?$"?8sV?Ցoc? ?bcF?2=b>#?>n>&>9#>L>2;K>7>bX>'L>x}F>pz3>o0(2x 4 57@Y+7@︖A@ڢM@7cZ@YA4i@Xx@'D:爗@3ez@=J)@T0\P@sX̗@D׼mޗ@v9@=%@6G`@GPr)&@8Ar9@ Q$L@h|2I^@ K @5}X @]ɷ @{t @"@'Pj4 @E @CC@(p@H@fy@Qg@*\@(-vW@lo T@&<]Q@x5I@#)qA@0h;@")8@/6@Gd5@E\ZM6@K7@2)8@":@y;@D@?gN@dū\@&)j@G;Iz@@N@ac3?@p@,ew˗@Vۗ@V @ݣT@W4m^@#@n*zr6@:I}k)I@@[@Aٓ@A8=Is@K| b@3Dn@;[Z@TQ@g@oţ"z@PKXAˈC.npyNUMPYF{'descr': '@@ꓠ@@ANC@@ `@@T@@@(K"@@'@@ ?@=h?@3?@pu?@Gx?@P'}?@xaa?@B>"?@t?@EwϞ?@|5?@uO?@?@q?@ _X@@Xj7@@?s\' >?)=?0>@=?<=?'=?i;?Huo8?g2?NY_*?G?#??e?+A_?^F?ZA ?ZlD ?1Di ?i ?ԌU ?0 ?ڋ ?#gɥ? ?/$?> ?ɜ?|u?^?`U?Vvh?:A43?2l?+?ո+?w ?LVG ?\r ?B ?r4 ?t\S ?ljW0 ? d ?&ǖ ?d^ ?v[i  ?z9ꄲ$?(YFZZ?TX^?kd?;%h?Axml?U "p?.^<u?3?}^y?i%}?<= ?A?]v?TZ? ?0?@`W?~C?nwv?=[l?K?w'?=6p?L~?va3?Ii?{3?T/ "Ĥ?"o~ڕ?xE?~? ,?t3?' 87?,ψ1?kw%?>`?%?|Ⱥv0?Hg(5?5~;?!KE?{DU!M?q\R?k]W?j[?3X-`?PKbd?Vh?o9l?Rp?rft?/0y?Y }?f#h ?-0?cg?Wr?j̉?'/?3:?~M8?E_?0 ?@?T(uښ?A[f?X.G6b?YB1??L(H? ]]]K?ouF?B;?0g"Q%?8,5?e[1O@?4`GF?~UK?:S?̜iW?PKXAސPPIspecvol_t_exact.npyNUMPYF{'descr': '?mS?#ay?ј?o@eNB?C6?5?K_?&u\l?J.w ?=w)?:3Q?=P?^ҵ~?`BI?}e?|y?^dU? X?d?UVw?8t@PR"s@6e@xD@U g@;U3m@3Ϟ@*@2V`?  ?@?o ?E?5?h4??|'D?PKXA6 XXuPS.npyNUMPYF{'descr': '[6JA`+ A>AFbA3!A78LiA{AI^A3AFAM_OHA -cCA AV2AmcR#A}AmsAѕ&iAcet^ACSAHA]#Ai5#AL#AzAk #AƼ"ABe"Am SF!Ao7H AKOAq_cAMTA6IAYcAюLA$KpAI$&AN A4AeA\ AЂAK:AT ­Aog{A)cIA; AAM\AtRA_%.Ao!Au`_A̧ABǧAFA|򉽥AAO/A\f-8 A{}A+^sAr{O"iAjTp^A_$SA,fHA>DhMAvڀMA @ LApRLAJKA'JAIdGA-DAPKXAސPPIgeo_strf_Cunningham.npyNUMPYF{'descr': 'W?; )W?'X@W?lAWW?y'oW?Dh W?\$lW?n3lW?CW?JuIW?ZΘ:W? X?m X?בdX?mX?Qh"X?:*S Y)X?sY/X?*R02X?z&5X? 8X?W08X?c 9X?uo 9X?.js9X?\UBcW?ѝٞW?`/X?5%X?7үg+Y?(!w[Y? Y? $X?PKXAސPP!Ichem_potential_water_t_exact.npyNUMPYF{'descr': 'R%@Kb-@`(Yf@1-IBZ@AsOB@]TZ@mK+@>±T5@?@ј@Õk @/7:h@Á頯@"@AK@sٙV@ WCkg{@8Da; @Y4؄Ծ@LO@FӸ@Yj@0債@ƌbHj@J1xF@njz@*@Ջ@`Jư@ҸU@D @Ϡ@4CY@' @/p$3@d^V@@x ^J@ @^@'>KjL@CE6@9eXZ@PzP@}HA@ޯ:@8bC@P"o]G@¨rGm@Դ@:.R@u@q,$a\X@f?0@zpƬ@E婫@i%"@$d@fzR@8I@Km?$@WG.x@:@;:1U@B@E\Ա@m @t|:@2q@PKXAސPPIionic_strength_from_SA.npyNUMPYF{'descr': 'sivh@"?*"?`}Rx#?dHX_$?=c%?wx%?lɖ&?2iT'?yk(?=(?1$z)?S*?3 +?DF+?O,?tuU4?M4?@L4?H>Nŗ4?zt4?~Dl4?j'k3?1?zK0?=vk%? D%?圊}&? '1'? 4F'?gƣ(?}R_ g)?{1%*?ˡ<;*?4)ߟ+?(X,?c[h*u?+?zjD&?zu?:,>\>>dm >c)N?PKXAG t_from_CT.npyNUMPYF{'descr': 'W?oo?K{/L?Ӛ?9#?46?7O;?%CK;@n;;@bL;@@;@7zG;@S(:@%+8@25@;E2@[}`.@ )@(Y&@0b$@"#@IH"@Sg!@zWr @-$ ]@Wf@Jǀ@y@7~aAo@v)e@\Cx@?p @ j( @Z a@@ZSn@_s?19?مZ?RLt? =_?[wd?2)m6?P2?Y?i⑃?{_1_?dMl?䥌I$?8?|?U'3?c;O$@m)A"@~v|{6@"j8@ @} @(Kh@7BIڢ@PKXA SA_from_SP.npyNUMPYF{'descr': 'N~A@jA@!MA@8.1DLA@WHOA@#RA@dfk_TA@\݌UA@;+_QWA@^XA@9>EZA@P[A@Ή@]A@+^A@7/`A@ח JaA@QM{bA@ZeA@6vgA@7[=CsnA@$nA@y>nA@G#oA@/ vZoA@dRSsoA@X[yZoA@caoA@aoA@6coA@hA@^NEiA@1kA@|?X "lA@@mA@mA@%hnA@ޯ^woA@`t1toA@GMNoA@bWpA@68pA@+'9pA@JpA@vrpA@u;pA@AMqA@Ng@)Z@ +ݦ@8Ҍ@I-Iv@`KJX@l8U"@Rhh$@PKXASP_salinometer.npyNUMPYF{'descr': 'A@?A@ xAA@fBA@n)DA@7}vuEA@7FA@[[x^*HA@(&oIA@x$^JA@߽KA@̘5NA@Y}A@>rgA@$"JA@NUA@UA@m4VA@?QWA@<WA@n-xXA@7YA@|yYA@YA@YA@mV^YA@*/YA@sZ| ZA@E@JZA@rE@VD@AV9>@NGɫ#@8 @p-@"@ S[ $@PKXAސPPISA_from_rho.npyNUMPYF{'descr': 'LJ.oBA'JtQbBAvDa BAЙBA@=wv9@;a7@"s4@i$2@G/@ȸݜ(@{x$@4u~"@;D @_L5h@y@L`@O(sH@6+^@f@*@QVA4 @ҴN @A&ft@I2 @y<6@Lg?8?x?B从??]?jD?{7?{`I&?#{+@x?[L6?bָ?iv?9Aqn?yuF?)??ICJ=?1&R;@Bk B;@Ak S;@%GgG;@ncN;@I΋ :@tlA8@x!35@q: 2@&PN.@y)@k&@'8Xc$@Y} #@e"@H?!@6w @+E[@l @0Oo@ߪw@+(n@Fs@ +v@~c @,*' @AZa@|q@vm@} ?מ?ڎ? ?5 ?Y`?t5?6F?8?/?~%?I*І?\b?$"o?ٌͭ?\ݏ?틥?E?6j%@E#@,y@2@`)~@;6'ZO @@Pr@PKXA6oalpha_CT_exact.npyNUMPYF{'descr': '4?\4?L4?BP+4?ږ4?.f4?Lp4? J3?T2?U1?3/?/a!h-?YJ(?#\&?K%?婿Ω$?axg#?MNʭ"?+IF#"?ڋN%!?Dc!? !?dN ?>Is; ?t ?޶v ?qv ?*eN ?Pˠ5u!? !?5+A"?T؟"?qi#?~b$?(̞~%?/a%?OPsÙ&?8&W'?< (?I~2(?$)?n:T*?#4t.+?\!+?́,?Yr224?OQΆ4?%+4?,ez4?,Ғ4?m4?k[l3?*1?K0?kQH,?K@)?/"(?lv&?N>&W&? 5%?lkx%?aD%{$?cr#??"&@"?,'"?7!?w0c!?X>!? dq!?C?  ?f~u ?9@i ?6I ?h~PP0!?f=t1*?ɖ+?y#X,?vRt? %?=?gpl?7Q">mkg>U]w >6<?PKXAސPPIpt_second_deriv.npyNUMPYF{'descr': 'u=]x= 3+2=kw,r&=|6?V=ÁD|=sNX=u_dh=d/܇=Z=c=.և=~k=| =~Ms=,K=)͵=Yϐ=(Lռ=[U=z#N=BZY=>^%ׅ=Uhvř=b|Z=oF=% y=]y='A5ϫy=y=~ݬy=+Ly=LA{=R}=Sui=3= LG=p$n<=MYkǃ=ν =BL~ E=M~=kyG=}{=޴$=UD=9AEF=I`̆=ͼ=A=fH=hqpp=A0=T^=g;W߇=/\҇={̒Ň=9D=Y=3 n=`'sfJ=6O&%=#,=Uц=% L=?>uh=?:0='ď$=1Z4=_u=ΙU5=ꑍ8=U= =%j=O>>=w <=/]=Нy=PKXAސPPIcp0.npyNUMPYF{'descr': 'I^O?*=O?c O?HVO?kX}O?'o#uO?9ZKlO?cO?pT(ZO?zZJRO?VkIO? jbUAO?y8O?Jݿ0O?۾q(O?= O?eO?yEcO?ܿ0]O?IceO?:;΢O?deHO?ƻ%O?;PO?E ~O?ߤCuO?5IlO? cO?=ZO?d7 RO?A榐IO?J AO?3m,8O?zP0O?~(O?|O?ЯO?_(fO?9)>MP?^*MP?2KP?)3GJP?},IP?P[4HP?V &BP?ֳ->P?PKXAސPPICT_freezing.npyNUMPYF{'descr': 'kH?bH?[ЗH?\AH?oUc{H?zn3H?*DH?%4H?cA(H?:n(H?4TH?9OH?`4H?̼/H?^H?cy0{H?֠߼H?jH?؆H?;`H?gc2yH?]eH?F.~PH?/;H?M 2'H?U5nH?GG?rG?IG?dh3G?gS,\G?dKdG?Sq~G?T3iG?TG?i0I?m2DI?1sI?[I?"I?7ҡI?RyI?0)I?PKXA[:ޣbrineSA_CT.npyNUMPYF{'descr': 'A@W>A@@">A@2yw>A@+AA@+YnܲBA@> \A@||A@7_ATA@P/A@9\8|A@*hA@/x6KA@p,JA@BMA@PPA@YIRA@ZB wSA@aL/ 7^A@ 9~A@" MiA@ZCA@_W>N~A@jA@5MA@>.1DLA@WHOA@%RA@gfk_TA@`݌UA@M+_QWA@PXA@9>EZA@P[A@㉈@]A@+^A@/`A@ח JaA@MM{bA@ZeA@66vgA@*[=CnA@0#oA@ vZoA@dRSsoA@w[yZoA@caoA@uaoA@8coA@%KMA@"KA@< CzOA@eqMA@{֙ NA@ TA@ rǦ#xA@aa@A@nk|A@ֺ*_A@BƒzZA@p_A@*tgA@ %iA@ŞhA@Q3fA@ 8#aA@zea]A@:_^q[A@IA][A@N[A@4E|\A@9) ]A@c_A@8d`A@FȘaA@g˛bA@/jeA@L %>hA@NEiA@1kA@d?X "lA@@mA@mA@&%hnA@^woA@Ft1toA@zGMNoA@XWpA@18pA@+'9pA@HpA@+vrpA@u;pA@AMqA@Ng@)Z@ +ݦ@8Ҍ@Q-Iv@aKJX@*8U"@.Shh$@PKXAސPPIentropy_t_exact.npyNUMPYF{'descr': ']R(=A=:ٺ=\ [Z=-*]="װ.=@E=r)> :>Ԗ d>ogFY>[L㥯>*cμ>]>E w>PKXAސPP ISonCl.npyNUMPYF{'descr': 'h @~ @)] @`R @ @.@ @_y @JX@mA@PX_@mգ@=ZI@K@6(@A@ Z@M5f@Pg "@ +t(@.@l4@66@B7:@+<@s;@ <@c<@<@@X@0@"u@~l@<@@ۀ@)Ź@d@ln7@ ]u @ᦂm @6 @ԇN @\ @  @J-D @vT۪ @ @㕏3= @%&} @N @@ @1@(R)@O@'$@EAQ@۪X@Ђ@@@?m@&@1@ :@9{C@I@@.0L@PO@cjP@HQ@~Q@rgS@#Ʈ g@ARnh@p@j@l@Ɍ=n@ސx!p@:" z@ 񗁏@PKXAސPPIentropy_first_deriv.npyNUMPYF{'descr': 'tHelmholtz_energy_t_exact.npyNUMPYF{'descr': '!xUeug%{k`b:#o38N=׃CuiHR`:YPKXAސPPISstar_from_SP.npyNUMPYF{'descr': 'oG?vYOG?3G?=X~ G? ~G?‡iG?\*UG?Oj^/I?[HHCI?~rI?ك}I?GLfI?[I?_ʿI?Ae I?PKXAސPPICT_from_t.npyNUMPYF{'descr': 'L??(XC)?_ő?3Ɩ?U?=ɋ?;k2?OzN?N[:&?/ څ?Svm?+ e^?!ÄAN?j#ǁ?C5W?J1?imZ}?4P|??cJ{?Qz?2qXz?4y?Yv,y?0ﷅx?6W`x?+$Px?Gy(8x?Ye x? gUw?w?w?k`w?dPksw?)ē?>4z?ԣ粅?Dvg^~?E𷂤?8Z@Q?XW?cT8?`Zx?6.MꤿsܤOaZTs$X*LxSp-|%+cf%ӻ_ca+ >(Ƒmkᖐ\,T썿ŀ Nj&';ov烈,n$KMׅFH{LiEānp%#;4T-}!J|蓕zD{fߎzөaz2H0y[ @'y:j4W=xI‹x-/KxWS2xoh2x&ZwyXfw;9wwY@wE&F5.V&КpΌM1 _ڵ_d>M(rb O3ϖKRܔ dENwMY 8 8 k)"-mAeh`q9{ xcXD~y >1_+w+` 7ߩ]*Pa~CA|So{Jn< {]W]zAy-yCxQxUpx4fwSe$6Hwuˌ+wv2Z1rvtKvKvR)挔vhb@$bZJO _z^¹Tr`olq EtL{hxPKXAސPPIbeta_const_pt_t_exact.npyNUMPYF{'descr': 'XA@ I)A@l &~A@BxjA@jYZMA@KA@d=NA@G"RA@n@]SA@ c_YTA@{:UA@5NcLWA@egXA@g+P@YA@u>2[A@-ҽu\A@h]A@y^A@'u"_A@$~hbA@dA@γ\LdfA@e¨gA@hA@GsiA@aTjA@jA@ >kA@vկkA@{LNy8lA@<_lA@6lA@iZblA@бlA@p$elA@^LlA@1 lA@cAMA@KA@3pOA@Y}MA@NA@5RTA@xA@c2ZqA@Eym|A@D__A@[<.ZA@._A@&vfA@SiA@ظgA@ \eA@L2`A@NIf\A@ !ZA@B*YA@9_A@k^`A@{ӠbA@ӒleA@&fA@ 4>hA@AR!)iA@%jA@jA@`K~kA@},lA@lA@e/HmA@immA@:~mA@ݟ)nA@tg>nA@]TInA@hWnA@OnA@Ng@)Z@ +ݦ@8Ҍ@I-Iv@`KJX@l8U"@Rhh$@PKXAސPPIrho_CTrab_exact.npyNUMPYF{'descr': '$۸ e;Ze {"WSwg#%)tUj% \ $!-0 Sbb %x1Nh1w'ğI?XU@re#Z ZI)P?F-?%/?N83"5 !J1-70cO. ;<Xp!g"5 b`#4%@KZ&{'. )G/p*Yi+<-6ȩ.h 0_e (0"1KB>2_ 2̗3U  $2< f`d`HmB -yoM'Z{;ZC*'y-utߺm=KhO,,f27C}X;r0aeTQTRqIV`@G9O}L6VB2ez13d}/yF0G!Q7hg"ݼ#ܦ%!e[&T'8h)tp*6 +"AG=-4.&,v4 00f01C\c>2Q f2V2|3iY@؁YI8@U4d@1lda@c`@'uJ@eAy?kwM?PKXAސPPIbeta_const_t_exact.npyNUMPYF{'descr': '"?*"?`}Rx#?dHX_$?=c%?wx%?lɖ&?2iT'?yk(?=(?1$z)?S*?3 +?DF+?O,?tuU4?M4?@L4?G>Nŗ4?yt4?~Dl4?j'k3?1?zK0?>vk%? D%?圊}&? '1'? 4F'?gƣ(?~R_ g)?{1%*?ʡ<;*?4)ߟ+?(X,?c[h*u?+?zjD&?{u?:,>\>>dm >c)N?PKXAސPPIenthalpy_t_exact.npyNUMPYF{'descr': 'j6ӿ ܿ3]!$SJ-pi}R<뿛G3Cνnh_z6DVH2¢RZP5`CɺT,h8wP{*r;y :h"@ ˠdb3eAZq:=ͺQ-X棺69jih m&9 ~߻W a( 7ig 37Io[q:/S# Bb$E۫To>ULƿO@CXͿrwv Rҿt< ۿj~9ݖPvKt%/ɰ9= #,cC1M=PHTZQTx0Z_SJ,$w{ޑl(VZ4~"Ȼ X |>VUAMIl^Gn:o2.Fj`2UξK2 o0/  ?Ҳ ][C ! 1pܾ `?~qGpQ?FsGhRBͿۧݿIt快7Q*_]PKXAސPPIt_freezing.npyNUMPYF{'descr': '"-77z[ܖHhϳc&E0r4uqgM󧿈5ݗUPE)U7pjgfbZ8Gu?r+sv۩R?~u:Z0O%OGh T4? ߢ`SoB+/ĪE4 ӪB몿#z&h hSx9 S Rep!ڡ&+0|509w];)=_heS?¨?Q@L@DU@Ž~&qD*[_dd ݝ6Eb0{]PKXAC0t_from_rho_exact.npyNUMPYF{'descr': 'W?o?N/L?D?49#?-6A@?A@ xAA@fBA@o)DA@6}vuEA@7FA@\[x^*HA@)&oIA@x$^JA@߽KA@̘5NA@Y}A@>rgA@$"JA@PNA@O@QA@IFžRA@ơ~TA@@>UA@UA@m4VA@?QWA@<WA@o-xXA@7YA@|yYA@YA@YA@mV^YA@+/YA@sZ| ZA@G@JZA@uE@UD@BV9>@OGɫ#@8 @p-@"@ S[ $@PKXAgxXX SonCl.npyNUMPYF{'descr': 'XA@I)A@n &~A@DxjA@jYZMA@KA@f=NA@G"RA@q@]SA@"c_YTA@}:UA@5NcLWA@hgXA@i+P@YA@x>2[A@/ҽu\A@h]A@y^A@)u"_A@$~hbA@dA@г\LdfA@ e¨gA@hA@GsiA@cTjA@jA@ >kA@xկkA@~LNy8lA@<_lA@6lA@kZblA@бlA@s$elA@^LlA@1 lA@eAMA@KA@3pOA@!Y}MA@NA@7RTA@xA@c2ZqA@Fym|A@D__A@]<.ZA@._A@(vfA@SiA@ڸgA@ \eA@L2`A@NIf\A@ !ZA@D*YA@<_A@k^`A@{ӠbA@ӒleA@(fA@ 4>hA@CR!)iA@%jA@jA@`K~kA@},lA@lA@e/HmA@kmmA@:~mA@ݟ)nA@vg>nA@`TInA@jWnA@OnA@Ng@)Z@ +ݦ@8Ҍ@I-Iv@`KJX@l8U"@Rhh$@PKXAސPPIenthalpy_second_deriv.npyNUMPYF{'descr': '&~<#~>T!~~os~=O~`]~0J~cm~~èW~UW9~U~~?Qy~ 5lH=K"ߪETIuH$uFsbA<.j{~bVT~$~[[G~╹{~~n٭~E|~~Ks|@~.0~nͫʠ~~"}fx~Dfq~Yj~<ƴZxc~da.]~-VW~2 ԽQ~dxK~,CR-F~bM~K<~2~6.~ z)~SfT l&~@ (e#~퓘 ~ |~F~dk~9Q~^Q ~b~v~P7~>.`#~C-P ~? (~Ä[BU9 *4r<"T2u{T5APKXAސPPIpt_first_deriv.npyNUMPYF{'descr': '@)>@,>@@F,>@4q7>@A>@@v>@@Ř_?@@@`d@@ @@`{\A@ rA@ 6FA@qv*A@ҽA@`IA@˄"G B@ h+B@ ~^&B@1B@*B@`fB@@B@GB@`)ƈB@@ʈB@Ѧw>@@uz>@}y>@G{>@@tދz>@@>@@>?@ P@@ @@'9#A@'6"{`A@ H^A@"+A@ A@`L;A@A@<9A@$@B@iCB@@!B@-*-B@`Kl8B@n$K@B@ JGB@`|9 OB@K9VB@"']B@f*<hB@qB@ ('vB@zB@m}B@@*B@fB@`ƳmB@b|FB@`=øPB@B@xiB@FmB@ JB@`%rB@@B@vB@@!B@H砵8,@O,@o#k-@@)K8.@.@@p9/@`0@`eI1@PKXAސPPIspecvol_anom_t_exact.npyNUMPYF{'descr': 'O@0 @a2"@H$@RP&@?XX(@cZ_T*@7/@_4@Ta{8@Φo=@<B@>F@g^J5K@)u:ۿO@ձD?T@zX@ .]@~ޚa@^e@F`j@ܥn@ris@*rMw@ {@@@Τf@f@@V@y]@OC@9@OE @ИpW @4 Q @TM@Zs4P@`+{@/^Φ@ZH@H@`Џ@@l@7! @l"@;;9$@(&@3x5(@{;*@ "!/@B4@R8@/e=@RB@C/F@#66K@|MO@0MT@$)X@kK]@da@'f@uj@{}%n@Д4s@Z? ~w@Լ {@#Ʈ g@elh@$fk@[An@7p@r@{$'|@@PKXAސPPImolality_from_SA.npyNUMPYF{'descr': '^W@Vdg/W@4ۂW@OW@ɳXXW@َW@hW@-PW@X~W@Ж^lW@p)W@&W@2ֲW@#ftX@(tX@pBtX@OsX@6sX@rX@]lX@="eX@ibg`X@|j[X@$XX@UX@؆\"SX@$QX@ٗMOX@2G+MX@_z[JX@*ZFX@Q CX@1&u}?X@Yv?k3?_? nt?vi?RHe?)h?/p?.6{?L%?j?֐.?u:߽t?'vXY? B?&9?9r? ?!?s&96?`ٰd?9" ]?C? !?PKXAppp_mid_IPVfN2.npyNUMPYF{'descr': '|1|,@rR,@,@,>[,@Sw,@?r,@?~'Y,@i,@,@ET2-@g-u -@sg-@CF[-@rR@-@{N-@v-@-&-@z@!-@ծ-@ -@,,5V-@ 6e-@0s-@L-@?|-@xC-@"N*@2T'*@(랒*@[U⊥*@/ *@GEG*@˻*@P)+@X+@*+@^t{+@{#j ,@P38P',@ Ŧ=5,@^A,@,,^L,@Ce,@V#},@ F,@fxލx,@\װ,@pO,@RF,@=,@1Ec9,@D ,@D]Z,@I8g,@l-@?o8w-@ -@^Tg-@8G-@: -@@m-@i-@74<-@E -@YI!-@B"-@ͬa#-@K^#-@C10n#-@ڶv#-@7ؖ#-@ե 1,@tmH,@` B~,@@2,@ G,@Y,@mN,@a,@PKXAސPPIsigma1_CT_exact.npyNUMPYF{'descr': 'QA.!,QApOQA QAbhQAu>QA^OQAf\QA|QA=PQAz_$QAoKQA @QAȘQAtQAp{GQA QAm(QAQAKQA(+ikQA!({?QAOAQA׭@QAQA^[gAt^9[gA=[gA[xt[gAHd[gAʮ[gA^{[gA/1[gA2[gAKc[gAģ[gA`Oq[gA[gAhp`[gAw[gA3R[gAG{[gA/9?c[gAճ:K[gA83[gA9Aj=[gA\TDZgAZgA#WZgAZLZgA~ZgANZgA6ZgA+oYgA#YgA^YgA=`"YgAEoXgA SXgAgInXgA_2XgAH~,WgAc޹WgA.i}WgAg~AWgAWgA!VgA~fVgAugjQVgAPKXAjvrho_CTrab_exact.npyNUMPYF{'descr': 'O@0 @a2"@H$@RP&@?XX(@cZ_T*@7/@_4@Ta{8@Φo=@<B@>F@g^J5K@)u:ۿO@ձD?T@zX@ .]@~ޚa@^e@F`j@ܥn@ris@*rMw@ {@@@Τf@f@@V@y]@OC@9@OE @ИpW @4 Q @TM@Zs4P@`+{@/^Φ@ZH@H@`Џ@@l@7! @l"@;;9$@(&@3x5(@{;*@ "!/@B4@R8@/e=@RB@C/F@#66K@|MO@0MT@$)X@kK]@da@'f@uj@{}%n@Д4s@Z? ~w@Լ {@#Ʈ g@elh@$fk@[An@7p@r@{$'|@@PKXA{ brineSA_t.npyNUMPYF{'descr': 'A@)>A@z &~>A@;j>A@d'AA@*PBA@b\A@ v|A@,_EA@ A@>)|A@jbhA@ KA@2Y+0JA@)sMA@urPA@K%]8RA@Gd1eSA@Dgl)UA@'VA@XA@-TYA@&[A@d;_\A@ܲ^A@R _A@TEحR`A@ CbA@ ," LeA@wgA@Vۻ`hA@uJ~\iA@-jA@ejA@FykA@{kA@7q]lA@! lA@lA@MZ+mA@6DmA@(+mA@XT,2mA@JFn1mA@eL3mA@2wKA@7lIA@hSMA@`KA@cDLA@HQA@ #uA@`A@sqdzA@p)i]A@oT5TXA@ fv]A@mv}ANeA@1$&gA@ 0[fA@9^dA@M^A@R8=`[A@GIYA@ɪW5YA@߉cYA@z"ZA@U[A@ө\A@P;^A@Eo_A@Z`A@$icA@fA@:gA@KiA@шiA@3jA@VkA@^TL;lA@GlA@OCCGmA@m@WmA@?u<)nA@f\nA@+nA@nA@!nA@]J4nA@9nA@[ӗ@-5@vN@kv@7`@DV ?B@/Y#J"@|w>$@PKXA (hhf.npyNUMPYF{'descr': 'n>1}=>06Qwb ?PKXAސPP Igrav.npyNUMPYF{'descr': '|8@4` %@$t@Pml@8://F@~k/ƣ@9& %@8Lف@Zϱ@u@6O@W@uM!@!PX@Nc$@ds@K9@ q@j_{@sl29F@F=a0@q-T@#>ʓJ@m5@n:.@U%5-h@\$@shG@Ei@ቸ@lKtζ@0LW@P!@W|録@!L@pz6@4\@`Y,@@=!@@r{@%w@p/@l@|mo\l@#@8f4i)@h}@--q@ƉP^w@nuet@PKXA+pt.npyNUMPYF{'descr': 'jd@f'@l؋@U%@@9UQ@|\Z@hWIy@eL@73&@g]f@}'7@I:uб@^+l@)i&@.%B@ĩ@$-@cpX@"QTx@wFn(@G@eL@\g1H)@VfP@@xl3@0`Q+@JŲ*@fm-@M7-@P>3@B<@Y@kdz@۽d@pDb@|@P@靯`.@/_@XG.x@4Ov@%~@la+@wx@B@R-GWY@6=gh@PKXAސPPIrho_t_exact.npyNUMPYF{'descr': 'XA@ I)A@k &~A@BxjA@jYZMA@KA@d=NA@G"RA@n@]SA@!c_YTA@{:UA@5NcLWA@egXA@g+P@YA@u>2[A@.ҽu\A@h]A@y^A@&u"_A@$~hbA@dA@ϳ\LdfA@e¨gA@hA@GsiA@aTjA@jA@ >kA@vկkA@{LNy8lA@<_lA@6lA@iZblA@бlA@p$elA@^LlA@1 lA@dAMA@KA@3pOA@Y}MA@NA@5RTA@xA@c2ZqA@Eym|A@D__A@[<.ZA@._A@'vfA@SiA@ظgA@ \eA@L2`A@NIf\A@ !ZA@B*YA@9_A@k^`A@{ӠbA@ӒleA@%fA@ 4>hA@AR!)iA@%jA@jA@`K~kA@},lA@lA@e/HmA@immA@9~mA@ݟ)nA@sg>nA@]TInA@hWnA@OnA@Ng@)Z@ +ݦ@8Ҍ@I-Iv@`KJX@l8U"@Rhh$@PKXAސPPIdepth_from_z.npyNUMPYF{'descr': '|*7Ȣ ~:?"AWA"q-ex`k@տGz/ֿν׿D \Kؿvi<ڿTQvۿ >TعPKXA|geo_strf_dyn_height.npyNUMPYF{'descr': 'ձp?U?;@㷽@ж=AjA#>Bl+8#B8+@C,_C8S"GD@DSR4A^ l"o&>vͯ+i";R[U!dŷ?y"G##NN*%ŧ'V6) ,_%K-9 /ʓ0r Q1"K2{33JZ&R48 57Y8c9Qb:L;"<c=h>ЏYL?\b@?e@@NA\"AhW6ByīBX!CD٘C g?\’z056ߝ! f" %@n5V0PKXAtdepth_from_z.npyNUMPYF{'descr': '@!x@Ueu@g%{@k`b:#@o3@8N=@׃C@uiH@R@`:Y@PKXAސPPIatomic_weight.npyNUMPYF{'descr': '>Ϳ3KEͿXͿBvv[ͿDͿ%ӿͿͿͿ:ƿͿ>.Ϳ&`ͿA#߸Ϳ˅п6(пtп)@пTG gпmv&п Uп-Pпrx#Ͽ<́ϿMjοxjοLtοuyhοYZYο AHο{}$ο(ο+NjͿ3Ϳ%9Ϳ̍QͿWD߳Ϳ߶Ϳ8OᰜͿB[ӰͿ EͿSrͿF?ͿͿJ_ا'ͿY[rͿ$QͿ+ͿnBy5Ϳc€KͿ6/ͿMͿ;cͿsӝͿ ͿIcͿ0UͿͿ2 $ͿRX&jX?g6?!'\|?lA?-H?hn? ?уfR?PKXAސPPIbrineSA_CT.npyNUMPYF{'descr': '5z ?C[ ? ʎE ?~nB ?Yu ?7K ?.SQ!?eT!?V4)"?,z0#?Kjb/5#?#݋$?F<%?b>I%?lc&?٠O'?Kh'?(?\=qZ)?xMǮ*?_l*?epV+? 螱4?&X4?CUe4?dk4?lۗ4?3rz4?!?"!!?r`7JS ?{p ?sM ?zDJ ?b ?efSIJ ?t5^]w!?|"?5 "? .C#?Xe(#?Z&($?Z/%?-%?I&Ex&?%'? w'?) (?a2,)?=v)?wÅ*?aT-+??.0W?~vS܌? 8 9?QfZ>IEW1>ܦ'/> FqR?PKXAސPPISA_from_rho_CT_exact.npyNUMPYF{'descr': 'S@@ G@Ii@d^V@^–@E@a5es@*I @j@ijd@p'@%؋@8T@@;ᣭQ@B\Z@0Iy@GNU@/@.]f@@27@Bб@:|@Y0@B@9A@zВ-@MTX@bŞTx@rLf6(@'n@4K@G)@ϲO@X~,@Gf3@ +@,*@(-@͚6-@=3@ "}<@Y@l(cz@i@3Η@V& P@݈.@v_@VG.x@9v@@o\=b+@Xx@TH@X\Y@.kh@PKXAkappa_t_exact.npyNUMPYF{'descr': 'E=dsC=ӕz=18==>'/=EpY 8=M;=C̍-<= y:= 8=d804=$Q"/=o'=RR=Mچ=[=c>m=R$=s=@̡uD=[=c9=톌=*eME=W P= =Z=@j=Z+=ObHY=j'B(=Hƃ=Դ>=O%qa=|n`=߂V]=!\=G]Y=0{]=a>Bi~=.l= =NVj=c? =tm>=a;t=L5_="=4=̦=2=sP*=ȯ[D/={!/=!=C?l|= @75=<8 = >J~=]=y=^ؑo= ^@=?Yl=?=dQ== ܆S=@9($=Md=//$=a3_5=`=!.=B=91zJ=k">Yi4>EMQb>s>7]>IEy>0e~>Pu>PKXA70>sigma0_pt0_exact.npyNUMPYF{'descr': 'i1;@@Jw0D;@?زT;@6zc;@ vq;@ge};@;@[o;@>֗;@@[c;@@V~;@@풷;@ JA;@@`;@jC;@@SM;@Y;@@Ê1;@:;@#0;@%;@gЍ;@1 ;@]n;@7;@%;@l+;@ u46@B76@?76@@ۻ86@ۏ76@PڙY6@297@6:8@@=@q8@,9@@[) :@@l7HW]:@G`:@nM:@:@@<2:@:@@R ;@ն*;@(G|>;@xLO;@@I_;@SDj;@@3u;@fL;@T;@20ē;@1 ;@@QPT-;@;@?;@@$.;@C@;@O;@@,a;@jm;@@0´;@@f;@C;@ /;@:;@0;@@G;@_a;@܆;@cW݆@ )7@h8n Q@cv@dS@LoH@@@ByCe @PKXAAppTu.npyNUMPYF{'descr': '0@f$7@Q7B@ F@vJ@МeL@T<wL@y2JG@.jCC@K!vB@ü$E@^*kԲD@XC@`?B@LsTB@xх.fB@Uc妱A@OnA@` @@GA@ el"?@z?6=@:;@|8@ 5at|:@H|A:@]9@kH\:@,5 :@6xw<@վ;@S} E:@,B>@ Xq>@`$B@2X@f)D@`? UG@pX +9@XSR@+c-V=T@yVיO<@;@-]]pA@s 2J@hK@zH@qlC@F؍ ?@XvB@S#mcI@z#J@ѻQL@^`(fOJ@p~y]I@ΦF@;SD@XD@ԖA@4).B@A@>5,A@보ZA@E=@P,=@Lm|9@J:@bu<<@km:@S%C>@,D ic@@A{@@A@؎H@@PM'=@SuaA@OB@PeA@XGB6@{Dշ(1y"xE @*cq(@hʟ )Q@wKl3DcFa"GPKXAސPPIsound_speed_CT_exact.npyNUMPYF{'descr': '.wF@ =F@w|F@&F@`I#BF@`vF@ 3F@@%F@+F@Zh9F@`kF@`>W0C@@Yi1C@}lu1C@`n,2C@ǧ1C@`DC@`"C@>TD@ƔPD@H}CE@qE@cTiE@~@E@`QE@* " F@dF@,V/F@HF@.`_F@`vGpF@}'SWF@ؤF@` MF@ oDF@@F@`yt.F@@4F@ ̡gF@@C<(F@ F@s,F@`-KF@`eF@`TTOF@ nF@S^F@`&F@"W4ZF@`ۭF@`F@`iF@ӴF@`_F@OF@ %F@^.F6@Y"{17@뒬7@@.8@88@@a8@{q9@q:@PKXA+p_from_Abs_Pressure.npyNUMPYF{'descr': '@D@I@S@@Y@_@b@f@@i@o@r@v@@y@@@@@@h@@\@@@ @@@@Ρ@̣@ʥ@ʧ@ȩ@ȫ@ȭ@ʯ@@@@@@@@@$@4@>@D@I@S@@Y@_@b@f@@i@o@r@v@@y@@@@@@h@@\@@@ @@@@Ρ@̣@ʥ@ʧ@ȩ@ȫ@ȭ@ʯ@@@@@@@@@$@4@>@D@I@S@@Y@PKXAސPPIentropy_second_deriv.npyNUMPYF{'descr': '-? Z[ w+kIN7tOz溟z:^UڈPKXA̜binternal_energy.npyNUMPYF{'descr': '!xUeug%{k`b:#o38N=׃CuiHR`:YPKXAސPPIinternal_energy_CT_exact.npyNUMPYF{'descr': '?)LFl?Gzє?/|?<#V?\ ?b46?1VzT?}]j?xz?}1ч?ʴh?u?O?Xf?E@?9? O?",?a ?Fפ?9?&Ƕ?|?6Lh??B??%'T?z]_? T?NE?֯?98?X"Eg?&B,W?À-?F?Ewo?)o?Id?! jL?nPK?w?PNh?d.?]X?@?,@?ZXi?o?# <?aS"U?o?#?Ks'?+ ??1\?~Ķ?ߟ8? ]p?8@? Pj?1? f?X??d5?u3?sN? ?ıLø?D?+:?e?PKXAސPPIalpha_CT_exact.npyNUMPYF{'descr': 'I^O?*=O?c O?HVO?kX}O?'o#uO?9ZKlO?cO?pT(ZO?zZJRO?VkIO? jbUAO?y8O?Jݿ0O?۾q(O?= O?eO?yEcO?ܿ0]O?IceO?:;΢O?deHO?ƻ%O?;PO?E ~O?ߤCuO?5IlO? cO?=ZO?d7 RO?A榐IO?J AO?3m,8O?zP0O?~(O?|O?ЯO?_(fO?9)>MP?^*MP?2KP?)3GJP?},IP?P[4HP?V &BP?ֳ->P?PKXA+bP chem_potential_water_t_exact.npyNUMPYF{'descr': '@Vy@<\@x}@!+'@@b1b@1p E8pmƬX@&Jp4@-U%_>+nG`>\M]>oR\^>v}a>=1Q>oC>nD>Y >Πۂ>-f>$;B>X>Eˆ>2Y>KkH>m}>v/)4>K- >5+x>fĒ_)>TT{3>zA7>Ū5>hG0>0~%>鍽>J>%|h>M>$!>1=*\>^J.>)Z>Rss:>ي>Dơv>w> e> vNL>l> n(?>|8ǟ'$>47W>P,>/y> <>>9 ~>S~>Y8>0 >R3>WE|f> (je" >Y{>M.jr>2L>Qv>wJ>6Y>m->m> >+f>P >P>=`޹>%@ >jdb>H >}} >e1>:7Z>ϲC(A >H#>`'1U>'{>Xti>ߡBg?>x?>Oo>$A!>d>v){\>.1Ɍ> 湕>ܥI 3>9^>S>h6V>wN>,5KT`>H$:>~2VW>0>dƘ >PKXA ^h_SA.npyNUMPYF{'descr': 'z@TpH~J 0]]NلS&q趐q V!hXt#R}l$Mw&4lV4* qT-[b0Ei2ۥ46qU66@6@7@n8@܋99@)ۉ. :@1,ԯ:@am,;@.S<@k=@+>@o?@@@H&d/@ 3/@i4/@bہ}/@=/@D` 0@+,0@E0oF0@rDX0@+^0@.,h0@r`Ts0@pɔ0@<90@1(0@,00@kɍ71@C㐟i1@e1@N"1@GN1@h2@5"G2@ _t2@ʹ32@o 2@hQ2@0De3@@3@[k4@+4@䝵5@63H6@ĹǙ6@7@e8@@,P'9@ʅ9@b:@;@Nhʑ<@=@$؇>@ ?@q)W@@H&d/@/@I/@e/@ \/@/@"E= /@/@PKXAސPPIgeo_strf_isopycnal.npyNUMPYF{'descr': 'N~A@jA@5MA@5.1DLA@WHOA@$RA@fk_TA@g݌UA@M+_QWA@]XA@9>EZA@Q[A@@]A@+^A@9/`A@ח JaA@DM{bA@ZeA@,6vgA@&[=CnA@#oA@ vZoA@dRSsoA@_[yZoA@caoA@yaoA@XcoA@4KMA@"KA@P CzOA@eqMA@֙ NA@ TA@)rǦ#xA@va@A@nk|A@ֺ*_A@BƒzZA@p_A@*tgA@,%iA@ŞhA@Q3fA@58#aA@ zea]A@:_^q[A@IA][A@N[A@/E|\A@5) ]A@c_A@8d`A@FȘaA@d˛bA@$jeA@a %>hA@NEiA@1kA@r?X "lA@3@mA@mA@%hnA@^woA@Pt1toA@|GMNoA@sigma0_CT_exact.npyNUMPYF{'descr': 'i1;@@Jw0D;@?زT;@6zc;@ vq;@ge};@;@[o;@>֗;@@[c;@@V~;@@풷;@ JA;@@`;@jC;@@SM;@Y;@@Ê1;@:;@#0;@%;@gЍ;@1 ;@]n;@7;@%;@l+;@ u46@B76@?76@@ۻ86@ۏ76@PڙY6@297@6:8@@=@q8@,9@@[) :@@l7HW]:@G`:@nM:@:@@<2:@:@@R ;@ն*;@(G|>;@xLO;@@I_;@SDj;@@3u;@fL;@T;@20ē;@1 ;@@QPT-;@;@?;@@$.;@C@;@O;@@,a;@jm;@@0´;@@f;@C;@ /;@:;@0;@@G;@_a;@܆;@cW݆@ )7@h8n Q@cv@dS@LoH@@@ByCe @PKXA&(beta_const_t_exact.npyNUMPYF{'descr': 'H?9H?{H?PMH?f>H?.? H?;EtH? R?_H?a4 KH?6H?k"H?J H?)V cG?r)G??ղG?rJkrG? [G?hIwG?TÀG?U 6mG?g@H?Ӓ H?G?SrG?poG?7=H?@{iH?(H?Y%zGH?[B_tH?SIH?.kH?aއmH?&_5H?e|4H?l*kH?uB=mH??cH?e2H?̛[H?W|bH?͇۩H? +_H?4{H?Fs H?v$H?^c,H?L×RH?Ŗx6H?åH?JH? |orH?_E^H?cM#JH?Kɀ6H?a% "H?iH?0|kG?d:N3G?$h G?*G?;|IG?nG? BG?Rb µoG?ڝ@wv9@;a7@"s4@i$2@G/@ʸݜ(@yx$@4u~"@;D @`L5h@y@M`@O(sH@4+^@f@(@NVA4 @ҴN @@&ft@I2 @y<6@Lg?8?x?B从??\?kD?{7?y`I&?${+@x?ZL6?bָ?iv?9Aqn?yuF?)??HCJ=?1&R;@Bk B;@Ak S;@%GgG;@ncN;@J΋ :@tlA8@u!35@s: 2@$PN.@y)@k&@'8Xc$@Y} #@e"@H?!@ 6w @+E[@k @/Oo@ઐw@+(n@Fs@ +v@}c @,*' @AZa@|q@vm@} ?מ?ڎ? ?5 ?Y`?t5?6F?8?/?~%?I*І?\b?$"o?یͭ?\ݏ??D?6j%@E#@,y@2@b)~@;6'ZO @@Pr@PKXAސPPIspecvol_anom.npyNUMPYF{'descr': '+@qկ@I@jIZ,@[=7E@r4e@7P@ܫ$@\~@5]k@T=#%@P' @_@eGNd@y$+@ΧnD@2r?"K^@pGz@CKď@#4A@9׃@: %@ ;>S@@ G@Ii@d^V@^–@E@a5es@+I @j@ijd@p'@%؋@8T@@9ᣭQ@B\Z@0Iy@GNU@/@.]f@=27@Bб@:|@X0@B@5A@|В-@MTX@bŞTx@pLf6(@&n@4K@G)@ϲO@X~,@Gf3@ +@,*@(-@͚6-@=3@ "}<@Y@l(cz@i@3Η@V& P@݈.@v_@WG.x@9v@@q\=b+@Xx@TH@X\Y@.kh@PKXAސPPISSO.npyNUMPYF{'descr': 'Tҿ@LH쿠X o${`f(vH$ PLtN B^@Hs! E"Hb$0 4%ګP'`<;M)`F{=/O+YR-M20/6w00:.G10 24Ɯ20.zo3 ] 4 (`4/(5(6@7z8F@9g X:Gsej;sw<@(b9?=!k>]?cH&B@t{@ki#AA:A;ABT/B`!{FC#CCѿx0B&PQq hEm` *)q6 /М> RH" `ʣJZ-:XBu P6ip W PG+";RT# T_)% jp'앀_)4 r+%G>-@}B. ?0 w1}6`1]c2̈3O4tS596 㵴7@E8@e9@|}:z;fv-<EW=>@z~??T[@ Fz@`BA?yMAX,Bj:B`T oM [=CLyS;#+#Q2PKXAސPPIisochoric_heat_cap_t_exact.npyNUMPYF{'descr': '_ײW@$tX@@JtX@l=CtX@sX@psX@H:mrX@7ͤlX@,2eX@`X@[X@pXX@ވUX@0"SX@Ҕ+QX@|MOX@D_~MX@vJX@!FX@bCX@q8W@a%W@1W@ W@ĆlW@t6'W@n;W@۷W@~WBW@dX@2 ^X@ ˓PX@F/X@ X@==X@;*kX@6X@PKXA,Urho_t_exact.npyNUMPYF{'descr': 'O@0 @a2"@H$@RP&@?XX(@cZ_T*@7/@_4@Ta{8@Φo=@<B@>F@g^J5K@)u:ۿO@ձD?T@zX@ .]@~ޚa@^e@F`j@ܥn@ris@*rMw@ {@@@Τf@f@@V@y]@OC@9@OE @ИpW @4 Q @TM@Zs4P@`+{@/^Φ@ZH@H@`Џ@@l@7! @l"@;;9$@(&@3x5(@{;*@ "!/@B4@R8@/e=@RB@C/F@#66K@|MO@0MT@$)X@kK]@da@'f@uj@{}%n@Д4s@Z? ~w@Լ {@#Ʈ g@elh@$fk@[An@7p@r@{$'|@@PKXAސPPIsigma0_CT_exact.npyNUMPYF{'descr': 'PKXAnLXXT0.npyNUMPYF{'descr': '\H?0H?2wŧJH?'dH?DjH?OsH?ē¢H? MH?-ŷH?H?*AsH?F2@H?4tH?=VH?O+H?(dgH?_H?e|T@H?CdH?\Yr.H?H?H?kH?yp`nH?j@YH?'CH?e.H?cYH? ?BH?7h&G?r䍥G? G?{*$G?EG?K7Q˅G?e)qG?lH\G?g@H? H?$G?[5bG?)0nG?8"H?}<9@H?J'H?ȏ3GH?ZtH?H?Z}6H?LzH?-|H?{H?9uH?qgmH?H?OH?H? FH?̒BH? ĸH?ryDH?7VH?BH?PDlH?Z7gH?$oH?oTH?!bWJH?@RlH?hrH'XH?>*yCH?.H?^JH?H?A(;7G?!҉B%G? 4G?f4lIG?_G?DbG?,#sG?Y=32_G?ڝ@kH?bH?[ЗH?\AH?pUc{H?zn3H?+DH?%4H?cA(H?9n(H?4TH?9OH?_4H?ͼ/H?^H?dy0{H?֠߼H?jH?؆H?;`H?gc2yH?]eH?F.~PH?/;H?M 2'H?U5nH?GG?rG?HG?ch3G?gS,\G?dKdG?Rq~G?T3iG?TG?i0I?m2DI?1sI?[I?"I?7ҡI?RyI?0)I?PKXAސPPIbeta_CT_exact.npyNUMPYF{'descr': '@߁@/6@R?uU?na_?+]ٸ?m?Fm1!?[ƻ?*\u"[?}@ ?pPZ?Fb?7?`?I?հuT{? m?ј`5?cI;@9;@umK;@(=@;@zNH;@d,:@e8@8`5@+@2@w7.@v|)@+'@.$@ƻ#@6m"@E"@zF"z @Vs@Ƙd@@a<@9Qg@1֕@=$n@D@Iѐ @0ڹmW @}WI@͏] @@7=H@M6,A?Ps&?c=?MYW?U*.?kq??;?I^ ?&?dO?G ?7?""%?nR*P?4^Q$@/ ]@"@J5@@Ⱦ @zd@V {@/k;f@PKXAސPP IntpptCT.npyNUMPYF{'descr': 'sivh@OaBLf/w*'vr@{/7\r)~NjR1ZX[Kw\?c3 s)mj 0z&sDjS̩쾮 O͎hmi> !YahT" ^mm.#<$NE&J'm(?ZwS*)V+v-]R4J{..zM/*4Z0ݚW1à 2 2:t3N!p f >B[/ !M >[5,,/!lh`1&АI+p21~cN%*;uq6o/g :.p}T|YWpF<;8m, $"M vn'RLEG(C i !ƻMT"bn#Y$NkF&'wB'k+(c5DT*Y+VYQ-!ɤ0|.ф/ɴ0К#X1= 2zsL20/u3pi59@\h @lZRx@m>mW@;raX@ x@_)?$?PKXAސPPICT_from_rho_exact.npyNUMPYF{'descr': '@@a>@=u!?@øN?@y]?@@ L?@#l?@E8?@l?@?@k@@ @@ !Q)@@a\G@@@@)%@@",@@z:Wm0@@3@@G6@@ 6v7@@(O9@@ G/:@@j ;@@`4<@@@ϣ=@@e =@@`}{>@@@)j>@@6I>@@8>@@̹>@@>vY>@@Pa:@kd:@(d:@7 e:@ Sd:@@pЇ:@@@ym;@@;`s>@@>@ $k?@Y-?@sO@?@;R?@@=hu?@Ǯ{B?@9b ?@Y?@;k?@79-?@b@@ (@@nr@@Tf@@@w[@@ I*P#@@+@@ G/@@ 3@@t5@@`'*7@@-9@@`!X;@@D=@@V>@@@:?@@@@@`1bA@@A@@`7h B@@dB@@L#l$B@@`KdB@@#@@ M|#@;$$@$/$@cCcU%@@ μ%@m?$(@w)@PKXA8Zi rho_rab.npyNUMPYF{'descr': 'T@dXX@a-]@c$a@`*e@Y`+`j@(n@s s@2KNw@`T{@s'}O@-LT@q 5X@wiOK]@C^a@(I'f@Xj@٤En@f[4s@R+i~w@O'{@Gq g@_s 8h@cfk@X]Wn@Ϣ98p@w.lr@ }@S@PKXASbeta_CT_exact.npyNUMPYF{'descr': 'oG?vYOG?3G?=X~ G? ~G?‡iG?\*UG?Oj^/I?[HHCI?~rI?ك}I?GLfI?[I?_ʿI?Ae I?PKXAސPPIt_from_CT.npyNUMPYF{'descr': 'N~A@jA@!MA@8.1DLA@WHOA@#RA@dfk_TA@\݌UA@;+_QWA@^XA@9>EZA@P[A@Ή@]A@+^A@7/`A@ח JaA@QM{bA@ZeA@6vgA@7[=CsnA@$nA@y>nA@G#oA@/ vZoA@dRSsoA@X[yZoA@caoA@aoA@6coA@hA@^NEiA@1kA@|?X "lA@@mA@mA@%hnA@ޯ^woA@`t1toA@GMNoA@bWpA@68pA@+'9pA@JpA@vrpA@u;pA@AMqA@Ng@)Z@ +ݦ@8Ҍ@I-Iv@`KJX@l8U"@Rhh$@PKXAސPPIkappa_const_t_exact.npyNUMPYF{'descr': '- adiabatic_lapse_rate_t_exact.npyNUMPYF{'descr': 'F~q=Y>PDZ6Y>*>+9Y>` 0Y>brQf#Y>X>}W>)+EV>>@cT>IRR>lSP>ԯ,SL>6HBI>4͓ԻcH>8d6G>/$E>~CD>l'D>c)C>C暶;C>QLB>'܃B>h2LB>i9;'B>.^ B>"uB>WLV:B>ȓUB>2,C>)tC>p6D>C+AE>:DuF>_yF>40bG>;QH>2 I>_7I>*J>K{%hK>k~S,L>$8mL>8LFM>hN>/I~X>c iX>o6X>=cX>]_#X>8!cAΛX><-5W>/#;U>V~a] S>KP>L6M>ksK>AeI>z">I>;;3ζH>N&:+H>xF>~E>蚕D> C&D>4C>2 I5C> (C>mZB>7N B>8y,v{B>j@WB>Db5LB>hSB>qu{VWC>𻳴bC>a͊D>&h##%XE>QnhF>4F>}}G>&ɟ4H>PH>upI>RYhXqJ>t2K>f)K>=@L>] _zM>g1T6N>Q>>\p;;>l I3>FʅA &><*>w>Vu:T > YY(>PKXAސPPIgeostrophic_velo.npyNUMPYF{'descr': 'D?PPy?PװO?s?t`{?o1?n9ҍ?Ș?2:z-r? Eِ?oh?HO R)?ʻ{*?o?v ?7 Ԑ? 1Q%!? P_?j>??&?F?Ov?l~}G? + H?{KM+?+?6&,?$e-?֡-?-,?u?43?r|:?4}D?8%Q?c \?!qd?JX Qk?ybn?Tij>p?Our?X)Vv?ؔ>?Az?|~Fu ?2?f?Ԙ T?VcL2?T?M,5:p?\(ދ?1,?3؉o?ȋ?GDDHX%?G] y?D?kG'?< j;z?WhB?%ِ?>@-]?-?#[Ȏ?TJ{6?,䷮׍?xK'[?犍?Cx?eh?PKXAސPP Irho_rab.npyNUMPYF{'descr': 'I^O?*=O?c O?HVO?kX}O?'o#uO?9ZKlO?cO?pT(ZO?zZJRO?VkIO? jbUAO?y8O?Jݿ0O?۾q(O?= O?eO?yEcO?ܿ0]O?IceO?:;΢O?deHO?ƻ%O?;PO?E ~O?ߤCuO?5IlO? cO?=ZO?d7 RO?A榐IO?J AO?3m,8O?zP0O?~(O?|O?ЯO?_(fO?9)>MP?^*MP?2KP?)3GJP?},IP?P[4HP?V &BP?ֳ->P?PKXArsound_speed_t_exact.npyNUMPYF{'descr': '+7@︖A@ڢM@7cZ@YA4i@Xx@'D:爗@3ez@=J)@T0\P@sX̗@D׼mޗ@v9@=%@6G`@GPr)&@8Ar9@ Q$L@h|2I^@ K @5}X @]ɷ @{t @"@'Pj4 @E @CC@(p@H@fy@Qg@*\@(-vW@lo T@&<]Q@x5I@#)qA@0h;@")8@/6@Gd5@E\ZM6@K7@2)8@":@y;@D@?gN@dū\@&)j@G;Iz@@N@ac3?@p@,ew˗@Vۗ@V @ݣT@W4m^@#@n*zr6@:I}k)I@@[@Aٓ@A8=Is@K| b@3Dn@;[Z@TQ@g@oţ"z@PKXA7$ pt_SA_SA.npyNUMPYF{'descr': ''?Q׆7'?̪F-I)?^)?l*?m*?([+? 5+?V,7 ,?Ԙ*@O,?04,?V?,?bw.-?NS;-?]y^h-?#1B-?#%d-?Jx-?]b*.?ҕ/J.?c8e.? hw.?9ֹ.?z.?%.?cݣ.?zū.?`.?0.?;X[R.?6.?@H߈.?9.??HP.?,i.?o]:>%?v@%?o.>%?t\?%?q">%?B=L%?k!g%?$m{XL&?.'?"i4(?T(?O)M|)?q)? %)*?!Y*?Ƀ+*?&**?E8k+?Td+?$%a&,?Y,Ikj,?zt,?լ ,?rB -?G*1<-?d:k-?ğ?-?"+-?+mB.?Z:9.??zV.?qgRkj.? $|.?Zp|.?n*.? .?i 7.?[T:.?,8.?vy.?d".?1.? 3:.? )l.?08(.? 6"?CJ ?ma!?GRh"#?Y%$?SyMϔ%? d1'?"#(?PKXAt_freezing.npyNUMPYF{'descr': 'rrNv /TJ6g bEO@n xQ@qFQ@U|ՂP@aTf/P@hO@`/O@_EN@{ .pN@O\M@*czM@ĉM@DL@d;F L@sf9/K@rzDK@J@|ήqJ@lɸsI@,41|H@G@y F@tE@e)D@? }C@NB@vB@@ #<@W*8;@V9@3E7@GR5@[^4@FS@#^yS@t(|S@hsS@OXkrS@$㪥cS@yYS@y͟R@sےQ@1/1Q@%2P@?P@hP@,VUFAP@,P@"O@:}=AO@DN@[y~N@9ZM@WjmTM@kmL@k#1L@x [K@6j gUK@uJ@<{J@1d~I@ 4.H@ZeqG@zXF@9$E@ID@]ݰC@ԫB@B|B@z\A@pb3@@9݂>@d)<@p޴ ;@G9@o'}ׄ7@L,5@W<:B4@^G Ф[$GvɡyFRnE?:gЏbD4uY0mC|:uJ:Hz2PKXAސPPIpt_from_entropy.npyNUMPYF{'descr': '4hw>hLKޡ~w>vt\?x=S?G,$?![Z0?3/*2?rHa3?o_Ҧ+?b$?K|8 ?:`g?ȃI?[{>L >,܎>qq [> 5>}Oz,>>;l>ve?= >PA>zp>Ͻb>s7>R>pF[> $h>}ʭ>y;>$(â>kcV>T>>۟ qn>/r">%>J}>-!A݀>Ah6B޴v>[KPJ>8<=>;K>&'nNYx>1`땑 J: ?e:5?aX\Y9?O41?1vV2?Gw;Qt$?P~?_E?[ۉ>|y+>Y >g$>/a_>%>>Vdƈ>q>MY->7x L>+-G>*I>l  >y(">cq>] >81>kdDh>:k*>95Yr>Ahy>vVw>W\W}&>])SI> 7>ra>hT5]>aސ>az> TyZ>6'mV>N[@x>%%?as}t1?+B"22?LDAw+?-b@q'?b텮 >?é"7?PKXAސPPIf.npyNUMPYF{'descr': '?Mܫt|?WW ?:?q|a?ff?Ik?|Dj??nʃ?뫿9?LIM??3,]?*?m?H;?Mİ9? 3/?͓B:??!'?W?.͌w ?R'?]v+?H?e ?W?N?%&?g*ˇ$??g%?p?Mb?5c?Pc?` ?x_C?Km?z(?(?iʉ?dDf? ;?Iл?k?8?(U3 ?{ vR?S̓?ArO?Hv/)?Ȟ`'|?D_?pR?aS?-e?_1O?Ys?|1?D/y4P?A?θ?:?0rFk??V?E ?H ??ƣ ?'?;y?n?6O?v#?|?PKXA[specvol_anom_CT_exact.npyNUMPYF{'descr': '"nN>'Ǵ>NG>r  >jv>>=BE>wk>\K~Q>R0zrp>ph >hJ*H>bJ@>D6L>3.>b(>P>L*>jw$>{-/>㬂X>D>F>ͥ>>~}>$ڡ>|@f>^>>_>( >8~>\>c>`01`>&!>.*5>2(^>X1*>䆮z> i>p@>p/>b>䣮>&>?>W'&>a>Vx><>]J >_@R >U>#͑>׸>@>:q%]>ӹ>ewE߳> ~9>R> >L: >x>B㽩>UJi>' >,ﶥ>kKk>Hd>v>@͟>k?f2>,#tC>L>b$V>@VU>nߙ> و>UjU>~>td⽗>繖>kx>Hߗ>> '>18u>@`M_d>:p>`wN>`Ւ>@İ`> I>@r>PKXARr specvol.npyPKXA kalpha_wrt_CT_t_exact.npyPKXAސPPo Igeo_strf_Montgomery.npyPKXAސPP IG_CT.npyPKXAސPPl ICT_maxdensity.npyPKXAސPP Ialpha_wrt_t_exact.npyPKXAp CT_from_rho_exact.npyPKXAI/+SP_from_SA.npyPKXAސPPIthermobaric.npyPKXAr]SA_from_rho.npyPKXAސPPIP0.npyPKXAS CT_SA_SA.npyPKXA6? 9pt_CT_CT.npyPKXAM #sigma4.npyPKXA29 (sigma1.npyPKXA7 K-sigma0.npyPKXAb 1sigma3.npyPKXAy 6sigma2.npyPKXApp [;IPVfN2.npyPKXANt?sound_speed.npyPKXA0@ Dgeo_strf_dyn_height_pc_p_mid.npyPKXAސPP nIIosmotic_coefficient_t_exact.npyPKXAސPPIIenthalpy_first_deriv.npyPKXAސPPJIsound_speed.npyPKXAސPPKIpt0.npyPKXAi93wKisochoric_heat_cap_t_exact.npyPKXAސPP;PISA_from_SP.npyPKXAސPPPIspecvol_CT_exact.npyPKXAz;Qentropy_from_CT.npyPKXA4Ubeta_const_CT_t_exact.npyPKXA6 Zp_from_z.npyPKXAސPPe_ISP_from_SR.npyPKXAn8_specvol_anom.npyPKXAސPP dIspecvol.npyPKXASeSA_SA_Sstar_from_SP.npyPKXAސPPiIR_from_SP.npyPKXA4qySSKjgeo_strf_isopycnal_pc_p_mid.npyPKXAސPP jIz_from_p.npyPKXAސPPVkICT_maxdensity_exact.npyPKXAސPPkIpt_from_t.npyPKXAhFXlcp_t_exact.npyPKXA?[S qCT_maxdensity_exact.npyPKXAސPPuISP_from_C.npyPKXAi.` EvCT_pt.npyPKXAސPPzIsound_speed_t_exact.npyPKXAސPPz{ISA_from_Sstar.npyPKXAސPP{ISP_from_SA.npyPKXA}`Iw|geo_strf_Montgomery.npyPKXA!4geo_strf_Cunningham.npyPKXA<CT_from_pt.npyPKXAݚalpha_wrt_pt_t_exact.npyPKXAwg cCT_SA_pt.npyPKXAސPPIsigma0_pt0_exact.npyPKXA0u( fdelta.npyPKXAސPPHIchem_potential_t_exact.npyPKXAސPPљIcabbeling.npyPKXA] շMSP_from_SR.npyPKXAσisopycnal_slope_ratio.npyPKXA1=13latentheat_evap_t.npyPKXAސPP{Iosmotic_pressure_t_exact.npyPKXAސPPIp_from_Abs_Pressure.npyPKXAސPPISA_Sstar_from_SP.npyPKXAЁentropy_from_pt.npyPKXAސPPȮICT_from_rho.npyPKXAސPPFIgeo_strf_isopycnal_pc.npyPKXA}dίgrav.npyPKXAL2|specvol_anom_t_exact.npyPKXAZXD:ionic_strength_from_SA.npyPKXAt90_from_t48.npyPKXAސPP Ibeta.npyPKXAސPP'Ialpha_wrt_CT_t_exact.npyPKXAkgSR_from_SP.npyPKXAސPPbICT_from_pt.npyPKXA"deltaSA_from_SP.npyPKXAސPPIt_maxdensity_exact.npyPKXAސPPIenthalpy_diff_CT_exact.npyPKXAސPP Isigma3.npyPKXAސPP Isigma2.npyPKXAސPP IC3515.npyPKXAސPP Isigma4.npyPKXA%' eta_SA_CT.npyPKXAސPP<Ilatentheat_melting.npyPKXAސPPIsigma4_CT_exact.npyPKXAސPPCIsigma1_CT.npyPKXA]J SP_from_R.npyPKXAnXXrP0.npyPKXA,sigma3_CT_exact.npyPKXAٗڪentropy_t_exact.npyPKXA>&Lj`molality_from_SA.npyPKXAސPP Idistance.npyPKXACpp Rsubrho.npyPKXA6o.alpha_CTrab_exact.npyPKXAސPPIt90_from_t68.npyPKXAĈ hSP_from_C.npyPKXAH8pt0_from_t.npyPKXAppp_mid_TuRsr.npyPKXA$8llat_chck_cast_temp.npyPKXAސPP(Ipt_from_CT.npyPKXAސPPIisopycnal_slope_ratio.npyPKXAސPP-Ipot_enthalpy.npyPKXAސPPIt_from_rho_exact.npyPKXA 5/ dynamic_enthalpy.npyPKXAސPP ISR_from_SP.npyPKXAx)finternal_energy_CT_exact.npyPKXAސPP (INsquared.npyPKXAސPPIz_from_depth.npyPKXA%"rho.npyPKXAx*XX gsw_chks.npyPKXAL QCT_pt_pt.npyPKXAAXXatomic_weight.npyPKXA 5sound_speed_CT_exact.npyPKXAˈH#C.npyPKXA 'ntpptCT.npyPKXAlZ ,h_SA_SA.npyPKXAސPPU1Ispecvol_t_exact.npyPKXAQpp1G_CT.npyPKXA6 XXm6uPS.npyPKXAV6latentheat_melting.npyPKXAސPP;Igeo_strf_Cunningham.npyPKXAސPP,<Ikappa_t_exact.npyPKXAސPP<ISA_from_rho_t_exact.npyPKXAސPP2=Ibeta_const_CT_t_exact.npyPKXA =pt_SA_CT.npyPKXAސPP!lBIchem_potential_water_t_exact.npyPKXAސPPBIdeltaSA_from_SP.npyPKXAސPP }CIenthalpy.npyPKXAICpot_enthalpy_from_pt.npyPKXAސPPHIionic_strength_from_SA.npyPKXApp?Ip_mid_G_CT.npyPKXAmWYMdynamic_enthalpy_t_exact.npyPKXAސPPRISP_salinometer.npyPKXAސPPSIsteric_height.npyPKXAH Sh_SA_CT.npyPKXAސPPOXIsigma3_CT_exact.npyPKXAx Xalpha_rab.npyPKXAG ]t_from_CT.npyPKXAސPP7bISP_from_R.npyPKXA bpt_from_t.npyPKXA fgSA_from_SP.npyPKXAlSP_salinometer.npyPKXAސPPpISA_from_rho.npyPKXAsXXPqSSO.npyPKXA'qqlatentheat_evap_CT.npyPKXAސPPvIbrineSA_t.npyPKXA(FwCT_chck_cast.npyPKXA6o{alpha_CT_exact.npyPKXAސPPsIpt_second_deriv.npyPKXAސPPIalpha_wrt_pt_t_exact.npyPKXA`|thermobaric.npyPKXAސPP1Icp0.npyPKXAhizspecvol_t_exact.npyPKXAސPP`ICT_freezing.npyPKXAސPPދIgeo_strf_dyn_height.npyPKXAp'[ dbeta_rab.npyPKXA[:ޣbrineSA_CT.npyPKXAސPPʕIenthalpy_CT_exact.npyPKXAސPP NIsigma0.npyPKXAސPPǖISstar_from_SA.npyPKXA24GSA_from_rho_t_exact.npyPKXAސPPIentropy_t_exact.npyPKXAͯkappa_const_t_exact.npyPKXAސPP CISonCl.npyPKXAސPPIlatentheat_evap_t.npyPKXAސPP?Ivalence_factor.npyPKXAސPPIrho.npyPKXAzρֈ6pot_rho_t_exact.npyPKXAސPPIentropy_first_deriv.npyPKXA>tuHelmholtz_energy_t_exact.npyPKXAip 7z_from_p.npyPKXAސPPISstar_from_SP.npyPKXASibeta_CTrab_exact.npyPKXAސPP#ICT_from_t.npyPKXA/ˈ pt_SA.npyPKXAސPPNIT0.npyPKXAސPPüIt90_from_t48.npyPKXAސPPBIrho_CT_exact.npyPKXA6 CT_SA.npyPKXAސPPpIbeta_const_pt_t_exact.npyPKXATJ؈Sstar_from_SP.npyPKXAސPPIrho_CTrab_exact.npyPKXA!I1CT_maxdensity.npyPKXAސPPIbeta_const_t_exact.npyPKXAC malpha.npyPKXAސPPIenthalpy_t_exact.npyPKXA steric_height.npyPKXAސPPVIt_freezing.npyPKXAٛ  geo_strf_velocity_mid_long.npyPKXAސPP/Idynamic_enthalpy.npyPKXA}thhgeo_strf_isopycnal.npyPKXAސPP NIchem_potential_salt_t_exact.npyPKXAV` eta_CT_CT.npyPKXAC0t_from_rho_exact.npyPKXAnISP_from_Sstar.npyPKXAgxXX SonCl.npyPKXA&Sstar_SA_Sstar_from_SP.npyPKXAސPP?Ienthalpy_second_deriv.npyPKXAސPPIlatentheat_evap_CT.npyPKXAސPPLIspecvol_anom_CT_exact.npyPKXAAĆ eta_SA_SA.npyPKXAސPPIpt_first_deriv.npyPKXAސPP IIPVfN2.npyPKXAVw  geo_strf_velocity_mid_lat.npyPKXAސPPIinternal_energy.npyPKXAFR^sigma2_CT_exact.npyPKXAސPPIspecvol_anom_t_exact.npyPKXAސPP Ip_from_z.npyPKXAjvrho_CT_exact.npyPKXAސPPImolality_from_SA.npyPKXA-XX RC3515.npyPKXAenthalpy_diff.npyPKXA- R.npyPKXApp3p_mid_IPVfN2.npyPKXAސPPICT_first_deriv.npyPKXA0E Reta_CT.npyPKXAސPPIsigma1_CT_exact.npyPKXAސPPIdelta_sa_ref.npyPKXAސPPICT_second_deriv.npyPKXA   distance.npyPKXAjvrho_CTrab_exact.npyPKXA{ #brineSA_t.npyPKXA (hh;(f.npyPKXAސPP (Igrav.npyPKXAڈ=)Abs_Pressure_from_p.npyPKXA[-internal_energy_t_exact.npyPKXA+2pt.npyPKXAސPPg7Isigma2_CT_exact.npyPKXA!a\$ 7enthalpy.npyPKXAސPP<Irho_t_exact.npyPKXAސPP=IHelmholtz_energy_t_exact.npyPKXA L=Sstar_from_SA.npyPKXAސPP[BIdepth_from_z.npyPKXA &BCT_freezing.npyPKXA|Ggeo_strf_dyn_height.npyPKXAtLLdepth_from_z.npyPKXAސPPQIatomic_weight.npyPKXAg$Qchem_potential_salt_t_exact.npyPKXA|E GVeta_SA.npyPKXAސPPZIbrineSA_CT.npyPKXAސPPt[Igeo_strf_dyn_height_pc.npyPKXA[alpha_wrt_t_exact.npyPKXAސPP`ISA_from_rho_CT_exact.npyPKXA?aenthalpy_CT_exact.npyPKXAekappa_t_exact.npyPKXA70>jsigma0_pt0_exact.npyPKXAAppkoTu.npyPKXAސPPsIsound_speed_CT_exact.npyPKXACCtsigma4_CT_exact.npyPKXA+?yp_from_Abs_Pressure.npyPKXAސPP}Ientropy_second_deriv.npyPKXAސPP~Iinternal_energy_t_exact.npyPKXA   geo_strf_velocity.npyPKXA̜b`internal_energy.npyPKXAސPP!Iadiabatic_lapse_rate_t_exact.npyPKXAސPPIuPS.npyPKXAސPP ITurner.npyPKXAipz_from_depth.npyPKXAސPPMIinternal_energy_CT_exact.npyPKXA<^sigma0_CT_exact.npyPKXA&(fbeta_const_t_exact.npyPKXAy,XX"cp0.npyPKXAS&rCT_from_entropy.npyPKXAސPPXIspecvol_anom.npyPKXAސPPIdynamic_enthalpy_t_exact.npyPKXA/benthalpy_t_exact.npyPKXAސPPISSO.npyPKXA%EXXvalence_factor.npyPKXAސPPICT_from_entropy.npyPKXApp p_mid_n2.npyPKXA6geo_strf_dyn_height_pc.npyPKXAސPPIisochoric_heat_cap_t_exact.npyPKXAPӈpt_from_entropy.npyPKXAސPP<IAbs_Pressure_from_p.npyPKXAzBenthalpy_diff_CT_exact.npyPKXA,Urho_t_exact.npyPKXAސPP7Isigma0_CT_exact.npyPKXAahhgeo_strf_isopycnal_pc.npyPKXAnLXXXT0.npyPKXAސPPIC_from_SP.npyPKXAx/ӈPbeta_const_pt_t_exact.npyPKXAfbeta.npyPKXAސPPIbeta_CT_exact.npyPKXAސPP=Idynamic_enthalpy_CT_exact.npyPKXAP5t90_from_t68.npyPKXAސPP IntpptCT.npyPKXA9)FĈdynamic_enthalpy_CT_exact.npyPKXA/2t_maxdensity_exact.npyPKXAސPPxICT_from_rho_exact.npyPKXA7sigma1_CT_exact.npyPKXA8Zi rho_rab.npyPKXASfbeta_CT_exact.npyPKXAސPPIt_from_CT.npyPKXAސPP Ialpha.npyPKXA SA_from_Sstar.npyPKXAސPPIkappa_const_t_exact.npyPKXAj>- Nadiabatic_lapse_rate_t_exact.npyPKXAސPPIgeostrophic_velo.npyPKXA*]Ɉdelta_sa_ref.npyPKXAސPP M$Irho_rab.npyPKXA*$long_chck_cast_temp.npyPKXA,Z%specvol_CT_exact.npyPKXAr*sound_speed_t_exact.npyPKXA7$ J/pt_SA_SA.npyPKXA3t_freezing.npyPKXAސPP8Ienthalpy_diff.npyPKXA?K݈09chem_potential_t_exact.npyPKXAސPP=Ipt_from_entropy.npyPKXAސPPr>Ientropy_from_pt.npyPKXAelpp>n2.npyPKXAސPPCIf.npyPKXACosmotic_pressure_t_exact.npyPKXA!Hosmotic_coefficient_t_exact.npyPKXA[Mspecvol_anom_CT_exact.npyPKHHQBRgsw-3.0.2/gsw/utilities/data/gsw_demo_data_v3_0.npz0000644000175000017500000000661412172027023023352 0ustar amckinstryamckinstryPKXAؚѸ gamma_n.npyNUMPYF{'descr': ':@2I,,:@jj:@#<;@ TR8;@JY+X;@Y-s;@JM!;@HI;@ZѮ;@sEq;@2I;@ 1a_;@I;@@;@`;@]<@k6 <@&><@4Q<@ޔN <@X38<@)f<@tP_<@oX$<@@(<@}<@p=<@ic <@)7D <@PKXAhhtns.npyNUMPYF{'descr': '@D@I@S@@Y@_@b@f@@i@o@r@v@@y@@@@@@h@@\@@@ @@@@Ρ@̣@ʥ@ʧ@ȩ@ȫ@ȭ@ʯ@@@@@@@@@PKXAhhsns.npyNUMPYF{'descr': 'VA@eWA@6TWA@jZ_$XA@vyYA@hUYA@d[A@#GGXA@c*SA@QA@,KA@)WDA@aO;59A@@/A@ǵA@ 1A@VCA@wR~RA@£A@a$A@3V+A@61A@&N6A@ u:A@-[닄>A@>EA@eF ^KA@ 8NA@~:3PQA@RA@ΪVTA@ecUA@y)VA@~TVA@ACWA@k&lWA@WA@@M-[WA@x=\rXA@"*XA@mXA@7XA@[ YA@PKXAEachh gamma_nns.npyNUMPYF{'descr': '@J %v@Y4 @q@U@?!y6?!9Y?;^?c 8?~6rݔr?6?bD?^-?hZbe4?;~?LP÷?g{?9]?ퟧd?):?fx?PKXAؚѸ gamma_n.npyPKXAhhtns.npyPKXAB{hhnpns.npyPKXAXX p_ref.npyPKXAm|XXzlong.npyPKXAyTp.npyPKXAhhsns.npyPKXA[XX`lat.npyPKXA'jSP.npyPKXAEachh gamma_nns.npyPKXAL t.npyPK O' gsw-3.0.2/gsw/utilities/data/gsw_data_v3_0.npz0000644000175000017500000015371012172027023022346 0ustar amckinstryamckinstryPKXA+5PPsigma_2_ref_cast.npyNUMPYF{'descr': '@ >@@pj>@H>@#}>@@71.?@@"@@ b|@@ 2f|A@`~fϼA@WypA@`%A@MA@FB@<B@ "(B@ (K]4B@`?B@ βFB@?NB@W1TB@` ZB@SUY^B@RAiB@rB@ RzB@`' =\B@ߴ{GB@B@`$ݼB@ 7B@ B@PKXA> qXXlong_ref_cast.npyNUMPYF{'descr': ':62,$@@$@,@2@6@:@>@A@C@E@G@I@K@M@O@P@Q@R@S@T@U@V@PKXA:[XXlat_ref_cast.npyNUMPYF{'descr': '@@@<@(@@@$@@@A@A@A@A@B@C@C@PKXAyT p_ref.npyNUMPYF{'descr': '@D@I@S@@Y@_@b@f@@i@o@r@v@@y@@@@@@h@@\@@@ @@@@Ρ@̣@ʥ@ʧ@ȩ@ȫ@ȭ@ʯ@@@@@@@@@PKXAU ocean_ref.npyNUMPYF{'descr': 'lA@iclA@p΃kA@ 3kA@ybqkA@\0VkA@9r$9kA@+αjA@^`jA@ iA@7iA@VO~iA@fiA@*@7iA@>T.iA@xZXhA@B*,hA@3-hA@/thA@n[I7A@3n8A@ڭ*8A@]'h?8A@9A@}>nX=A@FlNHA@ SA@0^A@J'peA@cpG iA@ 0+jA@SvlA@ TQ/mA@/emA@_gmA@mA@}=5NmA@2gmA@pRlA@lA@)UlA@[}lA@HkA@gzkA@mKbkA@iAkA@AOjA@߯`NjA@6(jA@y`iA@NJiA@g6NiA@·[ iA@-=hA@Z hA@hA@`5hA@IyghA@˞ hA@~+~ hA@=A@$ϧA@ǭbA@~A@InA@^A@t]7&A@ (2A@.pwtBA@g^A@My,gA@u3IjA@mQ lA@4oslA@a_%lA@fqlA@ctlA@QPlA@p^0lA@h7 kA@[/kA@pHkA@+8+]RkA@kA@BDjA@jA@jA@+jA@BiA@jX[iA@ƊPiA@c5x$iA@ PhA@hA@1ZhA@U`hA@u{GhA@PhA@S.gA@ WhA@2khA@ #hA@=rb^A@FpWpA@v>t{|A@H5A@A@9|A@GA@zO'A@l%2A@$B?EDA@8MUA@T)\A@xޅncA@=fA@iiA@ ɰjjA@{)kA@WmL,lA@_GUlA@)νNlA@5lA@#,kA@e}kA@FtkA@EkA@XqkA@+ jA@#&jjA@, jA@5,iA@jFZiA@oiA@$sChA@hA@!hA@%`nhA@%.hA@B?gA@gA@7]ܿgA@"HgA@rgA@VbgA@n;A@%(`A@lA@3ZA@߳A@>kA@~]n A@nA@M8"A@"{Ki&A@%4A@^^mBA@5r6KQA@Q ZA@ _A@:4bA@phA@?lA@~ nA@oA@qvmA@lA@^FkA@'IhkA@<]jA@8iA@iA@ϒNhA@mhA@ſshA@E[hA@զ/A@I+lA@ڭA@evA@A@ A@rA@v7, A@t#!A@,AiA@PnA@Mкn(A@!@D1A@' 9A@)U?A@^\e>vEA@ MA@͸UA@%io\A@t7HbA@MKfA@}jA@k%mA@{ oA@dLBqA@?rA@S rsA@|g>+tA@ғsA@74CrA@GpA@ oA@onA@5nA@*HROmA@MR+5lA@5\RmA@#FS!A@` A@1 A@9/0 A@bA@K`A@^:$A@ɇ4$A@N*A@4||-A@Gp0A@'0A@Vi,1A@VնI0A@"0A@0A@HE2A@6A@9dž;A@$_BA@x|QIA@?$PA@R VA@|Y[A@;n`A@ֲПeA@i9iA@ qA@,ivA@ 4y xA@w9wA@1{vA@/1uA@IsA@l!rA@RpA@(#pA@#qMoA@ᄋnoA@!ȼnA@8$KA@GtOLA@KݭKA@j4KA@|{KA@t2*KA@yrnINA@WOA@CaSA@UA@WA@tCVA@2<&RA@@NBMA@췶*HA@wܥBA@dk6A@N'q2A@}0A@}e3A@ ߢV7A@jAA@`g%}GA@T MA@/'TDTA@{[A@K_3RiA@žmtA@JDzA@%u~A@K3uuA@i>A@FvhA@: }A@oyA@TrvA@~4L4tA@2FdrA@#rA@<NrA@OfcA@:(A@aA@lĨA@xkA@'ұA@!A@ZjA@@|A@ νA@lOܻA@/ūA@cԫA@-UA@IbbA@)FA@j2xsA@N[A@6>:JA@?A@Y;A@|%ilA@V!YvA@ɭk|A@g@D@A@Y俀A@۵A@A@L˾߀A@YM8|A@%NIwA@!jwA@y sA@erA@nrA@8aA@A@{~pB@VM*mkA@ A@WW0A@l9tA@pCA@p-A@ٶA@YA@R$A@94A@ڭ&A@!.A@u0A@''BoA@I* YA@\- JA@t=BA@_JBA@h/QFA@@MA@=XUA@b]A@hdA@FYn'GkA@PGvA@󛲂|A@챊`A@m2A@8'cA@?"SǃA@`|{A@?A@D)A@pnA@QwS?A@yRA@]A@h B@FfOdB@-1 B@ |bB@G B@pq5B@ 8B@.0FA@BJA@GA@=wA@[GA@n〫A@TA@APA@;A@^,J$fA@tPA@Y*FA@ddEA@D3JA@0v;RA@m08ZA@uҡbA@"վ jA@jpA@TvA@y~A@ƻaA@k1A@_>A@̬׃A@,yA@o;A@޳A@m;A@΅A@ȵΚA@p GA@V̄A@KxA@@A@i(VA@ B@~B@oB@}TB@|B@ j3B@~!?B@A@O1A@uA@KA@pyƸA@gKѦA@gRA@E1!A@U7vA@WG_A@g72"QA@SMA@aNA@2RA@ԈEYA@*O aA@fhA@ oA@zg?uA@kj{A@x:A@g džA@A@aA@A@A@6A@źj{A@wFhA@a}qA@ZhA@HY@A@~,2A@JiWA@511A@F$A@0Cz0B@s#,)B@ŜW3B@+s-B@n7y&B@I\B@~¤B@TA@j&b2A@]A@@TA@zMA@]CA@E็A@lGwm{A@XoA@5^__A@J rUA@ ZQA@egRA@9ީVA@fo\A@9cA@{kA@/D{sA@GZ$zA@^oZ&A@JuA@?A@ڠ%X;A@^A@JA@K6dA@A@@ֆA@+Aj†A@?qA@*OGA@!1/A@gI\A@%xIA@B@(1B@ B@EA@뻗A@2A@ɼA@A=A@B~!PPA@ uǰA@,A@^f xA@A{;gA@> \A@4VA@slW{TA@FWA@#5v^A@"pfA@i%oA@ɫvA@"C}A@=;A@:A@tWA@xu/A@]A@RA@yA@xփaA@>A@ֵA@;}A@MDA@>. A@| ҅A@LA@ $A@Q#A@pA@X)B@>E.B@(m.B@%KK+B@ &B@UzsB@E^8-A@c˶A@X/A@yc:A@A@7nA@%C朚A@ȤA@A@[`)|A@Ϝ1kA@BNO^A@iWA@w"UA@o,YA@>_A@ hA@㲦qA@L侐yA@xw{A@1A@>A@$ɆA@VbtA@yi(A@[…A@W(pA@A@{NA@C|A@U^KCTA@1A@׆A@}B@՗A@6k A@2A@j.$A@ٺA@$byA@RnʻA@:XA@8%A@ A@cEnA@S5~}A@dDjA@$\A@i#5WA@$@WA@_ @/aaA@RdA@~vʞ[A@PUoVA@DZgZWA@;]A@[DWdA@a2oA@CyA@܃ޛA@uZsA@ 'A@m`}͏A@zA@{R|BA@Q莋A@f.G3A@n4&A@#?A@}9A@XĆA@!v A@Ue8ƊA@,A@;yA@KA@śLwA@ $J~A@V A@Z{GA@A@A@A@A@ 7A@E{A@D|KjA@;A@%6A@1UdA@5{q/'A@ ¼A@A@G:A@[XA@*mA@8_ˇA@0A@eҲNA@V&\oA@)?jA@ot5B@ddچB@XhB@(MB@_B@ iĩB@DzPB@JYB@-C@ߌS(C@\̙'C@%5C@RCC@kLC@٪PC@;xSC@)TC@VffTC@5WSC@IWLQC@RY6QC@xifV{B@mB@_JU~B@+B@ƷJB@ƩNB@}s}B@nB@?́B@ݳB@z@$B@8АWB@)aB@kOB@<#B@@B@lm5/B@SC@}SC@.K-SC@@;3QC@VLPC@l1|OC@jNC@8EOC@yo&OC@+ OC@C=̐OC@J򏾋pA@X[A@g]!A@5U4PA@ʆA@ØA@"nA@A@5F2pA@5A@f'^A@S7"{PA@vSA@Rz}uA@0A^+A@Rs5oA@*9A@5QA@[IY] _A@-4`A@ fA@t g?A@UƠA@mA@f[*C@GͥA@ZjA@]ɒA@Z懂'A@jA@S҄率A@tBmA@eqA@nItlA@4=̽A@݊bA@ TA@QA@:7A@_{A@ջA@j>A@!5A@K\6A@t_A@ʖA@ejA@>0A@9򟠛A@:,A@1fPA@1A@uA@6[yA@⻩ܟA@M2KA@ uзA@1=A@d\ԜA@(lA@!eɛA@4HA@XA@eA@BA@A@ A@~$A@)t;A@@m{A@稅A@v'BlA@OpGXA@FA@74A@br17A@ĔD@A@ RA@ A@vάᜉA@;ztA@W,CkC@ԛ|l\A@޿cA@ z)hA@E;pA@evA@2آS{A@bg:A@_ZA@_fp A@ 2tA@vA@A@&:A@9A@ A@22!2A@QA@WPA@jh]A@T A@bA@ A@LmA@҂A@)/?@ᚡ6?@~@@O6ؗ(@@)^F@@o@@EXL@@ڗRm@@iH&A@G@A@}7"TA@+#ZcA@MXyA@ ȅ_A@B=EA@uA@6r;MA@A@ӁA@O A@NWypA@,[A@gA@6ىA@6%A@.A@k!ߊA@`AA@UA@>fA@n-A@L ~A@XA@?;qA@:-A@1wriA@φA@:`A@P{i?@~`w?@VIޞ?@oe?@Uz!@@9I@@z@@jOG]A@S޴1A@.FA@%YA@TNVhA@XepVyA@A@ 0P~A@!MA@s̈́A@;A@иwFA@CɻA@ r.lA@X:A@7kA@A@R1A@T1A@`@)A@tCA@z!A@=nA@˹˥A@q5eA@M 7A@U𧨔A@hٌA@47A@(׍A@'^ڍA@PKXA,ѿ?? SAAR_ref.npyNUMPYF{'descr': '̚0?LvӁ0? ,`s0?ʨ: b0?M0?P ?B$^?Z|?N"22?=7(=e?öj ? Gڳ"??vM,?LUlG-?b04?2.?@.?ڛ۝/?/{ 0?Uyj;0?K`o0?b^k0?B0?.l0?,U0?8?o1?k-(1?@1?M1?ǤhT1?2yS1?EJ1?m71?t߿ 1?gZcE1?յ0?ƨ0?z0?r8ٗT0?E?.d0?u_DZ0?H2 D0?|9x@0?sq |?֮P%?q?bJ?)R?/<͌?3X??<8W?pfQ?FW!?%T^"?v ?$? ={%N%?2 B+&?Q@K'?iS'?#.(?Iv)?=4? *?-ҁ*? eD(+?otF+?ڻш,?>t&,-?rʼ-?5Rr.?%ݰ..?'+]0?% 7}}0?Ƣ'0?ye0?;u31?h떌]1?S *J1?b_y;11?o巢1?\Y 1?wE1?xX ?~y ^ ?[P|?-5K?\h>6g eD?몼E>:(ڟ?5E?kQ8p ?H$q?TjЈ?,i^?'`n??do?x骭? vKn!?€?ϰ"?t~#?OG{$?0$?6*M%?Ɋw@px%?qW%?L9%?"?H&?T?&?7'?`4)?Y*?jqK,?R[-?}ţ.?bVw/?HEp/? bg/?iRb/?NJ- e>(6 >+x3>RX>u>ʬ>Ap>I>X7f>/>F%@>'C>dD?$?@btv? 69 ?Ө?x.f?ܴ?f?;+jr?v2n ?oGK!?N!?\ m"?[6"?"?~-#?]#?7Fז$?_ߐ&?"#ޠ'?d|)?7cE+?my-,?]_]-?Ȅ.?ʻY "/?:*->+/?Mʐ)0?XZ 3h>JoZ'>KC>˲>Q;>Pz(>x>:>qni>pdvQ>HV@ >'R>Y0|>'a>ѱd=o>g<1e>}&8vo?uL.?_7`< ?3|?TRQ?kP?sp?l7? ?>3d!?ђ*. "?l"? & "?piq{!?܉B"?*"?7#?z%?('?So*?Ńf,?v;B-?V^-?ޏA5h-?ͱe-?_JhOt>~>v'X>Ѩ>Ʈ>L/6>u>m.>> j>C'>w#>2}v>bg;X>k7>s>֕#>ɋo?&v? ?Đ?n??^?S?鲥?ghu ?MO!?44!?KcP!?>R ?CB ?S#z߾ ?{j!?)@MW"?$?.(?6]+?o,?2 sJ>ZX)%>5j>l^.5>V;[>1/wI>2N*>y:7yj>Q3ߴ>ܾ>Z1>Ѵ)>>>PI->#->: e~>nlR0?QZq?|6?WB)w'?Q(8?6?qw??069 ?1t(܏ ? /6 , ?geG?,P?Re?+5?05fݏo ? !?oIh K%?B2q)?d+?')2-?؆=-w-?!-?j>{>FhP^`>6p$>byms>O0>^?">E>X>MN~>ض >$xt/->7Det>[fC>GT >XJs>&?ܬd?9?3b~F?7o;?fEyxt?ȹq?>?82n?c`m6?>o ?ʦQ?y!?8?8{?9+ֆ?+?t?wuh< ?2͒"?(zLl#?Yp=tE#? 鴐5$?/ף<>M>Gb`j>,> O >>J(>┚!X> >,>_k>$w>*'>&^L(>4l>8?{>AH?Vè ? ??`D? C_{?)l* ?p2#?{~v?!֠ɣ?`u?J<?]4?, Y?$q?}eھ?}7; ?=/ ?A-' ?. !?"!?B?!? 5"?5#?~2i$?b-Լ"?F$>!?G]>ץO>+f7s>9N9>I@+"9>Y6]&>>>eK>72>+K8{>BP>O,'U>-)>O=1?@ ?7߫?,׺?&@NҺ?Me?c+?IpK? (0?LOm?ᗪ?*b;?'h?=an?6cĂ?~$?_ _ ?a%?!?KȏM!?L#twM"?)M <"?T>"?rL"?J*Rl"?+8#?(#?~1#?z#?v>=4ˋ>Jvh>j!j{>5{G>VB/>gm;>F :>Qkzl><9^H\>&e>T>$4j>7BG?xR?1[?F6* ?dN?IGh?Rx40 ?ZYI?v;?Hb ?S ?#U?{r?%QB(?s^?Jَ?eT?7{om?-`?w=!?_s"?X#?6a$?BD$?=Or$?ؽ$?p`$?"'$?AY$?P-ޮ$?kfI%?<:a}>k>Yۭ>R-Ak^>6QS$>~TԎ>"'>e&(I4> Ʉ/>Q9>>C2R[?OS#?[bO(?tkU ?=f ? z??HR|5>_*>:{%>:[t>sC2 >j:Xm>t> >w9m?- ?=?sᤷi?c8 ?gYf!?)o?qs?+?w?c^?CZc3 ?`3*t ??n?;?a%N?'5?P#?t(o?%0a?`8{!?;4#?$?%W6&?onP'?{dQ'?կ,(?˂95:d(?Z4f(?ſlqh(?@{x(?!ǿy(?i߭U(?#!3>{_ >wU$>?s>YY>(t)>Zjb>NPNR>#j?s9L? ?5_L?ڭGS?0LD ?18?7zm?իpq?F?}?2LI ?i9 ?yEZ!?=02 ?1 ?+?fe d?.Yc?~:g?z=]?`Du ?;QG"?h$?%+%?[[T&? (? 9(?Ա~)?)f)g> U>nL>7>]9)>5>K.>_E?IA?"i`t?)Ƶ?5 ?@"_?p?PhT?å??*/v?]! ?U!?͸#!?3 I ?y?~;ԭ?@|@?AW?AXI}?l=)J?C?nyY"?#73$?W™a&?MQ<'?VЭ(??y)?Xa֮Q*?FPT+?Ӱ ,?T"z-?\|.?E{?>:R>QR>&>*Fư,>lSd>4=FV>) ?w+C?0? W?-Q}?:J ?7'?lh:%L?6c?o!?7 x? ?7 +"?/Kʏ"?^cyq"?Ic%!?Dkޅ?S?{3? c?S 0?G-s?6tr ?Ɂb#?FW%?_1mVյ'?u$)?9fP@*?~sګw+?R6,?8-?^5_P/?u00?(x0??,>B˯G>e;>K>#MU>p?6ӳ??|cvDِ?T2I$ ?"(K?^3?)Dn??7?ìӠ?Y(? W!?-j{l#?k@#?Uc #?r96"?0ۡd ?b ?`rO?P8?e$?XJ4?S"?«$?}{c'?8x&pb)?3>*?a&Б>),?R-?f >Q:>uGJ>AÌ>jV??z{?fC?44b>d?ML?r>?.9 ?:N?{$\ ?Fq ?:%} ?mZl\ ?"Lf ?PZ ?Ԇv ?7_x ?ts ?kv?]TBw?1?6*?Sk"?f9#?&w ?Z@M>nF>ב>#dw?P??V2 ? qR?uns;?,??3? e28? R?)Y ?.Ʊ< ?S.j ?aȗ8 ?x: ?q ?66 ?=x?'#5: ?Uw?0?6 ?yiӾa?cR?7.>loB&+ ?N~4!?$xE2JF?p Zc>1Mt??Z>>3,?"I!?)zq?4 Zm?Q1#1S?J?-?>o$#?*W.?E%\t?]r ?V'X ?3. ?.?t ?l<6 ?![u,l& ?e^ ??)?+&7((?˙~%>ě>);qU*>]B>1>zNj.>*p!>~N>C<><*>d]>nTd>@T5>U>)>t^i:>,>V>TV8>-?>N.>n|3O>J?\^>au\>dߐ >Gb)>@(I>u>:}?> J>gv>*k4$k?,?QP?~r??r|>ڹ'>%."_>BNŽ?m"sbS?"\?ڄ]1H?sͰN?s9_ ?j!z @/ ?=(ftA ?Fblq ?Pu+ ?li ?M0?90?çW37?~?O;/ |?gN??$5?vC7?¨/?)?Mp`?> 1X?*I-)?<@?jl%?%1R?d?>f;8>aü>GZd ? ,?شn3 ? ?-{g ?~FZ ? d ?˥ k ? U ?IUUs ?K ?%???rM|?Z:?yv? ?;J_&?fr?` O?'8LJ?>?`j*~-?pcQ?ٌ##?"J?ts7?Vql?0*?&p ?n{o= ?Hΐr ? ˵ ?(`@ ?8&. ?~m??X+?4Q6??Ǜ?;_ ?2n$?~z?_>c?78)j?UIo?Yr?Tr???C;?+<?ks@?ַ刡?¢?Nm? jE ?旔5 ?Kj?免 ?j|+I ?ۀ ?41* ?H{N???CRa8?Z ?[r+? ?pGU?5!B?iNDƭ?T򟁘?6 Q?+c;?WY$O ?h?g g/r8? aSm?2{?zJ Z?Cc?[K_?̼*М?cJD4?)`?N K?(,?-㴟?V\= ?BN)?+Ia?k]# <?ưʜ?4@I?߭_^?0JHɽ?|Rb?p|f?FTy?h=:W?@B1?sE?WZ%XK?ٔ?7 ?-D77?2Hu?}Z6?7Ph?Zs?41 ?C??˰py?/$?72Z?Yip)?FPzz?'Tf.?|'4?;)$#?mW? UV?}F7?a,G?/3e?- ?E5EX?o-?x[ ?6o ?_ ?_9?3/N?s@I@R@Y@@_@b@i@@o@r@y@@@@@@ @@@0@@P@@p@X@@@@p@X@@@@@|@PKXARRversion_date.npyNUMPYF{'descr': '޲@vRT @Yߙ @vɸ@dm0#@40 @m@FOoM?O?%ۻ?Ů?6Keh)??w7пPKXA3̷RRversion_number.npyNUMPYF{'descr': 'bʂ?ykpق?k?_?7m?R3I? P?G,Xw?re~<8k?+(if?T$-o?3Sq?ѩkr?dus?uiK[u?"-w??̃y?̯}?u~?A3f?,?YӀ?gD?v% ?zˁ?* ?* !W?$c? fuJ$?]x鄿?fZ˂???5?0c?O0?]f /?Ӄ?ΉE?aЃ?tUւ?*yǂ?~3☃?rVi秂?y?*7*|?_U?Ѓw?95?:?e ҁ?*p:軁?k/jk?͖Gh?QOAp?1kp?BzS\@p?x'sqq?,ys?1*Gu? w?>Qy?$6B{?QS¥|?NzNi~?奞Z}?w%x?,Zo?|~р?Q6?x?\@>?'}?Jl֚ ?)>?ha`?B)?d?(?VXǂ?uhՂ?;!܂?5 ڂ?|Ђ?k~V~?q5G)gc?Ge+?jKH? 4Á?M1ԁ?:Mʁ?CLN߱? fɭ?j?[āi?0j?Xtg? 3Jf?,Bh?KF^i?R?:'6)X?iґ_?#g`c?*1g?jj?~ rm?={o? Rq?NK>r?L,S߽?t?d!!Su?B7@v?w?]#MoLx?7k?x?&8(z?W!9sF{?d+4}?b+?d.b>?Ar nT?d&e?3SB^?;9A?.A?1l4ԟ5?3t%8?/5x8?8?'$/WG8?Snt:?)@O@?U1D?ZBW#H?M?yf%x`R?Ơ;5V?h4Y?}hy\?ׇ8*b?#-e?&i?^Om?BArp?sq?a2;r?%dxs?E t?)R^t?At?ArLt?ٍ2tu?zv?e x?6 y?Rpw ]?c;D;U?}m7?a?x6?@zM웁?ѕ,?s!)?mglKd#?TcAY%?H*ʜ&?o&?J(? J ")?߮-?Sb0?1;3?FXv6?g?2B?Tn@?:3?k\h2?Hh&?m#?R+?~?3Rn!=?q\ͫ?zW?2V'?|+#?Wê"?TGG? V ?:G ?h4>f;"?;5~ý%?j#n&? yݭ&?{n*a'?Twr?^N$r? i_mq?>q?nq?!0^,q?@}WoZq?*/Uq?ivs?(vEw?:{? YX~?Y=r?,3?jn;?kg"?6>t"?" R<?$?3lW?%m%"?"N#?M%?m((?0Z)?}zQ,?^EZ0?@G4?]^7?)EzDUTp?Y_p?pp?8g7o?> n?Dl?Tm? o?vzu1p?;/`q?q?[r?uɶ{Ger?;r? Aks?4{s?Fߧt?y0纏u?\\Z(Xv?ls?N{6?bUt:?HM*Ip>?!j*C?[X*H?$5O?]ܐ*MT??G]?76c?V+g?eǏk?7#n?ĥR>2p?;gjAp?cJo?2rwn?M `m?I'+l?nj?Ck?/p߫n?w"p?q?MGr?ojjs?0 t?kSt?ˏt?]=[t?Y&t?8q u?<#[u?t?7qu?^(? @S.?[m?!D;y?1 ?}+1?voQ'?tJIN3?Q1YRfK?%DVP?FU?M<)Y?b ٴP^?FLc?SnmMg?v]k?-Mn?&P>hJp?[p?\p?]oNp? o?.Hc]sm?Z,kl?c78Rk?Aa:el?(o?{x1q?$ Lr?Lhet?5-#^u?u?3v?[ev?Tv?OJv?Rbv?SVv?mG8v?\Pw?fk'?Erc?iI?YtO!&?g5ϫ,?mH}2?.S]5?);C?g7J?@r;P?n+,S?FS4U?Vʘ+Y?|\?:^"`?ғ Ka?ה h\e?Ih?(c}l?zE?Jo?`C^%m?mG :l?[f-n?Qmtp?ؖ^Br?g{MWt?kD+u?{6w?Ipw?q4~=x?˛vx?'x?ֶ#\nx?^r.x?nQ(y? \y? 'x?ۧ5cx?Fh+?ي.?R>u).?1?a|g6?E:?ST??V_J?%P?4MS?pU?1)'W?%ۨ)Z?U~]?,f`?Eb?+(Df?6/?8?? &6-&C?NsI?3\lwmUP?&PRR?RwT?989`wlm|?pDհ|?}-|?][}p|?K |?Ǔ:|?o7F}?"zQ)6?kQ>9?@9?0I q?6'+sfr?ax^0 s?A s?;q?GvO$p? =P?1X?| b?&d?4@k?%$l?yV&m?(Dֱn?} ^o?Et!p?}Op?\wp? t]p?Ƭt1m?>}2[?Hy f[?HQ%[?zp\?}N\?nXS]?v͆-`? h`?/`?U喽JDa?zSkZ~a?#닷a?eVFMb?&8hb?'mWb?_c?vd?9' +e?*+f?&<g?o=h?y{kQ$ri?Hj? b?. +Vb?x:c?Ua? ja?Pa?,La?0 Ea?JKZa?a?fMb?GjmGb?:Fc?(i=njd?N䬥e?1f?3h(ӨIh?A{si?/:푘[j?!<;q.k? k? !^|l?+m?rDn?M|n?MNv5o?2Mo?on?&$hn?qa m? Xxm?l b?Bc?]d?*e?FՅte?]GՇf?+7h?{`h?i? j?֣l?l?FWm?g9o?-)'o?(dYp?7p?yVZp?.~p?q?Έߦ'q?xBp?x f? aSi?5h?;T1 p?Eh3p?p? ӧCRo??j?Kud?<^d?O({c?$c?͜=d?{I d?ǽ9Vd?d? s'Fd?t-e?Ke?ؔ\rf? 2g?Bg?%1i?gzj? k? "l?B{sm?!o?vCWp?ij!p?~ip? -J q?"U_Dq?![Zq?gÝn}q?Khq?}lq?)jq?f?QV`X l?tk?&m̦oq?^|r?>JGr?ַ q?X]h?o*IBd?DUoFd?"' $d?c?ф4pc?l-d?y3d?e2d?pd? d?x $Ke?,}m|f?I^jOg?|xʬhh?)şi?|"*j?Al?NR}m? R~n?xp?SC q?O3q?c-q?Y?MTq?)nLxq?Ηo~q?Yvq?1ٝq?sgq?p.q?PKXA+5PPsigma_2_ref_cast.npyPKXA> qXXlong_ref_cast.npyPKXAl lats_ref.npyPKXA:[XXlat_ref_cast.npyPKXA!qndepth_ref.npyPKXAyT Up_ref.npyPKXAU 4ocean_ref.npyPKXAW((  longs_ref.npyPKXA?PPj SA_ref_cast.npyPKXAPPgamma_n_ref_cast.npyPKXA\~~?? iSR_ref.npyPKXA,ѿ?? )PSAAR_ref.npyPKXA4amPPp_ref_cast.npyPKXARRgversion_date.npyPKXAPPCT_ref_cast.npyPKXA3̷RRdversion_number.npyPKXA9??deltaSA_ref.npyPKgsw-3.0.2/gsw/utilities/utilities.py0000644000175000017500000000607412172027023020651 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import os import numpy as np __all__ = [ 'match_args_return', 'Dict2Struc', 'Cache_npz', 'read_data', 'strip_mask', ] class match_args_return(object): r"""Function decorator to homogenize input arguments and to make the output match the original input with respect to scalar versus array, and masked versus ndarray. """ def __init__(self, func): self.func = func self.__wrapped__ = func self.__doc__ = func.__doc__ self.__name__ = func.__name__ def __call__(self, *args, **kw): p = kw.get('p', None) if p is not None: args = list(args) args.append(p) self.array = np.any([hasattr(a, '__iter__') for a in args]) self.masked = np.any([np.ma.isMaskedArray(a) for a in args]) newargs = [np.ma.atleast_1d(np.ma.masked_invalid(a)) for a in args] newargs = [a.astype(np.float) for a in newargs] if p is not None: kw['p'] = newargs.pop() ret = self.func(*newargs, **kw) if not self.masked: ret = np.ma.filled(ret, np.nan) if not self.array: ret = ret[0] return ret class Dict2Struc(object): r"""Open variables from a dictionary in a "matlab-like-structure".""" def __init__(self, adict): for k in adict.files: self.__dict__[k] = adict[k] class Cache_npz(object): def __init__(self): self._cache = dict() self._default_path = os.path.join(os.path.dirname(__file__), 'data') def __call__(self, fname, datadir=None): if datadir is None: datadir = self._default_path fpath = os.path.join(datadir, fname) try: return self._cache[fpath] except KeyError: pass d = np.load(fpath) ret = Dict2Struc(d) self._cache[fpath] = ret return ret _npz_cache = Cache_npz() def read_data(fname, datadir=None): r"""Read variables from a numpy '.npz' file into a minimal class providing attribute access. A cache is used to avoid re-reading the same file.""" return _npz_cache(fname, datadir=datadir) def strip_mask(*args): r"""Process the standard arguments for efficient calculation. Return unmasked arguments, plus a mask. The first argument, SA, is handled specially so that it can be This could be absorbed into a decorator, but it would require redefining functions to take the additional mask argument or kwarg. """ mask = np.ma.getmaskarray(args[-1]) SA = args[0] if SA.shape: SA = np.ma.asarray(SA) SA[SA < 0] = np.ma.masked for a in args[:-1]: mask = np.ma.mask_or(mask, np.ma.getmask(a)) newargs = [SA.filled(0)] elif SA < 0: SA = 0 for a in args[1:-1]: mask = np.ma.mask_or(mask, np.ma.getmask(a)) newargs = [SA] newargs.extend([np.ma.filled(a, 0) for a in args[1:]]) newargs.append(mask) return newargs gsw-3.0.2/gsw/test/0000755000175000017500000000000012172027023015221 5ustar amckinstryamckinstrygsw-3.0.2/gsw/test/test_profiles.py0000644000175000017500000002636112172027023020465 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- """Unit check for standard profiles for the Gibbs Sea Water python package.""" # Auto generates and perform a set of test methods like: # # def test_funct(self): # out = gsw.func(arg1_chck_cast, arg2_chck_cast, ...) # maxdiff = np.nanmax(abs(out - cv.func) # self.assertTrue(maxdiff < cv.func_ca) # # cv is a Dict2Struc instance with all the check values from # the profile-file # The func, args are taken from the main dictionary below # giving a alphabetical table of all functions and their arguments # # Extra aliasing attributes are added to cv if the naming # convention is broken, if the targets or the attributes # in the check file has "wrong" names # # Bjørn Ådlandsvik # 2011-03-03 import os import unittest import functools # Requires python 2.5. import numpy as np import gsw from gsw.utilities import Dict2Struc # Read data file with check value profiles. datadir = os.path.join(os.path.dirname(gsw.utilities.__file__), 'data') cv = Dict2Struc(np.load(os.path.join(datadir, 'gsw_cv_v3_0.npz'))) cf = Dict2Struc(np.load(os.path.join(datadir, 'gsw_cf.npz'))) # Main dictionary of functions with arguments. Could perhaps be auto-generated. function_arguments = dict( # absolute_salinity_sstar_ct.py #SA_from_SP=('SP', 'p', 'long', 'lat'), BUG on SAAR #Sstar_from_SP TODO CT_from_t=('SA', 't', 'p'), # # basic_thermodynamic_t.py rho_t_exact=('SA', 't', 'p'), pot_rho_t_exact=('SA', 't', 'p', 'pr'), sigma0_pt0_exact=('SA', 'pt0'), alpha_wrt_CT_t_exact=('SA', 't', 'p'), alpha_wrt_pt_t_exact=('SA', 't', 'p'), alpha_wrt_t_exact=('SA', 't', 'p'), beta_const_CT_t_exact=('SA', 't', 'p'), beta_const_pt_t_exact=('SA', 't', 'p'), beta_const_t_exact=('SA', 't', 'p'), specvol_t_exact=('SA', 't', 'p'), specvol_anom_t_exact=('SA', 't', 'p'), sound_speed_t_exact=('SA', 't', 'p'), kappa_t_exact=('SA', 't', 'p'), kappa_const_t_exact=('SA', 't', 'p'), internal_energy_t_exact=('SA', 't', 'p'), enthalpy_t_exact=('SA', 't', 'p'), dynamic_enthalpy_t_exact=('SA', 't', 'p'), SA_from_rho_t_exact=('rho', 't', 'p'), #t_from_rho_exact=('rho', 'SA', 'p'), t_maxdensity_exact=('SA', 'p'), entropy_t_exact=('SA', 't', 'p'), cp_t_exact=('SA', 't', 'p'), isochoric_heat_cap_t_exact=('SA', 't', 'p'), chem_potential_relative_t_exact=('SA', 't', 'p'), chem_potential_water_t_exact=('SA', 't', 'p'), chem_potential_salt_t_exact=('SA', 't', 'p'), Helmholtz_energy_t_exact=('SA', 't', 'p'), adiabatic_lapse_rate_t_exact=('SA', 't', 'p'), osmotic_coefficient_t_exact=('SA', 't', 'p'), osmotic_pressure_t_exact=('SA', 't', 'p'), # # conversion.py #deltaSA_from_SP TODO #SA_Sstar_from_SP TODO SR_from_SP=('SP',), SP_from_SR=('SR',), #SP_from_SA=('SA', 'p', 'long', 'lat'), TODO #Sstar_from_SA=('SA', 'p', 'long', 'lat'), TODO #SA_from_Sstar=('Sstar', 'p', 'long', 'lat'), TODO #SP_from_Sstar=('Sstar', 'p', 'long', 'lat'), TODO pt_from_CT=('SA', 'CT'), t_from_CT=('SA', 'CT', 'p'), CT_from_pt=('SA', 'pt'), pot_enthalpy_from_pt=('SA', 'pt'), pt0_from_t=('SA', 't', 'p'), pt_from_t=('SA', 't', 'p', 'pr'), t90_from_t48=('t',), t90_from_t68=('t',), z_from_p=('p', 'lat'), p_from_z=('z', 'lat'), depth_from_z=('z'), z_from_depth=('depth',), Abs_Pressure_from_p=('p',), p_from_Abs_Pressure=('Abs_Pressure_from_p',), entropy_from_CT=('SA', 'CT'), CT_from_entropy=('SA', 'entropy'), entropy_from_pt=('SA', 'pt'), pt_from_entropy=('SA', 'entropy'), molality_from_SA=('SA',), ionic_strength_from_SA=('SA',), # # density_enthalpy_48_ct.py #rho_CT TODO #alpha_CT TODO #beta_CT TODO #rho_alpha_beta_CT TODO #specvol_CT TODO #specvol_anom_CT TODO #sigma0_CT TODO #sigma1_CT TODO #sigma2_CT TODO #sigma3_CT TODO #sigma4_CT TODO #sound_speed_CT TODO #internal_energy_CT TODO #enthalpy_CT TODO #enthalpy_diff_CT TODO #dynamic_enthalpy_CT TODO #SA_from_rho_CT TODO #CT_from_rho TODO #CT_maxdensity TODO # # density_enthalpy_48.py NOTE: None are tested on Matlab. rho=('SA', 'CT', 'p'), alpha=('SA', 'CT', 'p'), beta=('SA', 'CT', 'p'), rho_alpha_beta=('SA', 'CT', 'p'), specvol=('SA', 'CT', 'p'), specvol_anom=('SA', 'CT', 'p'), sigma0=('SA', 'CT'), sigma1=('SA', 'CT'), sigma2=('SA', 'CT'), sigma3=('SA', 'CT'), sigma4=('SA', 'CT'), sound_speed=('SA', 'CT', 'p'), internal_energy=('SA', 'CT', 'p'), enthalpy=('SA', 'CT', 'p'), enthalpy_diff=('SA', 'CT', 'p_shallow', 'p_deep'), dynamic_enthalpy=('SA', 'CT', 'p'), SA_from_rho=('rho_cf', 'CT', 'p'), # # density_enthalpy_ct_exact.py rho_CT_exact=('SA', 'CT', 'p'), alpha_CT_exact=('SA', 'CT', 'p'), beta_CT_exact=('SA', 'CT', 'p'), rho_alpha_beta_CT_exact=('SA', 'CT', 'p'), specvol_CT_exact=('SA', 'CT', 'p'), specvol_anom_CT_exact=('SA', 'CT', 'p'), sigma0_CT_exact=('SA', 'CT'), sigma1_CT_exact=('SA', 'CT'), sigma2_CT_exact=('SA', 'CT'), sigma3_CT_exact=('SA', 'CT'), sigma4_CT_exact=('SA', 'CT'), sound_speed_CT_exact=('SA', 'CT', 'p'), internal_energy_CT_exact=('SA', 'CT', 'p'), enthalpy_CT_exact=('SA', 'CT', 'p'), enthalpy_diff_CT_exact=('SA', 'CT', 'p_shallow', 'p_deep'), dynamic_enthalpy_CT_exact=('SA', 'CT', 'p'), SA_from_rho_CT_exact=('rho', 'CT', 'p'), # FIXME: NameError: 't_from_rho_exact' not defined #CT_from_rho_exact=('rho', 'SA', 'p'), CT_maxdensity_exact=('SA', 'p'), # # derivatives.py #CT_first_derivatives=('SA', 'pt'), FIXME: out should tuple. #CT_second_derivatives=('SA', 'pt'), FIXME: out should tuple. #enthalpy_first_derivatives=('SA', 'CT', 'p'), FIXME: out should tuple. #enthalpy_second_derivatives=('SA', 'CT', 'p'), FIXME: out should tuple. #entropy_first_derivatives=('SA', 'CT'), FIXME: out should tuple. #entropy_second_derivatives=('SA', 'CT'), FIXME: out should tuple. #pt_first_derivatives=('SA', 'CT'), FIXME: out should tuple. #pt_second_derivatives=('SA', 'CT'), FIXME: out should tuple. # # earth.py f=('lat',), grav=('lat', 'p'), distance=('long', 'lat', 'p'), # # freezing.py # NOTE: The matlab test does not use saturation_fraction=1 which is the # default! It uses saturation_fraction=0. CT_freezing=('SA', 'p', 'sat0'), t_freezing=('SA', 'p', 'sat0'), brineSA_CT=('CT_freezing', 'p', 'sat05'), brineSA_t=('t_freezing', 'p', 'sat05'), # # geostrophic.py #geostrophic_velocity TODO # # geostrophic_48.py #geo_strf_dyn_height TODO #geo_strf_dyn_height_pc TODO #geo_strf_isopycnal TODO #geof_str_isopycnal_pc TODO #geo_strf_Montgomery TODO #geo_strf_Cunningham TODO # # isobaric.py #latentheat_melting TODO #latentheat_evap_CT TODO #latentheat_evap_t=('SA', 't'), # # library.py #gibbs #SAAR TODO #Fdelta TODO #delta_SA_ref=('p', 'long', 'lat'), TODO #SA_from_SP_Baltic=('SP', 'long', 'lat'), NOTE: Not tested on Matlab. #SP_from_SA_Baltic=('SA', 'long', 'lat'), NOTE: Not tested on Matlab. #infunnel=('SA', 'CT', 'p'), NOTE: Not tested on Matlab. #entropy_part=('SA', 'CT', 'p'), NOTE: Not tested on Matlab. #entropy_part_zerop=('SA', 'pt0'), NOTE: Not tested on Matlab. #interp_ref_cast=('spycnl', 'gn'), NOTE: Not tested on Matlab. #interp_SA_CT=('SA', 'CT', 'p', 'p_i'), NOTE: Not tested on Matlab. #gibbs_pt0_pt0=('SA', 'pt0'), NOTE: Not tested on Matlab. #specvol_SSO_0_p=('p'), NOTE: Not tested on Matlab. #enthalpy_SSO_0_p=('p',), FIXME: No enthalpy_SSO_0_p. #Hill_ratio_at_SP2= ('t'), FIXME: No Hill_ratio_at_SP2. # #neutral_nonlinear_48.py #cabbeling, TODO #thermobaric, TODO #isopycnal_slope_ratio, TODO #isopycnal_vs_ntp_CT_ratio, TODO #ntp_pt_vs_CT_ratio TODO # # practical_salinity.py SP_from_C=('C', 't', 'p'), C_from_SP=('SP', 't', 'p'), SP_from_R=('R_cf', 't', 'p'), R_from_SP=('SP', 't', 'p'), SP_salinometer=('Rt', 't'), #SP_from_SK=('SK',), NOTE: Not tested on Matlab. #SK_from_SP=('SP',), NOTE: Not tested on Matlab. # # steric.py #steric_height=TODO # # water_column_48.py Nsquared=('SA', 'CT', 'p', 'lat'), Turner_Rsubrho=('SA', 'CT', 'p'), IPV_vs_fNsquared_ratio=('SA', 'CT', 'p') ) # Make aliases for some values to be used as arguments cv.entropy_chck_cast = cv.entropy_from_CT cv.Abs_Pressure_from_p_chck_cast = cv.Abs_Pressure_from_p cv.depth_chck_cast = cv.depth_from_z cv.C_chck_cast = cv.C_from_SP cv.pt_chck_cast = cv.pt_from_t cv.z_chck_cast = cv.z_from_p cv.SR_chck_cast = cv.SR_from_SP cv.pr_chck_cast = cv.pr cv.p_shallow_chck_cast = cv.p_chck_cast_shallow cv.p_deep_chck_cast = cv.p_chck_cast_deep cv.rho_chck_cast = cv.rho_CT_exact cv.rho_CTrab_exact_ca = cv.rho_CT_exact_rab_ca cv.CT_freezing_chck_cast = cv.CT_freezing cv.t_freezing_chck_cast = cv.t_freezing cv.sat0_chck_cast = 0 cv.sat05_chck_cast = 0.5 # Aliases from computed values. cv.R_cf_chck_cast = cf.R cv.rho_cf_chck_cast = cf.rho cv.pt0_chck_cast = cf.pt0_from_t # Functions and targets which does not follow the naming convention. not_match = { 'CT_first_derivatives': 'CT_SA', 'CT_second_derivatives': 'CT_SA_SA', 'enthalpy_first_derivatives': 'h_SA', 'enthalpy_second_derivatives': 'h_SA_SA', 'entropy_first_derivatives': 'eta_SA', 'entropy_second_derivatives': 'eta_SA_SA', 'pt_first_derivatives': 'pt_SA', 'pt_second_derivatives': 'pt_SA_SA', 'Turner_Rsubrho': 'Tu', 'IPV_vs_fNsquared_ratio': 'IPVfN2', 'Nsquared': 'n2', 'chem_potential_relative_t_exact': 'chem_potential_t_exact', 'rho_alpha_beta_CT_exact': 'rho_CTrab_exact', 'rho_alpha_beta': 'rho_rab', } # Add target aliases to cv. for f in not_match: setattr(cv, f, getattr(cv, not_match[f])) setattr(cv, f + '_ca', getattr(cv, not_match[f] + '_ca')) # Generic test method. def generic_test(self, func=None, argnames=None): """Generic test function, to be specialized by functools.partial.""" # Transform argument names to name convention in cv dataset. args = [getattr(cv, a + '_chck_cast') for a in argnames] # Perform the function call out = getattr(gsw, func)(*args) # FIXME: Testing just the first output! # Check that the maximal error is less than the given tolerance if isinstance(out, tuple): out = out[0] #print("""%s returns a tuple.""" % func) maxdiff = np.nanmax(abs(out - getattr(cv, func))) try: self.assertTrue(maxdiff < getattr(cv, func + '_ca')) except AssertionError, e: raise AssertionError("Error in %s %s" % (func, e.args)) # Dictionary of functions with corresponding test methods. function_test = {} for f in function_arguments: function_test[f] = functools.partial(generic_test, func=f, argnames=function_arguments[f]) # Auto-generated TestCase. class Test_profiles(unittest.TestCase): for f in function_test: method_def = ("test_" + f + " = lambda self: function_test['" + f + "'](self)") exec(method_def) if __name__ == '__main__': unittest.main(verbosity=2) gsw-3.0.2/gsw/test/test_tuples.py0000644000175000017500000000645212172027023020155 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- """Unit check for standard profiles for the Gibbs Sea Water python package.""" import os import sys import unittest import functools # Requires python 2.5. import numpy as np import gsw from gsw.utilities import Dict2Struc # Read data file with check value profiles datadir = os.path.join(os.path.dirname(gsw.utilities.__file__), 'data') fname = 'gsw_cv_v3_0.npz' cv = Dict2Struc(np.load(os.path.join(datadir, fname))) cf = Dict2Struc(np.load(os.path.join(datadir, 'gsw_cf_.npz'))) # derivatives.py #CT_first_derivatives=('SA', 'pt'), # NOTE: TI, BUG #CT_second_derivatives=('SA', 'pt'), # NOTE: TI FIXME BUG #enthalpy_first_derivatives=('SA', 'CT', 'p'), FIXME name match #enthalpy_second_derivatives=('SA', 'CT', 'p'), FIXME name match #entropy_first_derivatives=('SA', 'CT'), #NOTE: TI FIXME name match #entropy_second_derivatives=('SA', 'pt'), #NOTE: TI FIXME name match #pt_first_derivatives':, #NOTE: TI FIXME name match #pt_second_derivatives= #NOTE: TI FIXME name match # Make aliases for some values to be used as arguments cv.entropy_chck_cast = cv.entropy_from_CT cv.Abs_Pressure_from_p_chck_cast = cv.Abs_Pressure_from_p cv.depth_chck_cast = cv.depth_from_z cv.C_chck_cast = cv.C_from_SP cv.pt_chck_cast = cv.pt_from_t cv.z_chck_cast = cv.z_from_p cv.SR_chck_cast = cv.SR_from_SP cv.pr_chck_cast = cv.pr cv.p_shallow_chck_cast = cv.p_chck_cast_shallow cv.p_deep_chck_cast = cv.p_chck_cast_deep cv.rho_chck_cast = cv.rho_CT_exact cv.R_cf_chck_cast = cf.R cv.rho_cf_chck_cast = cf.rho def generic_test(self, func=None, argnames=None): """Generic test function, to be specialized by functools.partial""" # Transform argument names to name convention in cv dataset args = [getattr(cv, a + '_chck_cast') for a in argnames] # Perform the function call out = getattr(gsw, func)(*args) # FIXME: Testing just the first output! # TODO: Create the tuples and compare all together. # Check that the maximal error is less than the given tolerance if isinstance(out, tuple): out = out[0] maxdiff = np.nanmax(abs(out - getattr(cv, func))) try: self.assertTrue(maxdiff < getattr(cv, func + '_ca')) except AssertionError, e: raise AssertionError("Error in %s %s" % (func, e.args)) # Dictionary of functions with corresponding test methods function_test = {} for f in function_arguments: function_test[f] = functools.partial(generic_test, func=f, argnames=function_arguments[f]) # Auto-generated TestCase class Test_profiles(unittest.TestCase): for f in function_test: method_def = ("test_" + f + " = lambda self: function_test['" + f + "'](self)") #print method_def exec(method_def) if __name__ == '__main__': # A more verbose output suite = unittest.TestLoader().loadTestsFromTestCase(Test_profiles) a = unittest.TextTestRunner(verbosity=2).run(suite) if a.errors or a.failures: sys.exit(256) #unittest.main() [gsw_cf.CT_SA, gsw_cf.CT_pt] = gsw_CT_first_derivatives(gsw_cv.SA_chck_cast,gsw_cf.pt); [gsw_cf.ICT_first_deriv] = find(abs(gsw_cv.CT_SA - gsw_cf.CT_SA) >= gsw_cv.CT_SA_ca | ... (gsw_cv.CT_pt - gsw_cf.CT_pt) >= gsw_cv.CT_pt_ca); if ~isempty(gsw_cf.ICT_first_deriv) fprintf(2,'gsw_CT_first_derivatives: Failed\n'); gsw_cf.gsw_chks = 0; endgsw-3.0.2/gsw/test/quick_test.py0000644000175000017500000000062212172027023017746 0ustar amckinstryamckinstry# Quick value test import os import gsw import numpy as np from gsw.utilities import Dict2Struc # Read data file with check value profiles datadir = os.path.join(os.path.dirname(gsw.utilities.__file__), 'data') cv = Dict2Struc(np.load(os.path.join(datadir, 'gsw_cv_v3_0.npz'))) cf = Dict2Struc(np.load(os.path.join(datadir, 'gsw_cf.npz'))) SA = cv.SA_chck_cast CT = cv.CT_chck_cast p = cv.p_chck_castgsw-3.0.2/gsw/test/test_check_values.py0000644000175000017500000000420712172027023021271 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- """Unit tests using the check values from the version 3 documentation, http://www.teos-10.org/pubs/gsw/html/gsw_contents.html.""" import sys import unittest import numpy as np import numpy.testing import gsw # Standard values for arguments from # http://www.teos-10.org/pubs/gsw/html/gsw_contents.html C = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600] t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] p = [10, 50, 125, 250, 600, 1000] # Salinities #SP = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600] #SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] #Sstar = [34.7115, 34.8912, 35.0247, 34.8436, 34.7291, 34.7197] # Temperatures #t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] #pt = [28.7832, 28.4209, 22.7850, 10.2305, 6.8292, 4.3245] #CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236] #t48 = [29, 28, 23, 10, 7, 4] #t68 = [29, 28, 23, 10, 7, 4] # Other #p = [10, 50, 125, 250, 600, 1000] #z = [10, 50, 125, 250, 600, 1000] #rho = [1021.839, 1022.262, 1024.426, 1027.792, 1029.839, 1032.002] #entropy = [400.3892, 395.4378, 319.8668, 146.7910, 98.6471, 62.7919] #lon = 188 #lat = 4 class Test_standard(unittest.TestCase): #class Test_standard(numpy.testing.TestCase): # ---------------------- # practical_salinity.py # ---------------------- def test_SP_from_C(self): """Practical Salinity from Conductivity""" output = gsw.SP_from_C(C, t, p) check_values = np.array((20.009869599086951, 20.265511864874270, 22.981513062527689, 31.204503263727982, 34.032315787432829, 36.400308494388170)) numpy.testing.assert_array_equal(output, check_values) # ----------------------------------------------- if __name__ == '__main__': # Verbose output. suite = unittest.TestLoader().loadTestsFromTestCase(Test_standard) a = unittest.TextTestRunner(verbosity=2).run(suite) if a.errors or a.failures: sys.exit(1) #unittest.main() #numpy.testing.test() gsw-3.0.2/gsw/gibbs/0000755000175000017500000000000012172027023015330 5ustar amckinstryamckinstrygsw-3.0.2/gsw/gibbs/isobaric.py0000644000175000017500000000265712172027023017507 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division from gsw.utilities import match_args_return from conversions import CT_from_pt __all__ = [ #'latentheat_melting', #'latentheat_evap_CT', 'latentheat_evap_t' ] @match_args_return def latentheat_evap_t(SA, t): r"""Calculates latent heat, or enthalpy, of evaporation at p = 0 (the surface). It is defined as a function of Absolute Salinity, SA, and in-situ temperature, t, and is valid in the ranges 0 < SA < 40 g/kg and 0 < CT < 42 deg C. The errors range between -0.4 and 0.6 J/kg. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] Returns ------- latentheat_evap_t : array_like latent heat of evaporation [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.39. Modifications: 2011-03-29. Paul Barker, Trevor McDougall & Rainer Feistel """ CT = CT_from_pt(SA, t) return latentheat_evap_CT(SA, CT) gsw-3.0.2/gsw/gibbs/__init__.py0000644000175000017500000000104712172027023017443 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from absolute_salinity_sstar_ct import * from basic_thermodynamic_t import * from constants import * from conversions import * from density_enthalpy_48 import * from density_enthalpy_48_ct import * from density_enthalpy_ct_exact import * from derivatives import * from earth import * from freezing import * from geostrophic import * from geostrophic_48 import * from isobaric import * from library import * from neutral_nonlinear_48 import * from practical_salinity import * from steric import * from water_column_48 import * gsw-3.0.2/gsw/gibbs/practical_salinity.py0000644000175000017500000006474112172027023021574 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from library import Hill_ratio_at_SP2 from gsw.utilities import match_args_return __all__ = [ 'SP_from_C', 'C_from_SP', 'SP_from_R', 'R_from_SP', 'SP_salinometer', 'SP_from_SK', 'SK_from_SP' ] # Constants: a = (0.0080, -0.1692, 25.3851, 14.0941, -7.0261, 2.7081) b = (0.0005, -0.0056, -0.0066, -0.0375, 0.0636, -0.0144) c = (0.6766097, 2.00564e-2, 1.104259e-4, -6.9698e-7, 1.0031e-9) d = (3.426e-2, 4.464e-4, 4.215e-1, -3.107e-3) e = (2.070e-5, -6.370e-10, 3.989e-15) P = (4.577801212923119e-3, 1.924049429136640e-1, 2.183871685127932e-5, -7.292156330457999e-3, 1.568129536470258e-4, -1.478995271680869e-6, 9.086442524716395e-4, -1.949560839540487e-5, -3.223058111118377e-6, 1.175871639741131e-7, -7.522895856600089e-5, -2.254458513439107e-6, 6.179992190192848e-7, 1.005054226996868e-8, -1.923745566122602e-9, 2.259550611212616e-6, 1.631749165091437e-7, -5.931857989915256e-9, -4.693392029005252e-9, 2.571854839274148e-10, 4.198786822861038e-12) q = (5.540896868127855e-5, 2.015419291097848e-1, -1.445310045430192e-5, -1.567047628411722e-2, 2.464756294660119e-4, -2.575458304732166e-7, 5.071449842454419e-3, -9.081985795339206e-5, -3.635420818812898e-6, 2.249490528450555e-8, -1.143810377431888e-3, 2.066112484281530e-5, 7.482907137737503e-7, 4.019321577844724e-8, -5.755568141370501e-10, 1.120748754429459e-4, -2.420274029674485e-6, -4.774829347564670e-8, -4.279037686797859e-9, -2.045829202713288e-10, 5.025109163112005e-12) r = (3.432285006604888e-3, 1.672940491817403e-1, 2.640304401023995e-5, 1.082267090441036e-1, -6.296778883666940e-5, -4.542775152303671e-7, -1.859711038699727e-1, 7.659006320303959e-4, -4.794661268817618e-7, 8.093368602891911e-9, 1.001140606840692e-1, -1.038712945546608e-3, -6.227915160991074e-6, 2.798564479737090e-8, -1.343623657549961e-10, 1.024345179842964e-2, 4.981135430579384e-4, 4.466087528793912e-6, 1.960872795577774e-8, -2.723159418888634e-10, 1.122200786423241e-12) u = (5.180529787390576e-3, 1.052097167201052e-3, 3.666193708310848e-5, 7.112223828976632, -3.631366777096209e-4, -7.336295318742821e-7, -1.576886793288888e+2, -1.840239113483083e-3, 8.624279120240952e-6, 1.233529799729501e-8, 1.826482800939545e+3, 1.633903983457674e-1, -9.201096427222349e-5, -9.187900959754842e-8, -1.442010369809705e-10, -8.542357182595853e+3, -1.408635241899082, 1.660164829963661e-4, 6.797409608973845e-7, 3.345074990451475e-10, 8.285687652694768e-13) k = 0.0162 a, b, c, d, e, P, q, r, u, k = map(np.asarray, (a, b, c, d, e, P, q, r, u, k)) @match_args_return def SP_from_C(C, t, p): r"""Calculates Practical Salinity, SP, from conductivity, C, primarily using the PSS-78 algorithm. Note that the PSS-78 algorithm for Practical Salinity is only valid in the range 2 < SP < 42. If the PSS-78 algorithm produces a Practical Salinity that is less than 2 then the Practical Salinity is recalculated with a modified form of the Hill et al. (1986) formula. The modification of the Hill et al. (1986) expression is to ensure that it is exactly consistent with PSS-78 at SP = 2. Note that the input values of conductivity need to be in units of mS/cm (not S/m). Parameters ---------- C : array conductivity [mS cm :sup:`-1`] t : array in-situ temperature [:math:`^\circ` C (ITS-90)] p : array sea pressure [dbar] (i.e. absolute pressure - 10.1325 dbar) Returns ------- SP : array Practical Salinity [psu (PSS-78), unitless] Examples -------- TODO See Also -------- TODO Notes ----- TODO References ---------- .. [1] Culkin and Smith, 1980: Determination of the Concentration of Potassium Chloride Solution Having the Same Electrical Conductivity, at 15C and Infinite Frequency, as Standard Seawater of Salinity 35.0000 (Chlorinity 19.37394), IEEE J. Oceanic Eng, 5, 22-23. .. [2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng., 11, 109 - 112. .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Appendix E. .. [4] Unesco, 1983: Algorithms for computation of fundamental properties of seawater. Unesco Technical Papers in Marine Science, 44, 53 pp. Modifications: 2011-04-01. Paul Barker, Trevor McDougall and Rich Pawlowicz. """ C, t, p = np.broadcast_arrays(C, t, p) t68 = t * 1.00024 ft68 = (t68 - 15) / (1 + k * (t68 - 15)) # The dimensionless conductivity ratio, R, is the conductivity input, C, # divided by the present estimate of C(SP=35, t_68=15, p=0) which is # 42.9140 mS/cm (=4.29140 S/m), (Culkin and Smith, 1980). R = 0.023302418791070513 * C # 0.023302418791070513 = 1./42.9140 # rt_lc corresponds to rt as defined in the UNESCO 44 (1983) routines. rt_lc = c[0] + (c[1] + (c[2] + (c[3] + c[4] * t68) * t68) * t68) * t68 Rp = (1 + (p * (e[0] + e[1] * p + e[2] * p ** 2)) / (1 + d[0] * t68 + d[1] * t68 ** 2 + (d[2] + d[3] * t68) * R)) Rt = R / (Rp * rt_lc) Rt[Rt < 0] = np.nan Rtx = np.sqrt(Rt) SP = a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx) # The following section of the code is designed for SP < 2 based on the # Hill et al. (1986) algorithm. This algorithm is adjusted so that it is # exactly equal to the PSS-78 algorithm at SP = 2. I2, = np.nonzero(np.ravel(SP) < 2) if len(I2) > 0: Hill_ratio = Hill_ratio_at_SP2(t[I2]) x = 400 * Rt[I2] sqrty = 10 * Rtx[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) SP_Hill_raw = SP[I2] - a[0] / part1 - b[0] * ft68[I2] / part2 SP[I2] = Hill_ratio * SP_Hill_raw SP = np.maximum(SP, 0) # Ensure that SP is non-negative. return SP def C_from_SP(SP, t, p): r"""Calculates conductivity, C, from (SP, t, p) using PSS-78 in the range 2 < SP < 42. If the input Practical Salinity is less than 2 then a modified form of the Hill et al. (1986) fomula is used for Practical Salinity. The modification of the Hill et al. (1986) expression is to ensure that it is exactly consistent with PSS-78 at SP = 2. The conductivity ratio returned by this function is consistent with the input value of Practical Salinity, SP, to 2x10^-14 psu over the full range of input parameters (from pure fresh water up to SP = 42 psu). This error of 2x10^-14 psu is machine precision at typical seawater salinities. This accuracy is achieved by having four different polynomials for the starting value of Rtx (the square root of Rt) in four different ranges of SP, and by using one and a half iterations of a computationally efficient modified Newton-Raphson technique to find the root of the equation. Parameters ---------- SP : array Practical Salinity [psu (PSS-78), unitless] t : array in-situ temperature [:math:`^\circ` C (ITS-90)] p : array sea pressure [dbar] (i.e. absolute pressure - 10.1325 dbar) Returns ------- C : array conductivity [mS cm :sup:`-1`] See Also -------- TODO Notes ----- Note that strictly speaking PSS-78 (Unesco, 1983) defines Practical Salinity in terms of the conductivity ratio, R, without actually specifying the value of C(35,15,0) (which we currently take to be 42.9140 mS/cm). Examples -------- TODO References ---------- .. [1] Hill, K.D., T.M. Dauphinee and D.J. Woods, 1986: The extension of the Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng., OE-11, 1, 109 - 112. .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix E. .. [3] Unesco, 1983: Algorithms for computation of fundamental properties of seawater. Unesco Technical Papers in Marine Science, 44, 53 pp. """ C = 42.9140 * R_from_SP(SP, t, p) return C @match_args_return def SP_from_R(R, t, p): r"""Calculates Practical Salinity, SP, from the conductivity ratio, R, primarily using the PSS-78 algorithm. Note that the PSS-78 algorithm for Practical Salinity is only valid in the range 2 < SP < 42. If the PSS-78 algorithm produces a Practical Salinity that is less than 2 then the Practical Salinity is recalculated with a modified form of the Hill et al. (1986) formula. The modification of the Hill et al. (1986) expression are to ensure that it is exactly consistent with PSS-78 at SP = 2. Parameters ---------- R : array_like conductivity ratio [unitless] t : array_like in-situ temperature [:math:`^\circ` C (ITS-90)] p : array sea pressure [dbar] (i.e. absolute pressure - 10.1325 dbar) Returns ------- SP : array Practical Salinity [psu (PSS-78), unitless] Examples -------- TODO See Also -------- TODO Notes ----- TODO References ---------- .. [1] Culkin and Smith, 1980: Determination of the Concentration of Potassium Chloride Solution Having the Same Electrical Conductivity, at 15C and Infinite Frequency, as Standard Seawater of Salinity 35.0000 (Chlorinity 19.37394), IEEE J. Oceanic Eng, 5, 22-23. .. [2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng., 11, 109 - 112. .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Appendix E. .. [4] Unesco, 1983: Algorithms for computation of fundamental properties of seawater. Unesco Technical Papers in Marine Science, 44, 53 pp. Modifications: 2011-04-01. Paul Barker, Trevor McDougall and Rich Pawlowicz. """ R, t, p = np.broadcast_arrays(R, t, p) t68 = t * 1.00024 ft68 = (t68 - 15) / (1 + k * (t68 - 15)) # rt_lc corresponds to rt as defined in the UNESCO 44 (1983) routines. rt_lc = c[0] + (c[1] + (c[2] + (c[3] + c[4] * t68) * t68) * t68) * t68 Rp = (1 + (p * (e[0] + e[1] * p + e[2] * p ** 2)) / (1 + d[0] * t68 + d[1] * t68 ** 2 + (d[2] + d[3] * t68) * R)) Rt = R / (Rp * rt_lc) Rt[Rt < 0] = np.nan Rtx = np.sqrt(Rt) SP = a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx) # The following section of the code is designed for SP < 2 based on the # Hill et al. (1986) algorithm. This algorithm is adjusted so that it is # exactly equal to the PSS-78 algorithm at SP = 2. I2 = SP < 2 if I2.any(): Hill_ratio = Hill_ratio_at_SP2(t[I2]) x = 400 * Rt[I2] sqrty = 10 * Rtx[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) SP_Hill_raw = SP[I2] - a[0] / part1 - b[0] * ft68[I2] / part2 SP[I2] = Hill_ratio * SP_Hill_raw SP = np.maximum(SP, 0) # Ensure that SP is non-negative. return SP @match_args_return def R_from_SP(SP, t, p): r"""Calculates conductivity ratio from (SP, t, p) using PSS-78 in the range 2 < SP < 42. If the input Practical Salinity is less than 2 then a modified form of the Hill et al. (1986) formula is used for Practical Salinity. The modification of the Hill et al. (1986) expression is to ensure that it is exactly consistent with PSS-78 at SP = 2. The conductivity ratio returned by this function is consistent with the input value of Practical Salinity, SP, to 2x10^-14 psu over the full range of input parameters (from pure fresh water up to SP = 42 psu). This error of 2x10^-14 psu is machine precision at typical seawater salinities. This accuracy is achieved by having four different polynomials for the starting value of Rtx (the square root of Rt) in four different ranges of SP, and by using one and a half iterations of a computationally efficient modified Newton-Raphson technique to find the root of the equation. Parameters ---------- SP : array Practical Salinity [psu (PSS-78), unitless] t : array_like in-situ temperature [:math:`^\circ` C (ITS-90)] p : array sea pressure [dbar] (i.e. absolute pressure - 10.1325 dbar) Returns ------- R : array_like conductivity ratio [unitless] Examples -------- TODO See Also -------- TODO Notes ----- Strictly speaking PSS-78 (Unesco, 1983) defines Practical Salinity in terms of the conductivity ratio, R, without actually specifying the value of C(35, 15, 0) (which we currently take to be 42.9140 mS cm^-1. Culkin and Smith, 1980). References ---------- .. [1] Culkin and Smith, 1980: Determination of the Concentration of Potassium Chloride Solution Having the Same Electrical Conductivity, at 15C and Infinite Frequency, as Standard Seawater of Salinity 35.0000 (Chlorinity 19.37394), IEEE J. Oceanic Eng, 5, 22-23. .. [2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng., 11, 109 - 112. .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Appendix E. .. [4] Unesco, 1983: Algorithms for computation of fundamental properties of seawater. Unesco Technical Papers in Marine Science, 44, 53 pp. Modifications: 2011-04-06. Paul Barker, Trevor McDougall and Rich Pawlowicz. """ # These few lines ensure that SP is non-negative. if (SP < 0).any(): raise ValueError('R_from_SP: SP must be non-negative!') SP, t, p = np.broadcast_arrays(SP, t, p) # Setting up the constants t68 = t * 1.00024 ft68 = (t68 - 15) / (1 + k * (t68 - 15)) x = np.sqrt(SP) Rtx = np.zeros_like(SP) * np.nan # Finding the starting value of Rtx, the square root of Rt, using four # different polynomials of SP and t68. # TODO: Test case that cover all those "ifs" I = SP >= 9 if I.any(): Rtx[I] = P[0] + x[I] * (P[1] + P[4] * t68[I] + x[I] * (P[3] + P[7] * t68[I] + x[I] * (P[6] + P[11] * t68[I] + x[I] * (P[10] + P[16] * t68[I] + x[I] * P[15])))) + t68[I] * (P[2] + t68[I] * (P[5] + x[I] * x[I] * (P[12] + x[I] * P[17]) + P[8] * x[I] + t68[I] * (P[9] + x[I] * (P[13] + x[I] * P[18]) + t68[I] * (P[14] + P[19] * x[I] + P[20] * t68[I])))) I = np.logical_and(SP >= 0.25, SP < 9) if I.any(): Rtx[I] = q[0] + x[I] * (q[1] + q[4] * t68[I] + x[I] * (q[3] + q[7] * t68[I] + x[I] * (q[6] + q[11] * t68[I] + x[I] * (q[10] + q[16] * t68[I] + x[I] * q[15])))) + t68[I] * (q[2] + t68[I] * (q[5] + x[I] * x[I] * (q[12] + x[I] * q[17]) + q[8] * x[I] + t68[I] * (q[9] + x[I] * (q[13] + x[I] * q[18]) + t68[I] * (q[14] + q[19] * x[I] + q[20] * t68[I])))) I = np.logical_and(SP >= 0.003, SP < 0.25) if I.any(): Rtx[I] = r[0] + x[I] * (r[1] + r[4] * t68[I] + x[I] * (r[3] + r[7] * t68[I] + x[I] * (r[6] + r[11] * t68[I] + x[I] * (r[10] + r[16] * t68[I] + x[I] * r[15])))) + t68[I] * (r[2] + t68[I] * (r[5] + x[I] * x[I] * (r[12] + x[I] * r[17]) + r[8] * x[I] + t68[I] * (r[9] + x[I] * (r[13] + x[I] * r[18]) + t68[I] * (r[14] + r[19] * x[I] + r[20] * t68[I])))) I = SP < 0.003 if I.any(): Rtx[I] = u[0] + x[I] * (u[1] + u[4] * t68[I] + x[I] * (u[3] + u[7] * t68[I] + x[I] * (u[6] + u[11] * t68[I] + x[I] * (u[10] + u[16] * t68[I] + x[I] * u[15])))) + t68[I] * (u[2] + t68[I] * (u[5] + x[I] * x[I] * (u[12] + x[I] * u[17]) + u[8] * x[I] + t68[I] * (u[9] + x[I] * (u[13] + x[I] * u[18]) + t68[I] * (u[14] + u[19] * x[I] + u[20] * t68[I])))) # Finding the starting value of dSP_dRtx, the derivative of SP with # respect to Rtx. dSP_dRtx = a[1] + (2 * a[2] + (3 * a[3] + (4 * a[4] + 5 * a[5] * Rtx) * Rtx) * Rtx) * Rtx + ft68 * (b[1] + (2 * b[2] + (3 * b[3] + (4 * b[4] + 5 * b[5] * Rtx) * Rtx) * Rtx) * Rtx) # TODO: Test case that cover all those "ifs" I2 = SP < 2 if I2.any(): x = 400 * (Rtx[I2] ** 2) sqrty = 10 * Rtx[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) Hill_ratio = Hill_ratio_at_SP2(t[I2]) dSP_dRtx[I2] = (dSP_dRtx[I2] + a[0] * 800 * Rtx[I2] * (1.5 + 2 * x) / (part1 ** 2) + b[0] * ft68[I2] * (10 + sqrty * (20 + 30 * sqrty)) / (part2 ** 2)) dSP_dRtx[I2] = Hill_ratio * dSP_dRtx[I2] """One iteration through the modified Newton-Raphson method achieves an error in Practical Salinity of about 10^-12 for all combinations of the inputs. One and a half iterations of the modified Newton-Raphson method achieves a maximum error in terms of Practical Salinity of better than 2x10^-14 everywhere. We recommend one and a half iterations of the modified Newton-Raphson method.""" # Begin the modified Newton-Raphson method. SP_est = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx)) # TODO: Test case that cover all those "ifs" I2 = SP_est < 2 if I2.any(): x = 400 * (Rtx[I2] ** 2) sqrty = 10 * Rtx[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) SP_Hill_raw = SP_est[I2] - a[0] / part1 - b[0] * ft68[I2] / part2 Hill_ratio = Hill_ratio_at_SP2(t[I2]) SP_est[I2] = Hill_ratio * SP_Hill_raw Rtx_old = Rtx Rtx = Rtx_old - (SP_est - SP) / dSP_dRtx # This mean value of Rtx, Rtxm, is the value of Rtx at which the # derivative dSP_dRtx is evaluated. Rtxm = 0.5 * (Rtx + Rtx_old) dSP_dRtx = a[1] + (2 * a[2] + (3 * a[3] + (4 * a[4] + 5 * a[5] * Rtxm) * Rtxm) * Rtxm) * Rtxm + ft68 * (b[1] + (2 * b[2] + (3 * b[3] + (4 * b[4] + 5 * b[5] * Rtxm) * Rtxm) * Rtxm) * Rtxm) # TODO: Test case that cover all those "ifs" I2 = SP_est < 2 if I2.any(): x = 400 * (Rtxm[I2] ** 2) sqrty = 10 * Rtxm[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) dSP_dRtx[I2] = (dSP_dRtx[I2] + a[0] * 800 * Rtxm[I2] * (1.5 + 2 * x) / (part1 ** 2) + b[0] * ft68[I2] * (10 + sqrty * (20 + 30 * sqrty)) / (part2 ** 2)) Hill_ratio = Hill_ratio_at_SP2(t[I2]) dSP_dRtx[I2] = Hill_ratio * dSP_dRtx[I2] # End of the one full iteration of the modified Newton-Raphson technique. Rtx = Rtx_old - (SP_est - SP) / dSP_dRtx # Updated Rtx # Now we do another half iteration of the modified Newton-Raphson # technique, making a total of one and a half modified N-R iterations. SP_est = a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx) # TODO: Test case that cover all those "ifs" I2 = SP_est < 2 if I2.any(): x = 400 * (Rtx[I2] ** 2) sqrty = 10 * Rtx[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) SP_Hill_raw = SP_est[I2] - a[0] / part1 - b[0] * ft68[I2] / part2 Hill_ratio = Hill_ratio_at_SP2(t[I2]) SP_est[I2] = Hill_ratio * SP_Hill_raw Rtx = Rtx - (SP_est - SP) / dSP_dRtx """ TODO: add this as a kw. Return the error, SP_error, in Rtx (in terms of psu). SP_est = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx)) I2 = SP_est < 2 if I2.any(): x = 400 * (Rtx[I2] ** 2) sqrty = 10 * Rtx[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) SP_Hill_raw = SP_est[I2] - a[0] / part1 - b[0] * ft68[I2] / part2 Hill_ratio = Hill_ratio_at_SP2(t[I2]) SP_est[I2] = Hill_ratio * SP_Hill_raw SP_error = np.abs(SP - SP_est) This is the end of the error testing """ # Now go from Rtx to Rt and then to the conductivity ratio R at pressure p. Rt = Rtx ** 2 A = d[2] + d[3] * t68 B = 1 + d[0] * t68 + d[1] * t68 ** 2 C = p * (e[0] + e[1] * p + e[2] * p ** 2) # rt_lc (i.e. rt_lower_case) corresponds to rt as defined in the # UNESCO 44 (1983) routines. rt_lc = c[0] + (c[1] + (c[2] + (c[3] + c[4] * t68) * t68) * t68) * t68 D = B - A * rt_lc * Rt E = rt_lc * Rt * A * (B + C) Ra = np.sqrt(D ** 2 + 4 * E) - D return 0.5 * Ra / A @match_args_return def SP_salinometer(Rt, t): r"""Calculates Practical Salinity SP from a salinometer, primarily using the PSS-78 algorithm. Note that the PSS-78 algorithm for Practical Salinity is only valid in the range 2 < SP < 42. If the PSS-78 algorithm produces a Practical Salinity that is less than 2 then the Practical Salinity is recalculated with a modified form of the Hill et al. (1986) formula. The modification of the Hill et al. (1986) expression is to ensure that it is exactly consistent with PSS-78 at SP = 2. A laboratory salinometer has the ratio of conductivities, Rt, as an output, and the present function uses this conductivity ratio and the temperature t of the salinometer bath as the two input variables. Parameters ---------- Rt : array C(SP,t_68,0)/C(SP=35,t_68,0) [unitless] conductivity ratio :math:`R = \frac{C(S, t_68, 0)}{C(35, 15(IPTS-68),0)} [unitless] t : array Temperature of the bath of the salinometer [:math:`^\circ` C (ITS-90)] Returns ------- SP : array Practical Salinity [psu (PSS-78), unitless] See Also -------- TODO: sw.sals Notes ----- TODO Examples -------- TODO References ----------- ..[1] Fofonoff, P. and R.C. Millard Jr. 1983: Algorithms for computation of fundamental properties of seawater. Unesco Tech. Pap. in Mar. Sci., 44, 53 pp. ..[2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng., 11, 109 - 112. .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix E of this TEOS-10 Manual, and in particular, Eqns. (E.2.1) and (E.2.6). Modifications: 2011-04-30. Paul Barker, Trevor McDougall and Rich Pawlowicz. Version 3.0 """ Rt, t = np.broadcast_arrays(Rt, t) t68 = t * 1.00024 ft68 = (t68 - 15) / (1 + k * (t68 - 15)) Rt[Rt < 0] = np.NaN Rtx = np.sqrt(Rt) SP = a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx) """The following section of the code is designed for SP < 2 based on the Hill et al. (1986) algorithm. This algorithm is adjusted so that it is exactly equal to the PSS-78 algorithm at SP = 2.""" I2 = SP < 2 if I2.any(): Hill_ratio = Hill_ratio_at_SP2(t[I2]) x = 400 * Rt[I2] sqrty = 10 * Rtx[I2] part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) SP_Hill_raw = SP[I2] - a[0] / part1 - b[0] * ft68[I2] / part2 SP[I2] = Hill_ratio * SP_Hill_raw # Ensure that SP is non-negative. SP = np.maximum(SP, 0) return SP @match_args_return def SP_from_SK(SK): r"""Calculates Practical Salinity from Knudsen Salinity. Parameters ---------- SK : array_like Knudsen Salinity [parts per thousand, ppt] Returns ------- SP : array Practical Salinity [psu (PSS-78), unitless] Examples -------- TODO See Also -------- TODO Notes ----- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Appendix A.3. Modifications: 2011-11-16. Trevor McDougall and Paul Barker. """ SP = (SK - 0.03) * (1.80655 / 1.805) return np.maximum(SP, 0) # Ensure that SP is non-negative. @match_args_return def SK_from_SP(SP): r"""Calculates Knudsen Salinity from Practical Salinity. Parameters ---------- SP : array Practical Salinity [psu (PSS-78), unitless] Returns ------- SK : array_like Knudsen Salinity [parts per thousand, ppt] Examples -------- TODO See Also -------- TODO Notes ----- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Appendix A.3. Modifications: 2011-11-16. Trevor McDougall and Paul Barker. """ SP = np.maximum(SP, 0) # Ensure that SP is non-negative. return 0.03 + SP * (1.805 / 1.80655) if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/gsw/gibbs/water_column_48.py0000644000175000017500000002613512172027023020723 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from constants import db2Pascal from earth import grav from density_enthalpy_48 import rho from gsw.utilities import match_args_return from density_enthalpy_48 import rho_alpha_beta __all__ = [ 'Nsquared', 'Turner_Rsubrho', 'IPV_vs_fNsquared_ratio' ] # FIXME: match_args_return returns a # ndarray instead of a tuple. # Need to create a test for the match_args_return. #@match_args_return def Nsquared(SA, CT, p, lat=None): r"""Calculates the buoyancy frequency squared (N^2)(i.e. the Brunt-Väisälä frequency squared) at the mid pressure from the equation, .. math:: N^2 = g^2 \frac{\partial\rho}{\partial p} Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] lat : array_like, optional latitude in decimal degrees north [-90..+90] If lat is not supplied, a default gravitational acceleration of 9.7963 m/s^2 (Griffies, 2004) will be used. Returns ------- N2 : array_like Brunt-Väisälä frequency squared [1 s :math:`-2`] p_mid : array_like Mid pressure between p grid [dbar] See Also -------- TODO Notes ----- This routine uses rho from the computationally efficient 48-term expression for density in terms of SA, CT and p. Also that the pressure increment, :math:`\partial p`, in the above formula is in Pa, so that it is 10^4 times the pressure increment in dbar. The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.10 and Eqn. (3.10.2). ..[2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. ..[3] Griffies, S. M., 2004: Fundamentals of Ocean Climate Models. Princeton, NJ: Princeton University Press, 518 pp + xxxiv. Modifications: 2011-03-22. Trevor McDougall & Paul Barker """ if lat is not None: g = grav(lat, p) else: g = 9.7963 # Standard value from Griffies (2004). SA, CT, p, g = np.broadcast_arrays(SA, CT, p, g) p_mid = 0.5 * (p[1:, ...] + p[:-1, ...]) drho = (rho(SA[1:, ...], CT[1:, ...], p_mid) - rho(SA[:-1, ...], CT[:-1, ...], p_mid)) grav_local = 0.5 * (g[1:, ...] + g[:-1, ...]) dp = p[1:, ...] - p[:-1, ...] N2 = grav_local ** 2 * drho / (db2Pascal * dp) return N2, p_mid #@match_args_return def Turner_Rsubrho(SA, CT, p): r"""Calculates the Turner angle and the Rsubrho as a function of pressure down a vertical water column. These quantities express the relative contributions of the vertical gradients of Conservative Temperature and Absolute Salinity to the vertical stability (the square of the Brunt-Väisälä Frequency squared, N^2). `Tu` and `Rsubrho` are evaluated at the mid pressure between the individual data points in the vertical. This function uses computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Note that in the double-diffusive literature, papers concerned with the "diffusive" form of double-diffusive convection often define the stability ratio as the reciprocal of what is defined here as the stability ratio. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- Tu : array_like Turner angle, on the same (M-1)xN grid as p_mid. [degrees of rotation] Rsubrho : array_like Stability Ratio, on the same (M-1)xN grid as p_mid. [unitless] p_mid : array_like Mid pressure between p grid [dbar] See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (3.15.1) and (3.16.1). ..[2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-26. Trevor McDougall & Paul Barker """ if SA.ndim == 1: raise ValueError('There must be at least 2 columns.') SA.clip(0, np.inf) SA, CT, p = np.broadcast_arrays(SA, CT, p) p_mid = 0.5 * (p[0:-1, ...] + p[1:, ...]) SA_mid = 0.5 * (SA[0:-1, ...] + SA[1:, ...]) CT_mid = 0.5 * (CT[0:-1, ...] + CT[1:, ...]) dSA = SA[0:-1, ...] - SA[1:, ...] dCT = CT[0:-1, ...] - CT[1:, ...] [dummy, alpha, beta] = rho_alpha_beta(SA_mid, CT_mid, p_mid) """This function evaluates Tu and Rsubrho using the computationally efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute Tu and Rsubrho using the full TEOS-10 Gibbs function expression for density, the following lines of code would do that. pt_mid = pt_from_CT(SA_mid, CT_mid) pr0 = np.zeros_like(SA_mid) t_mid = pt_from_t(SA_mid, pt_mid, pr0, p_mid) beta = beta_const_CT_t_exact(SA_mid, t_mid, p_mid) alpha = alpha_wrt_CT_t_exact(SA_mid, t_mid, p_mid) """ Tu = np.arctan2((alpha * dCT + beta * dSA), (alpha * dCT - beta * dSA)) Tu = Tu * (180 / np.pi) Rsubrho = np.zeros_like(dSA) + np.NaN Inz = dSA != 0 Rsubrho[Inz] = (alpha[Inz] * dCT[Inz]) / (beta[Inz] * dSA[Inz]) return Tu, Rsubrho, p_mid #@match_args_return def IPV_vs_fNsquared_ratio(SA, CT, p, p_ref=0): r"""Calculates the ratio of the vertical gradient of potential density to the vertical gradient of locally-referenced potential density. This ratio is also the ratio of the planetary Isopycnal Potential Vorticity (IPV) to f times N^2, hence the name for this variable, IPV_vs_fNsquared_ratio (see Eqn. (3.20.5) of IOC et al. (2010)). The reference sea pressure, p_ref, of the potential density surface must have a constant value. IPV_vs_fNsquared_ratio is evaluated at the mid pressure between the individual data points in the vertical. This function uses the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] p_ref : int, float, optional reference pressure, default = 0 Returns ------- IPV_vs_fNsquared_ratio : array_like The ratio of the vertical gradient of potential density, on the same (M-1)xN grid as p_mid. [unitless] referenced to p_ref, to the vertical gradient of locally- referenced potential density. p_mid : array_like Mid pressure between p grid [dbar] See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (3.20.5). ..[2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-23. Trevor McDougall & Paul Barker """ p_ref = np.unique(np.asanyarray(p_ref)) # BUG #if not np.isscalar(p_ref): #raise ValueError('The reference pressure p_ref must be unique') if SA.ndim == 1: raise ValueError('There must be at least 2 columns.') SA.clip(0, np.inf) SA, CT, p, p_ref = np.broadcast_arrays(SA, CT, p, p_ref) p_ref = p_ref[:-1, ...] p_mid = 0.5 * (p[0:-1, ...] + p[1:, ...]) SA_mid = 0.5 * (SA[0:-1, ...] + SA[1:, ...]) CT_mid = 0.5 * (CT[0:-1, ...] + CT[1:, ...]) dSA = SA[0:-1, ...] - SA[1:, ...] dCT = CT[0:-1, ...] - CT[1:, ...] [dummy, alpha, beta] = rho_alpha_beta(SA_mid, CT_mid, p_mid) _, alpha, beta = rho_alpha_beta(SA_mid, CT_mid, p_mid) _, alpha_pref, beta_pref = rho_alpha_beta(SA_mid, CT_mid, p_ref) """This function calculates IPV_vs_fNsquared_ratio using the computationally efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute this with the full TEOS-10 Gibbs function expression for density, the following lines of code will enable this. pt_mid = pt_from_CT(SA_mid, CT_mid) pr0 = np.zeros_like(SA_mid) t_mid = pt_from_t(SA_mid, pt_mid, pr0, p_mid) beta = beta_const_CT_t_exact(SA_mid, t_mid, p_mid) alpha = alpha_wrt_CT_t_exact(SA_mid, t_mid, p_mid) beta_pref = beta_const_CT_t_exact(SA_mid, t_mid, p_ref) alpha_pref = alpha_wrt_CT_t_exact(SA_mid, t_mid, p_ref) """ numerator = dCT * alpha_pref - dSA * beta_pref denominator = dCT * alpha - dSA * beta """IPV_vs_fNsquared_ratio = np.zeros_like(SA_mid) * np.NaN I = denominator != 0. IPV_vs_fNsquared_ratio[I] = numerator[I] / denominator[I]""" IPV_vs_fNsquared_ratio = numerator / denominator return IPV_vs_fNsquared_ratio, p_mid if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/gsw/gibbs/absolute_salinity_sstar_ct.py0000644000175000017500000001771512172027023023351 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from constants import SSO, r1 from gsw.utilities import match_args_return from conversions import pt0_from_t, CT_from_pt import library as lib __all__ = [ 'SA_from_SP', # FIXME: Incomplete and untested. (need lib.SAAR) 'Sstar_from_SP', # FIXME: Incomplete and untested. (need lib.SAAR) 'CT_from_t' ] def check_input(SP, p, lon, lat): r"""Check for out of range values.""" lon, lat, p, SP = np.broadcast_arrays(lon, lat, p, SP) SP[(p < 100) & (SP > 120)] = np.NaN SP[(p >= 100) & (SP > 42)] = np.NaN lon = lon % 360 # FIXME: Test these exceptions, they are probably broken! # The original also checks for 9999s, not sure why. if ((p < -1.5) | (p > 12000)).any(): raise(Exception, 'Sstar_from_SP: pressure is out of range') if ((lon < 0) | (lon > 360)).any(): raise(Exception, 'Sstar_from_SP: longitude is out of range') if (np.abs(lat) > 90).any(): raise(Exception, 'Sstar_from_SP: latitude is out of range') SP = np.maximum(SP, 0) return SP, p, lon, lat @match_args_return def SA_from_SP(SP, p, lon, lat): r"""Calculates Absolute Salinity from Practical Salinity. Parameters ---------- SP : array_like salinity (PSS-78) [unitless] p : array_like pressure [dbar] lon : array_like decimal degrees east [0..+360] or [-180..+180] lat : array_like decimal degrees (+ve N, -ve S) [-90..+90] Returns ------- SA : masked array Absolute salinity [g kg :sup:`-1`] See Also -------- FIXME _delta_SA, _SA_from_SP_Baltic Notes ----- The mask is only set when the observation is well and truly on dry land; often the warning flag is not set until one is several hundred kilometers inland from the coast. Since SP is non-negative by definition, this function changes any negative input values of SP to be zero. Examples -------- >>> import seawater.gibbs as gsw >>> SP = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600] >>> p = [10, 50, 125, 250, 600, 1000] >>> lon, lat = 188, 4 >>> gsw.SA_from_SP(SP, p, lon, lat) array([ 34.71177971, 34.89152372, 35.02554774, 34.84723008, 34.7366296 , 34.73236186]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.5 and appendices A.4 and A.5. .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm for estimating Absolute Salinity in the global ocean. Submitted to Ocean Science. A preliminary version is available at Ocean Sci. Discuss., 6, 215-242. http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf Modifications: 2011-05-31. David Jackett, Trevor McDougall & Paul Barker. """ SP, p, lon, lat = check_input(SP, p, lon, lat) SAAR = lib.SAAR(p, lon, lat) #SAAR = lib.delta_SA(p, lon, lat) SA = (SSO / 35) * SP + (1 + SAAR) SA_baltic = lib.SA_from_SP_Baltic(SP, lon, lat) # The following function (SAAR) finds SAAR in the non-Baltic parts of # the world ocean. (Actually, this SAAR look-up table returns values # of zero in the Baltic Sea since SAAR in the Baltic is a function of SP, # not space. if SA_baltic is not None: SA[~SA_baltic.mask] = SA_baltic[~SA_baltic.mask] return SA @match_args_return def Sstar_from_SP(SP, p, lon, lat): r"""Calculates Preformed Salinity from Absolute Salinity. Parameters ---------- SP : array_like salinity (PSS-78) [unitless] p : array_like pressure [dbar] lon : array_like decimal degrees east [0..+360] or [-180..+180] lat : array_like decimal degrees (+ve N, -ve S) [-90..+90] Returns ------- Sstar : masked array Preformed Salinity [g kg :sup:`-1`] See Also -------- FIXME _delta_SA, _SA_from_SP_Baltic Notes ----- The mask is only set when the observation is well and truly on dry land; often the warning flag is not set until one is several hundred kilometers inland from the coast. Since SP is non-negative by definition, this function changes any negative input values of SP to be zero. Examples -------- >>> import seawater.gibbs as gsw >>> SP = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600] >>> p = [10, 50, 125, 250, 600, 1000] >>> lon, lat = 188, 4 >>> gsw.Sstar_from_SP(SP, p, lon, lat) array([ 34.7115532 , 34.89116101, 35.02464926, 34.84359277, 34.7290336 , 34.71967638]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.5 and appendices A.4 and A.5. .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm for estimating Absolute Salinity in the global ocean. Submitted to Ocean Science. A preliminary version is available at Ocean Sci. Discuss., 6, 215-242. Modifications: 2011-03-27. David Jackett, Trevor McDougall and Paul Barker. """ SP, p, lon, lat = check_input(SP, p, lon, lat) SAAR = lib.SAAR(p, lon, lat) #SAAR = lib.delta_SA(p, lon, lat) Sstar = (SSO / 35.) * SP - r1 * SAAR # In the Baltic Sea, Sstar==SA. Sstar_baltic = lib.SA_from_SP_Baltic(SP, lon, lat) # TODO: Create Baltic and non-Baltic test cases. if Sstar_baltic is not None: Sstar[~Sstar_baltic.mask] = Sstar_baltic[~Sstar_baltic.mask] return Sstar @match_args_return def CT_from_t(SA, t, p): r"""Calculates Conservative Temperature of seawater from in situ temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.3. Modifications: 2011-03-27. David Jackett, Trevor McDougall and Paul Barker """ # Find values that are out of range, set them to NaN. invalid = np.logical_and(p < 100, np.logical_or(t > 80, t < -12)) t[invalid] = np.NaN invalid = np.logical_and(p >= 100, np.logical_or(t > 40, t < -12)) t[invalid] = np.NaN pt0 = pt0_from_t(SA, t, p) CT = CT_from_pt(SA, pt0) return CT @match_args_return def SA_CT_plot(SA, CT, isopycs, title_string): r"""Calculates Conservative Temperature of seawater from in situ temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.3. Modifications: 2011-03-27. David Jackett, Trevor McDougall and Paul Barker """ return None if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/gsw/gibbs/conversions.py0000644000175000017500000010727612172027023020267 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from constants import SSO, cp0, Kelvin, sfac, uPS from constants import db2Pascal, gamma, P0, M_S, valence_factor from library import entropy_part, entropy_part_zerop, gibbs from library import gibbs_pt0_pt0, enthalpy_SSO_0_p, specvol_SSO_0_p from gsw.utilities import match_args_return, strip_mask __all__ = [ #'deltaSA_from_SP', TODO #'SA_Sstar_from_SP', TODO 'SR_from_SP', 'SP_from_SR', #'SP_from_SA', TODO: changed, check gsw_SAAR.m #'Sstar_from_SA', TODO: changed, check gsw_SAAR.m #'SA_from_Sstar', TODO: changed, check gsw_SAAR.m #'SP_from_Sstar', TODO: changed, check gsw_SAAR.m 'pt_from_CT', 't_from_CT', 'CT_from_pt', 'pot_enthalpy_from_pt', 'pt0_from_t', 'pt_from_t', 't90_from_t48', 't90_from_t68', 'z_from_p', # TODO: New test case with geo_strf_dyn_height != None 'p_from_z', 'depth_from_z', 'z_from_depth', 'Abs_Pressure_from_p', 'p_from_Abs_Pressure', 'entropy_from_CT', 'CT_from_entropy', 'entropy_from_pt', 'pt_from_entropy', 'molality_from_SA', 'ionic_strength_from_SA' ] DEG2RAD = np.pi / 180.0 n0, n1, n2 = 0, 1, 2 @match_args_return def pt_from_entropy(SA, entropy): r"""Calculates potential temperature with reference pressure p_ref = 0 dbar and with entropy as an input variable. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] entropy : array_like specific entropy [J kg :sup:`-1` K :sup:`-1`] Returns ------- pt : array_like potential temperature [:math:`^\circ` C (ITS-90)] with reference sea pressure (p_ref) = 0 dbar. See Also -------- TODO Notes ----- TODO Examples -------- >>> import seawater.gibbs as gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> entropy = [400.3892, 395.4378, 319.8668, 146.7910, 98.6471, 62.7919] >>> gsw.pt_from_entropy(SA, entropy) array([ 28.78317983, 28.42095483, 22.78495274, 10.23053207, 6.82921333, 4.32453778]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.10. Modifications: 2011-04-03. Trevor McDougall and Paul Barker. """ SA = np.maximum(SA, 0) part1 = 1 - SA / SSO part2 = 1 - 0.05 * part1 ent_SA = (cp0 / Kelvin) * part1 * (1 - 1.01 * part1) c = (entropy - ent_SA) * part2 / cp0 pt = Kelvin * (np.exp(c) - 1) dentropy_dt = cp0 / ((Kelvin + pt) * part2) # Initial dentropy_dt. for Number_of_iterations in range(0, 3): pt_old = pt dentropy = entropy_from_pt(SA, pt_old) - entropy # This is half way through the modified method # (McDougall and Wotherspoon, 2012) pt = pt_old - dentropy / dentropy_dt ptm = 0.5 * (pt + pt_old) dentropy_dt = -gibbs_pt0_pt0(SA, ptm) pt = pt_old - dentropy / dentropy_dt """maximum error of 2.2x10^-6 degrees C for one iteration. maximum error is 1.4x10^-14 degrees C for two iterations (two iterations is the default, "for Number_of_iterations = 1:2").""" return pt @match_args_return def t_from_CT(SA, CT, p): r"""Calculates *in-situ* temperature from Conservative Temperature of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.t_from_CT(SA, CT, p) array([ 28.78558023, 28.43287225, 22.81032309, 10.26001075, 6.8862863 , 4.40362445]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See sections 3.1 and 3.3. Modifications: 2011-03-29. Trevor McDougall and Paul Barker """ pt0 = pt_from_CT(SA, CT) return pt_from_t(SA, pt0, 0, p) @match_args_return def pt_from_t(SA, t, p, p_ref=0): r"""Calculates potential temperature with the general reference pressure, pr, from in situ temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] p_ref : int, float, optional reference pressure, default = 0 Returns ------- pt : array_like potential temperature [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- This function calls `entropy_part` which evaluates entropy except for the parts which are a function of Absolute Salinity alone. A faster routine exists pt0_from_t(SA,t,p) if p_ref is indeed zero dbar. Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.pt_from_t(SA, t, p) array([ 28.78319682, 28.42098334, 22.7849304 , 10.23052366, 6.82923022, 4.32451057]) >>> gsw.pt_from_t(SA, t, p, pr = 1000) array([ 29.02665528, 28.662375 , 22.99149634, 10.35341725, 6.92732954, 4.4036 ]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.1. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-29. Trevor McDougall, David Jackett, Claire Roberts-Thomson and Paul Barker. """ p_ref = np.asanyarray(p_ref) SA = np.maximum(SA, 0) s1 = SA * 35. / SSO pt = (t + (p - p_ref) * (8.65483913395442e-6 - s1 * 1.41636299744881e-6 - (p + p_ref) * 7.38286467135737e-9 + t * (-8.38241357039698e-6 + s1 * 2.83933368585534e-8 + t * 1.77803965218656e-8 + (p + p_ref) * 1.71155619208233e-10))) dentropy_dt = cp0 / ((Kelvin + pt) * (1 - 0.05 * (1 - SA / SSO))) true_entropy_part = entropy_part(SA, t, p) for Number_of_iterations in range(0, 2, 1): pt_old = pt dentropy = entropy_part(SA, pt_old, p_ref) - true_entropy_part pt = pt_old - dentropy / dentropy_dt # half way through the method ptm = 0.5 * (pt + pt_old) dentropy_dt = -gibbs(n0, n2, n0, SA, ptm, p_ref) pt = pt_old - dentropy / dentropy_dt """maximum error of 6.3x10^-9 degrees C for one iteration. maximum error is 1.8x10^-14 degrees C for two iterations (two iterations is the default, "for Number_of_iterations = 1:2). These errors are over the full "oceanographic funnel" of McDougall et al. (2010), which reaches down to p = 8000 dbar.""" return pt @match_args_return def CT_from_pt(SA, pt): r"""Calculates Conservative Temperature of seawater from potential temperature (whose reference sea pressure is zero dbar). Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt : array_like potential temperature referenced to a sea pressure of zero dbar [:math:`^\circ` C (ITS-90)] Returns ------- CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> pt = [28.7832, 28.4209, 22.7850, 10.2305, 6.8292, 4.3245] >>> gsw.CT_from_pt(SA, pt) array([ 28.80992302, 28.43914426, 22.78624661, 10.22616561, 6.82718342, 4.32356518]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.3. Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker. """ SA, pt, mask = strip_mask(SA, pt) pot_enthalpy = pot_enthalpy_from_pt(SA, pt) CT = pot_enthalpy / cp0 return np.ma.array(CT, mask=mask, copy=False) @match_args_return def pot_enthalpy_from_pt(SA, pt): r"""Calculates the potential enthalpy of seawater from potential temperature (whose reference sea pressure is zero dbar). Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt : array_like potential temperature referenced to a sea pressure of zero dbar [:math:`^\circ` C (ITS-90)] Returns ------- pot_enthalpy : array_like potential enthalpy [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> pt = [28.7832, 28.4209, 22.7850, 10.2305, 6.8292, 4.3245] >>> gsw.pot_enthalpy_from_pt(SA, pt) array([ 115005.40853458, 113525.30870246, 90959.68769935, 40821.50280454, 27253.21472227, 17259.10131183]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.2. Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker """ SA, pt, mask = strip_mask(SA, pt) SA = np.maximum(SA, 0) x2 = sfac * SA x = np.sqrt(x2) y = pt * 0.025 # Normalize for F03 and F08 pot_enthalpy = (61.01362420681071 + y * (168776.46138048015 + y * (-2735.2785605119625 + y * (2574.2164453821433 + y * (-1536.6644434977543 + y * (545.7340497931629 + (-50.91091728474331 - 18.30489878927802 * y) * y))))) + x2 * (268.5520265845071 + y * (-12019.028203559312 + y * (3734.858026725145 + y * (-2046.7671145057618 + y * (465.28655623826234 + (-0.6370820302376359 - 10.650848542359153 * y) * y)))) + x * (937.2099110620707 + y * (588.1802812170108 + y * (248.39476522971285 + (-3.871557904936333 - 2.6268019854268356 * y) * y)) + x * (-1687.914374187449 + x * (246.9598888781377 + x * (123.59576582457964 - 48.5891069025409 * x)) + y * (936.3206544460336 + y * (-942.7827304544439 + y * (369.4389437509002 + (-33.83664947895248 - 9.987880382780322 * y) * y))))))) """The above polynomial for pot_enthalpy is the full expression for potential enthalpy in terms of SA and pt, obtained from the Gibbs function as below. It has simply collected like powers of x and y so that it is computationally faster than calling the Gibbs function twice as is done in the commented code below. When this code below is run, the results are identical to calculating pot_enthalpy as above, to machine precision. g000 = gibbs(n0, n0, n0, SA, pt, 0) g010 = gibbs(n0, n1, n0, SA, pt, 0) pot_enthalpy = g000 - (Kelvin + pt) * g010 This is the end of the alternative code %timeit gsw.CT_from_pt(SA, pt) 1000 loops, best of 3: 1.34 ms per loop <- calling gibbs 1000 loops, best of 3: 254 us per loop <- standard """ return np.ma.array(pot_enthalpy, mask=mask, copy=False) @match_args_return def pt0_from_t(SA, t, p): r"""Calculates potential temperature with reference pressure, pr = 0 dbar. The present routine is computationally faster than the more general function "pt_from_t(SA, t, p, pr)" which can be used for any reference pressure value. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- pt0 : array_like potential temperature relative to 0 dbar [:math:`^\circ` C (ITS-90)] See Also -------- entropy_part, gibbs_pt0_pt0, entropy_part_zerop Notes ----- pt_from_t has the same result (only slower) Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.pt0_from_t(SA, t, p) array([ 28.78319682, 28.42098334, 22.7849304 , 10.23052366, 6.82923022, 4.32451057]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.1. .. [2] McDougall T. J., D. R. Jackett, P. M. Barker, C. Roberts-Thomson, R. Feistel and R. W. Hallberg, 2010: A computationally efficient 25-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-29. Trevor McDougall, David Jackett, Claire Roberts-Thomson and Paul Barker. """ SA = np.maximum(SA, 0) s1 = SA * (35. / SSO) pt0 = t + p * (8.65483913395442e-6 - s1 * 1.41636299744881e-6 - p * 7.38286467135737e-9 + t * (-8.38241357039698e-6 + s1 * 2.83933368585534e-8 + t * 1.77803965218656e-8 + p * 1.71155619208233e-10)) dentropy_dt = cp0 / ((Kelvin + pt0) * (1 - 0.05 * (1 - SA / SSO))) true_entropy_part = entropy_part(SA, t, p) for Number_of_iterations in range(0, 2, 1): pt0_old = pt0 dentropy = entropy_part_zerop(SA, pt0_old) - true_entropy_part # Half way the mod. method (McDougall and Wotherspoon, 2012). pt0 = pt0_old - dentropy / dentropy_dt pt0m = 0.5 * (pt0 + pt0_old) dentropy_dt = -gibbs_pt0_pt0(SA, pt0m) pt0 = pt0_old - dentropy / dentropy_dt """maximum error of 6.3x10^-9 degrees C for one iteration. maximum error is 1.8x10^-14 degrees C for two iterations (two iterations is the default, "for Number_of_iterations = 1:2"). These errors are over the full "oceanographic funnel" of McDougall et al. (2010), which reaches down to p = 8000 dbar.""" return pt0 @match_args_return def pt_from_CT(SA, CT): r"""Calculates potential temperature (with a reference sea pressure of zero dbar) from Conservative Temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- pt : array_like potential temperature referenced to a sea pressure of zero dbar [:math:`^\circ` C (ITS-90)] See Also -------- specvol_anom Notes ----- This function uses 1.5 iterations through a modified Newton-Raphson (N-R) iterative solution procedure, starting from a rational-function-based initial condition for both pt and dCT_dpt. Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236] >>> gsw.pt_from_CT(SA, CT) array([ 28.78317705, 28.4209556 , 22.78495347, 10.23053439, 6.82921659, 4.32453484]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See sections 3.1 and 3.3. .. [2] McDougall T. J., D. R. Jackett, P. M. Barker, C. Roberts-Thomson, R. Feistel and R. W. Hallberg, 2010: A computationally efficient 25-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-29. Trevor McDougall, David Jackett, Claire Roberts-Thomson and Paul Barker. """ SA, CT, mask = strip_mask(SA, CT) SA = np.maximum(SA, 0) s1 = SA * 35. / SSO a0 = -1.446013646344788e-2 a1 = -3.305308995852924e-3 a2 = 1.062415929128982e-4 a3 = 9.477566673794488e-1 a4 = 2.166591947736613e-3 a5 = 3.828842955039902e-3 b0 = 1.000000000000000e+0 b1 = 6.506097115635800e-4 b2 = 3.830289486850898e-3 b3 = 1.247811760368034e-6 a5CT = a5 * CT b3CT = b3 * CT CT_factor = (a3 + a4 * s1 + a5CT) pt_num = a0 + s1 * (a1 + a2 * s1) + CT * CT_factor pt_den = b0 + b1 * s1 + CT * (b2 + b3CT) pt = pt_num / pt_den dCT_dpt = pt_den / (CT_factor + a5CT - (b2 + b3CT + b3CT) * pt) # 1.5 iterations through the modified Newton-Rapshon iterative method CT_diff = CT_from_pt(SA, pt) - CT pt_old = pt pt = pt_old - CT_diff / dCT_dpt # 1/2-way through the 1st modified N-R. ptm = 0.5 * (pt + pt_old) # This routine calls gibbs_pt0_pt0(SA, pt0) to get the second derivative of # the Gibbs function with respect to temperature at zero sea pressure. dCT_dpt = -(ptm + Kelvin) * gibbs_pt0_pt0(SA, ptm) / cp0 pt = pt_old - CT_diff / dCT_dpt # End of 1st full modified N-R iteration. CT_diff = CT_from_pt(SA, pt) - CT pt_old = pt pt = pt_old - CT_diff / dCT_dpt # 1.5 iterations of the modified N-R. # Abs max error of result is 1.42e-14 deg C. return np.ma.array(pt, mask=mask, copy=False) @match_args_return def z_from_p(p, lat, geo_strf_dyn_height=None): r"""Calculates height from sea pressure using the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Dynamic height anomaly, geo_strf_dyn_height, if provided, must be computed with its pr=0 (the surface.) Parameters ---------- p : array_like pressure [dbar] lat : array_like latitude in decimal degrees north [-90..+90] geo_strf_dyn_height : float, optional dynamic height anomaly [ m :sup:`2` s :sup:`-2` ] Returns ------- z : array_like height [m] See Also -------- # FIXME: enthalpy_SSO_0_CT25, changed! Examples -------- >>> import gsw >>> p = [10, 50, 125, 250, 600, 1000] >>> lat = 4 >>> gsw.z_from_p(p, lat) array([ -9.94460074, -49.71817465, -124.2728275 , -248.47044828, -595.82618014, -992.0931748 ]) Notes ----- At sea level z = 0, and since z (HEIGHT) is defined to be positive upwards, it follows that while z is positive in the atmosphere, it is NEGATIVE in the ocean. References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. .. [3] Moritz (2000) Goedetic reference system 1980. J. Geodesy, 74, 128-133. Modifications: 2011-03-26. Trevor McDougall, Claire Roberts-Thomson and Paul Barker. """ if not geo_strf_dyn_height: geo_strf_dyn_height = np.zeros_like(p) X = np.sin(lat * DEG2RAD) sin2 = X ** 2 B = 9.780327 * (1.0 + (5.2792e-3 + (2.32e-5 * sin2)) * sin2) A = -0.5 * gamma * B C = enthalpy_SSO_0_p(p) - geo_strf_dyn_height return -2 * C / (B + np.sqrt(B ** 2 - 4 * A * C)) @match_args_return def p_from_z(z, lat, geo_strf_dyn_height=0): r"""Calculates sea pressure from height using computationally-efficient 48-term expression for density, in terms of SA, CT and p (McDougall et al., 2011). Dynamic height anomaly, geo_strf_dyn_height, if provided, must be computed with its pr=0 (the surface.) Parameters ---------- z : array_like height [m] lat : array_like latitude in decimal degrees north [-90..+90] geo_strf_dyn_height : float, optional dynamic height anomaly [ m :sup:`2` s :sup:`-2` ] The reference pressure (p_ref) of geo_strf_dyn_height must be zero (0) dbar. Returns ------- p : array_like pressure [dbar] See Also -------- #FIXME: specvol_SSO_0_CT25, enthalpy_SSO_0_CT25, changed! Examples -------- >>> import gsw >>> z = [-10., -50., -125., -250., -600., -1000.] >>> lat = 4. >>> gsw.p_from_z(z, lat) array([ 10.05521794, 50.2711751, 125.6548857, 251.23284504, 602.44050752, 1003.07609807]) >>> z = [9.94460074, 49.71817465, 124.2728275, 248.47044828, 595.82618014, ... 992.0931748] >>> gsw.p_from_z(z, lat) array([ 10., 50., 125., 250., 600., 1000.]) Notes ----- Height (z) is NEGATIVE in the ocean. Depth is -z. Depth is not used in the gibbs library. References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. .. [3] Moritz (2000) Goedetic reference system 1980. J. Geodesy, 74, 128-133. .. [4] Saunders, P. M., 1981: Practical conversion of pressure to depth. Journal of Physical Oceanography, 11, 573-574. Modifications: 2010-08-26. Trevor McDougall, Claire Roberts-Thomson and Paul Barker. 2011-03-26. Trevor McDougall, Claire Roberts-Thomson and Paul Barker """ X = np.sin(lat * DEG2RAD) sin2 = X ** 2 gs = 9.780327 * (1.0 + (5.2792e-3 + (2.32e-5 * sin2)) * sin2) # get the first estimate of p from Saunders (1981) c1 = 5.25e-3 * sin2 + 5.92e-3 p = -2 * z / ((1 - c1) + np.sqrt((1 - c1) * (1 - c1) + 8.84e-6 * z)) df_dp = db2Pascal * specvol_SSO_0_p(p) # Initial value for f derivative. f = (enthalpy_SSO_0_p(p) + gs * (z - 0.5 * gamma * (z ** 2)) - geo_strf_dyn_height) p_old = p p = p_old - f / df_dp p_mid = 0.5 * (p + p_old) df_dp = db2Pascal * specvol_SSO_0_p(p_mid) p = p_old - f / df_dp # After this one iteration through this modified Newton-Raphson iterative # procedure, the remaining error in p is at computer machine precision, # being no more than 1.6e-10 dbar. return p @match_args_return def t90_from_t48(t48): r"""Converts IPTS-48 temperature to International Temperature Scale 1990 (ITS-90) temperature. This conversion should be applied to all in-situ data collected prior to 31/12/1967. Parameters --------- t48 : array_like in-situ temperature [:math:`^\circ` C (ITPS-48)] Returns ------- t90 : array_like in-situ temperature [:math:`^\circ` C (ITS-90)] References ---------- .. [1] International Temperature Scales of 1948, 1968 and 1990, an ICES note, available from http://www.ices.dk/ocean/procedures/its.htm Modifications: 2011-03-29. Paul Barker and Trevor McDougall. """ return (t48 - (4.4e-6) * t48 * (100 - t48)) / 1.00024 @match_args_return def t90_from_t68(t68): r"""Converts IPTS-68 temperature to International Temperature Scale 1990 (ITS-90) temperature. This conversion should be applied to all in-situ data collected between 1/1/1968 and 31/12/1989. Parameters --------- t68 : array_like in-situ temperature [:math:`^\circ` C (ITPS-68)] Returns ------- t90 : array_like in-situ temperature [:math:`^\circ` C (ITS-90)] References ---------- .. [1] International Temperature Scales of 1948, 1968 and 1990, an ICES note, available from http://www.ices.dk/ocean/procedures/its.htm Modifications: 2011-03-29. Paul Barker and Trevor McDougall. """ # t90 = t68 / 1.00024 return t68 * 0.999760057586179 def depth_from_z(z): r"""Calculates depth from height, z. Note that in general height is negative in the ocean. Parameters --------- z : array_like height [m] Returns ------- depth : array_like depth [m] Modifications: 2011-03-26. Winston. """ return -z def z_from_depth(depth): r"""Calculates height, z, from depth. Note that in general height is negative in the ocean. Parameters --------- depth : array_like depth [m] Returns ------- z : array_like height [m] Modifications: 2011-03-26. Winston. """ return -depth @match_args_return def Abs_Pressure_from_p(p): r"""Calculates Absolute Pressure from sea pressure. Note that Absolute Pressure is in Pa NOT dbar. Parameters --------- p : array_like sea pressure [dbar] Returns ------- Absolute_Pressure : array_like Absolute Pressure [Pa] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.2.1). Modifications: 2011-03-29. Trevor McDougall & Paul Barker """ return p * db2Pascal + P0 @match_args_return def p_from_Abs_Pressure(Absolute_Pressure): r"""Calculates sea pressure from Absolute Pressure. Note that Absolute Pressure is in Pa NOT dbar. Parameters --------- Absolute_Pressure : array_like Absolute Pressure [Pa] Returns ------- p : array_like sea pressure [dbar] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.2.1). Modifications: 2011-03-29. Trevor McDougall & Paul Barker """ return (Absolute_Pressure - P0) * 1. / db2Pascal @match_args_return def SR_from_SP(SP): r"""Calculates Reference Salinity from Practical Salinity. Parameters --------- SP : array_like Practical Salinity (PSS-78) [unitless] Returns ------- SR : array_like Reference Salinity [g kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-03-27. Trevor McDougall & Paul Barker """ return uPS * SP @match_args_return def SP_from_SR(SR): r"""Calculates Practical Salinity from Reference Salinity. Parameters --------- SR : array_like Reference Salinity [g kg :sup:`-1`] Returns ------- SP : array_like Practical Salinity (PSS-78) [unitless] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-03-27. Trevor McDougall & Paul Barker """ return 1. / uPS * SR @match_args_return def ionic_strength_from_SA(SA): r"""Calculates the ionic strength of seawater from Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] Returns ------- ionic_strength : array_like ionic strength of seawater [mol kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> gsw.ionic_strength_from_SA(SA) array([ 0.71298118, 0.71680567, 0.71966059, 0.71586272, 0.71350891, 0.71341953]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Table L.1. .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See Eqns. 5.9 and 5.12. Modifications: 2011-03-29. Trevor McDougall and Paul Barker """ # Molality of seawater in mol kg :sup:`-1` molality = molality_from_SA(SA) return 0.5 * valence_factor * molality @match_args_return def molality_from_SA(SA): r"""Calculates the molality of seawater from Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] Returns ------- molality : array_like seawater molality [mol kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> gsw.molality(SA) array([ 1.14508476, 1.15122708, 1.15581223, 1.14971265, 1.14593231, 1.14578877]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-03-29. Trevor McDougall & Paul Barker """ # Molality of seawater in mol kg :sup:`-1`. SA = np.maximum(SA, 0) molality = SA / (M_S * (1000 - SA)) return molality @match_args_return def entropy_from_pt(SA, pt): r"""Calculates specific entropy of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt : array_like potential temperature [:math:`^\circ` C (ITS-90)] Returns ------- entropy : array_like specific entropy [J kg :sup:`-1` K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> pt = [28.7832, 28.4210, 22.7850, 10.2305, 6.8292, 4.3245] >>> gsw.entropy_from_pt(SA, pt) array([ 400.38946744, 395.43839949, 319.86743859, 146.79054828, 98.64691006, 62.79135672]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.10. Modifications: 2011-04-03. Trevor McDougall & Paul Barker """ SA = np.maximum(SA, 0) return -gibbs(n0, n1, n0, SA, pt, 0) @match_args_return def entropy_from_CT(SA, CT): r"""Calculates specific entropy of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- entropy : array_like specific entropy [J kg :sup:`-1` K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236] >>> gsw.entropy_from_CT(SA, CT) array([ 400.38916315, 395.43781023, 319.86680989, 146.79103279, 98.64714648, 62.79185763]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.10. Modifications: 2011-04-04. Trevor McDougall & Paul Barker """ SA = np.maximum(SA, 0) pt0 = pt_from_CT(SA, CT) return -gibbs(n0, n1, n0, SA, pt0, 0) @match_args_return def CT_from_entropy(SA, entropy): r"""Calculates Conservative Temperature with entropy as an input variable. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] entropy : array_like specific entropy [J kg :sup:`-1` K :sup:`-1`] Returns ------- CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> entropy = [400.3892, 395.4378, 319.8668, 146.7910, 98.6471, 62.7919] >>> gsw.CT_from_entropy(SA, entropy) array([ 28.80990279, 28.43919923, 22.78619927, 10.22619767, 6.82719674, 4.32360295]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.10. Modifications: 2011-03-03. Trevor McDougall and Paul Barker. """ SA = np.maximum(SA, 0) pt = pt_from_entropy(SA, entropy) return CT_from_pt(SA, pt) if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/gsw/gibbs/steric.py0000644000175000017500000001201212172027023017167 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from gsw.utilities import match_args_return #from conversions import geo_strf_dyn_height __all__ = ['steric_height'] @match_args_return def steric_height(SA, CT, p, p_ref): r"""Calculates steric height anomaly as the pressure integral of specific volume anomaly from the pressure p of the "bottle" to the reference pressure p_ref, divided by the constant value of the gravitational acceleration, 9.7963 m s^-2. That is, this function returns the dynamic height anomaly divided by 9.7963 m s^-2; this being the gravitational acceleration averaged over the surface of the global ocean (see page 46 of Griffies, 2004). Hence, steric_height is the steric height anomaly with respect to a given reference pressure p_ref. Dynamic height anomaly is the geostrophic streamfunction for the difference between the horizontal velocity at the pressure concerned, p, and the horizontal velocity at p_ref. Dynamic height anomaly is the exact geostrophic streamfunction in isobaric surfaces even though the gravitational acceleration varies with latitude and pressure. Steric height anomaly, being simply proportional to dynamic height anomaly, is also an exact geostrophic streamfunction in an isobaric surface (up to the constant of proportionality, 9.7963 m s^-2). Note however that steric_height is not exactly the height (in meters) of an isobaric surface above a geopotential surface. It is tempting to divide dynamic height anomaly by the local value of the gravitational acceleration, but doing so robs the resulting quantity of either being (i) an exact geostrophic streamfunction, or (ii) exactly the height of an isobaric surface above a geopotential surface. By using a constant value of the gravitational acceleration, we have retained the first of these two properties. So it should be noted that because of the variation of the gravitational acceleration with latitude, steric_height does not exactly represent the height of an isobaric surface above a geopotential surface under the assumption of geostropy. The reference values used for the specific volume anomaly are SSO = 35.16504 g/kg and CT = 0 deg C. This function calculates specific volume anomaly using the computationally efficient 48-term expression for specific volume of McDougall et al. (2011). Note that the 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011) and IOC et al. (2010). For dynamical oceanography we may take the 48-term rational function expression for density as essentially reflecting the full accuracy of TEOS-10. The GSW internal library function "infunnel(SA,CT,p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] p_ref : int, float, optional reference pressure, default = 0 Returns ------- steric_height : array_like dynamic height anomaly divided by 9.7963 m s^-2 [m] Notes ----- If p_ref exceeds the pressure of the deepest "bottle" on a vertical profile, the steric height anomaly for each "bottle" on the whole vertical profile is returned as NaN. See Also -------- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.27. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. .. [3] Griffies, S. M., 2004: Fundamentals of Ocean Climate Models. Princeton, NJ: Princeton University Press, 518 pp + xxxiv. Modifications: 2010-05-20. Trevor McDougall and Paul Barker. """ p_ref = np.asanyarray(p_ref) p_ref = np.unique(p_ref) if not np.isscalar(p_ref): raise ValueError('The reference pressure p_ref must be unique') if (p_ref < 0).any(): raise ValueError('The reference pressure p_ref must be positive') if (SA < 0).any(): raise ValueError('The Absolute Salinity must be positive!') # Start of the calculation. if p.max() < p_ref.max(): raise ValueError('The reference pressure p_ref is deeper than bottles') dynamic_height_anomaly = geo_strf_dyn_height(SA, CT, p, p_ref) const_grav = 9.7963 # Griffies, 2004. return dynamic_height_anomaly / const_grav gsw-3.0.2/gsw/gibbs/freezing.py0000644000175000017500000005306712172027023017526 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from constants import SSO from conversions import t_from_CT from gsw.utilities import match_args_return from absolute_salinity_sstar_ct import CT_from_t __all__ = [ 'CT_freezing', 't_freezing', 'brineSA_CT', 'brineSA_t' ] # Constants: c = (0.017947064327968736, -6.076099099929818, 4.883198653547851, -11.88081601230542, 13.34658511480257, -8.722761043208607, 2.082038908808201, -7.389420998107497, -2.110913185058476, 0.2295491578006229, -0.9891538123307282, -0.08987150128406496, 0.3831132432071728, 1.054318231187074, 1.065556599652796, -0.7997496801694032, 0.3850133554097069, -2.078616693017569, 0.8756340772729538, -2.079022768390933, 1.596435439942262, 0.1338002171109174, 1.242891021876471) T = (0.002519, -5.946302841607319, 4.136051661346983, -1.115150523403847e1, 1.476878746184548e1, -1.088873263630961e1, 2.961018839640730, -7.433320943962606, -1.561578562479883, 4.073774363480365e-2, 1.158414435887717e-2, -4.122639292422863e-1, -1.123186915628260e-1, 5.715012685553502e-1, 2.021682115652684e-1, 4.140574258089767e-2, -6.034228641903586e-1, -1.205825928146808e-2, -2.812172968619369e-1, 1.877244474023750e-2, -1.204395563789007e-1, 2.349147739749606e-1, 2.748444541144219e-3) # Adjust for the effects of dissolved air. Note that # a = 0.502500117621 / 35.16504 a, b = 0.014289763856964, 0.057000649899720 P = (2.570124672768757e-1, -1.917742353032266e+1, -1.413382858617969e-2, -5.427484830917552e-1, -4.126621135193472e-4, -4.176407833276121e-7, 4.688217641883641e-5, -3.039808885885726e-8, -4.990118091261456e-11, -9.733920711119464e-9, -7.723324202726337e-12, 7.121854166249257e-16, 1.256474634100811e-12, 2.105103897918125e-15, 8.663811778227171e-19) @match_args_return def CT_freezing(SA, p, saturation_fraction=1): r"""Calculates the Conservative Temperature at which seawater freezes. Parameters ---------- SA : array_like Absolute Salinity [g/kg] p : array_like sea pressure [dbar] saturation_fraction : fraction between 0, 1. The saturation fraction of dissolved air in seawater. Default is 0 or completely saturated. Returns ------- CT_freezing : array_like Conservative Temperature at freezing of seawater [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See sections 3.33 and 3.34. Modifications: 2011-11-04. Trevor McDougall, Paul Barker and Rainer Feistal. """ SA, p, saturation_fraction = np.broadcast_arrays(SA, p, saturation_fraction) if (SA < 0).any(): raise ValueError('SA must be non-negative!') if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any(): raise ValueError('Saturation_fraction MUST be between zero and one.') SA_r = SA * 1e-2 x = np.sqrt(SA_r) p_r = p * 1e-4 CT_freeze = c[0] + SA_r * (c[1] + x * (c[2] + x * (c[3] + x * (c[4] + x * (c[5] + c[6] * x))))) + p_r * (c[7] + p_r * (c[8] + c[9] * p_r)) + SA_r * p_r * (c[10] + p_r * (c[12] + p_r * (c[15] + c[21] * SA_r)) + SA_r * (c[13] + c[17] * p_r + c[19] * SA_r) + x * (c[11] + p_r * (c[14] + c[18] * p_r) + SA_r * (c[16] + c[20] * p_r + c[22] * SA_r))) """The error of this fit ranges between -5e-4 K and 6e-4 K when compared with the Conservative Temperature calculated from the exact in-situ freezing temperature which is found by a Newton-Raphson iteration of the equality of the chemical potentials of water in seawater and in ice. (Note that the in-situ freezing temperature can be found by this exact method using the function sea_ice_freezingtemperature_si in the SIA library).""" # Adjust for the effects of dissolved air. a, b = 0.014289763856964, 0.057000649899720 # Note that a = 0.502500117621 / 35.16504 CT_freeze = (CT_freeze - saturation_fraction * (1e-3) * (2.4 - a * SA) * (1 + b * (1 - SA / 35.16504))) tmp = np.logical_or(p > 10000, SA > 120) out = np.logical_or(tmp, p + SA * 71.428571428571402 > 13571.42857142857) CT_freeze[out] = np.ma.masked return CT_freeze @match_args_return def t_freezing(SA, p, saturation_fraction=1): r"""Calculates the in-situ temperature at which seawater freezes. Parameters ---------- SA : array_like Absolute Salinity [g/kg] p : array_like sea pressure [dbar] saturation_fraction : fraction between 0, 1. The saturation fraction of dissolved air in seawater. Default is 0 or completely saturated. Returns ------- t_freezing : array_like in-situ temperature at which seawater freezes [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See sections 3.33 and 3.34. Modifications: 2011-11-03. Trevor McDougall, Paul Barker and Rainer Feistal. """ """This function, t_freezing, calculates the in-situ freezing temperature, t_freezing, of seawater by first evaluating a polynomial of the Conservative Temperature at which seawater freezes, CT_freezing, using the GSW function CT_freezing. The in-situ freezing temperature is then calculated using the GSW function t_from_CT. However, if one wanted to compute the in-situ freezing temperature directly from a single polynomial expression without first calculating the Conservative Temperature at the freezing point, the following lines of code achieve this. The error of the following fit is similar to that of the present function, t_freezing, and ranges between -8e-4 K and 3e-4 K when compared with the in-situ freezing temperature evaluated by Newton-Raphson iteration of the equality of the chemical potentials of water in seawater and in ice. (Note that the in-situ freezing temperature can be found by this exact method using the function sea_ice_freezingtemperature_si in the SIA library). SA_r = SA * 1e-2 x = np.sqrt(SA_r) p_r = p * 1e-4 t_freeze = T[0] + SA_r * (T[1] + x * (T[2] + x * (T[3] + x * (T[4] + x * (T[5] + T[6] * x))))) + p_r * (T[7] + p_r * (T[8] + T[9] * p_r)) + SA_r * p_r * (T[10] + p_r * (T[12] + p_r * (T[15] + T[21] * SA_r)) + SA_r * (T[13] + T[17] * p_r + T[19] * SA_r) + x * (T[11] + p_r * (T[14] + T[18] * p_r) + SA_r * (T[16] + T[20] * p_r + T[22] * SA_r))) Adjust for the effects of dissolved air t_freezing -= saturation_fraction * (1e-3) * (2.4 - SA / 70.33008) """ SA, p, saturation_fraction = np.broadcast_arrays(SA, p, saturation_fraction) if (SA < 0).any(): raise ValueError('SA must be non-negative!') if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any(): raise ValueError('Saturation_fraction MUST be between zero and one.') CT_freeze = CT_freezing(SA, p, saturation_fraction) t_freeze = t_from_CT(SA, CT_freeze, p) tmp = np.logical_or(p > 10000, SA > 120) out = np.logical_or(tmp, p + SA * 71.428571428571402 > 13571.42857142857) t_freeze[out] = np.ma.masked return t_freeze @match_args_return def brineSA_CT(CT, p, saturation_fraction=1): r"""Calculates the Absolute Salinity of seawater at the freezing temperature. That is, the output is the Absolute Salinity of seawater, with the fraction saturation_fraction of dissolved air, that is in equilibrium with ice at Conservative Temperature CT and pressure p. If the input values are such that there is no positive value of Absolute Salinity for which seawater is frozen, the output, brineSA_CT, is put equal to -99. Parameters ---------- CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] saturation_fraction : fraction between 0, 1. The saturation fraction of dissolved air in seawater. Default is 0 or completely saturated. Returns ------- brine_SA_CT : array_like Absolute Salinity of seawater when it freezes [ g/kg ] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See sections 3.33. Modifications: 2011-28-03. Trevor McDougall and Paul Barker. """ CT, p, saturation_fraction = np.broadcast_arrays(CT, p, saturation_fraction) if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any(): raise ValueError('Saturation_fraction MUST be between zero and one.') p_r = p * 1e-4 # Form the first estimate of brine_SA_CT from a polynomial in CT and p_r. SA = -(CT + 9 * p_r) / 0.06 # A rough estimate to get the saturated CT. SA = np.maximum(SA, 0) CTsat = CT - (1 - saturation_fraction) * 1e-3 * (2.4 - a * SA) * (1 + b * (1 - SA / SSO)) SA = P[0] + p * (P[2] + P[4] * CTsat + p * (P[5] + CTsat * (P[7] + P[9] * CTsat) + p * (P[8] + CTsat * (P[10] + P[12] * CTsat) + p * (P[11] + P[13] * CTsat + P[14] * p)))) + CTsat * (P[1] + CTsat * (P[3] + P[6] * p)) CT_freezing_zero_SA = (c[0] + p_r * (c[7] + p_r * (c[8] + c[9] * p_r)) - saturation_fraction * 2.4e-3 * (1 + b)) # Find CT > CT_freezing_zero_SA. If this is the case, the input values # represent seawater that is not frozen (at any positive SA). Itw = (CT > CT_freezing_zero_SA) # tw stands for "too warm" SA[Itw] = np.ma.masked # Find -SA_cut_off < SA < SA_cut_off, replace the above estimate of SA # with one based on (CT_freezing_zero_SA - CT). SA_cut_off = 2.5 # This is the band of SA within +- 2.5 g/kg of SA = 0, # which we treat differently in calculating the initial # values of both SA and dCT_dSA. Ico = (np.abs(SA) < SA_cut_off) Icoa = np.logical_and(SA < 0, SA >= -SA_cut_off) SA[Icoa] = 0 # Find SA < -SA_cut_off, set them to NaN. SA[SA < -SA_cut_off] = np.ma.masked # Form the first estimate of dCT_dSA, the derivative of CT with respect # to SA at fixed p. SA_r = 0.01 * SA x = np.sqrt(SA_r) dCT_dSA_part = 2 * c[1] + x * (3 * c[2] + x * (4 * c[3] + x * (5 * c[4] + x * (6 * c[5] + 7 * c[6] * x)))) + p_r * (2 * c[10] + p_r * (2 * c[12] + p_r * (2 * c[15] + 4 * c[21] * x * x)) + x * x * (4 * c[13] + 4 * c[17] * p_r + 6 * c[19] * x * x) + x * (3 * c[11] + 3 * p_r * (c[14] + c[18] * p_r) + x * x * (5 * c[16] + 5 * c[20] * p_r + 7 * c[22] * x * x))) dCT_dSA = 0.5 * 0.01 * dCT_dSA_part - saturation_fraction * 1e-3 * (-a * (1 + b * (1 - SA / SSO)) - b * (2.4 - a * SA) / SSO) # Now replace the estimate of SA with the one based on # (CT_freezing_zero_SA - CT) when (np.abs(SA) < SA_cut_off). SA[Ico] = (CT[Ico] - CT_freezing_zero_SA[Ico]) / dCT_dSA[Ico] # Begin the modified Newton-Raphson method to solve the root of # CT_freezing = CT for SA. Number_of_Iterations = 2 for I_iter in range(0, Number_of_Iterations): # CT_freezing temperature function evaluation (the forward function # evaluation), the same as CT_freezing(SA, p, saturation_fraction). SA_r = 0.01 * SA x = np.sqrt(SA_r) SA_old = SA CT_freeze = (c[0] + SA_r * (c[1] + x * (c[2] + x * (c[3] + x * (c[4] + x * (c[5] + c[6] * x))))) + p_r * (c[7] + p_r * (c[8] + c[9] * p_r)) + SA_r * p_r * (c[10] + p_r * (c[12] + p_r * (c[15] + c[21] * SA_r)) + SA_r * (c[13] + c[17] * p_r + c[19] * SA_r) + x * (c[11] + p_r * (c[14] + c[18] * p_r) + SA_r * (c[16] + c[20] * p_r + c[22] * SA_r))) - saturation_fraction * 1e-3 * (2.4 - a * SA) * (1 + b * (1 - SA / SSO))) SA = SA_old - (CT_freeze - CT) / dCT_dSA # Half-way point of the modified Newton-Raphson solution method. SA_r = 0.5 * 0.01 * (SA + SA_old) # The mean value of SA and SA_old. x = np.sqrt(SA_r) dCT_dSA_part = 2 * c[1] + x * (3 * c[2] + x * (4 * c[3] + x * (5 * c[4] + x * (6 * c[5] + 7 * c[6] * x)))) + p_r * (2 * c[10] + p_r * (2 * c[12] + p_r * (2 * c[15] + 4 * c[21] * x * x)) + x * x * (4 * c[13] + 4 * c[17] * p_r + 6 * c[19] * x * x) + x * (3 * c[11] + 3 * p_r * (c[14] + c[18] * p_r) + x * x * (5 * c[16] + 5 * c[20] * p_r + 7 * c[22] * x * x))) dCT_dSA = (0.5 * 0.01 * dCT_dSA_part - saturation_fraction * 1e-3 * (-a * (1 + b * (1 - SA / SSO)) - b * (2.4 - a * SA) / SSO)) SA = SA_old - (CT_freeze - CT) / dCT_dSA """The following lines of code, if implemented, calculates the error of this function in terms of Conservative Temperature, CT_error. With Number_of_Iterations = 1, the maximum error in CT is 2x10^-7 C. With Number_of_Iterations = 2, the maximum error in CT is 7x10^-15 C, which is the machine precision of the computer. Number_of_Iterations = 2 is what we recommend. SA_r = 0.01 * SA x = np.sqrt(SA_r) CT_freeze = c[0] + SA_r * (c[1] + x * (c[2] + x * (c[3] + x * (c[4] + x * (c[5] + c[6] * x))))) + p_r * (c[7] + p_r * (c[8] + c[9] * p_r)) + SA_r * p_r * (c[10] + p_r * (c[12] + p_r * (c[15] + c[21] * SA_r)) + SA_r * (c[13] + c[17] * p_r + c[19] * SA_r) + x * (c[11] + p_r * (c[14] + c[18] * p_r) + SA_r * (c[16] + c[20] * p_r + c[22] * SA_r))) - saturation_fraction * 1e-3 * (2.4 - a * SA) * (1 + b * (1 - SA / SSO)) CT_error = np.abs(CT_freeze - CT) tmp = np.logical_or(p > 10000, SA > 120 out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857) CT_error[out] = np.ma.masked """ brine_SA_CT = SA tmp = np.logical_or(p > 10000, SA > 120) out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857) brine_SA_CT[out] = np.ma.masked # If the CT input is too warm, then there is no (positive) value of SA # that represents frozen seawater. brine_SA_CT[Itw] = -99 # NOTE: Mask these? return brine_SA_CT @match_args_return def brineSA_t(t, p, saturation_fraction=1): r"""Calculates the Absolute Salinity of seawater at the freezing temperature. That is, the output is the Absolute Salinity of seawater, with the fraction saturation_fraction of dissolved air, that is in equilibrium with ice at in-situ temperature t and pressure p. If the input values are such that there is no positive value of Absolute Salinity for which seawater is frozen, the output, brineSA_t, is put equal to -99. Parameters ---------- t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] saturation_fraction : fraction between 0, 1. The saturation fraction of dissolved air in seawater. Default is 0 or completely saturated. Returns ------- brine_SA_t : array_like Absolute Salinity of seawater when it freezes [ g/kg ] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See sections 3.33. Modifications: 2011-28-03. Trevor McDougall and Paul Barker. """ t, p, saturation_fraction = np.broadcast_arrays(t, p, saturation_fraction) if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any(): raise ValueError('Saturation_fraction MUST be between zero and one.') p_r = p * 1e-4 # Form the first estimate of brine_SA_t, called SA here, from a polynomial # in CT and p_r. SA = -(t + 9 * p_r) / 0.06 # A rough estimate to get the saturated CT. SA = np.maximum(SA, 0) CT = CT_from_t(SA, t, p) CTsat = CT - (1 - saturation_fraction) * 1e-3 * (2.4 - a * SA) * (1 + b * (1 - SA / SSO)) SA = P[0] + p * (P[2] + P[4] * CTsat + p * (P[5] + CTsat * (P[7] + P[9] * CTsat) + p * (P[8] + CTsat * (P[10] + P[12] * CTsat) + p * (P[11] + P[13] * CTsat + P[14] * p)))) + CTsat * (P[1] + CTsat * (P[3] + P[6] * p)) t_freezing_zero_SA = t_freezing(np.zeros_like(t), p, saturation_fraction) # Find t > t_freezing_zero_SA. If this is the case, the input values # represent seawater that is not frozen (at any positive SA). Itw = (t > t_freezing_zero_SA) # Itw stands for "I_too_warm" SA[Itw] = np.ma.masked # Find -SA_cut_off < SA < SA_cut_off, replace the above estimate of SA # with one based on (t_freezing_zero_SA - t). SA_cut_off = 2.5 # This is the band of SA within +- 2.5 g/kg of SA = 0, # which we treat differently in calculating the initial # values of both SA and dCT_dSA. Ico = (np.abs(SA) < SA_cut_off) Icoa = np.logical_and(SA < 0, SA >= -SA_cut_off) SA[Icoa] = 0 # Find SA < -SA_cut_off, set them to masked. SA[SA < -SA_cut_off] = np.ma.masked # Form the first estimate of dt_dSA, the derivative of t with respect # to SA at fixed p, using the coefficients, t0 ... t22 from t_freezing. SA_r = 0.01 * SA x = np.sqrt(SA_r) dt_dSA_part = 2 * T[1] + x * (3 * T[2] + x * (4 * T[3] + x * (5 * T[4] + x * (6 * T[5] + 7 * T[6] * x)))) + p_r * (2 * T[10] + p_r * (2 * T[12] + p_r * (2 * T[15] + 4 * T[21] * x * x)) + x * x * (4 * T[13] + 4 * T[17] * p_r + 6 * T[19] * x * x) + x * (3 * T[11] + 3 * p_r * (T[14] + T[18] * p_r) + x * x * (5 * T[16] + 5 * T[20] * p_r + 7 * T[22] * x * x))) dt_dSA = 0.5 * 0.01 * dt_dSA_part + saturation_fraction * 1e-3 / 70.33008 # Now replace the estimate of SA with the one based on # (t_freezing_zero_SA - t) when (abs(SA) < SA_cut_off). SA[Ico] = (t[Ico] - t_freezing_zero_SA[Ico]) / dt_dSA[Ico] # Begin the modified Newton-Raphson method to find the root of # t_freeze = t for SA. Number_of_Iterations = 5 for I_iter in range(0, Number_of_Iterations): SA_old = SA t_freeze = t_freezing(SA_old, p, saturation_fraction) SA = SA_old - (t_freeze - t) / dt_dSA # Half-way point of the modified Newton-Raphson solution method. SA_r = 0.5 * 0.01 * (SA + SA_old) # Mean value of SA and SA_old. x = np.sqrt(SA_r) dt_dSA_part = (2 * T[1] + x * (3 * T[2] + x * (4 * T[3] + x * (5 * T[4] + x * (6 * T[5] + 7 * T[6] * x)))) + p_r * (2 * T[10] + p_r * (2 * T[12] + p_r * (2 * T[15] + 4 * T[21] * x * x)) + x * x * (4 * T[13] + 4 * T[17] * p_r + 6 * T[19] * x * x) + x * (3 * T[11] + 3 * p_r * (T[14] + T[18] * p_r) + x * x * (5 * T[16] + 5 * T[20] * p_r + 7 * T[22] * x * x)))) dt_dSA = (0.5 * 0.01 * dt_dSA_part + saturation_fraction * 1e-3 / 70.33008) SA = SA_old - (t_freeze - t) / dt_dSA """The following lines of code, if implemented, calculate the error of this function in terms of in-situ temperature. With Number_of_Iterations = 4, the max error in t is 3x10^-13 C. With Number_of_Iterations = 5, the max error in t is 2x10^-14 C, which is the machine precision of the computer. Number_of_Iterations = 5 is what we recommend. SA[SA < 0] = np.ma.masked t_freeze = t_freezing(SA, p, saturation_fraction) t_error = np.abs(t_freeze - t) tmp = np.logical_or(p > 10000, SA > 120) out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857) t_error[out] = np.ma.masked """ brine_SA_t = SA tmp = np.logical_or(p > 10000, SA > 120) out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857) brine_SA_t[out] = np.ma.masked brine_SA_t[Itw] = -99 # If the t input is too warm, then there is no # (positive) value of SA that represents frozen # seawater. return brine_SA_t gsw-3.0.2/gsw/gibbs/constants.py0000644000175000017500000001451612172027023017725 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- """Constants""" from __future__ import division C3515 = 42.9140 r"""Conductivity of 42.914 [mmho cm :sup:`-1` == mS cm :sup:`-1`] at Salinity 35 psu, Temperature 15 :math:`^\\circ` C [ITPS 68] and Pressure 0 db. References ---------- .. [1] Culkin and Smith, 1980: Determination of the Concentration of Potassium Chloride Solution Having the Same Electrical Conductivity, at 15C and Infinite Frequency, as Standard Seawater of Salinity 35.0000 (Chlorinity 19.37394), IEEE J. Oceanic Eng, 5, 22-23. .. [2] Unesco, 1983: Algorithms for computation of fundamental properties of seawater. Unesco Technical Papers in Marine Science, 44, 53 pp.""" earth_radius = 6371000. r"""Mean radius of earth A.E. Gill.""" OMEGA = 7.292115e-5 r""":math:`\\Omega = \\frac{2\\pi}{\\textrm{sidereal day}}` = 7.292e-5.radians sec :sup:`-1` 1 sidereal day = 23.9344696 hours Changed to a more precise value at Groten 2004 References ---------- .. [1] A.E. Gill 1982. p.54 eqn 3.7.15 "Atmosphere-Ocean Dynamics" Academic Press: New York. ISBN: 0-12-283522-0. page: 597 .. [2] Groten, E., 2004: Fundamental Parameters and Current (2004) Best Estimates of the Parameters of Common Relevance to Astronomy, Geodesy, and Geodynamics. Journal of Geodesy, 77, pp. 724-797.""" gdef = 9.8 r"""Acceleration of gravity [m s :sup:`2`] used by sw.swvel and bfrq without lat info.""" DEG2NM, NM2KM = 60., 1.8520 r"""1 nm = 1.8520 km Used by sw.dist() to convert nautical miles to kilometers. References ---------- .. [1] S. Pond & G.Pickard 2nd Edition 1986 Introductory Dynamical Oceanography Pergamon Press Sydney. ISBN 0-08-028728-X. page: 303.""" T0 = Kelvin = 273.15 r"""The Celsius zero point; 273.15 K. That is T = t + T0 where T is the Absolute Temperature (in degrees K) and t is temperature in degrees C.""" db2Pascal = 1e4 r"""Decibar to pascal.""" gamma = 2.26e-7 r"""Gamma (A.E. Gill).""" M_S = 0.0314038218 r"""Mole-weighted average atomic weight of the elements of Reference-Composition sea salt, in units of kg mol :sup:`-1`. Strictly speaking, the formula below applies only to seawater of Reference Composition. If molality is required to an accuracy of better than 0.1% we suggest you contact the authors for further guidance.""" cp0 = 3991.86795711963 r"""The "specific heat" for use with Conservative Temperature. cp0 is the ratio of potential enthalpy to Conservative Temperature. See Eqn. (3.3.3) and Table D.5 from IOC et al. (2010).""" SSO = 35.16504 r"""SSO is the Standard Ocean Reference Salinity (35.16504 g/kg.) SSO is the best estimate of the Absolute Salinity of Standard Seawater when the seawater sample has a Practical Salinity, SP, of 35 (Millero et al., 2008), and this number is a fundamental part of the TEOS-10 definition of seawater. References: ----------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendices A.3, A.5 and Table D.4. .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See Table 4 and section 5.""" sfac = 0.0248826675584615 r"""sfac = 1 / (40. * (SSO / 35.))""" R = 8.314472 r"""The molar gas constant = 8.314472 m :sup:`2` kg s:sup:`-21 K :sup:`-1` mol :sup:`-1`.""" r1 = 0.35 """ TODO """ uPS = SSO / 35.0 r"""The unit conversion factor for salinities (35.16504/35) g/kg (Millero et al., 2008). Reference Salinity SR is uPS times Practical Salinity SP. Ratio, unit conversion factor for salinities [g kg :sup:`-1`] References ---------- Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See section 6, Eqn.(6.1).""" P0 = 101325 r"""Absolute Pressure of one standard atmosphere in Pa, 101325 Pa.""" SonCl = 1.80655 r"""The ratio of Practical Salinity, SP, to Chlorinity, 1.80655 kg/g for Reference Seawater (Millero et al., 2008). This is the ratio that was used by the JPOTS committee in their construction of the 1978 Practical Salinity Scale (PSS-78) to convert between the laboratory measurements of seawater samples (which were measured in Chlorinity) to Practical Salinity. References: ----------- .. [1] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See section 5 below Eqn. (5.5).""" atomic_weight = 31.4038218 r"""This function returns the mole-weighted atomic weight of sea salt of Reference Composition, which is 31.4038218 g/mol. This has been defined as part of the Reference-Composition Salinity Scale of 2008 (Millero et al., 2008). References: ----------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Table D.4 of this TEOS-10 Manual. .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See Eqn. (5.3)""" valence_factor = 1.2452898 r"""This function returns the valence factor of sea salt of Reference Composition, 1.2452898. This valence factor is exact, and follows from the definition of the Reference-Composition Salinity Scale 2008 of Millero et al. (2008). The valence factor is the mole-weighted square of the charges, Z, of the ions comprising Reference Composition sea salt. References: ----------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Table D.4 of this TEOS-10 Manual. .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See Eqn. (5.9).""" gsw-3.0.2/gsw/gibbs/derivatives.py0000644000175000017500000005522612172027023020241 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from library import gibbs from constants import Kelvin, cp0, sfac from gsw.utilities import match_args_return from conversions import pt_from_CT, pt_from_t __all__ = [ 'CT_first_derivatives', 'CT_second_derivatives', 'enthalpy_first_derivatives', 'enthalpy_second_derivatives', 'entropy_first_derivatives', 'entropy_second_derivatives', 'pt_first_derivatives', 'pt_second_derivatives', ] n0, n1, n2 = 0, 1, 2 @match_args_return def pt_first_derivatives(SA, CT): r"""Calculates the following two partial derivatives of potential temperature (the regular potential temperature whose reference sea pressure is 0 dbar) (1) pt_SA, the derivative with respect to Absolute Salinity at constant Conservative Temperature, and (2) pt_CT, the derivative with respect to Conservative Temperature at constant Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (TEOS-10)] Returns ------- pt_SA : array_like The derivative of potential temperature with respect to Absolute Salinity at constant Conservative Temperature. [K/(g/kg)] pt_CT : array_like The derivative of potential temperature with respect to Conservative Temperature at constant Absolute Salinity. [unitless] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (A.12.6), (A.12.3), (P.6) and (P.8). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. To be submitted to Ocean Science Discussions. Modifications: 2011-03-29. Trevor McDougall and Paul Barker. """ pt = pt_from_CT(SA, CT) abs_pt = Kelvin + pt CT_SA = ((gibbs(n1, n0, n0, SA, pt, 0) - abs_pt * gibbs(n1, n1, n0, SA, pt, 0)) / cp0) CT_pt = - (abs_pt * gibbs(n0, n2, n0, SA, pt, 0)) / cp0 pt_SA = - CT_SA / CT_pt pt_CT = 1.0 / CT_pt return pt_SA, pt_CT @match_args_return def pt_second_derivatives(SA, CT): r"""Calculates the following three second-order derivatives of potential temperature (the regular potential temperature which has a reference sea pressure of 0 dbar), (1) pt_SA_SA, the second derivative with respect to Absolute Salinity at constant Conservative Temperature, (2) pt_SA_CT, the derivative with respect to Conservative Temperature and Absolute Salinity, and (3) pt_CT_CT, the second derivative with respect to Conservative Temperature at constant Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (TEOS-10)] Returns ------- pt_SA_SA : array_like The second derivative of potential temperature (the regular potential temperature which has reference sea pressure of 0 dbar) with respect to Absolute Salinity at constant Conservative Temperature. [K/((g/kg)^2)] pt_SA_CT : array_like The derivative of potential temperature with respect to Absolute Salinity and Conservative Temperature. [1/(g/kg)] pt_CT_CT : array_like The second derivative of potential temperature (the regular one with p_ref = 0 dbar) with respect to Conservative Temperature at constant SA. [1/K] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (A.12.9) and (A.12.10). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. To be submitted to Ocean Science Discussions. Modifications: 2011-03-29. Trevor McDougall and Paul Barker. """ # Increment of Absolute Salinity is 0.001 g/kg. dSA = 1e-3 SA_l = SA - dSA SA_l = np.maximum(SA_l, 0) SA_u = SA + dSA pt_SA_l, pt_CT_l = pt_first_derivatives(SA_l, CT) pt_SA_u, pt_CT_u = pt_first_derivatives(SA_u, CT) pt_SA_SA = (pt_SA_u - pt_SA_l) / (SA_u - SA_l) # Can calculate this either way. # pt_SA_CT = (pt_CT_u - pt_CT_l) / (SA_u - SA_l) dCT = 1e-2 CT_l = CT - dCT CT_u = CT + dCT pt_SA_l, pt_CT_l = pt_first_derivatives(SA, CT_l) pt_SA_u, pt_CT_u = pt_first_derivatives(SA, CT_u) pt_SA_CT = (pt_SA_u - pt_SA_l) / (CT_u - CT_l) pt_CT_CT = (pt_CT_u - pt_CT_l) / (CT_u - CT_l) return pt_SA_SA, pt_SA_CT, pt_CT_CT @match_args_return def CT_first_derivatives(SA, pt): r"""Calculates the following two derivatives of Conservative Temperature (1) CT_SA, the derivative with respect to Absolute Salinity at constant potential temperature (with pr = 0 dbar), and (2) CT_pt, the derivative with respect to potential temperature (the regular potential temperature which is referenced to 0 dbar) at constant Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt : array_like potential temperature referenced to a sea pressure of zero dbar [:math:`^\circ` C (ITS-90)] Returns ------- CT_SA : array_like The derivative of CT with respect to SA at constant potential temperature reference sea pressure of 0 dbar. [K (g kg :sup:`-1`) :sup:`-1`] CT_pt : array_like The derivative of CT with respect to pt at constant SA. [ unitless ] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> pt = [28.7832, 28.4209, 22.7850, 10.2305, 6.8292, 4.3245] >>> gsw.CT_first_derivatives(SA, pt) array([[-0.04198109, -0.04155814, -0.03473921, -0.0187111 , -0.01407594, -0.01057172], [ 1.00281494, 1.00255482, 1.00164514, 1.00000377, 0.99971636, 0.99947433]]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (A.12.3) and (A.12.9a,b). .. [2] McDougall T. J., D. R. Jackett, P. M. Barker, C. Roberts-Thomson, R. Feistel and R. W. Hallberg, 2010: A computationally efficient 25-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2010-08-05. Trevor McDougall and Paul Barker. """ # FIXME: Matlab version 3.0 has a copy-and-paste of the gibbs function here # instead of a call. Why? abs_pt = Kelvin + pt CT_pt = -(abs_pt * gibbs(n0, n2, n0, SA, pt, 0)) / cp0 x2 = sfac * SA x = np.sqrt(x2) y_pt = 0.025 * pt g_SA_T_mod = (1187.3715515697959 + x * (-1480.222530425046 + x * (2175.341332000392 + x * (-980.14153344888 + 220.542973797483 * x) + y_pt * (-548.4580073635929 + y_pt * (592.4012338275047 + y_pt * (-274.2361238716608 + 49.9394019139016 * y_pt)))) + y_pt * (-258.3988055868252 + y_pt * (-90.2046337756875 + y_pt * 10.50720794170734))) + y_pt * (3520.125411988816 + y_pt * (-1351.605895580406 + y_pt * (731.4083582010072 + y_pt * (-216.60324087531103 + 25.56203650166196 * y_pt))))) g_SA_T_mod *= 0.5 * sfac * 0.025 g_SA_mod = (8645.36753595126 + x * (-7296.43987145382 + x * (8103.20462414788 + y_pt * (2175.341332000392 + y_pt * (-274.2290036817964 + y_pt * (197.4670779425016 + y_pt * (-68.5590309679152 + 9.98788038278032 * y_pt)))) + x * (-5458.34205214835 - 980.14153344888 * y_pt + x * (2247.60742726704 - 340.1237483177863 * x + 220.542973797483 * y_pt))) + y_pt * (-1480.222530425046 + y_pt * (-129.1994027934126 + y_pt * (-30.0682112585625 + y_pt * (2.626801985426835))))) + y_pt * (1187.3715515697959 + y_pt * (1760.062705994408 + y_pt * (-450.535298526802 + y_pt * (182.8520895502518 + y_pt * (-43.3206481750622 + 4.26033941694366 * y_pt)))))) g_SA_mod *= 0.5 * sfac CT_SA = (g_SA_mod - abs_pt * g_SA_T_mod) / cp0 return CT_SA, CT_pt @match_args_return def CT_second_derivatives(SA, pt): r"""Calculates the following three, second-order derivatives of Conservative Temperature (1) CT_SA_SA, the second derivative with respect to Absolute Salinity at constant potential temperature (with p_ref = 0 dbar), (2) CT_SA_pt, the derivative with respect to potential temperature (the regular potential temperature which is referenced to 0 dbar) and Absolute Salinity, and (3) CT_pt_pt, the second derivative with respect to potential temperature (the regular potential temperature which is referenced to 0 dbar) at constant Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt : array_like potential temperature [:math:`^\circ` C (ITS-90)] Returns ------- CT_SA_SA : array_like The second derivative of Conservative Temperature with respect to Absolute Salinity at constant potential temperature (the regular potential temperature which has reference sea pressure of 0 dbar). [K/((g/kg)^2)] CT_SA_pt : array_like The derivative of Conservative Temperature with respect to potential temperature (the regular one with p_ref = 0 dbar) and Absolute Salinity. [1/(g/kg)] CT_pt_pt : array_like The second derivative of Conservative Temperature with respect to potential temperature (the regular one with p_ref = 0 dbar) at constant SA. [1/K] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.12. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. To be submitted to Ocean Science Discussions. Modifications: 2011-03-29. Trevor McDougall. """ dSA = 1e-3 SA_l = SA - dSA SA_l = np.maximum(SA_l, 0) SA_u = SA + dSA CT_SA_l, _ = CT_first_derivatives(SA_l, pt) CT_SA_u, _ = CT_first_derivatives(SA_u, pt) CT_SA_SA = np.zeros_like(SA) * np.NaN CT_SA_SA[SA_u != SA_l] = ((CT_SA_u[SA_u != SA_l] - CT_SA_l[SA_u != SA_l]) / (SA_u[SA_u != SA_l] - SA_l[SA_u != SA_l])) # Increment of potential temperature is 0.01 degrees C. dpt = 1e-2 pt_l = pt - dpt pt_u = pt + dpt CT_SA_l, CT_pt_l = CT_first_derivatives(SA, pt_l) CT_SA_u, CT_pt_u = CT_first_derivatives(SA, pt_u) CT_SA_pt = (CT_SA_u - CT_SA_l) / (pt_u - pt_l) CT_pt_pt = (CT_pt_u - CT_pt_l) / (pt_u - pt_l) return CT_SA_SA, CT_SA_pt, CT_pt_pt @match_args_return def entropy_first_derivatives(SA, CT): r"""Calculates the following two partial derivatives of specific entropy (eta) (1) eta_SA, the derivative with respect to Absolute Salinity at constant Conservative Temperature, and (2) eta_CT, the derivative with respect to Conservative Temperature at constant Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (TEOS-10)] Returns ------- eta_SA : array_like The derivative of specific entropy with respect to SA at constant CT [J g :sup:`-1` K :sup:`-1`] eta_CT : array_like The derivative of specific entropy with respect to CT at constant SA [ J (kg K :sup:`-2`) :sup:`-1` ] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236] >>> gsw.entropy_first_derivatives(SA, CT) array([[ -0.2632868 , -0.26397728, -0.2553675 , -0.23806659, -0.23443826, -0.23282068], [ 13.22103121, 13.23691119, 13.48900463, 14.08659902, 14.25772958, 14.38642995]]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (A.12.8) and (P.14a,c). Modifications: 2011-03-29. Trevor McDougall. """ pt = pt_from_CT(SA, CT) eta_SA = -(gibbs(n1, n0, n0, SA, pt, 0)) / (Kelvin + pt) eta_CT = cp0 / (Kelvin + pt) return eta_SA, eta_CT @match_args_return def entropy_second_derivatives(SA, CT): r"""Calculates the following three second-order partial derivatives of specific entropy (eta) (1) eta_SA_SA, the second derivative with respect to Absolute Salinity at constant Conservative Temperature, and (2) eta_SA_CT, the derivative with respect to Absolute Salinity and Conservative Temperature. (3) eta_CT_CT, the second derivative with respect to Conservative Temperature at constant Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (TEOS-10)] Returns ------- eta_SA_SA : array_like The second derivative of specific entropy with respect to SA at constant CT [J (kg K (g kg :sup:`-1` ) :sup:`2`) :sup:`-1`] eta_SA_CT : array_like The second derivative of specific entropy with respect to SA and CT [J (kg (g kg :sup:`-1` ) K :sup:`2`) :sup:`-1` ] eta_CT_CT : array_like The second derivative of specific entropy with respect to CT at constant SA [J (kg K :sup:`3`) :sup:`-1` ] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236] >>> gsw.entropy_second_derivatives(SA, CT) TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (P.14b) and (P.15a,b). Modifications: 2011-03-29. Trevor McDougall and Paul Barker. """ pt = pt_from_CT(SA, CT) abs_pt = Kelvin + pt CT_SA = ((gibbs(n1, n0, n0, SA, pt, 0) - (abs_pt * gibbs(n1, n1, n0, SA, pt, 0))) / cp0) CT_pt = -(abs_pt * gibbs(n0, n2, n0, SA, pt, 0)) / cp0 eta_CT_CT = - cp0 / (CT_pt * abs_pt ** 2) eta_SA_CT = CT_SA * eta_CT_CT eta_SA_SA = -gibbs(n2, n0, n0, SA, pt, 0) / abs_pt - CT_SA * eta_SA_CT return eta_SA_SA, eta_SA_CT, eta_CT_CT @match_args_return def enthalpy_first_derivatives(SA, CT, p): r"""Calculates the following three derivatives of specific enthalpy (h) (1) h_SA, the derivative with respect to Absolute Salinity at constant CT and p, and (2) h_CT, derivative with respect to CT at constant SA and p. (3) h_P, derivative with respect to pressure (in Pa) at constant SA and CT. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (TEOS-10)] p : array_like pressure [dbar] Returns ------- h_SA : array_like The first derivative of specific enthalpy with respect to Absolute Salinity at constant CT and p. [J/(kg (g/kg))] i.e. [J/g] h_CT : array_like The first derivative of specific enthalpy with respect to CT at constant SA and p. [J/(kg K)] h_P : array_like The first partial derivative of specific enthalpy with respect to pressure (in Pa) at fixed SA and CT. Note that h_P is specific volume (1/rho.) See Also -------- TODO Notes ----- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (A.11.18), (A.11.15) and (A.11.12.) Modifications: 2010-09-24. Trevor McDougall. """ # FIXME: The gsw 3.0 has the gibbs derivatives "copy-and-pasted" here # instead of the calls to the library! Why? pt0 = pt_from_CT(SA, CT) t = pt_from_t(SA, pt0, 0, p) temp_ratio = (Kelvin + t) / (Kelvin + pt0) def enthalpy_derivative_SA(SA, CT, p): return (gibbs(n1, n0, n0, SA, t, p) - temp_ratio * gibbs(n1, n0, n0, SA, pt0, 0)) def enthalpy_derivative_CT(SA, CT, p): return cp0 * temp_ratio def enthalpy_derivative_p(SA, CT, p): return gibbs(n0, n0, n1, SA, t, p) return (enthalpy_derivative_SA(SA, CT, p), enthalpy_derivative_CT(SA, CT, p), enthalpy_derivative_p(SA, CT, p),) @match_args_return def enthalpy_second_derivatives(SA, CT, p): r"""Calculates the following three second-order derivatives of specific enthalpy (h), (1) h_SA_SA, second-order derivative with respect to Absolute Salinity at constant CT & p. (2) h_SA_CT, second-order derivative with respect to SA & CT at constant p. (3) h_CT_CT, second-order derivative with respect to CT at constant SA and p. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (TEOS-10)] p : array_like pressure [dbar] Returns ------- h_SA_SA : array_like The second derivative of specific enthalpy with respect to Absolute Salinity at constant CT & p. [J/(kg (g/kg)^2)] h_SA_CT : array_like The second derivative of specific enthalpy with respect to SA and CT at constant p. [J/(kg K(g/kg))] h_CT_CT : array_like The second derivative of specific enthalpy with respect to CT at constant SA and p. [J/(kg K^2)] References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (A.11.18), (A.11.15) and (A.11.12.) .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. To be submitted to Ocean Science Discussions. Modifications: 2011-03-29. Trevor McDougall. """ # NOTE: The Matlab version 3.0 mentions that this function is unchanged, # but that's not true! pt0 = pt_from_CT(SA, CT) abs_pt0 = Kelvin + pt0 t = pt_from_t(SA, pt0, 0, p) temp_ratio = (Kelvin + t) / abs_pt0 rec_gTT_pt0 = 1 / gibbs(n0, n2, n0, SA, pt0, 0) rec_gTT_t = 1 / gibbs(n0, n2, n0, SA, t, p) gST_pt0 = gibbs(n1, n1, n0, SA, pt0, 0) gST_t = gibbs(n1, n1, n0, SA, t, p) gS_pt0 = gibbs(n1, n0, n0, SA, pt0, 0) part = ((temp_ratio * gST_pt0 * rec_gTT_pt0 - gST_t * rec_gTT_t) / (abs_pt0)) factor = gS_pt0 / cp0 # h_CT_CT is naturally well-behaved as SA approaches zero. def enthalpy_derivative_CT_CT(SA, CT, p): return (cp0 ** 2 * ((temp_ratio * rec_gTT_pt0 - rec_gTT_t) / (abs_pt0 * abs_pt0))) # h_SA_SA has a singularity at SA = 0, and blows up as SA approaches zero. def enthalpy_derivative_SA_SA(SA, CT, p): SA[SA < 1e-100] = 1e-100 # NOTE: Here is the changes from 2.0 to 3.0. h_CT_CT = enthalpy_derivative_CT_CT(SA, CT, p) return (gibbs(n2, n0, n0, SA, t, p) - temp_ratio * gibbs(n2, n0, n0, SA, pt0, 0) + temp_ratio * gST_pt0 ** 2 * rec_gTT_pt0 - gST_t ** 2 * rec_gTT_t - 2.0 * gS_pt0 * part + factor ** 2 * h_CT_CT) """h_SA_CT should not blow up as SA approaches zero. The following lines of code ensure that the h_SA_CT output of this function does not blow up in this limit. That is, when SA < 1e-100 g/kg, we force the h_SA_CT output to be the same as if SA = 1e-100 g/kg.""" def enthalpy_derivative_SA_CT(SA, CT, p): h_CT_CT = enthalpy_derivative_CT_CT(SA, CT, p) return cp0 * part - factor * h_CT_CT return (enthalpy_derivative_SA_SA(SA, CT, p), enthalpy_derivative_SA_CT(SA, CT, p), enthalpy_derivative_CT_CT(SA, CT, p)) if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/gsw/gibbs/density_enthalpy_ct_exact.py0000644000175000017500000006201612172027023023144 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from library import match_args_return from constants import cp0 from conversions import t_from_CT, pt_from_CT from absolute_salinity_sstar_ct import CT_from_t from basic_thermodynamic_t import rho_t_exact, alpha_wrt_CT_t_exact from basic_thermodynamic_t import beta_const_CT_t_exact, specvol_t_exact from basic_thermodynamic_t import specvol_anom_t_exact, sound_speed_t_exact from basic_thermodynamic_t import t_maxdensity_exact, enthalpy_t_exact from basic_thermodynamic_t import internal_energy_t_exact, sigma0_pt0_exact from basic_thermodynamic_t import t_from_rho_exact __all__ = [ 'rho_CT_exact', 'alpha_CT_exact', 'beta_CT_exact', 'rho_alpha_beta_CT_exact', 'specvol_CT_exact', 'specvol_anom_CT_exact', 'sigma0_CT_exact', 'sigma1_CT_exact', 'sigma2_CT_exact', 'sigma3_CT_exact', 'sigma4_CT_exact', 'sound_speed_CT_exact', 'internal_energy_CT_exact', 'enthalpy_CT_exact', 'enthalpy_diff_CT_exact', 'dynamic_enthalpy_CT_exact', 'SA_from_rho_CT_exact', 'CT_from_rho_exact', 'CT_maxdensity_exact' ] def rho_CT_exact(SA, CT, p): r"""Calculates in-situ density from Absolute Salinity and Conservative Temperature. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- rho_CT_exact : array_like in-situ density [kg/m**3] See Also -------- TODO Notes ----- The potential density with respect to reference pressure, p_ref, is obtained by calling this function with the pressure argument being p_ref (i.e. "rho_CT_exact(SA, CT, p_ref)"). This function uses the full Gibbs function. There is an alternative to calling this function, namely rho_CT(SA, CT, p), which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.8.2). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-03. Trevor McDougall and Paul Barker. """ t = t_from_CT(SA, CT, p) return rho_t_exact(SA, t, p) def alpha_CT_exact(SA, CT, p): r"""Calculates the thermal expansion coefficient of seawater with respect to Conservative Temperature from Absolute Salinity and Conservative Temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- alpha_CT_exact : array_like thermal expansion coefficient [K :sup:`-1`] with respect to Conservative Temperature See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely alpha_wrt_CT(SA, CT, p) which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., (2011)). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.18.3). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-23. David Jackett, Trevor McDougall and Paul Barker. """ t = t_from_CT(SA, CT, p) return alpha_wrt_CT_t_exact(SA, t, p) def beta_CT_exact(SA, CT, p): r"""Calculates the saline (i.e. haline) contraction coefficient of seawater at constant Conservative Temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- beta_CT_exact : array_like thermal expansion coefficient [K :sup:`-1`] See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely beta_const_CT(SA, CT, p) which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., (2011)). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.19.3). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-23. Trevor McDougall and Paul Barker. """ t = t_from_CT(SA, CT, p) return beta_const_CT_t_exact(SA, t, p) def rho_alpha_beta_CT_exact(SA, CT, p): r"""Calculates in-situ density, the appropriate thermal expansion coefficient and the appropriate saline contraction coefficient of seawater from Absolute Salinity and Conservative Temperature. See the individual functions rho_CT_exact, alpha_CT_exact, and beta_CT_exact. Retained for compatibility with the Matlab GSW toolbox. """ t = t_from_CT(SA, CT, p) rho_CT_exact = rho_t_exact(SA, t, p) alpha_CT_exact = alpha_wrt_CT_t_exact(SA, t, p) beta_CT_exact = beta_const_CT_t_exact(SA, t, p) return rho_CT_exact, alpha_CT_exact, beta_CT_exact def specvol_CT_exact(SA, CT, p): r"""Calculates specific volume from Absolute Salinity, Conservative Temperature and pressure. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- specvol_CT_exact : array_like specific volume [m**3/kg] See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely specvol_CT(SA, CT, p), which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.7.2). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-06. Trevor McDougall and Paul Barker. """ t = t_from_CT(SA, CT, p) return specvol_t_exact(SA, t, p) def specvol_anom_CT_exact(SA, CT, p): r"""Calculates specific volume anomaly from Absolute Salinity, Conservative Temperature and pressure. The reference value of Absolute Salinity is SSO and the reference value of Conservative Temperature is equal to 0 deg C. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- specvol_anom_CT_exact : array_like specific volume anomaly [m**3/kg] See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely specvol_anom_CT(SA, CT, p), which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (3.7.3). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-06. Trevor McDougall and Paul Barker. """ t = t_from_CT(SA, CT, p) return specvol_anom_t_exact(SA, t, p) def sigma0_CT_exact(SA, CT): r"""Calculates potential density anomaly with reference pressure of 0 dbar, this being this particular potential density minus 1000 kg/m^3. This function has inputs of Absolute Salinity and Conservative Temperature. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- sigma0_CT_exact: array_like Potential density anomaly with [kg/m**3] respect to a reference pressure of 0 dbar that is, this potential density - 1000 kg/m**3. Notes ----- Note that this function uses the full Gibbs function. There is an alternative to calling this function, namely gsw_sigma0_CT(SA,CT,p), which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (A.30.1). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-03. Trevor McDougall and Paul Barker. """ pt0 = pt_from_CT(SA, CT) return sigma0_pt0_exact(SA, pt0) def sigma1_CT_exact(SA, CT): r"""Calculates potential density anomaly with reference pressure of 1000 dbar.""" t = t_from_CT(SA, CT, 1000.) return rho_t_exact(SA, t, 1000.) - 1000 def sigma2_CT_exact(SA, CT): r"""Calculates potential density anomaly with reference pressure of 2000 dbar.""" t = t_from_CT(SA, CT, 2000.) return rho_t_exact(SA, t, 2000.) - 1000 def sigma3_CT_exact(SA, CT): r"""Calculates potential density anomaly with reference pressure of 3000 dbar.""" t = t_from_CT(SA, CT, 3000.) return rho_t_exact(SA, t, 3000.) - 1000 def sigma4_CT_exact(SA, CT): r"""Calculates potential density anomaly with reference pressure of 4000 dbar.""" t = t_from_CT(SA, CT, 4000.) return rho_t_exact(SA, t, 4000.) - 1000 def sound_speed_CT_exact(SA, CT, p): r"""Calculates the speed of sound in seawater from Absolute Salinity and Conservative Temperature and pressure. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- sound_speed_CT_exact : array_like Speed of sound in seawater [m s :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.17.1). Modifications: 2011-04-05. David Jackett, Paul Barker and Trevor McDougall. """ t = t_from_CT(SA, CT, p) return sound_speed_t_exact(SA, t, p) def internal_energy_CT_exact(SA, CT, p): r"""Calculates the specific internal energy of seawater from Absolute Salinity, Conservative Temperature and pressure. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- internal_energy_CT_exact: array_like specific internal energy (u) [J/kg] See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.11.1). Modifications: 2011-04-05. Trevor McDougall. """ t = t_from_CT(SA, CT, p) return internal_energy_t_exact(SA, t, p) def enthalpy_CT_exact(SA, CT, p): r"""Calculates specific enthalpy of seawater from Absolute Salinity and Conservative Temperature and pressure. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- enthalpy_CT_exact : array_like specific enthalpy [J/kg] See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely enthalpy_CT(SA, CT, p), which uses the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.11. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-06. Trevor McDougall and Paul Barker. """ t = t_from_CT(SA, CT, p) return enthalpy_t_exact(SA, t, p) def enthalpy_diff_CT_exact(SA, CT, p_shallow, p_deep): r"""Calculates the difference of the specific enthalpy of seawater between two different pressures, p_deep (the deeper pressure) and p_shallow (the shallower pressure), at the same values of SA and CT. The output (enthalpy_diff_CT_exact) is the specific enthalpy evaluated at (SA, CT, p_deep) minus the specific enthalpy at (SA,CT,p_shallow). parameters ---------- Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p_shallow : array_like lower sea pressure [dbar] p_deep : array-like upper sea pressure [dbar] returns ------- enthalpy_diff_CT_exact : array_like difference of specific enthalpy [J/kg] (deep minus shallow) See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely enthalpy_diff_CT(SA, CT, p), which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns (3.32.2). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-06. Trevor McDougall and Paul Barker. """ t_shallow = t_from_CT(SA, CT, p_shallow) t_deep = t_from_CT(SA, CT, p_deep) return (enthalpy_t_exact(SA, t_deep, p_deep) - enthalpy_t_exact(SA, t_shallow, p_shallow)) def dynamic_enthalpy_CT_exact(SA, CT, p): r"""Calculates the dynamic enthalpy of seawater from Absolute Salinity and Conservative Temperature and pressure. Dynamic enthalpy is defined as enthalpy minus potential enthalpy (Young, 2010). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- dynamic_enthalpy_CT_exact : array_like dynamic enthalpy [J/kg] See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely dynamic_enthalpy(SA, CT, p), which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See apendix A.30. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. .. [3] Young, W.R., 2010: Dynamic enthalpy, Conservative Temperature, and the seawater Boussinesq approximation. Journal of Physical Oceanography, 40, 394-400. Modifications: 2011-04-05. Trevor McDougall and Paul Barker. """ t = t_from_CT(SA, CT, p) return enthalpy_t_exact(SA, t, p) - cp0 * CT @match_args_return def SA_from_rho_CT_exact(rho, CT, p): r"""Calculates the Absolute Salinity of a seawater sample, for given values of its density, Conservative Temperature and sea pressure (in dbar). Parameters ---------- rho : array_like density of a seawater sample [kg/m**3] This input has not had 1000 kg/m^3 subtracted from it (e.g. 1026 kg m**-3), that is, it is density, NOT density anomaly. CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- SA : array_like Absolute Salinity [g/kg] See Also -------- TODO Notes ----- This function uses the full Gibbs function. There is an alternative to calling this function, namely SA_from_rho_CT(rho, CT, p), which uses the computationally efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.5. .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. Modifications: 2011-04-05. Trevor McDougall and Paul Barker. """ v_lab = 1. / rho v_0 = specvol_CT_exact(np.zeros_like(rho), CT, p) v_120 = specvol_CT_exact(120 * np.ones_like(rho), CT, p) SA = 120 * (v_lab - v_0) / (v_120 - v_0) # Initial estimate of SA. SA[np.logical_or(SA < 0, SA > 120)] = np.NaN v_SA = (v_120 - v_0) / 120 # Initial v_SA estimate (SA derivative of v). # Begin the modified Newton-Raphson iterative procedure. for Number_of_iterations in range(0, 3): SA_old = SA delta_v = specvol_CT_exact(SA_old, CT, p) - v_lab # Half way the mod. N-R method (McDougall and Wotherspoon, 2012). SA = SA_old - delta_v / v_SA SA_mean = 0.5 * (SA + SA_old) rho, alpha, beta = rho_alpha_beta_CT_exact(SA_mean, CT, p) v_SA = -beta / rho SA = SA_old - delta_v / v_SA SA[np.logical_or(SA < 0, SA > 120)] = np.ma.masked """After two iterations of this modified Newton-Raphson iteration, the error in SA is no larger than 8x10^-13 g kg^-1, which is machine precision for this calculation.""" return SA def CT_from_rho_exact(rho, SA, p): r"""Calculates the in-situ temperature of a seawater sample, for given values of its density, Absolute Salinity and sea pressure (in dbar). Parameters ---------- rho : array_like density of a seawater sample [kg/m**3] This input has not had 1000 kg/m^3 subtracted from it (e.g. 1026 kg m**-3), that is, it is density, NOT density anomaly. SA : array_like Absolute Salinity [g/kg] p : array_like sea pressure [dbar] Returns ------- CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] CT_multiple : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- At low salinities, in brackish water, there are two possible temperatures for a single density. This program will output both valid solutions (t, t_multiple), if there is only one possible solution the second variable will be set to NaN. Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.5. Modifications: 2011-04-21. Trevor McDougall and Paul Barker. """ t, t_multiple = t_from_rho_exact(rho, SA, p) return CT_from_t(SA, t, p), CT_from_t(SA, t_multiple, p) def CT_maxdensity_exact(SA, p): r"""Calculates the Conservative Temperature of maximum density of seawater. This function returns the Conservative temperature at which the density of seawater is a maximum, at given Absolute Salinity, SA, and sea pressure, p (in dbar). Parameters ---------- SA : array_like Absolute Salinity [g/kg] p : array_like sea pressure [dbar] Returns ------- CT_maxdensity_exact : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] at which the density of seawater is a maximum for given SA and p. See Also -------- TODO Notes ----- TODO Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.42. Modifications: 2011-04-03. Trevor McDougall and Paul Barker. """ t_max_exact = t_maxdensity_exact(SA, p) return CT_from_t(SA, t_max_exact, p) if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/gsw/gibbs/earth.py0000644000175000017500000001334312172027023017011 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from constants import gamma, earth_radius, OMEGA from gsw.utilities import match_args_return from conversions import z_from_p __all__ = ['f', 'grav', 'distance'] DEG2RAD = np.pi / 180 def f(lat): r"""Calculates the Coriolis parameter (f) defined by: f = 2*omega*sin(lat) where, omega = 7.292115e-5 (Groten, 2004) [radians s :sup:`-1`] Parameters ---------- lat : array_like latitude [degrees north] Returns ------- f : array_like Coriolis paramter [s :sup:`-1`] References ---------- .. [1] Groten, E., 2004: Fundamental Parameters and Current (2004) Best Estimates of the Parameters of Common Relevance to Astronomy, Geodesy, and Geodynamics. Journal of Geodesy, 77, pp. 724-797. .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 1993-04-20. Phil Morgan 2010-07-28. Paul Barker """ lat = np.asanyarray(lat) return 2 * OMEGA * np.sin(lat * DEG2RAD) @match_args_return def grav(lat, p=0): r"""Calculates acceleration due to gravity as a function of latitude and as a function of pressure in the ocean. Parameters ---------- lat : array_like latitude in decimal degrees north [-90...+90] p : number or array_like. Default p = 0 pressure [dbar] Returns ------- g : array_like gravity [m s :sup:`2`] See Also -------- TODO Notes ----- In the ocean z is negative. Examples -------- >>> import gsw >>> lat = [-90, -60, -30, 0] >>> p = 0 >>> gsw.grav(lat, p) array([ 9.83218621, 9.81917886, 9.79324926, 9.780327 ]) >>> gsw.grav(45) 9.8061998770458008 References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [2] Moritz (2000) Goedetic reference system 1980. J. Geodesy, 74, 128-133. .. [3] Saunders, P.M., and N.P. Fofonoff (1976) Conversion of pressure to depth in the ocean. Deep-Sea Res.,pp. 109 - 111. Modifications: 2011-03-29. Trevor McDougall & Paul Barker """ X = np.sin(lat * DEG2RAD) sin2 = X ** 2 gs = 9.780327 * (1.0 + (5.2792e-3 + (2.32e-5 * sin2)) * sin2) z = z_from_p(p, lat) # z is the height corresponding to p. grav = gs * (1 - gamma * z) return grav @match_args_return def distance(lon, lat, p=0): r"""Calculates the distance in met res between successive points in the vectors lon and lat, computed using the Haversine formula on a spherical earth of radius 6,371 km, being the radius of a sphere having the same volume as Earth. For a spherical Earth of radius 6,371,000 m, one nautical mile is 1,853.2488 m, thus one degree of latitude is 111,194.93 m. Haversine formula: R = earth's radius (mean radius = 6,371 km) .. math:: a = \sin^2(\delta \text{lat}/2) + \cos(\text{lat}_1) \cos(\text{lat}_2) \sin^2(\delta \text{lon}/2) c = 2 \times \text{atan2}(\sqrt{a}, \sqrt{(1-a)}) d = R \times c Parameters ---------- lon : array_like decimal degrees east [0..+360] or [-180 ... +180] lat : array_like latitude in decimal degrees north [-90..+90] p : number or array_like. Default p = 0 pressure [dbar] Returns ------- dist: array_like distance between points on a spherical Earth at pressure (p) [m] See Also -------- TODO Notes ----- z is height and is negative in the oceanographic. Distances are probably good to better than 1\% of the "true" distance on the ellipsoidal earth. Examples -------- >>> import gsw >>> lon = [159, 220] >>> lat = [-35, 35] >>> gsw.distance(lon, lat) array([[ 10030974.652916]]) >>> p = [200, 1000] >>> gsw.distance(lon, lat, p) array([[ 10030661.63878009]]) >>> p = [[200], [1000]] >>> gsw.distance(lon, lat, p) array([[ 10030661.63878009], [ 10029412.58776001]]) References ---------- .. [1] http://www.eos.ubc.ca/~rich/map.html Modifications: 2000-11-06. Rich Pawlowicz 2011-04-04. Paul Barker and Trevor McDougall """ # FIXME? The argument handling seems much too complicated. # Maybe we can come up with some simple specifications of # what argument combinations are permitted, and handle everything # with broadcasting. - EF # FIXME: Eric what do you think? This assume p(stations, depth) lon, lat, = np.atleast_2d(lon), np.atleast_2d(lat) if (lon.size == 1) & (lat.size == 1): raise ValueError('more than one point is needed to compute distance') elif lon.ndim != lat.ndim: raise ValueError('lon, lat must have the same dimension') lon, lat, p = np.broadcast_arrays(lon, lat, p) dlon = np.diff(lon * DEG2RAD) dlat = np.diff(lat * DEG2RAD) a = ((np.sin(dlat / 2)) ** 2 + np.cos(lat[:, :-1] * DEG2RAD) * np.cos(lat[:, 1:] * DEG2RAD) * (np.sin(dlon / 2)) ** 2) angles = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a)) p_mid = 0.5 * (p[:, 0:-1] + p[:, 0:-1]) lat_mid = 0.5 * (lat[:, :-1] + lat[:, 1:]) z = z_from_p(p_mid, lat_mid) distance = (earth_radius + z) * angles return distance if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/gsw/gibbs/geostrophic_48.py0000644000175000017500000000054012172027023020542 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np __all__ = [ #'geo_strf_dyn_height', TODO #'geo_strf_dyn_height_pc', TODO #'geo_strf_isopycnal', TODO #'geof_str_isopycnal_pc', TODO #'geo_strf_Montgomery', TODO #'geo_strf_Cunningham' TODO ] gsw-3.0.2/gsw/gibbs/density_enthalpy_48_ct.py0000644000175000017500000000135012172027023022265 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np __all__ = [ #'rho_CT', TODO #'alpha_CT', TODO #'beta_CT', TODO #'rho_alpha_beta_CT', TODO #'specvol_CT', TODO #'specvol_anom_CT', TODO #'sigma0_CT', TODO #'sigma1_CT', TODO #'sigma2_CT', TODO #'sigma3_CT', TODO #'sigma4_CT', TODO #'sound_speed_CT', TODO #'internal_energy_CT', TODO #'enthalpy_CT', TODO #'enthalpy_diff_CT', TODO #'dynamic_enthalpy_CT', TODO #'SA_from_rho_CT', TODO #'CT_from_rho', TODO #'CT_maxdensity', TODO ] gsw-3.0.2/gsw/gibbs/neutral_nonlinear_48.py0000644000175000017500000000045012172027023021733 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np __all__ = [ #'cabbeling', TODO #'thermobaric', TODO #'isopycnal_slope_ratio', TODO #'isopycnal_vs_ntp_CT_ratio', TODO #'ntp_pt_vs_CT_ratio' TODO ] gsw-3.0.2/gsw/gibbs/density_enthalpy_48.py0000644000175000017500000012346212172027023021610 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from library import specvol_SSO_0_p from constants import P0, db2Pascal, cp0 from gsw.utilities import match_args_return __all__ = [ 'rho', 'alpha', 'beta', 'rho_alpha_beta', 'specvol', 'specvol_anom', 'sigma0', 'sigma1', 'sigma2', 'sigma3', 'sigma4', 'sound_speed', 'internal_energy', 'enthalpy', 'enthalpy_diff', 'dynamic_enthalpy', 'SA_from_rho' ] # NOTE: 48-term equation? v01 = 9.998420897506056e+2 v02 = 2.839940833161907 v03 = -3.147759265588511e-2 v04 = 1.181805545074306e-3 v05 = -6.698001071123802 v06 = -2.986498947203215e-2 v07 = 2.327859407479162e-4 v08 = -3.988822378968490e-2 v09 = 5.095422573880500e-4 v10 = -1.426984671633621e-5 v11 = 1.645039373682922e-7 v12 = -2.233269627352527e-2 v13 = -3.436090079851880e-4 v14 = 3.726050720345733e-6 v15 = -1.806789763745328e-4 v16 = 6.876837219536232e-7 v17 = -3.087032500374211e-7 v18 = -1.988366587925593e-8 v19 = -1.061519070296458e-11 v20 = 1.550932729220080e-10 v21 = 1.0 v22 = 2.775927747785646e-3 v23 = -2.349607444135925e-5 v24 = 1.119513357486743e-6 v25 = 6.743689325042773e-10 v26 = -7.521448093615448e-3 v27 = -2.764306979894411e-5 v28 = 1.262937315098546e-7 v29 = 9.527875081696435e-10 v30 = -1.811147201949891e-11 v31 = -3.303308871386421e-5 v32 = 3.801564588876298e-7 v33 = -7.672876869259043e-9 v34 = -4.634182341116144e-11 v35 = 2.681097235569143e-12 v36 = 5.419326551148740e-6 v37 = -2.742185394906099e-5 v38 = -3.212746477974189e-7 v39 = 3.191413910561627e-9 v40 = -1.931012931541776e-12 v41 = -1.105097577149576e-7 v42 = 6.211426728363857e-10 v43 = -1.119011592875110e-10 v44 = -1.941660213148725e-11 v45 = -1.864826425365600e-14 v46 = 1.119522344879478e-14 v47 = -1.200507748551599e-15 v48 = 6.057902487546866e-17 a01 = 2.839940833161907 a02 = -6.295518531177023e-2 a03 = 3.545416635222918e-3 a04 = -2.986498947203215e-2 a05 = 4.655718814958324e-4 a06 = 5.095422573880500e-4 a07 = -2.853969343267241e-5 a08 = 4.935118121048767e-7 a09 = -3.436090079851880e-4 a10 = 7.452101440691467e-6 a11 = 6.876837219536232e-7 a12 = -1.988366587925593e-8 a13 = -2.123038140592916e-11 a14 = 2.775927747785646e-3 a15 = -4.699214888271850e-5 a16 = 3.358540072460230e-6 a17 = 2.697475730017109e-9 a18 = -2.764306979894411e-5 a19 = 2.525874630197091e-7 a20 = 2.858362524508931e-9 a21 = -7.244588807799565e-11 a22 = 3.801564588876298e-7 a23 = -1.534575373851809e-8 a24 = -1.390254702334843e-10 a25 = 1.072438894227657e-11 a26 = -3.212746477974189e-7 a27 = 6.382827821123254e-9 a28 = -5.793038794625329e-12 a29 = 6.211426728363857e-10 a30 = -1.941660213148725e-11 a31 = -3.729652850731201e-14 a32 = 1.119522344879478e-14 a33 = 6.057902487546866e-17 b01 = -6.698001071123802 b02 = -2.986498947203215e-2 b03 = 2.327859407479162e-4 b04 = -5.983233568452735e-2 b05 = 7.643133860820750e-4 b06 = -2.140477007450431e-5 b07 = 2.467559060524383e-7 b08 = -1.806789763745328e-4 b09 = 6.876837219536232e-7 b10 = 1.550932729220080e-10 b11 = -7.521448093615448e-3 b12 = -2.764306979894411e-5 b13 = 1.262937315098546e-7 b14 = 9.527875081696435e-10 b15 = -1.811147201949891e-11 b16 = -4.954963307079632e-5 b17 = 5.702346883314446e-7 b18 = -1.150931530388857e-8 b19 = -6.951273511674217e-11 b20 = 4.021645853353715e-12 b21 = 1.083865310229748e-5 b22 = -1.105097577149576e-7 b23 = 6.211426728363857e-10 b24 = 1.119522344879478e-14 c01 = -2.233269627352527e-2 c02 = -3.436090079851880e-4 c03 = 3.726050720345733e-6 c04 = -1.806789763745328e-4 c05 = 6.876837219536232e-7 c06 = -6.174065000748422e-7 c07 = -3.976733175851186e-8 c08 = -2.123038140592916e-11 c09 = 3.101865458440160e-10 c10 = -2.742185394906099e-5 c11 = -3.212746477974189e-7 c12 = 3.191413910561627e-9 c13 = -1.931012931541776e-12 c14 = -1.105097577149576e-7 c15 = 6.211426728363857e-10 c16 = -2.238023185750219e-10 c17 = -3.883320426297450e-11 c18 = -3.729652850731201e-14 c19 = 2.239044689758956e-14 c20 = -3.601523245654798e-15 c21 = 1.817370746264060e-16 def v_hat_denominator(SA, CT, p): return (v01 + CT * (v02 + CT * (v03 + v04 * CT)) + SA * (v05 + CT * (v06 + v07 * CT) + np.sqrt(SA) * (v08 + CT * (v09 + CT * (v10 + v11 * CT)))) + p * (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT) + p * (v17 + CT * (v18 + v19 * CT) + v20 * SA))) def v_hat_numerator(SA, CT, p): return (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) + SA * (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) + v36 * SA + np.sqrt(SA) * (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT))))) + p * (v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA * (v41 + v42 * CT) + p * (v43 + CT * (v44 + v45 * CT + v46 * SA) + p * (v47 + v48 * CT)))) @match_args_return def rho(SA, CT, p): r"""Calculates in-situ density from Absolute Salinity and Conservative Temperature, using the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- rho : array_like in-situ density [kg/m**3] See Also -------- TODO Notes ----- The potential density with respect to reference pressure, pr, is obtained by calling this function with the pressure argument being pr (i.e. "rho(SA,CT,pr)"). The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA,CT,p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.20 and appendix K. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-18. Paul Barker and Trevor McDougall. """ SA = np.maximum(SA, 0) """This function calculates rho using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute rho from SA, CT, and p with the full TEOS-10 Gibbs function, the following lines of code will enable this. pt0 = pt_from_CT(SA, CT) t = pt_from_t(SA, pt0, 0, p) rho = rho_t_exact(SA, t, p) or call the following, it is identical to the lines above. rho = rho_CT_exact(SA, CT, p) or call the following, it is identical to the lines above. rho,_ ,_ = rho_alpha_beta_CT_exact(SA, CT, p) """ return v_hat_denominator(SA, CT, p) / v_hat_numerator(SA, CT, p) @match_args_return def alpha(SA, CT, p): r"""Calculates the thermal expansion coefficient of seawater with respect to Conservative Temperature using the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011) Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- alpha : array_like thermal expansion coefficient [K :math:`-1`] with respect to Conservative Temperature See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.18.3). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-23. Paul Barker and Trevor McDougall. """ SA = np.maximum(SA, 0) sqrtSA = np.sqrt(SA) spec_vol = v_hat_numerator(SA, CT, p) / v_hat_denominator(SA, CT, p) dvhatden_dCT = (a01 + CT * (a02 + a03 * CT) + SA * (a04 + a05 * CT + sqrtSA * (a06 + CT * (a07 + a08 * CT))) + p * (a09 + a10 * CT + a11 * SA + p * (a12 + a13 * CT))) dvhatnum_dCT = (a14 + CT * (a15 + CT * (a16 + a17 * CT)) + SA * (a18 + CT * (a19 + CT * (a20 + a21 * CT)) + sqrtSA * (a22 + CT * (a23 + CT * (a24 + a25 * CT)))) + p * (a26 + CT * (a27 + a28 * CT) + a29 * SA + p * (a30 + a31 * CT + a32 * SA + a33 * p))) return ((dvhatnum_dCT - dvhatden_dCT * spec_vol) / v_hat_numerator(SA, CT, p)) @match_args_return def beta(SA, CT, p): r"""Calculates the saline (i.e. haline) contraction coefficient of seawater at constant Conservative Temperature using the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- beta : array_like saline contraction coefficient [kg g :math:`-1`] at constant Conservative Temperature. See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.19.3). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-23. Paul Barker and Trevor McDougall. """ SA = np.maximum(SA, 0) sqrtSA = np.sqrt(SA) spec_vol = v_hat_numerator(SA, CT, p) / v_hat_denominator(SA, CT, p) dvhatden_dSA = (b01 + CT * (b02 + b03 * CT) + sqrtSA * (b04 + CT * (b05 + CT * (b06 + b07 * CT))) + p * (b08 + b09 * CT + b10 * p)) dvhatnum_dSA = (b11 + CT * (b12 + CT * (b13 + CT * (b14 + b15 * CT))) + sqrtSA * (b16 + CT * (b17 + CT * (b18 + CT * (b19 + b20 * CT)))) + b21 * SA + p * (b22 + CT * (b23 + b24 * p))) return ((dvhatden_dSA * spec_vol - dvhatnum_dSA) / v_hat_numerator(SA, CT, p)) def rho_alpha_beta(SA, CT, p): r"""Calculates in-situ density, the appropriate thermal expansion coefficient and the appropriate saline contraction coefficient of seawater from Absolute Salinity and Conservative Temperature. This function uses the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). The potential density (pot_rho) with respect to reference pressure p_ref is obtained by calling this function with the pressure argument being p_ref as in pot_rho, _, _] = rho_alpha_beta(SA, CT, p_ref). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- rho : array_like in-situ density [kg/m**3] alpha : array_like thermal expansion coefficient [K :math:`-1`] with respect to Conservative Temperature beta : array_like saline contraction coefficient [kg g :math:`-1`] at constant Conservative Temperature. See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.20 and appendix K. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-03. Paul Barker and Trevor McDougall. """ return rho(SA, CT, p), alpha(SA, CT, p), beta(SA, CT, p) @match_args_return def specvol(SA, CT, p): r"""Calculates specific volume from Absolute Salinity, Conservative Temperature and pressure, using the computationally-efficient 48-term expression for density (McDougall et al., 2011). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- specvol : array_like specific volume [m**3/kg] See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA,CT,p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.7.2). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-18. Paul Barker and Trevor McDougall. """ SA = np.maximum(SA, 0) """This function calculates specvol using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute specvol from SA, CT, and p with the full TEOS-10 Gibbs function, the following lines of code will enable this. pt = pt_from_CT(SA, CT) t = pt_from_t(SA, pt, 0, p) specvol = specvol_t_exact(SA, t, p) or call the following, it is identical to the lines above. specvol = specvol_CT_exact(SA, CT, p) """ return v_hat_numerator(SA, CT, p) / v_hat_denominator(SA, CT, p) @match_args_return def specvol_anom(SA, CT, p): r"""Calculates specific volume anomaly from Absolute Salinity, Conservative Temperature and pressure. It uses the computationally-efficient 48-term expression for density as a function of SA, CT and p (McDougall et al., 2011). The reference value of Absolute Salinity is SSO and the reference value of Conservative Temperature is equal to 0 degrees C. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- specvol_anom : array_like specific volume anomaly [m**3/kg] See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA,CT,p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (3.7.3). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-24. Paul Barker and Trevor McDougall. """ SA = np.maximum(SA, 0) """This function calculates specvol_anom using the computationally- efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute specvol_anom from SA, CT, and p with the full TEOS-10 Gibbs function, the following lines of code will enable this. pt = pt_from_CT(SA, CT) t = pt_from_t(SA, pt, 0, p) specvol_anom = specvol_anom_t_exact(SA, t, p) or call the following, it is identical to the lines above. specvol_anom = specvol_anom_CT_exact(SA, CT, p) """ return (v_hat_numerator(SA, CT, p) / v_hat_denominator(SA, CT, p) - specvol_SSO_0_p(p)) def sigma0(SA, CT): r"""Calculates potential density anomaly with reference pressure of 0 dbar, this being this particular potential density minus 1000 kg/m^3. This function has inputs of Absolute Salinity and Conservative Temperature. This function uses the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- sigma0 : array_like potential density anomaly with [kg/m**3] respect to a reference pressure of 0 dbar See Also -------- gsw.rho """ """This function calculates sigma0 using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute sigma0 with the full TEOS-10 Gibbs function expression for density, the following lines of code will enable this. sigma0 = rho_CT_exact(SA, CT, 0) - 1000 """ return rho(SA, CT, 0.) - 1000 def sigma1(SA, CT): r"""Calculates potential density anomaly with reference pressure of 1000 dbar, this being this particular potential density minus 1000 kg/m^3. This function has inputs of Absolute Salinity and Conservative Temperature. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- sigma1 : array_like potential density anomaly with [kg/m**3] respect to a reference pressure of 1000 dbar See Also -------- gsw.rho """ """This function calculates sigma1 using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute sigma1 with the full TEOS-10 Gibbs function expression for density, the following lines of code will enable this. rho1 = rho_CT_exact(SA, CT, 1000) """ return rho(SA, CT, 1000.) - 1000 def sigma2(SA, CT): r"""Calculates potential density anomaly with reference pressure of 2000 dbar, this being this particular potential density minus 1000 kg/m^3. This function has inputs of Absolute Salinity and Conservative Temperature. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- sigma2 : array_like potential density anomaly with [kg/m**3] respect to a reference pressure of 2000 dbar See Also -------- gsw.rho """ """This function calculates sigma2 using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute sigma2 with the full TEOS-10 Gibbs function expression for density, the following lines of code will enable this. rho2 = rho_CT_exact(SA, CT, 2000.) """ return rho(SA, CT, 2000.) - 1000 def sigma3(SA, CT): r"""Calculates potential density anomaly with reference pressure of 3000 dbar, this being this particular potential density minus 1000 kg/m^3. This function has inputs of Absolute Salinity and Conservative Temperature. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- sigma1 : array_like potential density anomaly with [kg/m**3] respect to a reference pressure of 3000 dbar See Also -------- gsw.rho """ """This function calculates sigma3 using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute sigma3 with the full TEOS-10 Gibbs function expression for density, the following lines of code will enable this. rho3 = rho_CT_exact(SA, CT, 3000.) """ return rho(SA, CT, 3000.) - 1000 def sigma4(SA, CT): r"""Calculates potential density anomaly with reference pressure of 4000 dbar, this being this particular potential density minus 1000 kg/m^3. This function has inputs of Absolute Salinity and Conservative Temperature. Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] Returns ------- sigma1 : array_like potential density anomaly with [kg/m**3] respect to a reference pressure of 4000 dbar See Also -------- gsw.rho """ """This function calculates sigma3 using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute sigma3 with the full TEOS-10 Gibbs function expression for density, the following lines of code will enable this. rho4 = rho_CT_exact(SA, CT, 4000.) """ return rho(SA, CT, 4000.) - 1000 @match_args_return def sound_speed(SA, CT, p): r"""Calculates the speed of sound in seawater. This function has inputs of Absolute Salinity and Conservative Temperature. This function uses the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- sound_speed : array_like speed of sound in seawater [m/s] See Also -------- TODO Notes ----- Approximate with a r.m.s. of 6.7 cm s^-1. The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.17.1). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-23. Paul Barker and Trevor McDougall. """ SA = np.maximum(SA, 0) dvden_dp = (c01 + CT * (c02 + c03 * CT) + SA * (c04 + c05 * CT) + p * (c06 + CT * (c07 + c08 * CT) + c09 * SA)) dvnum_dp = (c10 + CT * (c11 + CT * (c12 + c13 * CT)) + SA * (c14 + c15 * CT) + p * (c16 + CT * (c17 + c18 * CT + c19 * SA) + p * (c20 + c21 * CT))) drho_dp = ((dvden_dp * v_hat_numerator(SA, CT, p) - dvnum_dp * v_hat_denominator(SA, CT, p)) / (v_hat_numerator(SA, CT, p) * v_hat_numerator(SA, CT, p))) return 100 * np.sqrt(1. / drho_dp) @match_args_return def internal_energy(SA, CT, p): r"""Calculates specific internal energy of seawater using the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- internal_energy : array_like specific internal energy [J/kg] See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-04. Trevor McDougall and Paul Barker. """ SA = np.maximum(SA, 0) """This function calculates enthalpy using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute enthalpy from SA, CT, and p with the full TEOS-10 Gibbs function, the following line of code will enable this. internal_energy = internal_energy_CT_exact(SA, CT, p) """ return (enthalpy(SA, CT, p) - (P0 + db2Pascal * p) * specvol(SA, CT, p)) @match_args_return def enthalpy(SA, CT, p): r"""Calculates specific enthalpy of seawater using the computationally- efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011) Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- enthalpy : array_like specific enthalpy [J/kg] See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (A.30.6). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-04-05. Trevor McDougall, David Jackett, Claire Roberts-Thomson and Paul Barker. """ SA = np.maximum(SA, 0) sqrtSA = np.sqrt(SA) a0 = (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) + SA * (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) + v36 * SA + sqrtSA * (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT)))))) a1 = v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA * (v41 + v42 * CT) a2 = v43 + CT * (v44 + v45 * CT + v46 * SA) a3 = v47 + v48 * CT b0 = (v01 + CT * (v02 + CT * (v03 + v04 * CT)) + SA * (v05 + CT * (v06 + v07 * CT) + sqrtSA * (v08 + CT * (v09 + CT * (v10 + v11 * CT))))) b1 = 0.5 * (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT)) b2 = v17 + CT * (v18 + v19 * CT) + v20 * SA b1sq = b1 * b1 sqrt_disc = np.sqrt(b1sq - b0 * b2) N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2 M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2 A = b1 - sqrt_disc B = b1 + sqrt_disc part = (N * b2 - M * b1) / (b2 * (B - A)) """This function calculates enthalpy using the computationally-efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute enthalpy from SA, CT, and p with the full TEOS-10 Gibbs function, the following lines of code will enable this. pt = pt_from_CT(SA, CT) t = pt_from_t(SA, pt, 0, p) enthalpy = enthalpy_t_exact(SA, t, p) or call the following, it is identical to the lines above. enthalpy = enthalpy_CT_exact(SA, CT, p) """ return (cp0 * CT + db2Pascal * (p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p) / b2 + (M / (2 * b2)) * np.log(1 + p * (2 * b1 + b2 * p) / b0) + part * np.log(1 + (b2 * p * (B - A)) / (A * (B + b2 * p))))) @match_args_return def enthalpy_diff(SA, CT, p_shallow, p_deep): r"""Calculates the difference of the specific enthalpy of seawater between two different pressures, p_deep (the deeper pressure) and p_shallow (the shallower pressure), at the same values of SA and CT. This function uses the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). The output (enthalpy_diff_CT) is the specific enthalpy evaluated at (SA, CT, p_deep) minus the specific enthalpy at (SA, CT, p_shallow). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p_shallow : array_like lower sea pressure [dbar] p_deep : array-like upper sea pressure [dbar] Returns ------- enthalpy_diff : array_like difference of specific enthalpy [J/kg] (deep minus shallow) See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (3.32.2) and (A.30.6). .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. Modifications: 2011-03-21. Trevor McDougall & Paul Barker. """ SA = np.maximum(SA, 0) sqrtSA = np.sqrt(SA) a0 = (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) + SA * (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) + v36 * SA + sqrtSA * (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT)))))) a1 = v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA * (v41 + v42 * CT) a2 = v43 + CT * (v44 + v45 * CT + v46 * SA) a3 = v47 + v48 * CT b0 = (v01 + CT * (v02 + CT * (v03 + v04 * CT)) + SA * (v05 + CT * (v06 + v07 * CT) + sqrtSA * (v08 + CT * (v09 + CT * (v10 + v11 * CT))))) b1 = 0.5 * (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT)) b2 = v17 + CT * (v18 + v19 * CT) + v20 * SA b1sq = b1 * b1 sqrt_disc = np.sqrt(b1sq - b0 * b2) N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2 M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2 A = b1 - sqrt_disc B = b1 + sqrt_disc delta_p = p_deep - p_shallow p_sum = p_deep + p_shallow part1 = b0 + p_shallow * (2 * b1 + b2 * p_shallow) part2 = (B + b2 * p_deep) * (A + b2 * p_shallow) part3 = (N * b2 - M * b1) / (b2 * (B - A)) """This function calculates enthalpy_diff using the computationally efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute the enthalpy difference using the full TEOS-10 Gibbs function, the following lines of code will enable this. pt = pt_from_CT(SA, CT) t_shallow = pt_from_t(SA, pt, 0, p_shallow) t_deep = pt_from_t(SA, pt, 0, p_deep) enthalpy_diff = (enthalpy_t_exact(SA, t_deep, p_deep) - enthalpy_t_exact(SA, t_shallow, p_shallow)) or call the following, it is identical to the lines above. enthalpy_diff = enthalpy_diff_CT_exact(SA, CT, p_shallow, p_deep) """ return (db2Pascal * (delta_p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p_sum) / b2 + (M / (2 * b2)) * np.log(1 + delta_p * (2 * b1 + b2 * p_sum) / part1) + part3 * np.log(1 + delta_p * b2 * (B - A) / part2))) @match_args_return def dynamic_enthalpy(SA, CT, p): r"""Calculates dynamic enthalpy of seawater using the computationally- efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Dynamic enthalpy is defined as enthalpy minus potential enthalpy (Young, 2010). Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- dynamic_enthalpy : array_like dynamic enthalpy [J/kg] See Also -------- TODO Notes ----- The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.2 .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. .. [3] Young, W.R., 2010: Dynamic enthalpy, Conservative Temperature, and the seawater Boussinesq approximation. Journal of Physical Oceanography, 40, 394-400. Modifications: 2011-04-05. Trevor McDougall and Paul Barker. """ SA = np.maximum(SA, 0) sqrtSA = np.sqrt(SA) a0 = (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) + SA * (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) + v36 * SA + sqrtSA * (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT)))))) a1 = v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA * (v41 + v42 * CT) a2 = v43 + CT * (v44 + v45 * CT + v46 * SA) a3 = v47 + v48 * CT b0 = (v01 + CT * (v02 + CT * (v03 + v04 * CT)) + SA * (v05 + CT * (v06 + v07 * CT) + sqrtSA * (v08 + CT * (v09 + CT * (v10 + v11 * CT))))) b1 = 0.5 * (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT)) b2 = v17 + CT * (v18 + v19 * CT) + v20 * SA b1sq = b1 * b1 sqrt_disc = np.sqrt(b1sq - b0 * b2) N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2 M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2 A = b1 - sqrt_disc B = b1 + sqrt_disc part = (N * b2 - M * b1) / (b2 * (B - A)) """This function calculates dynamic_enthalpy using the computationally- efficient 48-term expression for density in terms of SA, CT and p. If one wanted to compute dynamic_enthalpy from SA, CT, and p with the full TEOS-10 Gibbs function, the following lines of code will enable this. dynamic_enthalpy = dynamic_enthalpy_CT_exact(SA, CT, p) """ return db2Pascal * (p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p) / b2 + (M / (2 * b2)) * np.log(1 + p * (2 * b1 + b2 * p) / b0) + part * np.log(1 + (b2 * p * (B - A)) / (A * (B + b2 * p)))) @match_args_return def SA_from_rho(rho, CT, p): r"""Calculates the Absolute Salinity of a seawater sample, for given values of its density, Conservative Temperature and sea pressure (in dbar). This function uses the computationally-efficient 48-term expression for density in terms of SA, CT and p (McDougall et al., 2011). Parameters ---------- rho : array_like density of a seawater sample [kg/m**3] This input has not had 1000 kg/m^3 subtracted from it (e.g. 1026 kg m**-3), that is, it is density, NOT density anomaly. CT : array_like Conservative Temperature [:math:`^\circ` C (ITS-90)] p : array_like sea pressure [dbar] Returns ------- SA : array_like Absolute Salinity [g/kg] See Also -------- TODO Notes ----- This is expressed on the Reference-Composition Salinity Scale of Millero et al. (2008). The 48-term equation has been fitted in a restricted range of parameter space, and is most accurate inside the "oceanographic funnel" described in McDougall et al. (2011). The GSW library function "infunnel(SA, CT, p)" is available to be used if one wants to test if some of one's data lies outside this "funnel". Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.5 .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A computationally efficient 48-term expression for the density of seawater in terms of Conservative Temperature, and related properties of seawater. .. [3] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. Modifications: 2011-04-04. Trevor McDougall and Paul Barker. """ v_lab = 1. / rho v_0 = specvol(np.zeros_like(rho), CT, p) v_50 = specvol(50 * np.ones_like(rho), CT, p) SA = 50 * (v_lab - v_0) / (v_50 - v_0) # Initial estimate of SA. SA[np.logical_or(SA < 0, SA > 50)] = np.NaN v_SA = (v_50 - v_0) / 50. # Initial v_SA estimate (SA derivative of v). # Begin the modified Newton-Raphson iterative procedure. for Number_of_iterations in range(0, 3): SA_old = SA delta_v = specvol(SA_old, CT, p) - v_lab # Half way the mod. N-R method (McDougall and Wotherspoon, 2012) SA = SA_old - delta_v / v_SA # Half way through the mod. N-R method. SA_mean = 0.5 * (SA + SA_old) rho, alpha, beta = rho_alpha_beta(SA_mean, CT, p) v_SA = -beta / rho SA = SA_old - delta_v / v_SA SA[np.logical_or(SA < 0, SA > 50)] = np.NaN # After two iterations of this modified Newton-Raphson iteration, # the error in SA is no larger than 8x10^-13 g kg^-1, which # is machine precision for this calculation. return SA gsw-3.0.2/gsw/gibbs/library.py0000644000175000017500000020120612172027023017347 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from constants import sfac, SSO, db2Pascal from gsw.utilities import match_args_return, strip_mask, read_data __all__ = [ 'gibbs', #'SAAR', TODO #'Fdelta', TODO #'delta_SA_ref', TODO: delta_SA ? 'SA_from_SP_Baltic', 'SP_from_SA_Baltic', 'infunnel', 'entropy_part', 'entropy_part_zerop', 'interp_ref_cast', 'interp_SA_CT', 'gibbs_pt0_pt0', 'specvol_SSO_0_p', 'enthalpy_SSO_0_p', 'Hill_ratio_at_SP2' ] def gibbs(ns, nt, npr, SA, t, p): r"""Calculates specific Gibbs energy and its derivatives up to order 2 for seawater. The Gibbs function approach allows the calculation of internal energy, entropy, enthalpy, potential enthalpy and the chemical potentials of seawater as well as the freezing temperature, and the latent heats of freezing and of evaporation. These quantities were not available from EOS-80 but are essential for the accurate accounting of heat in the ocean and for the consistent and accurate treatment of air-sea and ice-sea heat fluxes. Parameters ---------- ns : int order of SA derivative [0, 1 or 2 ] nt : int order of t derivative [0, 1 or 2 ] npr : int order of p derivative [0, 1 or 2 ] SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- gibbs : array_like Specific Gibbs energy or its derivatives. Gibbs energy (ns=nt=npr=0) has units of: [J kg :sup:`-1`] Absolute Salinity derivatives are output in units of: [(J kg :sup:`-1`) (g kg :sup:`-1`) :sup:`-ns`] Temperature derivatives are output in units of: [(J kg :sup:`-1`) K :sup:`-nt`] Pressure derivatives are output in units of: [(J kg :sup:`-1`) Pa :sup:`-npr`] The mixed derivatives are output in units of: [(J kg :sup:`-1`) (g kg :sup:`-1`) :sup:`-ns` K :sup:`-nt` Pa :sup:`-npr`] Notes ----- The Gibbs function for seawater is that of TEOS-10 (IOC et al., 2010), being the sum of IAPWS-08 for the saline part and IAPWS-09 for the pure water part. These IAPWS releases are the officially blessed IAPWS descriptions of Feistel (2008) and the pure water part of Feistel (2003). Absolute Salinity, SA, in all of the GSW routines is expressed on the Reference-Composition Salinity Scale of 2008 (RCSS-08) of Millero et al. (2008). The derivatives are taken with respect to pressure in Pa, not withstanding that the pressure input into this routine is in dbar. References ---------- .. [1] Feistel, R., 2003: A new extended Gibbs thermodynamic potential of seawater Progr. Oceanogr., 58, 43-114. .. [2] Feistel, R., 2008: A Gibbs function for seawater thermodynamics for -6 to 80 :math:`^\circ` C and salinity up to 120 g kg :sup:`-1`, Deep-Sea Res. I, 55, 1639-1671. .. [3] IAPWS, 2008: Release on the IAPWS Formulation 2008 for the Thermodynamic Properties of Seawater. The International Association for the Properties of Water and Steam. Berlin, Germany, September 2008, available from http://www.iapws.org. This Release is referred to as IAPWS-08. .. [4] IAPWS, 2009: Supplementary Release on a Computationally Efficient Thermodynamic Formulation for Liquid Water for Oceanographic Use. The International Association for the Properties of Water and Steam. Doorwerth, The Netherlands, September 2009, available from http://www.iapws.org. This Release is referred to as IAPWS-09. .. [5] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.6 and appendices A.6, G and H. .. [6] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. Modifications: 2010-09-24. David Jackett, Paul Barker and Trevor McDougall """ SA, t, p = np.asanyarray(SA), np.asanyarray(t), np.asanyarray(p) SA = np.atleast_1d(SA) nonzero_SA = np.any(SA > 0) _SA = SA _t = t _p = p SA = np.ma.filled(SA, 0) t = np.ma.filled(t, 20) p = np.ma.filled(p, 10) SA, t, p = np.broadcast_arrays(SA, t, p) gibbs = np.zeros(SA.shape, dtype=np.float) # Use if all_masked is True all_masked = False # Ensure a full mask, so we can set elements if necessary. mask = np.ma.mask_or(np.ma.getmaskarray(_SA), np.ma.getmask(_t)) mask = np.ma.mask_or(mask, np.ma.getmask(_p)) mask = np.ma.mask_or(mask, SA < 0) ipos = (SA > 0) # inpos = ~ipos # FIXME: Assigned but never used. if np.all(ipos): ipos = slice(None) # More efficient for usual case. x2 = sfac * SA x = np.sqrt(x2) y = t * 0.025 z = p * 1e-4 # The input pressure (p) is sea pressure in units of dbar. if (ns == 0) & (nt == 0) & (npr == 0): g03 = (101.342743139674 + z * (100015.695367145 + z * (-2544.5765420363 + z * (284.517778446287 + z * (-33.3146754253611 + (4.20263108803084 - 0.546428511471039 * z) * z)))) + y * (5.90578347909402 + z * (-270.983805184062 + z * (776.153611613101 + z * (-196.51255088122 + (28.9796526294175 - 2.13290083518327 * z) * z))) + y * (-12357.785933039 + z * (1455.0364540468 + z * (-756.558385769359 + z * (273.479662323528 + z * (-55.5604063817218 + 4.34420671917197 * z)))) + y * (736.741204151612 + z * (-672.50778314507 + z * (499.360390819152 + z * (-239.545330654412 + (48.8012518593872 - 1.66307106208905 * z) * z))) + y * (-148.185936433658 + z * (397.968445406972 + z * (-301.815380621876 + (152.196371733841 - 26.3748377232802 * z) * z)) + y * (58.0259125842571 + z * (-194.618310617595 + z * (120.520654902025 + z * (-55.2723052340152 + 6.48190668077221 * z))) + y * (-18.9843846514172 + y * (3.05081646487967 - 9.63108119393062 * z) + z * (63.5113936641785 + z * (-22.2897317140459 + 8.17060541818112 * z))))))))) if nonzero_SA: g08 = x2 * (1416.27648484197 + z * (-3310.49154044839 + z * (384.794152978599 + z * (-96.5324320107458 + (15.8408172766824 - 2.62480156590992 * z) * z))) + x * (-2432.14662381794 + x * (2025.80115603697 + y * (543.835333000098 + y * (-68.5572509204491 + y * (49.3667694856254 + y * (-17.1397577419788 + 2.49697009569508 * y))) - 22.6683558512829 * z) + x * (-1091.66841042967 - 196.028306689776 * y + x * (374.60123787784 - 48.5891069025409 * x + 36.7571622995805 * y) + 36.0284195611086 * z) + z * (-54.7919133532887 + (-4.08193978912261 - 30.1755111971161 * z) * z)) + z * (199.459603073901 + z * (-52.2940909281335 + (68.0444942726459 - 3.41251932441282 * z) * z)) + y * (-493.407510141682 + z * (-175.292041186547 + (83.1923927801819 - 29.483064349429 * z) * z) + y * (-43.0664675978042 + z * (383.058066002476 + z * (-54.1917262517112 + 25.6398487389914 * z)) + y * (-10.0227370861875 - 460.319931801257 * z + y * (0.875600661808945 + 234.565187611355 * z))))) + y * (168.072408311545 + z * (729.116529735046 + z * (-343.956902961561 + z * (124.687671116248 + z * (-31.656964386073 + 7.04658803315449 * z)))) + y * (880.031352997204 + y * (-225.267649263401 + y * (91.4260447751259 + y * (-21.6603240875311 + 2.13016970847183 * y) + z * (-297.728741987187 + (74.726141138756 - 36.4872919001588 * z) * z)) + z * (694.244814133268 + z * (-204.889641964903 + (113.561697840594 - 11.1282734326413 * z) * z))) + z * (-860.764303783977 + z * (337.409530269367 + z * (-178.314556207638 + (44.2040358308 - 7.92001547211682 * z) * z)))))) g08[ipos] += x2[ipos] * (5812.81456626732 + 851.226734946706 * y[ipos]) * np.log(x[ipos]) else: g08 = 0 gibbs = g03 + g08 elif (ns == 1) & (nt == 0) & (npr == 0): if nonzero_SA: g08 = (8645.36753595126 + z * (-6620.98308089678 + z * (769.588305957198 + z * (-193.0648640214916 + (31.6816345533648 - 5.24960313181984 * z) * z))) + x * (-7296.43987145382 + x * (8103.20462414788 + y * (2175.341332000392 + y * (-274.2290036817964 + y * (197.4670779425016 + y * (-68.5590309679152 + 9.98788038278032 * y))) - 90.6734234051316 * z) + x * (-5458.34205214835 - 980.14153344888 * y + x * (2247.60742726704 - 340.1237483177863 * x + 220.542973797483 * y) + 180.142097805543 * z) + z * (-219.1676534131548 + (-16.32775915649044 - 120.7020447884644 * z) * z)) + z * (598.378809221703 + z * (-156.8822727844005 + (204.1334828179377 - 10.23755797323846 * z) * z)) + y * (-1480.222530425046 + z * (-525.876123559641 + (249.57717834054571 - 88.449193048287 * z) * z) + y * (-129.1994027934126 + z * (1149.174198007428 + z * (-162.5751787551336 + 76.9195462169742 * z)) + y * (-30.0682112585625 - 1380.9597954037708 * z + y * (2.626801985426835 + 703.695562834065 * z))))) + y * (1187.3715515697959 + z * (1458.233059470092 + z * (-687.913805923122 + z * (249.375342232496 + z * (-63.313928772146 + 14.09317606630898 * z)))) + y * (1760.062705994408 + y * (-450.535298526802 + y * (182.8520895502518 + y * (-43.3206481750622 + 4.26033941694366 * y) + z * (-595.457483974374 + (149.452282277512 - 72.9745838003176 * z) * z)) + z * (1388.489628266536 + z * (-409.779283929806 + (227.123395681188 - 22.2565468652826 * z) * z))) + z * (-1721.528607567954 + z * (674.819060538734 + z * (-356.629112415276 + (88.4080716616 - 15.84003094423364 * z) * z)))))) g08[ipos] = g08[ipos] + (11625.62913253464 + 1702.453469893412 * y[ipos]) * np.log(x[ipos]) gibbs = 0.5 * sfac * g08 else: all_masked = True elif (ns == 0) & (nt == 1) & (npr == 0): g03 = (5.90578347909402 + z * (-270.983805184062 + z * (776.153611613101 + z * (-196.51255088122 + (28.9796526294175 - 2.13290083518327 * z) * z))) + y * (-24715.571866078 + z * (2910.0729080936 + z * (-1513.116771538718 + z * (546.959324647056 + z * (-111.1208127634436 + 8.68841343834394 * z)))) + y * (2210.2236124548363 + z * (-2017.52334943521 + z * (1498.081172457456 + z * (-718.6359919632359 + (146.4037555781616 - 4.9892131862671505 * z) * z))) + y * (-592.743745734632 + z * (1591.873781627888 + z * (-1207.261522487504 + (608.785486935364 - 105.4993508931208 * z) * z)) + y * (290.12956292128547 + z * (-973.091553087975 + z * (602.603274510125 + z * (-276.361526170076 + 32.40953340386105 * z))) + y * (-113.90630790850321 + y * (21.35571525415769 - 67.41756835751434 * z) + z * (381.06836198507096 + z * (-133.7383902842754 + 49.023632509086724 * z)))))))) if nonzero_SA: g08 = x2 * (168.072408311545 + z * (729.116529735046 + z * (-343.956902961561 + z * (124.687671116248 + z * (-31.656964386073 + 7.04658803315449 * z)))) + x * (-493.407510141682 + x * (543.835333000098 + x * (-196.028306689776 + 36.7571622995805 * x) + y * (-137.1145018408982 + y * (148.10030845687618 + y * (-68.5590309679152 + 12.4848504784754 * y))) - 22.6683558512829 * z) + z * (-175.292041186547 + (83.1923927801819 - 29.483064349429 * z) * z) + y * (-86.1329351956084 + z * (766.116132004952 + z * (-108.3834525034224 + 51.2796974779828 * z)) + y * (-30.0682112585625 - 1380.9597954037708 * z + y * (3.50240264723578 + 938.26075044542 * z)))) + y * (1760.062705994408 + y * (-675.802947790203 + y * (365.7041791005036 + y * (-108.30162043765552 + 12.78101825083098 * y) + z * (-1190.914967948748 + (298.904564555024 - 145.9491676006352 * z) * z)) + z * (2082.7344423998043 + z * (-614.668925894709 + (340.685093521782 - 33.3848202979239 * z) * z))) + z * (-1721.528607567954 + z * (674.819060538734 + z * (-356.629112415276 + (88.4080716616 - 15.84003094423364 * z) * z))))) g08[ipos] += 851.226734946706 * x2[ipos] * np.log(x[ipos]) gibbs = (g03 + g08) * 0.025 else: gibbs = g03 elif (ns == 0) & (nt == 0) & (npr == 1): g03 = (100015.695367145 + z * (-5089.1530840726 + z * (853.5533353388611 + z * (-133.2587017014444 + (21.0131554401542 - 3.278571068826234 * z) * z))) + y * (-270.983805184062 + z * (1552.307223226202 + z * (-589.53765264366 + (115.91861051767 - 10.664504175916349 * z) * z)) + y * (1455.0364540468 + z * (-1513.116771538718 + z * (820.438986970584 + z * (-222.2416255268872 + 21.72103359585985 * z))) + y * (-672.50778314507 + z * (998.720781638304 + z * (-718.6359919632359 + (195.2050074375488 - 8.31535531044525 * z) * z)) + y * (397.968445406972 + z * (-603.630761243752 + (456.589115201523 - 105.4993508931208 * z) * z) + y * (-194.618310617595 + y * (63.5113936641785 - 9.63108119393062 * y + z * (-44.5794634280918 + 24.511816254543362 * z)) + z * (241.04130980405 + z * (-165.8169157020456 + 25.92762672308884 * z)))))))) if nonzero_SA: g08 = x2 * (-3310.49154044839 + z * (769.588305957198 + z * (-289.5972960322374 + (63.3632691067296 - 13.1240078295496 * z) * z)) + x * (199.459603073901 + x * (-54.7919133532887 + 36.0284195611086 * x - 22.6683558512829 * y + (-8.16387957824522 - 90.52653359134831 * z) * z) + z * (-104.588181856267 + (204.1334828179377 - 13.65007729765128 * z) * z) + y * (-175.292041186547 + (166.3847855603638 - 88.449193048287 * z) * z + y * (383.058066002476 + y * (-460.319931801257 + 234.565187611355 * y) + z * (-108.3834525034224 + 76.9195462169742 * z)))) + y * (729.116529735046 + z * (-687.913805923122 + z * (374.063013348744 + z * (-126.627857544292 + 35.23294016577245 * z))) + y * (-860.764303783977 + y * (694.244814133268 + y * (-297.728741987187 + (149.452282277512 - 109.46187570047641 * z) * z) + z * (-409.779283929806 + (340.685093521782 - 44.5130937305652 * z) * z)) + z * (674.819060538734 + z * (-534.943668622914 + (176.8161433232 - 39.600077360584095 * z) * z))))) else: g08 = 0 # Pressure derivative of the Gibbs function # in units of (J kg :sup:`-1`) (Pa :sup:`-1`) = m :sup:`3` kg :sup:`-1` gibbs = (g03 + g08) * 1e-8 elif (ns == 1) & (nt == 1) & (npr == 0): if nonzero_SA: g08 = (1187.3715515697959 + z * (1458.233059470092 + z * (-687.913805923122 + z * (249.375342232496 + z * (-63.313928772146 + 14.09317606630898 * z)))) + x * (-1480.222530425046 + x * (2175.341332000392 + x * (-980.14153344888 + 220.542973797483 * x) + y * (-548.4580073635929 + y * (592.4012338275047 + y * (-274.2361238716608 + 49.9394019139016 * y))) - 90.6734234051316 * z) + z * (-525.876123559641 + (249.57717834054571 - 88.449193048287 * z) * z) + y * (-258.3988055868252 + z * (2298.348396014856 + z * (-325.1503575102672 + 153.8390924339484 * z)) + y * (-90.2046337756875 - 4142.8793862113125 * z + y * (10.50720794170734 + 2814.78225133626 * z)))) + y * (3520.125411988816 + y * (-1351.605895580406 + y * (731.4083582010072 + y * (-216.60324087531103 + 25.56203650166196 * y) + z * (-2381.829935897496 + (597.809129110048 - 291.8983352012704 * z) * z)) + z * (4165.4688847996085 + z * (-1229.337851789418 + (681.370187043564 - 66.7696405958478 * z) * z))) + z * (-3443.057215135908 + z * (1349.638121077468 + z * (-713.258224830552 + (176.8161433232 - 31.68006188846728 * z) * z))))) g08[ipos] = g08[ipos] + 1702.453469893412 * np.log(x[ipos]) gibbs = 0.5 * sfac * 0.025 * g08 # FIXME: commented by FF, g110 without nan did not pass #mask[inpos] = True else: all_masked = True elif (ns == 1) & (nt == 0) & (npr == 1): g08 = (-6620.98308089678 + z * (1539.176611914396 + z * (-579.1945920644748 + (126.7265382134592 - 26.2480156590992 * z) * z)) + x * (598.378809221703 + x * (-219.1676534131548 + 180.142097805543 * x - 90.6734234051316 * y + (-32.65551831298088 - 362.10613436539325 * z) * z) + z * (-313.764545568801 + (612.4004484538132 - 40.95023189295384 * z) * z) + y * (-525.876123559641 + (499.15435668109143 - 265.347579144861 * z) * z + y * (1149.174198007428 + y * (-1380.9597954037708 + 703.695562834065 * y) + z * (-325.1503575102672 + 230.7586386509226 * z)))) + y * (1458.233059470092 + z * (-1375.827611846244 + z * (748.126026697488 + z * (-253.255715088584 + 70.4658803315449 * z))) + y * (-1721.528607567954 + y * (1388.489628266536 + y * (-595.457483974374 + (298.904564555024 - 218.92375140095282 * z) * z) + z * (-819.558567859612 + (681.370187043564 - 89.0261874611304 * z) * z)) + z * (1349.638121077468 + z * (-1069.887337245828 + (353.6322866464 - 79.20015472116819 * z) * z))))) # Derivative of the Gibbs function is in units of # (m :sup:`3` kg :sup:`-1`) / (g kg :sup:`-1`) = m :sup:`3` g :sup:`-1` # that is, it is the derivative of specific volume with respect to # Absolute Salinity measured in g kg :sup:`-1` gibbs = g08 * sfac * 0.5e-8 elif (ns == 0) & (nt == 1) & (npr == 1): g03 = (-270.983805184062 + z * (1552.307223226202 + z * (-589.53765264366 + (115.91861051767 - 10.664504175916349 * z) * z)) + y * (2910.0729080936 + z * (-3026.233543077436 + z * (1640.877973941168 + z * (-444.4832510537744 + 43.4420671917197 * z))) + y * (-2017.52334943521 + z * (2996.162344914912 + z * (-2155.907975889708 + (585.6150223126464 - 24.946065931335752 * z) * z)) + y * (1591.873781627888 + z * (-2414.523044975008 + (1826.356460806092 - 421.9974035724832 * z) * z) + y * (-973.091553087975 + z * (1205.20654902025 + z * (-829.084578510228 + 129.6381336154442 * z)) + y * (381.06836198507096 - 67.41756835751434 * y + z * (-267.4767805685508 + 147.07089752726017 * z))))))) if nonzero_SA: g08 = x2 * (729.116529735046 + z * (-687.913805923122 + z * (374.063013348744 + z * (-126.627857544292 + 35.23294016577245 * z))) + x * (-175.292041186547 - 22.6683558512829 * x + (166.3847855603638 - 88.449193048287 * z) * z + y * (766.116132004952 + y * (-1380.9597954037708 + 938.26075044542 * y) + z * (-216.7669050068448 + 153.8390924339484 * z))) + y * (-1721.528607567954 + y * (2082.7344423998043 + y * (-1190.914967948748 + (597.809129110048 - 437.84750280190565 * z) * z) + z * (-1229.337851789418 + (1022.055280565346 - 133.5392811916956 * z) * z)) + z * (1349.638121077468 + z * (-1069.887337245828 + (353.6322866464 - 79.20015472116819 * z) * z)))) else: g08 = 0 # Derivative of the Gibbs function is in units of (m :sup:`3` (K kg)) # that is, the pressure of the derivative in Pa. gibbs = (g03 + g08) * 2.5e-10 elif (ns == 2) & (nt == 0) & (npr == 0): g08 = 2.0 * (8103.20462414788 + y * (2175.341332000392 + y * (-274.2290036817964 + y * (197.4670779425016 + y * (-68.5590309679152 + 9.98788038278032 * y))) - 90.6734234051316 * z) + 1.5 * x * (-5458.34205214835 - 980.14153344888 * y + (4.0 / 3.0) * x * (2247.60742726704 - 340.1237483177863 * 1.25 * x + 220.542973797483 * y) + 180.142097805543 * z) + z * (-219.1676534131548 + (-16.32775915649044 - 120.7020447884644 * z) * z)) if nonzero_SA: tmp = ((-7296.43987145382 + z * (598.378809221703 + z * (-156.8822727844005 + (204.1334828179377 - 10.23755797323846 * z) * z)) + y * (-1480.222530425046 + z * (-525.876123559641 + (249.57717834054571 - 88.449193048287 * z) * z) + y * (-129.1994027934126 + z * (1149.174198007428 + z * (-162.5751787551336 + 76.9195462169742 * z)) + y * (-30.0682112585625 - 1380.9597954037708 * z + y * (2.626801985426835 + 703.695562834065 * z))))) / x + (11625.62913253464 + 1702.453469893412 * y) / x2) g08[ipos] += tmp[ipos] gibbs = 0.25 * sfac ** 2 * g08 elif (ns == 0) & (nt == 2) & (npr == 0): g03 = (-24715.571866078 + z * (2910.0729080936 + z * (-1513.116771538718 + z * (546.959324647056 + z * (-111.1208127634436 + 8.68841343834394 * z)))) + y * (4420.4472249096725 + z * (-4035.04669887042 + z * (2996.162344914912 + z * (-1437.2719839264719 + (292.8075111563232 - 9.978426372534301 * z) * z))) + y * (-1778.231237203896 + z * (4775.621344883664 + z * (-3621.784567462512 + (1826.356460806092 - 316.49805267936244 * z) * z)) + y * (1160.5182516851419 + z * (-3892.3662123519 + z * (2410.4130980405 + z * (-1105.446104680304 + 129.6381336154442 * z))) + y * (-569.531539542516 + y * (128.13429152494615 - 404.50541014508605 * z) + z * (1905.341809925355 + z * (-668.691951421377 + 245.11816254543362 * z))))))) if nonzero_SA: g08 = x2 * (1760.062705994408 + x * (-86.1329351956084 + x * (-137.1145018408982 + y * (296.20061691375236 + y * (-205.67709290374563 + 49.9394019139016 * y))) + z * (766.116132004952 + z * (-108.3834525034224 + 51.2796974779828 * z)) + y * (-60.136422517125 - 2761.9195908075417 * z + y * (10.50720794170734 + 2814.78225133626 * z))) + y * (-1351.605895580406 + y * (1097.1125373015109 + y * (-433.20648175062206 + 63.905091254154904 * y) + z * (-3572.7449038462437 + (896.713693665072 - 437.84750280190565 * z) * z)) + z * (4165.4688847996085 + z * (-1229.337851789418 + (681.370187043564 - 66.7696405958478 * z) * z))) + z * (-1721.528607567954 + z * (674.819060538734 + z * (-356.629112415276 + (88.4080716616 - 15.84003094423364 * z) * z)))) else: g08 = 0 gibbs = (g03 + g08) * 0.000625 elif (ns == 0) & (nt == 0) & (npr == 2): g03 = (-5089.1530840726 + z * (1707.1066706777221 + z * (-399.7761051043332 + (84.0526217606168 - 16.39285534413117 * z) * z)) + y * (1552.307223226202 + z * (-1179.07530528732 + (347.75583155301 - 42.658016703665396 * z) * z) + y * (-1513.116771538718 + z * (1640.877973941168 + z * (-666.7248765806615 + 86.8841343834394 * z)) + y * (998.720781638304 + z * (-1437.2719839264719 + (585.6150223126464 - 33.261421241781 * z) * z) + y * (-603.630761243752 + (913.178230403046 - 316.49805267936244 * z) * z + y * (241.04130980405 + y * (-44.5794634280918 + 49.023632509086724 * z) + z * (-331.6338314040912 + 77.78288016926652 * z))))))) if nonzero_SA: g08 = x2 * (769.588305957198 + z * (-579.1945920644748 + (190.08980732018878 - 52.4960313181984 * z) * z) + x * (-104.588181856267 + x * (-8.16387957824522 - 181.05306718269662 * z) + (408.2669656358754 - 40.95023189295384 * z) * z + y * (166.3847855603638 - 176.898386096574 * z + y * (-108.3834525034224 + 153.8390924339484 * z))) + y * (-687.913805923122 + z * (748.126026697488 + z * (-379.883572632876 + 140.9317606630898 * z)) + y * (674.819060538734 + z * (-1069.887337245828 + (530.4484299696 - 158.40030944233638 * z) * z) + y * (-409.779283929806 + y * (149.452282277512 - 218.92375140095282 * z) + (681.370187043564 - 133.5392811916956 * z) * z)))) else: g08 = 0 # Second derivative of the Gibbs function with respect to pressure, # measured in Pa; units of (J kg :sup:`-1`) (Pa :sup:`-2`). gibbs = (g03 + g08) * 1e-16 else: raise ValueError('Illegal derivative of the Gibbs function') gibbs = np.ma.array(gibbs, mask=mask, copy=False) # BÅ: Code below is not needed? #if all_masked: # gibbs[:] = np.ma.masked # Do not allow zero salinity with salinity derivatives if ns > 0: gibbs = np.ma.masked_where(SA == 0, gibbs) return gibbs def entropy_part(SA, t, p): r"""Calculates entropy, except that it does not evaluate any terms that are functions of Absolute Salinity alone. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- entropy_part : array_like entropy minus the terms that due to SA alone [J kg :sup:`-1` K :sup:`-1`] Notes ----- By not calculating these terms, which are a function only of Absolute Salinity, several unnecessary computations are avoided (including saving the computation of a natural logarithm). These terms are a necessary part of entropy, but are not needed when calculating potential temperature from in situ temperature. Modifications: """ SA, t, p, mask = strip_mask(SA, t, p) x2 = sfac * SA x = np.sqrt(x2) y = t * 0.025 z = p * 1e-4 g03 = (z * (-270.983805184062 + z * (776.153611613101 + z * (-196.51255088122 + (28.9796526294175 - 2.13290083518327 * z) * z))) + y * (-24715.571866078 + z * (2910.0729080936 + z * (-1513.116771538718 + z * (546.959324647056 + z * (-111.1208127634436 + 8.68841343834394 * z)))) + y * (2210.2236124548363 + z * (-2017.52334943521 + z * (1498.081172457456 + z * (-718.6359919632359 + (146.4037555781616 - 4.9892131862671505 * z) * z))) + y * (-592.743745734632 + z * (1591.873781627888 + z * (-1207.261522487504 + (608.785486935364 - 105.4993508931208 * z) * z)) + y * (290.12956292128547 + z * (-973.091553087975 + z * (602.603274510125 + z * (-276.361526170076 + 32.40953340386105 * z))) + y * (-113.90630790850321 + y * (21.35571525415769 - 67.41756835751434 * z) + z * (381.06836198507096 + z * (-133.7383902842754 + 49.023632509086724 * z)))))))) # TODO? short-circuit this if SA is zero g08 = x2 * (z * (729.116529735046 + z * (-343.956902961561 + z * (124.687671116248 + z * (-31.656964386073 + 7.04658803315449 * z)))) + x * (x * (y * (-137.1145018408982 + y * (148.10030845687618 + y * (-68.5590309679152 + 12.4848504784754 * y))) - 22.6683558512829 * z) + z * (-175.292041186547 + (83.1923927801819 - 29.483064349429 * z) * z) + y * (-86.1329351956084 + z * (766.116132004952 + z * (-108.3834525034224 + 51.2796974779828 * z)) + y * (-30.0682112585625 - 1380.9597954037708 * z + y * (3.50240264723578 + 938.26075044542 * z)))) + y * (1760.062705994408 + y * (-675.802947790203 + y * (365.7041791005036 + y * (-108.30162043765552 + 12.78101825083098 * y) + z * (-1190.914967948748 + (298.904564555024 - 145.9491676006352 * z) * z)) + z * (2082.7344423998043 + z * (-614.668925894709 + (340.685093521782 - 33.3848202979239 * z) * z))) + z * (-1721.528607567954 + z * (674.819060538734 + z * (-356.629112415276 + (88.4080716616 - 15.84003094423364 * z) * z))))) entropy_part = -(g03 + g08) * 0.025 return np.ma.array(entropy_part, mask=mask, copy=False) def gibbs_pt0_pt0(SA, pt0): r"""Calculates the second derivative of the specific Gibbs function with respect to temperature at zero sea pressure or _gibbs(0,2,0,SA,t,0). Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt0 : array_like potential temperature relative to 0 dbar [:math:`^\circ` C (ITS-90)] Returns ------- gibbs_pt0_pt0 : array_like TODO: write the eq. for the second derivative of the specific Gibbs function. FIXME: [units] Notes ----- This library function is called by both "pt_from_CT(SA,CT)" and "pt0_from_t(SA,t,p)". Modifications: """ SA, pt0, mask = strip_mask(SA, pt0) x2 = sfac * SA x = np.sqrt(x2) y = pt0 * 0.025 g03 = (-24715.571866078 + y * (4420.4472249096725 + y * (-1778.231237203896 + y * (1160.5182516851419 + y * (-569.531539542516 + y * 128.13429152494615))))) g08 = x2 * (1760.062705994408 + x * (-86.1329351956084 + x * (-137.1145018408982 + y * (296.20061691375236 + y * (-205.67709290374563 + 49.9394019139016 * y))) + y * (-60.136422517125 + y * 10.50720794170734)) + y * (-1351.605895580406 + y * (1097.1125373015109 + y * (-433.20648175062206 + 63.905091254154904 * y)))) gibbs_pt0_pt0 = (g03 + g08) * 0.000625 return np.ma.array(gibbs_pt0_pt0, mask=mask, copy=False) def entropy_part_zerop(SA, pt0): r"""Calculates entropy at a sea surface (p = 0 dbar), except that it does not evaluate any terms that are functions of Absolute Salinity alone. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt0 : array_like potential temperature relative to 0 dbar [:math:`^\circ` C (ITS-90)] Returns ------- entropy_part_zerop : array_like [J kg :sup:`-1` K :sup:`-1`] Notes ----- By not calculating these terms, which are a function only of Absolute Salinity, several unnecessary computations are avoided (including saving the computation of a natural logarithm). These terms are a necessary part of entropy, but are not needed when calculating potential temperature from in situ temperature. Modifications: """ SA, pt0, mask = strip_mask(SA, pt0) x2 = sfac * SA x = np.sqrt(x2) y = pt0 * 0.025 g03 = y * (-24715.571866078 + y * (2210.2236124548363 + y * (-592.743745734632 + y * (290.12956292128547 + y * (-113.90630790850321 + y * 21.35571525415769))))) g08 = x2 * (x * (x * (y * (-137.1145018408982 + y * (148.10030845687618 + y * (-68.5590309679152 + 12.4848504784754 * y)))) + y * (-86.1329351956084 + y * (-30.0682112585625 + y * 3.50240264723578))) + y * (1760.062705994408 + y * (-675.802947790203 + y * (365.7041791005036 + y * (-108.30162043765552 + 12.78101825083098 * y))))) entropy_part_zerop = -(g03 + g08) * 0.025 return np.ma.array(entropy_part_zerop, mask=mask, copy=False) # FIXME: Check if this is still used and remove it. def enthalpy_SSO_0_CT25(p): r"""Calculates enthalpy at the Standard Ocean Salinity (SSO) and at a Conservative Temperature of zero degrees C (CT=0), as a function of pressure (p [dbar]) or enthalpy_CT25(35.16504,0,p). Parameters ---------- p : array_like pressure [dbar] Returns ------- enthalpy_CT25 : array_like enthalpy_CT25 at (SSO, CT = 0, p), 25-term equation. [J kg :sup:`-1`] Notes ----- Uses a streamlined version of the 25-term CT version of the Gibbs function, that is, a streamlined version of the code "enthalpy_CT25(SA,CT,p)" Modifications: """ p = np.asanyarray(p) mask = np.ma.getmask(p) p = np.ma.filled(p, 0) a0 = 1 + SSO * (2.0777716085618458e-3 + np.sqrt(SSO) * 3.4688210757917340e-6) a1 = 6.8314629554123324e-6 b0 = 9.9984380290708214e2 + SSO * (2.8925731541277653e0 + SSO * 1.9457531751183059e-3) b1 = 0.5 * (1.1930681818531748e-2 + SSO * 5.9355685925035653e-6) b2 = -2.5943389807429039e-8 A = b1 - np.sqrt(b1 ** 2 - b0 * b2) B = b1 + np.sqrt(b1 ** 2 - b0 * b2) part = (a0 * b2 - a1 * b1) / (b2 * (B - A)) enthalpy_SSO_0_CT25 = db2Pascal * ((a1 / (2 * b2)) * np.log(1 + p * (2 * b1 + b2 * p) / b0) + part * np.log(1 + (b2 * p * (B - A)) / (A * (B + b2 * p)))) return np.ma.array(enthalpy_SSO_0_CT25, mask=mask, copy=False) # FIXME: Check if this is still used and remove it. def specvol_SSO_0_CT25(p): r"""Calculates specific volume at the Standard Ocean Salinity (SSO) and Conservative Temperature of zero degrees C (CT=0), as a function of pressure (p [dbar]) or spec_vol_CT25(35.16504,0,p). Parameters ---------- p : array_like pressure [dbar] Returns ------- specvol_SSO_0_CT25 : array_like Specific volume at (SSO, CT=0, p), 25-term equation. [m :sup:`3` kg :sup:`-1`] Notes ----- It uses a streamlined version of the 25-term CT version of specific volume that is, a streamlined version of the code "rho_alpha_beta_CT25(SA,CT,p)" Modifications """ p = np.asanyarray(p) # No need to strip mask and replace it here; the calculation is simple. specvol_SSO_0_CT25 = ((1.00000000e+00 + SSO * (2.0777716085618458e-003 + np.sqrt(SSO) * 3.4688210757917340e-006) + p * 6.8314629554123324e-006) / (9.9984380290708214e+002 + SSO * (2.8925731541277653e+000 + SSO * 1.9457531751183059e-003) + p * (1.1930681818531748e-002 + SSO * 5.9355685925035653e-006 + p * -2.5943389807429039e-008))) return specvol_SSO_0_CT25 # Salinity lib functions def in_Baltic(lon, lat): """Check if positions are in the Baltic Sea Parameters ---------- lon, lat : array_like or masked arrays Returns ------- in_Baltic : boolean array (at least 1D) True for points in the Baltic Sea False for points outside, masked or NaN """ lon, lat = np.atleast_1d(lon, lat) # Polygon bounding the Baltic, (xb, yb) # Effective boundary is the intersection of this polygon # with rectangle defined by xmin, xmax, ymin, ymax # # start with southwestern point and go round cyclonically xb = np.array([12.6, 45.0, 26.0, 7.0, 12.6]) yb = np.array([50.0, 50.0, 69.0, 59.0, 50.0]) # Enclosing rectangle #xmin, xmax = xb.min(), xb.max() #ymin, ymax = yb.min(), yb.max() xmin, xmax = 7.0, 32.0 ymin, ymax = 52.0, 67.0 # First check if outside the rectangle in_rectangle = ((xmin < lon) & (lon < xmax) & (ymin < lat) & (lat < ymax)) # Masked values are also considered outside the rectangle if np.ma.is_masked(in_rectangle): in_rectangle = in_rectangle.data & ~in_rectangle.mask # Closer check for points in the rectangle if np.any(in_rectangle): lon, lat = np.broadcast_arrays(lon, lat) in_baltic = np.zeros(lon.shape, dtype='bool') lon1 = lon[in_rectangle] lat1 = lat[in_rectangle] # There are general ways of testing for point in polygon # This works for this special configuration of points xx_right = np.interp(lat1, yb[1:3], xb[1:3]) xx_left = np.interp(lat1, yb[-1:1:-1], xb[-1:1:-1]) in_baltic[in_rectangle] = (xx_left <= lon1) & (lon1 <= xx_right) return in_baltic else: # Nothing inside the rectangle, return the False array. return in_rectangle def SP_from_SA_Baltic(SA, lon, lat): r"""Calculates Practical Salinity (SP) for the Baltic Sea, from a value computed analytically from Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] lon : array_like decimal degrees east [0..+360] lat : array_like decimal degrees (+ve N, -ve S) [-90..+90] Returns ------- SP_baltic : array_like salinity [psu (PSS-78)], unitless See Also -------- SP_from_SA, SP_from_Sstar Notes ----- This program will only produce Practical Salinity values for the Baltic Sea. Examples -------- >>> import gsw.library as lib >>> SA = [6.6699, 6.7738, 6.9130, 7.3661, 7.5862, 10.3895] >>> lon, lat = 20, 59 >>> lat = 59 >>> lib.SP_from_SA_Baltic(SA, lon, lat) masked_array(data = [6.56825466873 6.67192351682 6.8108138311 7.26290579519 7.4825161269 10.2795794748], mask = [False False False False False False], fill_value = 1e+20) References ---------- .. [1] Feistel, R., S. Weinreben, H. Wolf, S. Seitz, P. Spitzer, B. Adel, G. Nausch, B. Schneider and D. G. Wright, 2010c: Density and Absolute Salinity of the Baltic Sea 2006-2009. Ocean Science, 6, 3-24. http://www.ocean-sci.net/6/3/2010/os-6-3-2010.pdf .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [3] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm for estimating Absolute Salinity in the global ocean. Submitted to Ocean Science. A preliminary version is available at Ocean Sci. Discuss., 6, 215-242. http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf Modifications: 2010-07-23. David Jackett, Trevor McDougall & Paul Barker """ SA, lon, lat = map(np.ma.masked_invalid, (SA, lon, lat)) lon, lat, SA = np.broadcast_arrays(lon, lat, SA) inds_baltic = in_Baltic(lon, lat) if not inds_baltic.sum(): return None SP_baltic = np.ma.masked_all(SA.shape, dtype=np.float) SP_baltic[inds_baltic] = ((35 / (SSO - 0.087)) * (SA[inds_baltic] - 0.087)) return SP_baltic # FIXME: Check if this is still used and remove it. def SP_from_SA_Baltic_old(SA, lon, lat): r"""Calculates Practical Salinity (SP) for the Baltic Sea, from a value computed analytically from Absolute Salinity. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] lon : array_like decimal degrees east [0..+360] lat : array_like decimal degrees (+ve N, -ve S) [-90..+90] Returns ------- SP_baltic : array_like salinity [psu (PSS-78)], unitless See Also -------- SP_from_SA, SP_from_Sstar Notes ----- This program will only produce Practical Salinity values for the Baltic Sea. Examples -------- >>> import gsw.library as lib >>> SA = [6.6699, 6.7738, 6.9130, 7.3661, 7.5862, 10.3895] >>> lon, lat = 20, 59 >>> lat = 59 >>> lib.SP_from_SA_Baltic(SA, lon, lat) masked_array(data = [6.56825466873 6.67192351682 6.8108138311 7.26290579519 7.4825161269 10.2795794748], mask = [False False False False False False], fill_value = 1e+20) References ---------- .. [1] Feistel, R., S. Weinreben, H. Wolf, S. Seitz, P. Spitzer, B. Adel, G. Nausch, B. Schneider and D. G. Wright, 2010c: Density and Absolute Salinity of the Baltic Sea 2006-2009. Ocean Science, 6, 3-24. http://www.ocean-sci.net/6/3/2010/os-6-3-2010.pdf .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [3] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm for estimating Absolute Salinity in the global ocean. Submitted to Ocean Science. A preliminary version is available at Ocean Sci. Discuss., 6, 215-242. http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf Modifications: 2010-07-23. David Jackett, Trevor McDougall & Paul Barker """ SA, lon, lat = map(np.ma.masked_invalid, (SA, lon, lat)) lon, lat, SA = np.broadcast_arrays(lon, lat, SA) xb1, xb2, xb3 = 12.6, 7., 26. xb1a, xb3a = 45., 26. yb1, yb2, yb3 = 50., 59., 69. inds_baltic = (xb2 < lon) & (lon < xb1a) & (yb1 < lat) & (lat < yb3) if not inds_baltic.sum(): return None SP_baltic = np.ma.masked_all(SA.shape, dtype=np.float) xx_left = np.interp(lat[inds_baltic], [yb1, yb2, yb3], [xb1, xb2, xb3]) xx_right = np.interp(lat[inds_baltic], [yb1, yb3], [xb1a, xb3a]) inds_baltic1 = ((xx_left <= lon[inds_baltic]) & (lon[inds_baltic] <= xx_right)) if not inds_baltic1.sum(): return None SP_baltic[inds_baltic[inds_baltic1]] = ((35 / (SSO - 0.087)) * (SA[inds_baltic[inds_baltic1]] - 0.087)) return SP_baltic def SA_from_SP_Baltic(SP, lon, lat): r"""Computes absolute salinity from practical in the Baltic Sea. Parameters ---------- SP : array_like or masked array Practical salinity (PSS-78) lon, lat : array_like or masked arrays geographical position Returns ------- SA : masked array, at least 1D Absolute salinity [g/kg] masked where inputs are masked or position outside the Baltic """ # Handle masked array input input_mask = False if np.ma.is_masked(SP): input_mask = input_mask | SP.mask if np.ma.is_masked(lon): input_mask = input_mask | lon.mask if np.ma.is_masked(lat): input_mask = input_mask | lat.mask SP, lon, lat = map(np.atleast_1d, (SP, lon, lat)) SP, lon, lat = np.broadcast_arrays(SP, lon, lat) inds_baltic = in_Baltic(lon, lat) #SA_baltic = np.ma.masked_all(SP.shape, dtype=np.float) all_nans = np.nan + np.zeros_like(SP) SA_baltic = np.ma.MaskedArray(all_nans, mask=~inds_baltic) if np.any(inds_baltic): SA_baltic[inds_baltic] = (((SSO - 0.087) / 35) * SP[inds_baltic] + 0.087) SA_baltic.mask = SA_baltic.mask | input_mask | np.isnan(SP) return SA_baltic class SA_table(object): """ TODO: Write docstring. """ # Central America barrier x_ca = np.array([260.0, 272.59, 276.5, 278.65, 280.73, 295.217]) y_ca = np.array([19.55, 13.97, 9.6, 8.1, 9.33, 0.0]) def __init__(self, fname="gsw_data_v3_0.npz", max_p_fudge=10000, min_frac=0): self.fname = fname self.max_p_fudge = max_p_fudge self.min_frac = min_frac data = read_data(fname) # Make the order x, y, z: temp = data.delta_SA_ref.transpose((2, 1, 0)).copy() self.dsa = np.ma.masked_invalid(temp) self.dsa.data[self.dsa.mask] = 0 self.lon = data.longs_ref.astype(np.float) self.lat = data.lats_ref.astype(np.float) self.p = data.p_ref # Depth levels # ndepth from the file disagrees with the unmasked count from # delta_SA_ref in a few places; this should be fixed in the # file, but for now we will simply calculate ndepth directly from # delta_SA_ref. #self.ndepth = np.ma.masked_invalid(data.ndepth_ref.T).astype(np.int8) ndepth = self.dsa.count(axis=-1) self.ndepth = np.ma.masked_equal(ndepth, 0) self.dlon = self.lon[1] - self.lon[0] self.dlat = self.lat[1] - self.lat[0] self.i_ca, self.j_ca = self.xy_to_ij(self.x_ca, self.y_ca) def xy_to_ij(self, x, y): """ Convert from lat/lon to grid index coordinates, without truncation or rounding. """ i = (x - self.lon[0]) / self.dlon j = (y - self.lat[0]) / self.dlat return i, j def _central_america(self, di, dj, ii, jj, gm): """ Use a line running through Central America to zero the goodmask for grid points in the Pacific forming the grid box around input locations in the Atlantic, and vice-versa. """ ix, jy = ii[0] + di, jj[0] + dj # Reconstruction: minor inefficiency. inear = ((ix >= self.i_ca[0]) & (ix <= self.i_ca[-1]) & (jy >= self.j_ca[-1]) & (jy <= self.j_ca[0])) if not inear.any(): return gm inear_ind = inear.nonzero()[0] ix = ix[inear] jy = jy[inear] ii = ii[:, inear] jj = jj[:, inear] jy_ca = np.interp(ix, self.i_ca, self.j_ca) above = jy - jy_ca # > 0 if input point is above dividing line # Intersections of left and right grid lines with dividing line jleft_ca = np.interp(ii[0], self.i_ca, self.j_ca) jright_ca = np.interp(ii[1], self.i_ca, self.j_ca) jgrid_ca = [jleft_ca, jright_ca, jright_ca, jleft_ca] # Zero the goodmask for grid points on opposite side of divider for i in range(4): opposite = (above * (jj[i] - jgrid_ca[i])) < 0 gm[i, inear_ind[opposite]] = 0 return gm def xy_interp(self, di, dj, ii, jj, k): """ 2-D interpolation, bilinear if all 4 surrounding grid points are present, but treating missing points as having the average value of the remaining grid points. This matches the matlab V2 behavior. """ # Array of weights, CCW around the grid box w = np.vstack(((1 - di) * (1 - dj), # lower left di * (1 - dj), # lower right di * dj, # upper right (1 - di) * dj)) # upper left gm = ~self.dsa.mask[ii, jj, k] # gm is "goodmask" gm = self._central_america(di, dj, ii, jj, gm) # Save a measure of real interpolation quality. frac = (w * gm).sum(axis=0) # Now loosen the interpolation, allowing a value to # be calculated on a grid point that is masked. # This matches the matlab gsw version 2 behavior. jm_partial = gm.any(axis=0) & (~(gm.all(axis=0))) # The weights of the unmasked points will be increased # by the sum of the weights of the masked points divided # by the number of unmasked points in the grid square. # This is equivalent to setting the masked data values # to the average of the unmasked values, and then # unmasking, which is the matlab v2 implementation. if jm_partial.any(): w_bad = w * (~gm) w[:, jm_partial] += (w_bad[:, jm_partial].sum(axis=0) / gm[:, jm_partial].sum(axis=0)) w *= gm wsum = w.sum(axis=0) valid = wsum > 0 # Only need to prevent division by zero here. w[:, valid] /= wsum[:, valid] w[:, ~valid] = 0 vv = self.dsa.data[ii, jj, k] vv *= w dsa = vv.sum(axis=0) return dsa, frac def delta_SA(self, p, lon, lat): r"""Table lookup of salinity anomaly, given pressure, lon, and lat.""" p = np.ma.masked_less(p, 0) mask_in = np.ma.mask_or(np.ma.getmask(p), np.ma.getmask(lon)) mask_in = np.ma.mask_or(mask_in, np.ma.getmask(lat)) p, lon, lat = [np.ma.filled(a, 0).astype(float) for a in (p, lon, lat)] p, lon, lat = np.broadcast_arrays(p, lon, lat) if p.ndim > 1: shape_in = p.shape p, lon, lat = map(np.ravel, (p, lon, lat)) reshaped = True else: reshaped = False p_orig = p.copy() # Save for comparison to clipped p. ix0, iy0 = self.xy_to_ij(lon, lat) i0raw = np.floor(ix0).astype(int) i0 = np.clip(i0raw, 0, len(self.lon) - 2) di = ix0 - i0 j0raw = np.floor(iy0).astype(int) j0 = np.clip(j0raw, 0, len(self.lat) - 2) dj = iy0 - j0 # Start at lower left and go CCW; match order in _xy_interp. ii = np.vstack((i0, i0 + 1, i0 + 1, i0)) jj = np.vstack((j0, j0, j0 + 1, j0 + 1)) k1 = np.searchsorted(self.p, p, side='right') # Clip p and k1 at max p of grid cell. kmax = (self.ndepth[ii, jj].max(axis=0) - 1) mask_out = kmax.mask kmax = kmax.filled(1) clip_p = (p >= self.p[kmax]) p[clip_p] = self.p[kmax[clip_p]] k1[clip_p] = kmax[clip_p] k0 = k1 - 1 dsa0, frac0 = self.xy_interp(di, dj, ii, jj, k0) dsa1, frac1 = self.xy_interp(di, dj, ii, jj, k1) dp = np.diff(self.p) pfrac = (p - self.p[k0]) / dp[k0] delta_SA = dsa0 * (1 - pfrac) + dsa1 * pfrac # Save intermediate results in case we are curious about # them; the frac values are most likely to be useful. # We won't bother to reshape them, though, and we may # delete them later. self.dsa0 = dsa0 self.frac0 = frac0 self.dsa1 = dsa1 self.frac1 = frac1 self.pfrac = pfrac self.p_fudge = p_orig - p # Editing options, in case we don't want to use # values calculated from the wrong pressure, or from # an incomplete SA table grid square. mask_out |= self.p_fudge > self.max_p_fudge mask_out |= self.frac1 < self.min_frac delta_SA = np.ma.array(delta_SA, mask=mask_out, copy=False) if reshaped: delta_SA.shape = shape_in self.p_fudge.shape = shape_in if mask_in is not np.ma.nomask: delta_SA = np.ma.array(delta_SA, mask=mask_in, copy=False) return delta_SA @match_args_return def SAAR(p, lon, lat): r"""Absolute Salinity Anomaly Ratio (excluding the Baltic Sea). Calculates the Absolute Salinity Anomaly Ratio, SAAR, in the open ocean by spatially interpolating the global reference data set of SAAR to the location of the seawater sample. This function uses version 3.0 of the SAAR look up table. Parameters ---------- p : array_like pressure [dbar] lon : array_like decimal degrees east (will be treated modulo 360) lat : array_like decimal degrees (+ve N, -ve S) [-90..+90] Returns ------- SAAR : masked array; masked where no nearby ocean is found in data Absolute Salinity Anomaly Ratio [unitless] FIXME: [g kg :sup:`-1`]? Notes ----- The Absolute Salinity Anomaly Ratio in the Baltic Sea is evaluated separately, since it is a function of Practical Salinity, not of space. The present function returns a SAAR of zero for data in the Baltic Sea. The correct way of calculating Absolute Salinity in the Baltic Sea is by calling SA_from_SP. The mask is only set when the observation is well and truly on dry land; often the warning flag is not set until one is several hundred kilometers inland from the coast. References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm for estimating Absolute Salinity in the global ocean. Submitted to Ocean Science. A preliminary version is available at Ocean Sci. Discuss., 6, 215-242. http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf The algorithm is taken from the matlab implementation of the references, but the numpy implementation here differs substantially from the matlab implementation. Modifications: """ #FIXME: Compare old delta_SA with new SAAR. return SA_table().delta_SA(p, lon, lat) def infunnel(SA, CT, p): r"""Oceanographic funnel check for the 25-term equation Parameters ---------- SA : array_like Absolute Salinity [g/kg] CT : array_like Conservative Temperature [°C] p : array_like sea pressure [dbar] (ie. absolute pressure - 10.1325 dbar) Returns ------- in_funnel : boolean ndarray or scalar True, if SA, CT and p are inside the "funnel" False, if SA, CT and p are outside the "funnel", or one of the values are NaN or masked Note. The term "funnel" describes the range of SA, CT and p over which the error in the fit of the computationally-efficient 25-term expression for density in terms of SA, CT and p was calculated (McDougall et al., 2010). author: Trevor McDougall and Paul Barker 2011-02-27: Bjørn Ådlandsvik, python version """ # Check variables and resize if necessary scalar = np.isscalar(SA) and np.isscalar(CT) and np.isscalar(p) SA, CT, p = np.broadcast_arrays(SA, CT, p) input_nan = np.isnan(SA) | np.isnan(CT) | np.isnan(p) infunnel = ((p <= 8000) & (SA >= 0) & (SA <= 42.2) & (CT >= (-0.3595467 - 0.0553734 * SA)) & ((p >= 5500) | (SA >= 0.006028 * (p - 500))) & ((p >= 5500) | (CT <= (33.0 - 0.003818181818182 * p))) & ((p <= 5500) | (SA >= 30.14)) & ((p <= 5500) | (CT <= 12.0))) infunnel = infunnel & np.logical_not(input_nan) if scalar: infunnel = bool(infunnel) return infunnel @match_args_return def Hill_ratio_at_SP2(t): r"""TODO: Write docstring Hill ratio at SP = 2 """ # USAGE: # Hill_ratio = Hill_ratio_at_SP2(t) # # DESCRIPTION: # Calculates the Hill ratio, which is the adjustment needed to apply for # Practical Salinities smaller than 2. This ratio is defined at a # Practical Salinity = 2 and in-situ temperature, t using PSS-78. The Hill # ratio is the ratio of 2 to the output of the Hill et al. (1986) formula # for Practical Salinity at the conductivity ratio, Rt, at which Practical # Salinity on the PSS-78 scale is exactly 2. # # INPUT: # t = in-situ temperature (ITS-90) [ deg C ] # # OUTPUT: # Hill_ratio = Hill ratio at SP of 2 [ unitless ] # # AUTHOR: # Trevor McDougall and Paul Barker # # VERSION NUMBER: 3.0 (26th March, 2011) SP2 = 2 * np.ones_like(t) #------------------------------ # Start of the calculation #------------------------------ a0 = 0.0080 a1 = -0.1692 a2 = 25.3851 a3 = 14.0941 a4 = -7.0261 a5 = 2.7081 b0 = 0.0005 b1 = -0.0056 b2 = -0.0066 b3 = -0.0375 b4 = 0.0636 b5 = -0.0144 g0 = 2.641463563366498e-1 g1 = 2.007883247811176e-4 g2 = -4.107694432853053e-6 g3 = 8.401670882091225e-8 g4 = -1.711392021989210e-9 g5 = 3.374193893377380e-11 g6 = -5.923731174730784e-13 g7 = 8.057771569962299e-15 g8 = -7.054313817447962e-17 g9 = 2.859992717347235e-19 k = 0.0162 t68 = t * 1.00024 ft68 = (t68 - 15) / (1 + k * (t68 - 15)) #-------------------------------------------------------------------------- # Find the initial estimates of Rtx (Rtx0) and of the derivative dSP_dRtx # at SP = 2. #-------------------------------------------------------------------------- Rtx0 = g0 + t68 * (g1 + t68 * (g2 + t68 * (g3 + t68 * (g4 + t68 * (g5 + t68 * (g6 + t68 * (g7 + t68 * (g8 + t68 * g9)))))))) dSP_dRtx = (a1 + (2 * a2 + (3 * a3 + (4 * a4 + 5 * a5 * Rtx0) * Rtx0) * Rtx0) * Rtx0 + ft68 * (b1 + (2 * b2 + (3 * b3 + (4 * b4 + 5 * b5 * Rtx0) * Rtx0) * Rtx0) * Rtx0)) #-------------------------------------------------------------------------- # Begin a single modified Newton-Raphson iteration to find Rt at SP = 2. #-------------------------------------------------------------------------- SP_est = (a0 + (a1 + (a2 + (a3 + (a4 + a5 * Rtx0) * Rtx0) * Rtx0) * Rtx0) * Rtx0 + ft68 * (b0 + (b1 + (b2 + (b3 + (b4 + b5 * Rtx0) * Rtx0) * Rtx0) * Rtx0) * Rtx0)) Rtx = Rtx0 - (SP_est - SP2) / dSP_dRtx Rtxm = 0.5 * (Rtx + Rtx0) dSP_dRtx = (a1 + (2 * a2 + (3 * a3 + (4 * a4 + 5 * a5 * Rtxm) * Rtxm) * Rtxm) * Rtxm + ft68 * (b1 + (2 * b2 + (3 * b3 + (4 * b4 + 5 * b5 * Rtxm) * Rtxm) * Rtxm) * Rtxm)) Rtx = Rtx0 - (SP_est - SP2) / dSP_dRtx # This is the end of one full iteration of the modified Newton-Raphson # iterative equation solver. The error in Rtx at this point is equivalent # to an error in SP of 9e-16 psu. x = 400 * Rtx * Rtx sqrty = 10 * Rtx part1 = 1 + x * (1.5 + x) part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty)) SP_Hill_raw_at_SP2 = SP2 - a0 / part1 - b0 * ft68 / part2 return 2. / SP_Hill_raw_at_SP2 def interp_S_T(S, T, z, znew, P=None): r"""Linear interpolation of ndarrays *S* and *T* from *z* to *znew*. Optionally interpolate a third ndarray, *P*. *z* must be strictly increasing or strictly decreasing. It must be a 1-D array, and its length must match the last dimension of *S* and *T*. *znew* may be a scalar or a sequence. It is assumed, but not checked, that *S*, *T*, and *z* are all plain ndarrays, not masked arrays or other sequences. Out-of-range values of *znew*, and *nan* in *S* and *T*, yield corresponding *nan* in the output. The basic algorithm is from scipy.interpolate. """ isscalar = False if not np.iterable(znew): isscalar = True znew = [znew] znew = np.asarray(znew) inverted = False if z[1] - z[0] < 0: inverted = True z = z[::-1] S = S[..., ::-1] T = T[..., ::-1] if P is not None: P = P[..., ::-1] if (np.diff(z) <= 0).any(): raise ValueError("z must be strictly increasing or decreasing") hi = np.searchsorted(z, znew) hi = hi.clip(1, len(z) - 1).astype(int) lo = hi - 1 z_lo = z[lo] z_hi = z[hi] S_lo = S[lo] S_hi = S[hi] T_lo = T[lo] T_hi = T[hi] zratio = (znew - z_lo) / (z_hi - z_lo) Si = S_lo + (S_hi - S_lo) * zratio Ti = T_lo + (T_hi - T_lo) * zratio if P is not None: Pi = P[lo] + (P[hi] - P[lo]) * zratio if inverted: Si = Si[..., ::-1] Ti = Ti[..., ::-1] if P is not None: Pi = Pi[..., ::-1] outside = (znew < z.min()) | (znew > z.max()) if np.any(outside): Si[..., outside] = np.nan Ti[..., outside] = np.nan if P is not None: Pi[..., outside] = np.nan if isscalar: Si = Si[0] Ti = Ti[0] if P is not None: Pi = Pi[0] if P is None: return Si, Ti return Si, Ti, Pi def interp_SA_CT(SA, CT, p, p_i): r"""TODO: Write docstring. function [SA_i, CT_i] = interp_SA_CT(SA,CT,p,p_i) interp_SA_CT linear interpolation to p_i on a cast ========================================================================== This function interpolates the cast with respect to the interpolating variable p. This function finds the values of SA, CT at p_i on this cast. """ return interp_S_T(SA, CT, p, p_i) def interp_ref_cast(spycnl, A="gn"): r"""Translation of: [SA_iref_cast, CT_iref_cast, p_iref_cast] = interp_ref_cast(spycnl, A) interp_ref_cast linear interpolation of the reference cast ========================================================================== This function interpolates the reference cast with respect to the interpolating variable "spycnl". This reference cast is at the location 188E,4N from the reference data set which underlies the Jackett & McDougall (1997) Neutral Density computer code. This function finds the values of SA, CT and p on this reference cast which correspond to the value of isopycnal which is passed to this function from the function "geo_strf_isopycnal_CT". The isopycnal could be either gamma_n or sigma_2. If A is set to any of the following 's2','S2','sigma2','sigma_2' the interpolation will take place in sigma 2 space, any other input will result in the programme working in gamma_n space. VERSION NUMBER: 3.0 (14th April, 2011) REFERENCE: Jackett, D. R. and T. J. McDougall, 1997: A neutral density variable for the world<92>s oceans. Journal of Physical Oceanography, 27, 237-263. FIXME? Do we need argument checking here to handle masked arrays, etc.? I suspect not, since I don't think this is intended to be user-callable, but is instead used internally by user-callable functions. """ if A.lower() in ["s2", "sigma2", "sigma_2"]: A = "s2" gsw_data = read_data("gsw_data_v3_0.npz") SA_ref = gsw_data.SA_ref_cast CT_ref = gsw_data.CT_ref_cast p_ref = gsw_data.p_ref_cast if A == "s2": zvar_ref = gsw_data.sigma_2_ref_cast else: zvar_ref = gsw_data.gamma_n_ref_cast # Not sure why this is needed, but it is in the Matlab version, # and presumably can't hurt. cond = (spycnl >= 21.805) & (spycnl <= 28.3614) zvar_new = spycnl[cond] Si, Ci, Pi = interp_S_T(SA_ref, CT_ref, zvar_ref, zvar_new, P=p_ref) return Si, Ci, Pi def enthalpy_SSO_0_p(p): r"""This function calculates enthalpy at the Standard Ocean Salinty, SSO, and at a Conservative Temperature of zero degrees C, as a function of pressure, p, in dbar, using a streamlined version of the 48-term CT version of the Gibbs function, that is, a streamlined version of the code "enthalpy(SA,CT,p). Modifications: """ v01 = 9.998420897506056e+2 v05 = -6.698001071123802 v08 = -3.988822378968490e-2 v12 = -2.233269627352527e-2 v15 = -1.806789763745328e-4 v17 = -3.087032500374211e-7 v20 = 1.550932729220080e-10 v21 = 1.0 v26 = -7.521448093615448e-3 v31 = -3.303308871386421e-5 v36 = 5.419326551148740e-6 v37 = -2.742185394906099e-5 v41 = -1.105097577149576e-7 v43 = -1.119011592875110e-10 v47 = -1.200507748551599e-15 a0 = v21 + SSO * (v26 + v36 * SSO + v31 * np.sqrt(SSO)) a1 = v37 + v41 * SSO a2 = v43 a3 = v47 b0 = v01 + SSO * (v05 + v08 * np.sqrt(SSO)) b1 = 0.5 * (v12 + v15 * SSO) b2 = v17 + v20 * SSO b1sq = b1 ** 2 sqrt_disc = np.sqrt(b1sq - b0 * b2) N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2 M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2 A = b1 - sqrt_disc B = b1 + sqrt_disc part = (N * b2 - M * b1) / (b2 * (B - A)) return db2Pascal * (p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p) / b2 + (M / (2 * b2)) * np.log(1 + p * (2 * b1 + b2 * p) / b0) + part * np.log(1 + (b2 * p * (B - A)) / (A * (B + b2 * p)))) def specvol_SSO_0_p(p): r"""This function calculates specific volume at the Standard Ocean Salinity, SSO, and at a Conservative Temperature of zero degrees C, as a function of pressure, p, in dbar, using a streamlined version of the 48-term CT version of specific volume, that is, a streamlined version of the code "specvol(SA, CT, p)". Modifications: """ v01 = 9.998420897506056e+2 v05 = -6.698001071123802 v08 = -3.988822378968490e-2 v12 = -2.233269627352527e-2 v15 = -1.806789763745328e-4 v17 = -3.087032500374211e-7 v20 = 1.550932729220080e-10 v21 = 1.0 v26 = -7.521448093615448e-3 v31 = -3.303308871386421e-5 v36 = 5.419326551148740e-6 v37 = -2.742185394906099e-5 v41 = -1.105097577149576e-7 v43 = -1.119011592875110e-10 v47 = -1.200507748551599e-15 return ((v21 + SSO * (v26 + v36 * SSO + v31 * np.sqrt(SSO)) + p * (v37 + v41 * SSO + p * (v43 + v47 * p))) / (v01 + SSO * (v05 + v08 * np.sqrt(SSO)) + p * (v12 + v15 * SSO + p * (v17 + v20 * SSO)))) gsw-3.0.2/gsw/gibbs/geostrophic.py0000644000175000017500000000022112172027023020223 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np __all__ = [ #'geostrophic_velocity ' TODO ] gsw-3.0.2/gsw/gibbs/basic_thermodynamic_t.py0000644000175000017500000016715612172027023022251 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- from __future__ import division import numpy as np from library import gibbs from absolute_salinity_sstar_ct import CT_from_t from gsw.utilities import match_args_return, strip_mask from conversions import pt_from_CT, pt_from_t, pt0_from_t from constants import Kelvin, db2Pascal, P0, SSO, cp0, R, sfac, M_S __all__ = [ 'rho_t_exact', 'pot_rho_t_exact', 'sigma0_pt0_exact', 'alpha_wrt_CT_t_exact', 'alpha_wrt_pt_t_exact', 'alpha_wrt_t_exact', 'beta_const_CT_t_exact', 'beta_const_pt_t_exact', 'beta_const_t_exact', 'specvol_t_exact', 'specvol_anom_t_exact', 'sound_speed_t_exact', 'kappa_t_exact', 'kappa_const_t_exact', 'internal_energy_t_exact', 'enthalpy_t_exact', 'dynamic_enthalpy_t_exact', 'SA_from_rho_t_exact', #'t_from_rho_exact', 't_maxdensity_exact', 'entropy_t_exact', 'cp_t_exact', 'isochoric_heat_cap_t_exact', 'chem_potential_relative_t_exact', 'chem_potential_water_t_exact', 'chem_potential_salt_t_exact', 'Helmholtz_energy_t_exact', 'adiabatic_lapse_rate_t_exact', 'osmotic_coefficient_t_exact', 'osmotic_pressure_t_exact' ] n0, n1, n2 = 0, 1, 2 @match_args_return def Helmholtz_energy_t_exact(SA, t, p): r"""Calculates the Helmholtz energy of seawater. The specific Helmholtz energy of seawater :math:`f` is given by: .. math:: f(SA, t, p) = g - (p + P_0) \nu = g - (p + P_0) \frac{\partial g}{\partial P}\Big|_{SA,T} Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- Helmholtz_energy : array_like Helmholtz energy [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.Helmholtz_energy_t_exact(SA, t, p) array([-5985.58288209, -5830.81845224, -3806.96617841, -877.66369421, -462.17033905, -245.50407205]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.13. Modifications: 2011-03-29. Trevor McDougall """ return (gibbs(n0, n0, n0, SA, t, p) - (db2Pascal * p + P0) * gibbs(n0, n0, n1, SA, t, p)) @match_args_return def rho_t_exact(SA, t, p): r"""Calculates in situ density of seawater from Absolute Salinity and in situ temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- rho_t_exact : array_like in situ density [kg m :sup:`-3`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.rho(SA, t, p) array([ 1021.84017319, 1022.26268993, 1024.42771594, 1027.79020181, 1029.83771473, 1032.00240412]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.8. Modifications: 2011-03-29. Paul Barker, David Jackett and Trevor McDougal """ return 1. / gibbs(n0, n0, n1, SA, t, p) @match_args_return def sigma0_pt0_exact(SA, pt0): r"""Calculates potential density anomaly with reference sea pressure of zero (0) dbar. The temperature input to this function is potential temperature referenced to zero dbar. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] pt0 : array_like potential temperature [:math:`^\circ` C (ITS-90)] with respect to a reference sea pressure of 0 dbar Returns ------- sigma0_pt0_exact : array_like potential density anomaly [kg m :sup:`-3`] respect to a reference pressure of 0 dbar See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.rho(SA, t, p) array([ 1021.84017319, 1022.26268993, 1024.42771594, 1027.79020181, 1029.83771473, 1032.00240412]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (3.6.1). Modifications: 2011-03-29. Trevor McDougal and Paul Barker. """ SA = np.maximum(SA, 0) # Ensure that SA is non-negative. x2 = sfac * SA x = np.sqrt(x2) y = pt0 * 0.025 g03 = (100015.695367145 + y * (-270.983805184062 + y * (1455.0364540468 + y * (-672.50778314507 + y * (397.968445406972 + y * (-194.618310617595 + y * (63.5113936641785 - y * 9.63108119393062))))))) g08 = x2 * (-3310.49154044839 + x * (199.459603073901 + x * (-54.7919133532887 + x * 36.0284195611086 - y * 22.6683558512829) + y * (-175.292041186547 + y * (383.058066002476 + y * (-460.319931801257 + y * 234.565187611355)))) + y * (729.116529735046 + y * (-860.764303783977 + y * (694.244814133268 + y * (-297.728741987187))))) """The above code is exactly the same as the following two lines of code. sigma0_pt_exact = rho_t_exact(SA, pt0, 0.) - 1000 """ return 100000000. / (g03 + g08) - 1000.0 @match_args_return def enthalpy_t_exact(SA, t, p): r"""Calculates the specific enthalpy of seawater. The specific enthalpy of seawater :math:`h` is given by: .. math:: h(SA, t, p) = g + (T_0 + t)\eta = g - (T_0 + t) \frac{\partial g}{\partial T}\Big|_{SA,p} Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- enthalpy : array_like specific enthalpy [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.enthalpy(SA, t, p) array([ 115103.26047838, 114014.8036012 , 92179.9209311 , 43255.32838089, 33087.21597002, 26970.5880448 ]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See appendix A.11. Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker. """ return (gibbs(n0, n0, n0, SA, t, p) - (t + Kelvin) * gibbs(n0, n1, n0, SA, t, p)) @match_args_return def specvol_t_exact(SA, t, p): r"""Calculates the specific volume of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- specvol : array_like specific volume [m :sup:`3` kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.specvol(SA, t, p) array([ 0.00097863, 0.00097822, 0.00097615, 0.00097296, 0.00097103, 0.00096899]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.7. Modifications: 2011-03-23. David Jackett and Paul Barker. """ return gibbs(n0, n0, n1, SA, t, p) @match_args_return def entropy_t_exact(SA, t, p): r"""Calculates specific entropy of seawater. The specific entropy of seawater :math:`\eta` is given by: .. math:: \eta(SA, t, p) = -g_T = \frac{\partial g}{\partial T}\Big|_{SA,p} When taking derivatives with respect to *in situ* temperature, the symbol :math:`T` will be used for temperature in order that these derivatives not be confused with time derivatives. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- entropy : array_like specific entropy [J kg :sup:`-1` K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.entropy_t_exact(SA, t, p) array([ 400.38942528, 395.43817843, 319.8664982 , 146.79088159, 98.64734087, 62.79150873]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker. """ return -gibbs(n0, n1, n0, SA, t, p) @match_args_return def cp_t_exact(SA, t, p): r"""Calculates the isobaric heat capacity of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- cp_t_exact : array_like heat capacity of seawater [J kg :sup:`-1` K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.cp_t_exact(SA, t, p) array([ 4002.88800396, 4000.98028393, 3995.54646889, 3985.07676902, 3973.59384348, 3960.18408479]) .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker """ return -(t + Kelvin) * gibbs(n0, n2, n0, SA, t, p) @match_args_return def sound_speed_t_exact(SA, t, p): r"""Calculates the speed of sound in seawater. The speed of sound in seawater :math:`c` is given by: .. math:: c(SA, t, p) = \sqrt{ \partial P / \partial \rho |_{SA,\eta}} = \sqrt{(\rho\kappa)^{-1}} = g_P \sqrt{g_{TT}/(g^2_{TP} - g_{TT}g_{PP})} Note that in these expressions, since sound speed is in m s :sup`-1` and density has units of kg m :sup:`-3` it follows that the pressure of the partial derivatives must be in Pa and the isentropic compressibility :math:`kappa` must have units of Pa :sup:`-1`. The sound speed c produced by both the SIA and the GSW software libraries (appendices M and N) has units of m s :sup:`-1`. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- sound_speed : array_like speed of sound in seawater [m s :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.sound_speed_t_exact(SA, t, p) array([ 1542.61580359, 1542.70353407, 1530.84497914, 1494.40999692, 1487.37710252, 1483.93460908]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.17.1) Modifications: 2011-03-29. David Jackett, Paul Barker and Trevor McDougall. """ return (gibbs(n0, n0, n1, SA, t, p) * np.sqrt(gibbs(n0, n2, n0, SA, t, p) / (gibbs(n0, n1, n1, SA, t, p) ** 2 - gibbs(n0, n2, n0, SA, t, p) * gibbs(n0, n0, n2, SA, t, p)))) @match_args_return def specvol_anom_t_exact(SA, t, p): r"""Calculates specific volume anomaly from Absolute Salinity, in situ temperature and pressure, using the full TEOS-10 Gibbs function. The reference value of Absolute Salinity is SSO and the reference value of Conservative Temperature is equal to 0 :math:`^\circ` C. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- specvol_anom_t_exact : array_like specific volume anomaly [m :sup:`3` kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.specvol_anom_t_exact(SA, t, p) array([ 6.01044463e-06, 5.78602432e-06, 4.05564999e-06, 1.42198662e-06, 1.04351837e-06, 7.63964850e-07]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (3.7.3) Modifications: 2011-03-23. Trevor McDougall and Paul Barker """ pt_zero = pt_from_CT(SSO, 0) t_zero = pt_from_t(SSO, pt_zero, 0, p) return (gibbs(n0, n0, n1, SA, t, p) - gibbs(n0, n0, n1, SSO, t_zero, p)) @match_args_return def chem_potential_relative_t_exact(SA, t, p): r"""Calculates the adiabatic lapse rate of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- chem_potential_relative : array_like relative chemical potential [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.chem_potential_relative_t_exact(SA, t, p) array([ 79.4254481 , 79.25989214, 74.69154859, 65.64063719, 61.22685656, 57.21298557]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-03-29. Trevor McDougall and Paul Barker """ return gibbs(n1, n0, n0, SA, t, p) @match_args_return def internal_energy_t_exact(SA, t, p): r"""Calculates the Helmholtz energy of seawater. The specific internal energy of seawater :math:`u` is given by: .. math:: u(SA, t, p) = g + (T_0 + t)\eta - (p + P_0)\nu = g - (T_0 + t)\frac{\partial g}{\partial T}\Big|_{SA,p} - (p + P_0)\frac{\partial g}{\partial P}\Big|_{SA,T} where :math:`T_0` is the Celsius zero point, 273.15 K and :math:`P_0` = 101 325 Pa is the standard atmosphere pressure. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- internal_energy (u) : array_like specific internal energy [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.internal_energy_t_exact(SA, t, p) array([ 114906.23847309, 113426.57417062, 90860.81858842, 40724.34005719, 27162.66600185, 17182.50522667]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.11.1) Modifications: 2011-03-29. Trevor McDougall """ return (gibbs(n0, n0, n0, SA, t, p) - (Kelvin + t) * gibbs(n0, n1, n0, SA, t, p) - (db2Pascal * p + P0) * gibbs(n0, n0, n1, SA, t, p)) @match_args_return def kappa_const_t_exact(SA, t, p): r"""Calculates isothermal compressibility of seawater at constant in situ temperature. .. math:: \kappa^t(SA, t, p) = \rho^{-1}\frac{\partial \rho}{\partial P}\Big|_{SA,T} = -\nu^{-1}\frac{\partial \nu}{\partial P}\Big|_{SA,T} = -\frac{g_{PP}}{g_P} Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- kappa : array_like Isothermal compressibility [Pa :sup:`-1`] See Also -------- TODO Notes ----- This is the compressibility of seawater at constant in situ temperature. Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.kappa_const_t_exact(SA, t, p) array([ 4.19071646e-10, 4.18743202e-10, 4.22265764e-10, 4.37735100e-10, 4.40373818e-10, 4.41156577e-10]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.15.1) Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker """ return -gibbs(n0, n0, n2, SA, t, p) / gibbs(n0, n0, n1, SA, t, p) @match_args_return def alpha_wrt_t_exact(SA, t, p): r"""Calculates the thermal expansion coefficient of seawater with respect to in situ temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- alpha_wrt_t : array_like thermal expansion coefficient [K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.alpha_wrt_t_exact(SA, t, p) array([ 0.0003256 , 0.00032345, 0.00028141, 0.00017283, 0.00014557, 0.00012836]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.18.1) .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm for estimating Absolute Salinity in the global ocean. Submitted to Ocean Science. A preliminary version is available at Ocean Sci. Discuss., 6, 215-242. Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker """ return gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p) @match_args_return def isochoric_heat_cap_t_exact(SA, t, p): r"""Calculates the isochoric heat capacity of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- isochoric_heat_cap : array_like isochoric heat capacity [J kg :sup:`-1` K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.isochoric_heat_cap_t_exact(SA, t, p) array([ 3928.13708702, 3927.27381633, 3941.36418525, 3966.26126146, 3960.50903222, 3950.13901342]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.21. Modifications: 2011-03-29. Trevor McDougall """ return (-(Kelvin + t) * (gibbs(n0, n2, n0, SA, t, p) - gibbs(n0, n1, n1, SA, t, p) ** 2 / gibbs(n0, n0, n2, SA, t, p))) @match_args_return def kappa_t_exact(SA, t, p): r"""Calculates the isentropic compressibility of seawater. When the entropy and Absolute Salinity are held constant while the pressure is changed, the isentropic and isohaline compressibility :math:`kappa` is obtained: .. math:: \kappa(SA, t, p) = \rho^{-1}\frac{\partial \rho}{\partial P}\Big|_{SA,\eta} = -\nu^{-1}\frac{\partial \nu}{\partial P}\Big|_{SA,\eta} = \rho^{-1}\frac{\partial \rho}{\partial P}\Big|_{SA,\theta} = -\nu^{-1}\frac{\partial \nu}{\partial P}\Big|_{SA,\theta} = -\frac{ (g_{TP}^2 - g_{TT} g_{PP} ) }{g_P g_{TT}} The isentropic and isohaline compressibility is sometimes called simply the isentropic compressibility (or sometimes the "adiabatic compressibility"), on the unstated understanding that there is also no transfer of salt during the isentropic or adiabatic change in pressure. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- kappa : array_like Isentropic compressibility [Pa :sup:`-1`] See Also -------- TODO Notes ----- The output is Pascal and not dbar. Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.kappa_t_exact(SA, t, p) array([ 4.11245799e-10, 4.11029072e-10, 4.16539558e-10, 4.35668338e-10, 4.38923693e-10, 4.40037576e-10]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqns. (2.16.1) and the row for kappa in Table P.1 of appendix P Modifications: 2011-03-23. David Jackett, Trevor McDougall and Paul Barker """ return ((gibbs(n0, n1, n1, SA, t, p) ** 2 - gibbs(n0, n2, n0, SA, t, p) * gibbs(n0, n0, n2, SA, t, p)) / (gibbs(n0, n0, n1, SA, t, p) * gibbs(n0, n2, n0, SA, t, p))) @match_args_return def SA_from_rho_t_exact(rho, t, p): r"""Calculates the Absolute Salinity of a seawater sample, for given values of its density, in situ temperature and sea pressure (in dbar). One use for this function is in the laboratory where a measured value of the in situ density :math:`\rho` of a seawater sample may have been made at the laboratory temperature :math:`t` and at atmospheric pressure :math:`p`. The present function will return the Absolute Salinity SA of this seawater sample. Parameters ---------- rho : array_like in situ density [kg m :sup:`-3`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- SA : array_like Absolute salinity [g kg :sup:`-1`] See Also -------- TODO Notes ----- This is expressed on the Reference-Composition Salinity Scale of Millero et al. (2008). After two iterations of a modified Newton-Raphson iteration, the error in SA is typically no larger than 2 :math:`^\times` 10 :sup:`-13` [g kg :sup:`-1`] Examples -------- >>> import gsw >>> rho = [1021.839, 1022.262, 1024.426, 1027.792, 1029.839, 1032.002] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.SA_from_rho_t_exact(rho, t, p) array([ 34.71022966, 34.89057683, 35.02332421, 34.84952096, 34.73824809, 34.73188384]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.5. .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The composition of Standard Seawater and the definition of the Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. Modifications: 2011-03-28. Trevor McDougall and Paul Barker. """ v_lab = np.ones_like(rho) / rho v_0 = gibbs(n0, n0, n1, 0, t, p) v_120 = gibbs(n0, n0, n1, 120, t, p) # Initial estimate of SA. SA = 120 * (v_lab - v_0) / (v_120 - v_0) Ior = np.logical_or(SA < 0, SA > 120) # Initial estimate of v_SA, SA derivative of v v_SA = (v_120 - v_0) / 120 for k in range(0, 2): SA_old = SA delta_v = gibbs(n0, n0, n1, SA_old, t, p) - v_lab # Half way the mod. N-R method (McDougall and Wotherspoon, 2012) SA = SA_old - delta_v / v_SA SA_mean = 0.5 * (SA + SA_old) v_SA = gibbs(n1, n0, n1, SA_mean, t, p) SA = SA_old - delta_v / v_SA SA[Ior] = np.ma.masked return SA @match_args_return def t_from_rho_exact(rho, SA, p): r"""Calculates the in-situ temperature of a seawater sample, for given values of its density, Absolute Salinity and sea pressure (in dbar). Parameters ---------- rho : array_like in situ density [kg m :sup:`-3`] SA : array_like Absolute salinity [g kg :sup:`-1`] p : array_like pressure [dbar] Returns ------- t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] t_multiple : array_like in situ temperature [:math:`^\circ` C (ITS-90)] See Also -------- TODO Notes ----- At low salinities, in brackish water, there are two possible temperatures for a single density. This program will output both valid solutions (t, t_multiple), if there is only one possible solution the second variable will be set to NaN. Examples -------- TODO References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-04-21. Trevor McDougall and Paul Barker. """ """alpha_limit is the positive value of the thermal expansion coefficient which is used at the freezing temperature to distinguish between I_salty and I_fresh.""" alpha_limit = 1e-5 """rec_half_rho_TT is a constant representing the reciprocal of half the second derivative of density with respect to temperature near the temperature of maximum density.""" rec_half_rho_TT = -110.0 t = np.zeros_like(SA) + np.NaN t_multiple = np.zeros_like(SA) + np.NaN I_SA = np.logical_or(SA < 0, SA > 42) I_p = np.logical_or(p < -1.5, p > 12000) I_SA_p = np.logical_or(I_SA, I_p) SA[I_SA_p] = np.ma.masked rho_40 = rho_t_exact(SA, 40 * np.ones_like(SA), p) I_rho_light = (rho - rho_40) < 0 SA[I_rho_light] = np.ma.masked t_max_rho = t_maxdensity_exact(SA, p) rho_max = rho_t_exact(SA, t_max_rho, p) rho_extreme = rho_max t_freezing = t_freezing(SA, p) # Assumes seawater is saturated with air. rho_freezing = rho_t_exact(SA, t_freezing, p) I_fr_gr_max = (t_freezing - t_max_rho) > 0 rho_extreme[I_fr_gr_max] = rho_freezing[I_fr_gr_max] I_rho_dense = rho > rho_extreme SA[I_rho_dense] = np.ma.masked # FIXME: Is this needed? I_bad = np.isnan(SA * p * rho) SA[I_bad] = np.ma.masked alpha_freezing = alpha_wrt_t_exact(SA, t_freezing, p) I_salty = alpha_freezing > alpha_limit t_diff = 40. * np.ones_like(I_salty) - t_freezing(I_salty) top = (rho_40[I_salty] - rho_freezing[I_salty] + rho_freezing[I_salty] * alpha_freezing[I_salty] * t_diff) a = top / (t_diff ** 2) b = -rho_freezing[I_salty] * alpha_freezing[I_salty] c = rho_freezing[I_salty] - rho[I_salty] sqrt_disc = np.sqrt(b ** 2 - 4 * a * c) # The value of t[I_salty] is the initial guess `t` in the range of I_salty. t[I_salty] = t_freezing[I_salty] + 0.5 * (-b - sqrt_disc) / a I_fresh = alpha_freezing <= alpha_limit t_diff = 40 * np.ones_like[I_fresh] - t_max_rho[I_fresh] factor = ((rho_max[I_fresh] - rho[I_fresh]) / (rho_max[I_fresh] - rho_40[I_fresh])) delta_t = t_diff * np.sqrt(factor) I_fresh_NR = delta_t > 5 t[I_fresh[I_fresh_NR]] = (t_max_rho[I_fresh[I_fresh_NR]] + delta_t[I_fresh_NR]) I_quad = delta_t <= 5 t_a = np.zeros_like(SA) + np.NaN # Set the initial value of the quadratic solution roots. t_a[I_fresh[I_quad]] = (t_max_rho[I_fresh[I_quad]] + np.sqrt(rec_half_rho_TT * (rho[I_fresh[I_quad]] - rho_max[I_fresh[I_quad]]))) for Number_of_iterations in range(0, 5): t_old = t_a rho_old = rho_t_exact(SA, t_old, p) factorqa = (rho_max - rho) / (rho_max - rho_old) t_a = t_max_rho + (t_old - t_max_rho) * np.sqrt(factorqa) t_a[t_freezing - t_a < 0] = np.ma.masked t_b = np.zeros_like(SA) + np.NaN # Set the initial value of the quadratic solution routes. t_b[I_fresh[I_quad]] = (t_max_rho[I_fresh[I_quad]] - np.sqrt(rec_half_rho_TT * (rho[I_fresh[I_quad]] - rho_max[I_fresh[I_quad]]))) for Number_of_iterations in range(0, 6): t_old = t_b rho_old = rho_t_exact(SA, t_old, p) factorqb = (rho_max - rho) / (rho_max - rho_old) t_b = t_max_rho + (t_old - t_max_rho) * np.sqrt(factorqb) # After seven iterations of this quadratic iterative procedure, # the error in rho is no larger than 4.6x10^-13 kg/m^3. t_b[t_freezing - t_b < 0] = np.ma.masked # Begin the modified Newton-Raphson iterative method, which will only # operate on non-masked data. v_lab = np.ones_like(rho) / rho v_t = gibbs(0, 1, 1, SA, t, p) for Number_of_iterations in range(0, 3): t_old = t delta_v = gibbs(0, 0, 1, SA, t_old, p) - v_lab t = t_old - delta_v / v_t # Half way through the modified N-R method. t_mean = 0.5 * (t + t_old) v_t = gibbs(0, 1, 1, SA, t_mean, p) t = t_old - delta_v / v_t I_quad = ~np.isnan(t_a) t[I_quad] = t_a[I_quad] I_quad = ~np.isnan(t_b) t_multiple[I_quad] = t_b[I_quad] # After three iterations of this modified Newton-Raphson iteration, # the error in rho is no larger than 4.6x10^-13 kg/m^3. return t, t_multiple @match_args_return def pot_rho_t_exact(SA, t, p, p_ref=0): r"""Calculates potential density of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] p_ref : int, float, optional reference pressure, default = 0 Returns ------- pot_rho : array_like potential density [kg m :sup:`-3`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.pot_rho_t_exact(SA, t, p) array([ 1021.79814581, 1022.05248442, 1023.89358365, 1026.66762112, 1027.10723087, 1027.40963126]) >>> gsw.pot_rho(SA, t, p, p_ref=1000) array([ 1025.95554512, 1026.21306986, 1028.12563226, 1031.1204547 , 1031.63768355, 1032.00240412]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.4. Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker """ pt = pt_from_t(SA, t, p, p_ref=p_ref) return rho_t_exact(SA, pt, p_ref) @match_args_return def alpha_wrt_CT_t_exact(SA, t, p): r"""Calculates the thermal expansion coefficient of seawater with respect to Conservative Temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- alpha_wrt_CT : array_like thermal expansion coefficient [K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.alpha_wrt_CT_t_exact(SA, t, p) array([ 0.00032471, 0.00032272, 0.00028118, 0.00017314, 0.00014627, 0.00012943]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.18.3). Modifications: 2011-03-29. Trevor McDougall and Paul Barker """ pt0 = pt0_from_t(SA, t, p) factor = -cp0 / ((Kelvin + pt0) * gibbs(n0, n2, n0, SA, t, p)) return factor * (gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p)) @match_args_return def alpha_wrt_pt_t_exact(SA, t, p): r"""Calculates the thermal expansion coefficient of seawater with respect to potential temperature, with a reference pressure of zero. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- alpha_wrt_pt : array_like thermal expansion coefficient [K :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.alpha_wrt_pt_t_exact(SA, t, p) array([ 0.00032562, 0.00032355, 0.00028164, 0.00017314, 0.00014623, 0.00012936]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.18.2). Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker """ pt0 = pt0_from_t(SA, t, p) factor = gibbs(n0, n2, n0, SA, pt0, 0) / gibbs(n0, n2, n0, SA, t, p) return factor * (gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p)) @match_args_return def beta_const_CT_t_exact(SA, t, p): r"""Calculates the saline (i.e. haline) contraction coefficient of seawater at constant Conservative Temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- beta_const_CT : array_like saline contraction coefficient [kg g :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.beta_const_CT_t_exact(SA, t, p) array([ 0.00071749, 0.00071765, 0.00072622, 0.00075051, 0.00075506, 0.00075707]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.19.3) Modifications: 2010-07-23. David Jackett, Trevor McDougall and Paul Barker """ # TODO: Original GSW-V3 re-implements gibbs, check what to do here! pt0 = pt0_from_t(SA, t, p) factora = (gibbs(n1, n1, n0, SA, t, p) - gibbs(n1, n0, n0, SA, pt0, 0) / (Kelvin + pt0)) factor = (factora / (gibbs(n0, n0, n1, SA, t, p) * gibbs(n0, n2, n0, SA, t, p))) return (gibbs(n0, n1, n1, SA, t, p) * factor - gibbs(n1, n0, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p)) @match_args_return def beta_const_pt_t_exact(SA, t, p): r"""Calculates the saline (i.e. haline) contraction coefficient of seawater at constant potential temperature with a reference pressure of 0 dbar. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- beta_const_pt : array_like saline contraction coefficient [kg g :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.beta_const_pt_t_exact(SA, t, p) array([ 0.00073112, 0.00073106, 0.00073599, 0.00075375, 0.00075712, 0.00075843]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.19.2) Modifications: 2011-04-10. Trevor McDougall and Paul Barker """ # NOTE: The original Matlab toolbox re-implement some code here. Why? pt0 = pt0_from_t(SA, t, p) factora = gibbs(n1, n1, n0, SA, t, p) - gibbs(n1, n1, n0, SA, pt0, 0) factor = (factora / (gibbs(n0, n0, n1, SA, t, p) * gibbs(n0, n2, n0, SA, t, p))) return (gibbs(n0, n1, n1, SA, t, p) * factor - gibbs(n1, n0, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p)) @match_args_return def beta_const_t_exact(SA, t, p): r"""Calculates the saline (i.e. haline) contraction coefficient of seawater at constant in situ temperature. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- beta_const_t : array_like saline contraction coefficient [kg g :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.beta_const_t_exact(SA, t, p) array([ 0.00073112, 0.00073107, 0.00073602, 0.00075381, 0.00075726, 0.00075865]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.19.1) Modifications: 2011-03-29. David Jackett, Trevor McDougall and Paul Barker """ return -gibbs(n1, n0, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p) @match_args_return def chem_potential_water_t_exact(SA, t, p): r"""Calculates the chemical potential of water in seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- chem_potential_water : array_like chemical potential of water in seawater [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.chem_potential_water_t_exact(SA, t, p) array([-8545.56114628, -8008.08554834, -5103.98013987, -634.06778275, 3335.56680347, 7555.43444597]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-03-29. Trevor McDougall and Paul Barker """ SA, t, p, mask = strip_mask(SA, t, p) # FIXME: Ugly copy from gibbs, why? x2 = sfac * SA x = np.sqrt(x2) y = t * 0.025 z = p * 1e-4 # Pressure (p) is sea pressure in units of dbar. g03_g = (101.342743139674 + z * (100015.695367145 + z * (-2544.5765420363 + z * (284.517778446287 + z * (-33.3146754253611 + (4.20263108803084 - 0.546428511471039 * z) * z)))) + y * (5.90578347909402 + z * (-270.983805184062 + z * (776.153611613101 + z * (-196.51255088122 + (28.9796526294175 - 2.13290083518327 * z) * z))) + y * (-12357.785933039 + z * (1455.0364540468 + z * (-756.558385769359 + z * (273.479662323528 + z * (-55.5604063817218 + 4.34420671917197 * z)))) + y * (736.741204151612 + z * (-672.50778314507 + z * (499.360390819152 + z * (-239.545330654412 + (48.8012518593872 - 1.66307106208905 * z) * z))) + y * (-148.185936433658 + z * (397.968445406972 + z * (-301.815380621876 + (152.196371733841 - 26.3748377232802 * z) * z)) + y * (58.0259125842571 + z * (-194.618310617595 + z * (120.520654902025 + z * (-55.2723052340152 + 6.48190668077221 * z))) + y * (-18.9843846514172 + y * (3.05081646487967 - 9.63108119393062 * z) + z * (63.5113936641785 + z * (-22.2897317140459 + 8.17060541818112 * z))))))))) g08_g = x2 * (1416.27648484197 + x * (-2432.14662381794 + x * (2025.80115603697 + y * (543.835333000098 + y * (-68.5572509204491 + y * (49.3667694856254 + y * (-17.1397577419788 + 2.49697009569508 * y))) - 22.6683558512829 * z) + x * (-1091.66841042967 - 196.028306689776 * y + x * (374.60123787784 - 48.5891069025409 * x + 36.7571622995805 * y) + 36.0284195611086 * z) + z * (-54.7919133532887 + (-4.08193978912261 - 30.1755111971161 * z) * z)) + z * (199.459603073901 + z * (-52.2940909281335 + (68.0444942726459 - 3.41251932441282 * z) * z)) + y * (-493.407510141682 + z * (-175.292041186547 + (83.1923927801819 - 29.483064349429 * z) * z) + y * (-43.0664675978042 + z * (383.058066002476 + z * (-54.1917262517112 + 25.6398487389914 * z)) + y * (-10.0227370861875 - 460.319931801257 * z + y * (0.875600661808945 + 234.565187611355 * z))))) + y * (168.072408311545)) g_SA_part = (8645.36753595126 + x * (-7296.43987145382 + x * (8103.20462414788 + y * (2175.341332000392 + y * (-274.2290036817964 + y * (197.4670779425016 + y * (-68.5590309679152 + 9.98788038278032 * y))) - 90.6734234051316 * z) + x * (-5458.34205214835 - 980.14153344888 * y + x * (2247.60742726704 - 340.1237483177863 * x + 220.542973797483 * y) + 180.142097805543 * z) + z * (-219.1676534131548 + (-16.32775915649044 - 120.7020447884644 * z) * z)) + z * (598.378809221703 + z * (-156.8822727844005 + (204.1334828179377 - 10.23755797323846 * z) * z)) + y * (-1480.222530425046 + z * (-525.876123559641 + (249.57717834054571 - 88.449193048287 * z) * z) + y * (-129.1994027934126 + z * (1149.174198007428 + z * (-162.5751787551336 + 76.9195462169742 * z)) + y * (-30.0682112585625 - 1380.9597954037708 * z + y * (2.626801985426835 + 703.695562834065 * z))))) + y * (1187.3715515697959)) chem_potential_water = g03_g + g08_g - 0.5 * sfac * SA * g_SA_part return np.ma.array(chem_potential_water, mask=mask, copy=False) @match_args_return def chem_potential_salt_t_exact(SA, t, p): r"""Calculates the chemical potential of salt in seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- chem_potential_salt : array_like chemical potential of salt in seawater [J kg :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.chem_potential_salt_t_exact(SA, t, p) array([-8466.13569818, -7928.8256562 , -5029.28859129, -568.42714556, 3396.79366004, 7612.64743154]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 2.9. Modifications: 2010-03-29. Trevor McDougall and Paul Barker """ return (chem_potential_relative_t_exact(SA, t, p) + chem_potential_water_t_exact(SA, t, p)) @match_args_return def adiabatic_lapse_rate_t_exact(SA, t, p): r"""Calculates the adiabatic lapse rate of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- adiabatic_lapse_rate : array_like Adiabatic lapse rate [K Pa :sup:`-1`] See Also -------- TODO Notes ----- The output is in unit of degrees Celsius per Pa, (or equivalently K/Pa) not in units of K/dbar Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.adiabatic_lapse_rate_t_exact(SA, t, p) array([ 2.40350282e-08, 2.38496700e-08, 2.03479880e-08, 1.19586543e-08, 9.96170718e-09, 8.71747270e-09]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See Eqn. (2.22.1). Modifications: 2011-03-29. Trevor McDougall and Paul Barker """ return -gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n2, n0, SA, t, p) @match_args_return def osmotic_coefficient_t_exact(SA, t, p): r"""Calculates the osmotic coefficient of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- osmotic_coefficient : array_like osmotic coefficient of seawater [unitless] See Also -------- TODO Notes ----- TODO Examples -------- >>> import gsw >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324] >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036] >>> p = [10, 50, 125, 250, 600, 1000] >>> gsw.osmotic_coefficient_t_exact(SA,t , p) array([ 0.90284718, 0.90298624, 0.90238866, 0.89880927, 0.89801054, 0.89767912]) References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. Modifications: 2011-04-01. Trevor McDougall and Paul Barker. 2012-11-15. Trevor McDougall and Paul Barker. """ SA = np.maximum(SA, 0) k = M_S / R part = k * (1000 - SA) / (Kelvin + t) x2 = sfac * SA x = np.sqrt(x2) y = t * 0.025 # Note that the input pressure (p) is sea pressure in units of dbar. z = p / db2Pascal oc = (7.231916621570606e1, 1.059039593127674e1, -3.025914794694813e1, 5.040733670521486e1, -4.074543321119333e1, 1.864215613820487e1, -3.022566485046178, -6.138647522851840, 1.353207379758663e1, -7.316560781114737, 1.829232499785750, -5.358042980767074e-1, -1.705887283375562, -1.246962174707332e-1, 1.228376913546017, 1.089364009088042e-2, -4.264828939262248e-1, 6.213127679460041e-2, 2.481543497315280, -1.363368964861909, -5.640491627443773e-1, 1.344724779893754, -2.180866793244492, 4.765753255963401, -5.726993916772165, 2.918303792060746, -6.506082399183509e-1, -1.015695507663942e-1, 1.035024326471108, -6.742173543702397e-1, 8.465642650849419e-1, -7.508472135244717e-1, -3.668086444057845e-1, 3.189939162107803e-1, -4.245629194309487e-2) tl = (oc[0] + oc[1] * y + x * (oc[2] + x * (oc[3] + x * (oc[4] + x * (oc[5] + oc[6] * x))) + y * (oc[7] + x * (oc[8] + x * (oc[9] + oc[10] * x)) + y * (oc[11] + oc[12] * x + y * (oc[13] + oc[14] * x + y * (oc[15] + x * (oc[16] + oc[17] * y))))) + z * (oc[18] + x * (oc[19] + oc[20] * y + oc[21] * x) + y * (oc[22] + y * (oc[23] + y * (oc[24] + oc[25] * y))) + z * (oc[26] + oc[27] * x + y * (oc[28] + oc[29] * y) + z * (oc[30] + oc[31] * x + y * (oc[32] + oc[33] * y) + oc[34] * z))))) return tl * part @match_args_return def dynamic_enthalpy_t_exact(SA, t, p): r"""Calculates the dynamic enthalpy of seawater from Absolute Salinity, in situ temperature and pressure. Dynamic enthalpy was defined by Young (2010) as the difference between enthalpy and potential enthalpy. Note that this function uses the full TEOS-10 Gibbs function (i.e. the sum of the IAPWS-09 and IAPWS-08 Gibbs functions, see the TEOS-10 Manual, IOC et al. (2010)). Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] p : array_like pressure [dbar] Returns ------- dynamic_enthalpy_t_exact : array_like dynamic enthalpy [J :sup:`-1`] See Also -------- TODO Notes ----- TODO Examples -------- References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. .. [2] Young, W.R., 2010: Dynamic enthalpy, Conservative Temperature, and the seawater. Boussinesq approximation. Journal of Physical Oceanography, 40, 394-400. Modifications: 2011-04-11. Trevor McDougall and Paul Barker """ CT = CT_from_t(SA, t, p) return enthalpy_t_exact(SA, t, p) - cp0 * CT @match_args_return def t_maxdensity_exact(SA, p): r"""Calculates the in-situ temperature of maximum density of seawater. This function returns the in-situ temperature at which the density of seawater is a maximum, at given Absolute Salinity, SA, and sea pressure, p (in dbar). Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] p : array_like pressure [dbar] Returns ------- t_maxdensity_exact : array_like max in-situ temperature [:math:`^\circ` C] See Also -------- TODO Notes ----- TODO Examples -------- References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.42. Modifications: 2011-04-03. Trevor McDougall and Paul Barker """ # The temperature increment for calculating the gibbs_PTT derivative. dt = 0.001 t = 3.978 - 0.22072 * SA # The initial guess of t_maxden. gibbs_PTT = 1.1e-8 # The initial guess for g_PTT. for Number_of_iterations in range(0, 3): t_old = t gibbs_PT = gibbs(n0, n1, n1, SA, t_old, p) # Half way through the mod. method (McDougall and Wotherspoon, 2012) t = t_old - gibbs_PT / gibbs_PTT t_mean = 0.5 * (t + t_old) gibbs_PTT = (gibbs(n0, n1, n1, SA, t_mean + dt, p) - gibbs(n0, n1, n1, SA, t_mean - dt, p)) / (dt + dt) t = t_old - gibbs_PT / gibbs_PTT # After three iterations of this modified Newton-Raphson iteration, the # error in t_maxdensity_exact is typically no larger than 1x10^-15 deg C. return t @match_args_return def osmotic_pressure_t_exact(SA, t, pw): r"""Calculates the osmotic pressure of seawater. Parameters ---------- SA : array_like Absolute salinity [g kg :sup:`-1`] t : array_like in situ temperature [:math:`^\circ` C (ITS-90)] pw : array_like sea pressure of the pure water side [dbar] Returns ------- osmotic_pressure_t_exact : array_like dynamic osmotic pressure of seawater [dbar] See Also -------- TODO Notes ----- TODO Examples -------- References ---------- .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of seawater - 2010: Calculation and use of thermodynamic properties. Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, UNESCO (English), 196 pp. See section 3.41. Modifications: 2011-05-26. Trevor McDougall and Paul Barker """ SA = np.maximum(SA, 0) gibbs_pure_water = gibbs(0, 0, 0, 0, t, pw) # Initial guess of p, in dbar. p = pw + 235.4684 # Initial guess of df/dp. df_dp = -db2Pascal * (gibbs(n0, n0, n1, SA, t, p) - SA * gibbs(n1, n0, n1, SA, t, p)) for Number_of_iterations in range(0, 2): p_old = p f = gibbs_pure_water - chem_potential_water_t_exact(SA, t, p_old) # This is half way through the modified N-R method. p = p_old - f / df_dp p_mean = 0.5 * (p + p_old) df_dp = -db2Pascal * (gibbs(0, 0, 1, SA, t, p_mean) - SA * gibbs(1, 0, 1, SA, t, p_mean)) p = p_old - f / df_dp # After two iterations though the modified Newton-Raphson technique the # maximum error is 6x10^-12 dbar. # Osmotic pressure of seawater in dbar. return p - pw if __name__ == '__main__': import doctest doctest.testmod() gsw-3.0.2/docs/0000755000175000017500000000000012172027023014372 5ustar amckinstryamckinstrygsw-3.0.2/docs/conf.py0000644000175000017500000001436212172027023015677 0ustar amckinstryamckinstry# -*- coding: utf-8 -*- # # seawater documentation build configuration file, created by # sphinx-quickstart on Tue Aug 10 16:47:25 2010. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.append(os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.pngmath', 'numpydoc', 'numpydoc.plot_directive'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = u'seawater' copyright = u'2010, Filipe Fernandes' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '3.0' # The full version, including alpha/beta/rc tags. release = '3.0.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'gswdoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'gsw.tex', u'GSW Documentation', u'Filipe Fernandes', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True gsw-3.0.2/docs/index.rst0000644000175000017500000000154312172027023016236 0ustar amckinstryamckinstry.. seawater documentation master file, created by sphinx-quickstart on Tue Aug 10 16:47:25 2010. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to gsw's documentation! ==================================== python gsw ========== Introduction: ------------- Python implementation of the Thermodynamic Equation Of Seawater - 2010 (TEOS-10) For more information go to: http://www.teos-10.org/ Modules: -------- .. toctree:: :maxdepth: 4 gibbs Seawater Documentation ============================ This page contains the gsw Module documentation. The :mod:`gibbs` module ----------------------- .. automodule:: seawater.gibbs :members: :undoc-members: :show-inheritance: Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` gsw-3.0.2/docs/Makefile0000644000175000017500000000607212172027023016037 0ustar amckinstryamckinstry# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/seawater.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/seawater.qhc" latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." gsw-3.0.2/CHANGES.txt0000644000175000017500000000010012172027023015242 0ustar amckinstryamckinstry2012-03-14 -- New repository with TEOS10 code (version 3 only). gsw-3.0.2/README.rst0000644000175000017500000002232312172027023015133 0ustar amckinstryamckinstry========== python gsw ========== Python implementation of the Thermodynamic Equation Of Seawater - 2010 (TEOS-10) -------------------------------------------------------------------------------- For more information go to: http://www.teos-10.org/ gsw vs. csiro ^^^^^^^^^^^^^ .. role:: raw-math(raw) :format: latex html This table shows some function names in the gibbs library and the corresponding function names in the csiro library. +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | **Variable** | **SeaWater (EOS 80)** | **Gibbs SeaWater (GSW TEOS 10)** | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | Absolute Salinity | NA | gsw.SA_from_SP(SP,p,long,lat) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | Conservative Temperature | NA | gsw.CT_from_t(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | density (i.e. in situ density) | sw.dens(SP,t,p) | gsw.rho_CT(SA,CT,p), or gsw.rho(SA,t,p), or | | | | gsw.rho_CT25(SA,CT,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | potential density | sw.pden(SP,t,p,pr) | gsw.rho_CT(SA,CT,pr), or | | | | gsw.rho_CT25(SA,CT,pr) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | potential temperature | sw.ptmp(SP,t,p,pr) | gsw.pt_from_t(SA,t,p,pr) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | :math:`\sigma_0`, using | sw.dens(SP, :math:`\theta_o`, 0) | gsw.sigma0_CT(SA,CT) | | :math:`\theta_o` = sw.ptmp(SP,t,p,0) | -1000 kg m :sup:`-3` | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | :math:`\sigma_2`, using | sw.dens(SP,:math:`\theta_2`, 2000) | gsw.sigma2_CT(SA,CT) | | :math:`\theta_2` = sw.ptmp(SP,t,p,2000) | -1000 kg m :sup:`-3` | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | :math:`\sigma_4`, using | sw.dens(SP,:math:`\theta_4`, 4000) | gsw.sigma2_CT(SA,CT) | | :math:`\theta_4` = sw.ptmp(SP,t,p,2000) | -1000 kg m :sup:`-3` | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | specific volume anomaly | sw.svan(SP,t,p) | gsw.specvol_anom_CT(SA,CT,p) or | | | | gsw.specvol_anom_CT25(SA,CT,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | dynamic height anomaly | -sw.gpan(SP,t,p) | gsw.geo_strf_dyn_height(SA,CT,p,delta_p,interp_style) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | geostrophic velocity | sw.gvel(ga,lat,long) | gsw.geostrophic_velocity(geo_str,long,lat,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | N :sup:`2` | sw.bfrq(SP,t,p,lat) | gsw.Nsquared_CT25(SA,CT,p,lat) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | pressure from height | sw.pres(-z,lat) | gsw.p_from_z(z,lat) | | (SW uses depth, not height) | | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | height from pressure | z = -sw.dpth(p,lat) | gsw.z_from_p(p,lat) | | (SW outputs depth, not height) | | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | in situ temperature from pt | sw.temp(SP,pt,p,pr) | gsw.pt_from_t(SA,pt,pr,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | sound speed | sw.svel(SP,t,p) | gsw.sound_speed(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | isobaric heat capacity | sw.cp(SP,t,p) | gsw.cp(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | adiabatic lapse rate* | sw.adtg(SP,t,p) | gsw.adiabatic_lapse_rate(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | SP from cndr, (PSS 78) | sw.salt(cndr,t,p) | gsw.SP_from_cndr(cndr,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | cndr from SP, (PSS 78) | sw.cndr(SP,t,p) | gsw.cndr_from_SP(SP,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | distance | sw.dist(lat,long,units) | gsw.distance(long,lat,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | gravitational acceleration | sw.g(lat,z) | gsw.grav(lat,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | Coriolis parameter | sw.f(lat) | gsw.f(lat) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | testing of all functions | sw.test() | gsw.test() | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ \* The SW and GSW functions output the adiabatic lapse rate in different units, being K (dbar) :sup:`-1` and K Pa :sup:`-1` respectively. Thanks ====== * Bjørn Ådlandsvik - Testing unit and several bug fixes * Eric Firing - Support for masked arrays, re-write of _delta_SA * Trevor J. McDougall (and all of SCOR/IAPSO WG127) for making available the Matlab and Fortran versions of this software Acknowledgments --------------- * SCOR/IAPSO WG127. Most of module is derived from the GSW Oceanographic Toolbox of TEOS-10. The MAJOR.MINOR.MICRO will be used to represent: MAJOR == The matlab version from the TEOS-10 Group MINOR == Significant changes made in the python version MICRO == Bug fixes only gsw-3.0.2/PKG-INFO0000644000175000017500000002757412172027023014556 0ustar amckinstryamckinstryMetadata-Version: 1.1 Name: gsw Version: 3.0.2 Summary: Gibbs SeaWater Oceanographic Package of TEOS-10 Home-page: http://pypi.python.org/pypi/seawater/ Author: Filipe Fernandes Author-email: ocefpaf@gmail.com License: Copyright Notice and Statement for the gsw project: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Download-URL: https://pypi.python.org/pypi/gsw/ Description: ========== python gsw ========== Python implementation of the Thermodynamic Equation Of Seawater - 2010 (TEOS-10) -------------------------------------------------------------------------------- For more information go to: http://www.teos-10.org/ gsw vs. csiro ^^^^^^^^^^^^^ .. role:: raw-math(raw) :format: latex html This table shows some function names in the gibbs library and the corresponding function names in the csiro library. +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | **Variable** | **SeaWater (EOS 80)** | **Gibbs SeaWater (GSW TEOS 10)** | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | Absolute Salinity | NA | gsw.SA_from_SP(SP,p,long,lat) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | Conservative Temperature | NA | gsw.CT_from_t(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | density (i.e. in situ density) | sw.dens(SP,t,p) | gsw.rho_CT(SA,CT,p), or gsw.rho(SA,t,p), or | | | | gsw.rho_CT25(SA,CT,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | potential density | sw.pden(SP,t,p,pr) | gsw.rho_CT(SA,CT,pr), or | | | | gsw.rho_CT25(SA,CT,pr) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | potential temperature | sw.ptmp(SP,t,p,pr) | gsw.pt_from_t(SA,t,p,pr) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | :math:`\sigma_0`, using | sw.dens(SP, :math:`\theta_o`, 0) | gsw.sigma0_CT(SA,CT) | | :math:`\theta_o` = sw.ptmp(SP,t,p,0) | -1000 kg m :sup:`-3` | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | :math:`\sigma_2`, using | sw.dens(SP,:math:`\theta_2`, 2000) | gsw.sigma2_CT(SA,CT) | | :math:`\theta_2` = sw.ptmp(SP,t,p,2000) | -1000 kg m :sup:`-3` | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | :math:`\sigma_4`, using | sw.dens(SP,:math:`\theta_4`, 4000) | gsw.sigma2_CT(SA,CT) | | :math:`\theta_4` = sw.ptmp(SP,t,p,2000) | -1000 kg m :sup:`-3` | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | specific volume anomaly | sw.svan(SP,t,p) | gsw.specvol_anom_CT(SA,CT,p) or | | | | gsw.specvol_anom_CT25(SA,CT,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | dynamic height anomaly | -sw.gpan(SP,t,p) | gsw.geo_strf_dyn_height(SA,CT,p,delta_p,interp_style) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | geostrophic velocity | sw.gvel(ga,lat,long) | gsw.geostrophic_velocity(geo_str,long,lat,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | N :sup:`2` | sw.bfrq(SP,t,p,lat) | gsw.Nsquared_CT25(SA,CT,p,lat) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | pressure from height | sw.pres(-z,lat) | gsw.p_from_z(z,lat) | | (SW uses depth, not height) | | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | height from pressure | z = -sw.dpth(p,lat) | gsw.z_from_p(p,lat) | | (SW outputs depth, not height) | | | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | in situ temperature from pt | sw.temp(SP,pt,p,pr) | gsw.pt_from_t(SA,pt,pr,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | sound speed | sw.svel(SP,t,p) | gsw.sound_speed(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | isobaric heat capacity | sw.cp(SP,t,p) | gsw.cp(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | adiabatic lapse rate* | sw.adtg(SP,t,p) | gsw.adiabatic_lapse_rate(SA,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | SP from cndr, (PSS 78) | sw.salt(cndr,t,p) | gsw.SP_from_cndr(cndr,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | cndr from SP, (PSS 78) | sw.cndr(SP,t,p) | gsw.cndr_from_SP(SP,t,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | distance | sw.dist(lat,long,units) | gsw.distance(long,lat,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | gravitational acceleration | sw.g(lat,z) | gsw.grav(lat,p) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | Coriolis parameter | sw.f(lat) | gsw.f(lat) | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ | testing of all functions | sw.test() | gsw.test() | +-------------------------------------------+-------------------------------------+-------------------------------------------------------+ \* The SW and GSW functions output the adiabatic lapse rate in different units, being K (dbar) :sup:`-1` and K Pa :sup:`-1` respectively. Thanks ====== * Bjørn Ådlandsvik - Testing unit and several bug fixes * Eric Firing - Support for masked arrays, re-write of _delta_SA * Trevor J. McDougall (and all of SCOR/IAPSO WG127) for making available the Matlab and Fortran versions of this software Acknowledgments --------------- * SCOR/IAPSO WG127. Most of module is derived from the GSW Oceanographic Toolbox of TEOS-10. The MAJOR.MINOR.MICRO will be used to represent: MAJOR == The matlab version from the TEOS-10 Group MINOR == Significant changes made in the python version MICRO == Bug fixes only Keywords: oceanography,seawater Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Intended Audience :: Science/Research Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Education Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Scientific/Engineering Classifier: Topic :: Education Classifier: Topic :: Software Development :: Libraries :: Python Modules gsw-3.0.2/LICENSE.txt0000644000175000017500000000206412172027023015267 0ustar amckinstryamckinstryCopyright Notice and Statement for the gsw project: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.