ポテンシャル水温とポテンシャル密度 | 海洋観測

山頂の気温が低いのは、気圧が低いためです。標高が100m高くなるたびに気圧は約10hPa下がり、気温は約0.6℃下がるといわれています。これと同じことが海洋でも起こります。

深層になるほど海水は圧力の影響を強く受け、わずかですが水温が高めに出ます。したがって海水の密度を考えるとき、圧力を一定にして考える必要があります。このため気象学でいうところの温位に相当するものとして、海洋学にはポテンシャル水温というものがあります。

ポテンシャル水温とは、海水を断熱的(周囲と熱のやり取りなし)にある基準の深さまで持ってきたとき、その海水の示す水温を表します。これに対して、その場所での水温を現場水温といいます。通常基準の深さは海面にとります。またポテンシャル水温と塩分から計算した密度を、ポテンシャル密度といいます。

目次

ポテンシャル水温の計算式

  • 本計算式の定義は古く、現在の温度の定義ITS-90とは異なるIPTS-68の時代のものです。このため本計算を行うためには、ITS-90とIPTS-68の温度換算が必要です。本ページ内において「$T$」はITS-90の温度を、「$t$」はIPTS-68の温度を表します。
  • 1MPa = 100dbar ≒ 100m

実用塩分を$S$、現場水温を$T$ [℃]、現場圧力を$P$ [dbar]、基準圧力を$P_{r}$ [dbar]とすると、ポテンシャル水温$\theta$ [℃]は下記式1により求められます。なおポテンシャル水温の計算は少し特殊で、下記式を上から順に計算していくことになります。

$ \begin{aligned}
t &= 1.00024 \cdot T \\
h &= P_{r} – P \\
xk &= h \cdot {\rm \Gamma}(S, t, P) \\
t &= t + 0.5 \cdot xk \\
q &= xk \\
p &= P + 0.5 \cdot h \\
xk &= h \cdot {\rm \Gamma}(S, t, p) \\
t &= t + 0.29289322 \cdot (xk – q) \\
q &= 0.58578644 \cdot xk + 0.121320344 \cdot q \\
xk &= h \cdot {\rm \Gamma}(S, t, p) \\
t &= t + 1.707106781 \cdot ( xk – q ) \\
q &= 3.414213562 \cdot xk – 4.121320344 \cdot q \\
p &= p + 0.5 \cdot h \\
xk &= h \cdot {\rm \Gamma}(S, t, p) \\
\theta’ &= t + \frac{ xk – 2.0 \cdot q }{ 6.0 }\\
\theta(S, T, P, P_{r}) &= \theta’ \cdot 0.99976
\end{aligned} $

ここで${\rm \Gamma}(S, t, p)$は下記式により求められます。

$ \begin{aligned}
{\rm \Gamma}(S, t, p) &= a_{0} + a_{1} \cdot t + a_{2} \cdot t^{2} + a_{3} \cdot t^{3} + \left( b_{0} + b_{1} \cdot t \right) \cdot ( S – 35 ) \\
& + \left\{ c_{0} + c_{1} \cdot t + c_{2} \cdot t^{2} + c_{3} \cdot t^{3} +
\left( d_{0} + d_{1} \cdot t \right) \cdot ( S – 35 ) \right\} \cdot p \\
& + \left( e_{0} + e_{1} \cdot t + e_{2} \cdot t^{2} \right) \cdot p^{2}
\end{aligned} $

なお上記計算式で使用する係数は下記のとおりです。

$a_{0} = 3.5803 \times 10^{-5}$、$a_{1} = 8.5258 \times 10^{-6}$、$a_{2} = -6.8360 \times 10^{-8}$、$a_{3} = 6.6228 \times 10^{-10}$
$b_{0} = 1.8932 \times 10^{-6}$、$b_{1} = -4.2393 \times 10^{-8}$
$c_{0} = 1.8741 \times 10^{-8}$、$c_{1} = -6.7795 \times 10^{-10}$、$c_{2} = 8.7330 \times 10^{-12}$、$c_{3} = -5.4481 \times 10^{-14}$
$d_{0} = -1.1351 \times 10^{-10}$、$d_{1} = 2.7759 \times 10^{-12}$
$e_{0} = -4.6206 \times 10^{-13}$、$e_{1} = 1.8676 \times 10^{-14}$、$e_{2} = -2.1687 \times 10^{-16}$

計算例
スクロールできます
$S$$t$ [℃]$P$ [dbar]$P_r$ [dbar]$\theta’$ [℃]
2510100009.8935
30205000019.0211
353010000027.3851

サンプルコード

[potential_temp.c]

/**
 * @file potential_temp.c
 * @brief ポテンシャル水温の計算
 * @brief 1MPa = 100dbar
 */

