Skip to content

Commit

Permalink
Conversion documentation (#59)
Browse files Browse the repository at this point in the history
* Initializing documentation for sr_from_sp

* Guidance for missing functions

* Tagging source code in documentation

* doc: ct_from_pt()

* doc: t90_from_t48()

* doc: t68_from_t90()

* Adding Saunders 1990

* Adding Millero 2008 reference

* typo: License in the README file

* refactor: Re-routing t68_from_t90()

* doc: Extending documentation

Note that is it still missing some references, but I have to make time
to carefully read each one.

* doc: Adding some symbols

* Upgrade version to reflect on the public documentation
  • Loading branch information
castelao authored Sep 13, 2023
1 parent 51e7829 commit 8a461ed
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gsw"
version = "0.1.3"
version = "0.1.4"
authors = ["Guilherme Castelão <[email protected]>", "Luiz Irber <[email protected]>"]
edition = "2018"
description = "TEOS-10 v3.06.12 Gibbs Seawater Oceanographic Toolbox in Rust"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ https://doi.org/10.5281/zenodo.5348561
title = {{Gibbs Sea Water Oceanographic Toolbox of TEOS-10 implemented in Rust}},
author = {Castelao, Guilherme and Irber, Luiz},
year = {2021},
license = {MIT OR Apache-2.0},
license = {BSD-3-Clause},
version = {0.1.1},
doi = {10.5281/zenodo.5348561},
url = {https://github.com/castelao/GSW-rs}
Expand Down
210 changes: 203 additions & 7 deletions src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ use crate::{Error, Result};
/*
/// Absolute Salinity Anomaly from Practical Salinity
///
/// # Arguments
///
/// * `sp`:
/// * `p`:
/// * `lon`:
/// * `lat`:
///
/// # Returns
///
/// # References
///
/// # Examples
///
pub fn deltasa_from_sp(sp: f64, p: f64, lon: f64, lat: f64) -> Result<f64> {
// Remove out of range values
if ((p < 100.0) & (sp > 120.0)) | ((p >= 100.0) & (sp > 42.0)) {
Expand Down Expand Up @@ -50,10 +63,30 @@ pub fn deltasa_from_sp(sp: f64, p: f64, lon: f64, lat: f64) -> Result<f64> {
*/

/*
gsw_deltaSA_from_SP(gsw_sa_from_sp, gsw_sr_from_sp)
gsw_SA_Sstar_from_SP
*/

/// Reference Salinity from Practical Salinity
/// Reference Salinity ($S_R$) from Practical Salinity ($S_P$)
///
/// # Arguments
///
/// * `sp`: Practical salinity (PSS-78) \[unitless\]
///
/// # Returns
///
/// * `sr`: Reference salinity \[g kg-1\]
///
/// # Features
///
/// If compiled with 'compat', $u_{PS}$ is approximated to
/// 1.004715428571429, which can cause a minimal rounding error.
///
/// # 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.
///
/// # Examples
/// ```
Expand All @@ -70,7 +103,26 @@ pub fn sr_from_sp(sp: f64) -> f64 {
}
}

/// Practical Salinity from Reference Salinity
/// Practical Salinity ($S_P$) from Reference Salinity ($S_R$)
///
/// # Arguments
///
/// * `sr`: Reference salinity \[g kg-1\]
///
/// # Returns
///
/// * `sp`: Practical salinity (PSS-78) \[unitless\]
///
/// # Features
///
/// If compiled with 'compat', $1/u_{PS}$ is approximated to
/// 0.995306702338459, which can cause a minimal rounding error.
///
/// # 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.
///
/// # Examples
/// ```
Expand All @@ -88,16 +140,38 @@ pub fn sp_from_sr(sr: f64) -> f64 {
}

/*
gsw_SP_from_SA
gsw_SP_from_SA(gsw_sp_from_sa_baltic)
gsw_Sstar_from_SA
gsw_SA_from_Sstar
gsw_SP_from_Sstar
gsw_pt_from_CT
gsw_t_from_CT
gsw_pt_from_CT(gsw_ct_from_pt, gsw_gibbs_pt0_pt0)
gsw_t_from_CT(gsw_ct_from_pt, gsw_pt_from_t)
*/

/// Conservative Temperature from potential temperature
///
/// # Arguments
///
/// * `sa`: Absolute salinity \[g kg-1\]
/// * `pt`: Potential temperature (ITS-90) \[deg C\]
///
/// # Returns
///
/// * `ct`: Conservative Temperature (ITS-90) \[deg C\]
///
/// # Features
///
/// * default: Negative salinity returns [Error::NegativeSalinity].
/// * compat:
/// * Negative salinity is assumed to be zero.
/// * S factor is approximated to 0.0248826675584615, which can cause a
/// minimal error.
/// * invalidasnan: Negative salinity results in NaN.
///
/// # References
///
/// # Examples
/// ```
/// use gsw::conversions::ct_from_pt;
Expand Down Expand Up @@ -153,12 +227,33 @@ pub fn ct_from_pt(sa: f64, pt: f64) -> Result<f64> {
/*
gsw_pot_enthalpy_from_pt
gsw_pt_from_t
gsw_pt0_from_t
gsw_pt0_from_t(gsw_entropy_part, gsw_entropy_part_zerop, gsw_gibbs_pt0_pt0)
gsw_t_from_pt0
*/

/// ITS-90 temperature from IPTS-48 temperature
///
/// # Arguments
///
/// * `t48`: Temperature (IPTS-48) \[deg C\]
///
/// # Returns
///
/// * `t90`: Temperature ITS-90 \[deg C\]
///
/// # References
///
/// Saunders, P. 1990: The International Temperature Scale of 1990, ITS-90.
/// WOCE Newsletter 10, IOS, Wormley, UK.
///
/// # Examples
/// ```
/// use gsw::conversions::t90_from_t48;
///
/// let t90 = t90_from_t48(12.0);
/// assert!((t90 - 11.992475405902583).abs() <= f64::EPSILON);
/// ```
///
pub fn t90_from_t48(t48: f64) -> f64 {
(t48 - (4.4e-6) * t48 * (100. - t48)) / 1.00024
}
Expand All @@ -177,11 +272,28 @@ pub fn t90_from_t48(t48: f64) -> f64 {
///
/// * `t90`: Temperature ITS-90 \[deg C\]
///
/// # Features
///
/// * default: Calculate precise $t_{68}$ / 1.00024
/// * compat: Approximate 1 / 1.00024 to 0.999760057586179, which can cause
/// a negligible error.
///
/// # Notes
///
/// * TEOS-10 manual recommends to continue using Saunders 1990 instead of
/// Rusby 1991.
///
/// # References
///
/// Saunders, P. 1990: The International Temperature Scale of 1990, ITS-90.
/// WOCE Newsletter 10, IOS, Wormley, UK.
///
/// # Examples
/// ```
/// use gsw::conversions::t90_from_t68;
///
/// let t90 = t90_from_t68(13.42);
/// assert!((t90 - 13.416779972806527).abs() <= f64::EPSILON);
/// ```
pub fn t90_from_t68(t68: f64) -> f64 {
if cfg!(feature = "compat") {
Expand All @@ -191,6 +303,32 @@ pub fn t90_from_t68(t68: f64) -> f64 {
}
}

/// IPTS-68 temperature from ITS-90 temperature
///
/// # Arguments
///
/// * `t90`: Temperature ITS-90 \[deg C\]
///
/// # Returns
///
/// * `t68`: Temperature IPTS-68 \[deg C\]
///
/// # References
///
/// Saunders, P. 1990: The International Temperature Scale of 1990, ITS-90.
/// WOCE Newsletter 10, IOS, Wormley, UK.
///
/// # Examples
/// ```
/// use gsw::conversions::t68_from_t90;
///
/// let t = t68_from_t90(13.42);
/// assert!((t - 13.4232208).abs() <= f64::EPSILON);
/// ```
pub fn t68_from_t90(t90: f64) -> f64 {
t90 * 1.00024
}

/// Height from pressure
///
/// Calculates the height z from pressure p
Expand All @@ -206,15 +344,24 @@ pub fn t90_from_t68(t68: f64) -> f64 {
/// * `z`: Height \[m\], where z points upward and is zero at the sea level,
/// thus it is negative in the ocean.
///
/// # Features
///
/// * default: $gamma$ = 2.26e-7.
/// * nodgdz: $gamma$ = 0, i.e. gravity doesn't depend on depth.
///
/// # References
///
/// # Notes
///
/// If geo_strf_dyn_height was obtained from geo_strf_dyn_height(), reference
/// pressure (p_ref) must be zero dbar.
///
/// # Examples
/// ```
/// use gsw::conversions::z_from_p;
///
/// let z = z_from_p(100.0, -60.250, 0.0, 0.0);
/// let z = z_from_p(6131., 11.0, 0.0, 0.0);
/// assert!((z - (-6010.854959777581)).abs() <= f64::EPSILON);
/// ```
pub fn z_from_p(
pressure: f64,
Expand All @@ -234,17 +381,34 @@ pub fn z_from_p(

/// Pressure from height (75-term polynomial approximation)
///
/// # Arguments
///
/// * `z`: Height \[m\], where z points upward and is zero at the sea level,
/// thus it is negative in the ocean.
/// * `lat`: Latitude \[deg\]
/// * `geo_strf_dyn_height`: Dynamic height anomaly \[m2 s-2\]. Optional
/// argument, thus can use 'None' to assume it zero.
/// * `sea_surface_geopotential`: Geopotential at zero sea pressure \[m2 s-2\].
/// Optional argument, thus can use 'None' to assume it zero.
///
/// # Returns
///
/// * `pressure`: Sea Pressure \[dbar\], i.e. absolute pressure - 10.1325 dbar.
///
/// # Notes
///
/// - The GSW-C does not allow dynamic height anomaly or geopotential at zero
/// * The GSW-C does not allow dynamic height anomaly or geopotential at zero
/// sea pressure.
/// * Optional arguments might change in the future to require instead an
/// explicit value.
///
/// # References
///
/// # Examples
/// ```
/// use gsw::conversions::p_from_z;
///
/// let z = p_from_z(-1000.0, 15., None, None).unwrap();
/// dbg!(&z);
/// assert!((z - 1008.321764487538).abs() <= f64::EPSILON);
/// ```
pub fn p_from_z(
Expand Down Expand Up @@ -289,6 +453,23 @@ gsw_depth_from_z

/// Absolute Pressure, P, from sea pressure, p
///
/// # Arguments
///
/// * `pressure`: Sea Pressure \[dbar\], i.e. absolute pressure - 10.1325 dbar.
///
/// # Returns
///
/// * absolute_pressure: Absolute pressure \[Pa\]
///
/// # References
///
/// # Examples
/// ```
/// use gsw::conversions::abs_pressure_from_p;
///
/// let P = abs_pressure_from_p(100.0);
/// assert!((P - 1101325.0).abs() <= f64::EPSILON);
/// ```
pub fn abs_pressure_from_p(p: f64) -> f64 {
p * DB2PA + GSW_P0
}
Expand All @@ -297,6 +478,20 @@ pub fn abs_pressure_from_p(p: f64) -> f64 {
///
/// # Arguments
/// * absolute_pressure: Absolute pressure \[Pa\]
///
/// # Returns
///
/// * `pressure`: Sea Pressure \[dbar\], i.e. absolute pressure - 10.1325 dbar.
///
/// # References
///
/// # Examples
/// ```
/// use gsw::conversions::p_from_abs_pressure;
///
/// let p = p_from_abs_pressure(1101325.0);
/// assert!((p - 100.0).abs() <= f64::EPSILON);
/// ```
pub fn p_from_abs_pressure(absolute_pressure: f64) -> f64 {
(absolute_pressure - GSW_P0) / DB2PA
}
Expand Down Expand Up @@ -331,5 +526,6 @@ mod tests {
#[test]
fn test_z_from_p() {
assert!((0.0 - z_from_p(0.0, 33.3482, 0.0, 0.0)).abs() < f64::EPSILON);
// assert_eq!(-6010.85496, z_from_p(6131.0, 11.0, 0.0, 0.0));
}
}
2 changes: 1 addition & 1 deletion src/gsw_internal_funcs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub(crate) fn enthalpy_sso_0(p: f64) -> f64 {
pub(crate) fn hill_ratio_at_sp2(t: f64) -> f64 {
let sp2 = 2.0;

let t68: f64 = crate::practical_salinity::t68_from_t90(t);
let t68: f64 = crate::conversions::t68_from_t90(t);
let ft68: f64 = (t68 - 15.0) / (1.0 + K * (t68 - 15.0));

// Find the initial estimates of Rtx (Rtx0) and of the derivative dSP_dRtx
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
//!
//! ## Design considerations
//!
//! - Functions that can result in failure return type Result<T>, as usual
//! - Functions that can result in failure return type `Result<T>`, as usual
//! in Rust. We prefer to return errors instead of NaN for two main reasons:
//! We can shortcut unnecessary long calculations, and we can provide more
//! information context for the next layer to support automatic decisions.
Expand Down
5 changes: 1 addition & 4 deletions src/practical_salinity.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
//! Practical Salinity
//!
use crate::conversions::t68_from_t90;
use crate::gsw_internal_const::*;
use crate::gsw_internal_funcs::*;
use crate::gsw_sp_coefficients::*;
use crate::{Error, Result};

pub(crate) fn t68_from_t90(t90: f64) -> f64 {
t90 * 1.00024
}

/// Practical Salinity from conductivity
///
/// # Arguments
Expand Down

0 comments on commit 8a461ed

Please sign in to comment.