0%

利用GEE云平台的HYCOM数据进行海洋流速分析及可视化

GEE中的HYCOM

GEE,或者说Google Earth Engine,你可能听过或者没听过,但它确实是当前地球科学领域的一颗璀璨明星。为什么?想象一下,地学数据的规模巨大到我们很难在个人电脑上进行存储和分析。但有了GEE,这一切都变得简单了。它让我们可以直接在云端处理这些庞大的数据,不必费心把数据拷贝回本地,更不用说还能借助谷歌强大的计算能力了。关于这点,不少从事光学遥感、合成孔径雷达(SAR)研究的学者都给出了自己的实证研究和论文成果。

说起HYCOM,这可不是一两句话能说清楚的。它是Hybrid Coordinate Ocean Model的缩写,由美国多家机构联手组建的开源海洋环流建模系统,得到了美国国家海洋合作项目(NOPP)的赞助,并作为美国全球海洋数据同化实验(GODAE)的一部分。该模型主要用于研究海洋和大气之间的相互作用,包括短期和长期过程,它对于海洋预测、数据同化乃至气候研究都是至关重要的。而GEE上的HYCOM数据集,无疑是为我们这些研究者铺设了一条快捷之路,轻松获取、分析,再也不用为数据的下载、分析和可视化而烦恼了。

南大洋流场

南大洋,也被称为南极洋或南极圈内的海洋,是地球上最冷、最偏远的海洋。它环绕整个南极大陆,并与三大洋——大西洋、太平洋和印度洋接壤。南大洋的流场特征对全球气候和海洋环流有着重要影响。最显著的流场特征是西风漂流,这是一种东向的表面流,由于缺乏大陆的阻碍,它在南大洋的纬度范围内持续不断地环绕地球。此外,南大洋还是形成深海下沉流的关键区域,这些冷的盐水从表面下沉到深海,成为全球深海环流的驱动力。

通过下面的例子,我们不仅会看到如何利用GEE计算二十年的流速均值和其变化特征,而且还会深入到如何计算涡度、Enstrophy和KE等关键的物理海洋参数。这些参数为我们提供了关于流动形态、能量分布和流动稳定性的关键信息。值得注意的是,使用GEE,这样的复杂分析可以在几秒钟内完成,这在传统的数据处理方法中是难以想象的。这种处理速度不仅加速了研究的进程,而且为实时监测和预测提供了新的可能性。

HYCOM在南大洋某时的流场

20年的流速平均

下面这段代码是在分析和展示南大洋在过去20年(从2002年至2022年)中每年1月的前15天的海洋流速均值。

首先,代码定义了南大洋的矩形区域。接着,通过一个函数获取每年1月的前15天的流速数据并计算其均值。这个函数主要过滤特定日期的HYCOM海洋流速数据,并对数据进行了单位转换(除以1000)。然后,我们为2002至2022的每一年都调用了这个函数,得到这20年中的每年均值,并进一步计算出20年的总均值。最终,将结果限制在我们定义的南大洋区域内,裁剪后的速度被添加到了地图上,并将地图的中心设置为南大洋区域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 1. 定义南大洋的区域
var southernOceanRegion = ee.Geometry.Rectangle([0, -80, 180, -35]); // 注意调整了范围以覆盖整个南大洋

// 2. 定义一个函数来获取每年4月的数据,并返回这个月的均值
function getAprilAverage(year) {
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = ee.Date.fromYMD(year, 1, 15);

var collection = ee.ImageCollection('HYCOM/sea_water_velocity')
.filterDate(startDate, endDate)
.map(function(image) {
return image.divide(1000);
});

return collection.mean();
}

// 3. 使用循环来获取2002至2022这20年的4月的均值
var years = ee.List.sequence(2002, 2022);
var averages = years.map(function(year) {
return getAprilAverage(year);
});

var twoDecadesAverage = ee.ImageCollection.fromImages(averages).mean();

// 4. 从这个二十年的均值图像中计算速度
var speed = twoDecadesAverage.select('velocity_u_0').hypot(twoDecadesAverage.select('velocity_v_0'));