//------------------------------------------------------------------------------
// include
//------------------------------------------------------------------------------
#include "potential_temp.h"

//------------------------------------------------------------------------------
// private function
//------------------------------------------------------------------------------
static double Calc_ATG(double sal, double temp, double press);

/** ----------------------------------------------------------------------------
 * @brief ポテンシャル水温の計算
 * @details UNESCO (1983) "Potential Temperature"
 *
 * @param temp : 現場水温[℃] (ITS-90)
 * @param sal : 塩分
 * @param press : 現場圧力[dbar]
 * @param press0 : 基準圧力[dbar]
 * @return ポテンシャル水温[℃] (ITS-90)
 */
double Calc_PotentialTemp(double temp, double sal, double press, double press0)
{
  double h, p, q, t, xk;
  double ptemp;

  t = temp * 1.00024;  // ITS-90 ⇒ IPTS-68

  h     = press0 - press;
  xk    = h * Calc_ATG(sal, temp, press);
  t     = t + 0.5 * xk;
  q     = xk;
  p     = press + 0.5 * h;
  xk    = h * Calc_ATG(sal, t, p);
  t     = t + 0.29289322 * (xk - q);
  q     = 0.58578644 * xk + 0.121320344 * q;
  xk    = h * Calc_ATG(sal, t, p);
  t     = t + 1.707106781 * (xk - q);
  q     = 3.414213562 * xk - 4.121320344 * q;
  p     = p + 0.5 * h;
  xk    = h * Calc_ATG(sal, t, p);
  ptemp = t + (xk - 2.0 * q) / 6.0;
  ptemp *= 0.99976;  // IPTS-68 ⇒ ITS-90

  return ptemp;
}

/** ----------------------------------------------------------------------------
 * @brief 断熱温度勾配 (Adiabatic Temperature Gradient)
 *
 * @param sal : 塩分
 * @param temp : 温度[℃]
 * @param press : 圧力[dbar]
 * @return 断熱温度勾配[℃/dbar]
 */
static double Calc_ATG(double sal, double temp, double press)
{
  static const double a[4] = {3.5803e-5, 8.5258e-6, -6.8360e-8, 6.6228e-10};
  static const double b[2] = {1.8932e-6, -4.2393e-8};
  static const double c[4] = {1.8741e-8, -6.7795e-10, 8.7330e-12, -5.4481e-14};
  static const double d[2] = {-1.1351e-10, 2.7759e-12};
  static const double e[3] = {-4.6206e-13, 1.8676e-14, -2.1687e-16};

  double gamma, ds;
  double t, t2, t3;
  double aa, bb, cc, dd, ee;

  t  = temp;
  t2 = t * t;
  t3 = t2 * t;

  aa = a[0] + a[1] * t + a[2] * t2 + a[3] * t3;
  bb = b[0] + b[1] * t;
  cc = c[0] + c[1] * t + c[2] * t2 + c[3] * t3;
  dd = d[0] + d[1] * t;
  ee = e[0] + e[1] * t + e[2] * t2;

  ds    = sal - 35.0;
  gamma = aa + bb * ds + (cc + dd * ds) * press + ee * press * press;

  return gamma;
}

[potential_temp.h]

#ifndef POTENTIAL_TEMP_H
#define POTENTIAL_TEMP_H

#ifdef __cplusplus
extern "C" {
#endif

//------------------------------------------------------------------------------
// function
//------------------------------------------------------------------------------
double Calc_PotentialTemp(double temp, double sal, double press, double press0);

#ifdef __cplusplus
}
#endif

#endif

サンプルコードの使用例

使用例代わりに、CppUTestによるテストコードを掲載しておきます。

#include "CppUTest/TestHarness.h"

#include "potential_temp.h"

// clang-format off
TEST_GROUP(ptemp){
  TEST_SETUP(){
  }

  TEST_TEARDOWN(){
  }
};
// clang-format on

TEST(ptemp, Test_ptem)
{
  double ptemp;

  ptemp = Calc_PotentialTemp(10.0 / 1.00024, 25.0, 1000.0, 0.0);
  DOUBLES_EQUAL(ptemp, 9.8935 * 0.99976, 5e-5);

  ptemp = Calc_PotentialTemp(20.0 / 1.00024, 30.0, 5000.0, 0.0);
  DOUBLES_EQUAL(ptemp, 19.0211 * 0.99976, 5e-5);

  ptemp = Calc_PotentialTemp(30.0 / 1.00024, 35.0, 10000.0, 0.0);
  DOUBLES_EQUAL(ptemp, 27.3851 * 0.99976, 5e-5);
}

脚注

  1. UNESCO (1983) “Potential Temperature” Unesco technical papers in marine science No.44 ↩︎
目次