// 5. 使用南大洋区域裁剪速度图像
var maskedSpeed = speed.clip(southernOceanRegion);

// 6. 将裁剪后的速度图像添加到地图上
Map.addLayer(maskedSpeed, {min: 0, max: 1, palette: ['blue', 'yellow', 'red']}, 'Southern Ocean Speed 20-Year Average');

// 7. 将地图的中心设置为南大洋区域
Map.centerObject(southernOceanRegion, 4);

HYCOM在南大洋二十年的平均流

20年流速变化特征

使用标准偏差进行流场变化的统计。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 1. 定义南大洋的区域
var southernOceanRegion = ee.Geometry.Rectangle([0, -80, 180, -35]);

// 2. 定义一个函数来获取每年4月的数据,并返回这个月的速度
function getAprilSpeed(year) {
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = ee.Date.fromYMD(year, 1, 15);

var velocity = ee.ImageCollection('HYCOM/sea_water_velocity')
.filterDate(startDate, endDate)
.mean()
.divide(1000);

return velocity.select('velocity_u_0').hypot(velocity.select('velocity_v_0'));
}

// 3. 使用循环来获取1993至2022这30年的4月的速度
var years = ee.List.sequence(2002, 2022);
var speeds = years.map(function(year) {
return getAprilSpeed(year);
});

var speedCollection = ee.ImageCollection.fromImages(speeds);
var speedStdDev = speedCollection.reduce(ee.Reducer.stdDev());

// 4. 使用南大洋区域裁剪速度标准差图像
var maskedStdDev = speedStdDev.clip(southernOceanRegion);

// 5. 将裁剪后的速度标准差图像添加到地图上
Map.addLayer(maskedStdDev, {min: 0, max: 1, palette: ['blue', 'yellow', 'red']}, 'Southern Ocean Speed STD');

// 6. 将地图的中心设置为南大洋区域
Map.centerObject(southernOceanRegion, 4);

HYCOM在南大洋二十年的流速变化特征

涡度

涡度 (Vorticity) 是流体力学中的一个重要概念,特别在描述流体中旋转现象时。它是一种局 部旋转度量,描述了流体旋转的强度和方向。涡度的方向垂直于流体的旋转平面。
涡度的计算公式:
涡度的定义基于流体速度场。在二维流中,涡度(通常用符号 $\zeta$ 表示)的定义如下:
$$
\zeta=\frac{\partial v}{\partial x}-\frac{\partial u}{\partial y}
$$
其中:

  • $u$ 是流速的 $\mathrm{x}$ 分量
  • $v$ 是流速的 $\mathrm{y}$ 分量
  • $\frac{\partial v}{\partial x}$ 是流速 $\mathbf{v}$ 关于 $\mathbf{x}$ 的偏导数
  • $\frac{\partial u}{\partial y}$ 是流速 $\mathrm{u}$ 关于 $\mathrm{y}$ 的偏导数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var dateStr = '2023010100';
var velocity = ee.Image('HYCOM/sea_water_velocity/' + dateStr);

// var projection = velocity.select('velocity_u_0').projection();
// var nominalScale = projection.nominalScale();

// print('Nominal scale (in meters):', nominalScale);

// 1. 加载指定日期的速度数据
// var date = '2023-01-01';
// var velocity = ee.Image('HYCOM/sea_water_velocity/' + date).divide(1000);

// 2. 提取 u 和 v 的分量
var u = velocity.select('velocity_u_0');
var v = velocity.select('velocity_v_0');

// 3. 计算偏导数
var dudx = u.gradient().select('x');
var dvdx = v.gradient().select('x');
var dudy = u.gradient().select('y');
var dvdy = v.gradient().select('y');

// 4. 使用上述的旋度公式
var vorticity = dvdx.subtract(dudy);

// 5. 在地图上显示结果
Map.addLayer(vorticity, {min: -0.1, max: 0.1, palette: ['blue', 'white', 'red']}, 'Vorticity');

HYCOM在南大洋某时的涡度特征

Enstrophy

Enstrophy 在流体动力学中表示流体内部的涡旋强度,常用于研究湍流流动。Enstrophy 是涡 度 (vorticity) 的平方的一半,表示为:
Enstrophy $=\frac{1}{2} \omega^2$
其中 $\omega$ 是涡度。在之前的涡度计算中,我们得到了涡度 $\omega=d v / d x-d u / d y$ 。
接下来,我们可以根据上述的涡度计算来进一步计算Enstrophy。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 定义2023年1月的日期范围
var startDate = ee.Date('2023-01-01');
var endDate = ee.Date('2023-01-7');

// 从HYCOM数据集中加载2023年1月份的所有数据
var januaryCollection = ee.ImageCollection('HYCOM/sea_water_velocity')
.filterDate(startDate, endDate);

// 使用map函数计算每天的涡度(Enstrophy)
var enstrophyCollection = januaryCollection.map(function(image) {
var u = image.select('velocity_u_0');
var v = image.select('velocity_v_0');
var dudx = u.gradient().select('x');
var dvdx = v.gradient().select('x');
var dudy = u.gradient().select('y');
var dvdy = v.gradient().select('y');
var vorticity = dvdx.subtract(dudy);
return vorticity.pow(2).multiply(0.5);
});

// 计算2023年1月份的涡度(Enstrophy)均值
var meanEnstrophy = enstrophyCollection.mean();

// 对均值进行对数变换,避免对数0的情况,通常会加上一个小的值
var logMeanEnstrophy = meanEnstrophy.add(1e-10).log();

// 在地图上显示对数转换后的结果
Map.addLayer(logMeanEnstrophy, {min: -20, max: -4, palette: ['blue', 'white', 'red']}, 'Log Enstrophy');

HYCOM在南大洋一月份的Enstrophy

KE

要计算流体中的动能 (Kinetic Energy, KE),公式为 $K E=0.5 *\left(u^2+v^2\right)$ ,其中 $u$ 和 $v$ 分 别是速度的水平和垂直分量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 定义2023年1月的日期范围
var startDate = '2023-01-01';
var endDate = '2023-01-31';

// 获取该日期范围内的速度数据集
var velocityCollection = ee.ImageCollection('HYCOM/sea_water_velocity')
.filterDate(startDate, endDate);

// 使用map函数来为每一天计算动能 (KE)
var keCollection = velocityCollection.map(function(image) {
var u = image.select('velocity_u_0');
var v = image.select('velocity_v_0');

// 计算 KE
return u.pow(2).add(v.pow(2)).multiply(0.5);
});

// 计算整月的KE均值
var monthlyMeanKE = keCollection.mean();

// 定义要计算均值的区域,例如全球范围
var globalRegion = ee.Geometry.Rectangle([-180, -90, 180, 90]);

// 使用 reduceRegion 来计算全球的KE均值
var globalAverageKE = monthlyMeanKE.reduceRegion({
reducer: ee.Reducer.mean(),
geometry: globalRegion,
scale: 10000, // 此处的scale取决于HYCOM数据集的分辨率
maxPixels: 1e13
});

// 打印统计信息
print('Global Average KE for January 2023:', globalAverageKE);

// 在地图上显示月均值的KE
var logmonthlyMeanKE = monthlyMeanKE.add(1e-10).log();
var keViz = {min: 10, max: 15, palette: ['blue', 'green', 'red']};
Map.addLayer(logmonthlyMeanKE, keViz, 'Monthly Mean KE January 2023');

KE

本代码仅供参考和学习之用,用于展示基本的功能和计算方法。在使用这些代码进行实际的数据处理和分析之前,请确保您已对输入数据进行了适当的单位统一和其他必要的预处理。特别是涉及速度单位的部分,直接使用这些代码可能会导致不准确或误导的结果。建议在实际应用中进行仔细的数据验证和校准,以确保结果的准确性和可靠性。

  • 思考题:如何使用GEE绘制某范围内的流速的长时间序列?