Gerakan vertikal atmosfer — naik atau turunnya massa udara — adalah salah satu variabel paling penting dalam analisis sinoptik, namun juga yang paling sulit diukur langsung. Radiosonde hanya akurat hingga sekitar ±1 m/s, sementara gerakan vertikal sinoptik tipikal hanya 1–2 cm/s. Kita harus menyimpulkannya dari angin horizontal. Tutorial ini menunjukkan cara melakukan itu dengan data ERA5.
Mengapa Omega Penting dalam Analisis Sinoptik
Dalam meteorologi operasional, kecepatan vertikal hampir selalu dinyatakan dalam koordinat tekanan sebagai omega (\(\omega = dp/dt\), satuan Pa/s), bukan dalam koordinat tinggi (\(w = dz/dt\), satuan m/s). Alasannya praktis: hampir semua model NWP dan produk reanalysis — termasuk ERA5 — bekerja pada lapisan tekanan konstan, sehingga \(\omega\) jauh lebih mudah dihitung dan diinterpretasikan langsung dari output model.
Konvensi tandanya berbalik dari intuisi: karena tekanan berkurang dengan ketinggian, parsel udara yang naik akan mengalami tekanan yang makin kecil, sehingga \(dp/dt < 0\). Artinya \(\omega < 0\) berarti gerakan naik (ascending), \(\omega > 0\) berarti gerakan turun (descending). Nilainya kecil: pada skala sinoptik, \(\omega\) tipikal berkisar antara \(-0{,}5\) hingga \(+0{,}5\) Pa/s, setara dengan \(w \approx \pm 1\) cm/s.
Di atas Maritime Continent Indonesia dan zona ITCZ, gerakan naik yang kuat (\(\omega < 0\)) mendorong konveksi yang persisten sepanjang tahun. Dua mekanisme utamanya adalah konvergensi angin laut (sea-breeze dari arah berbeda yang bertemu di atas pulau) dan orographic lifting saat udara lembap menabrak punggungan vulkanik. Inilah mengapa peta \(\omega\) pada 500 hPa menjadi alat standar untuk mengidentifikasi area aktif konveksi di Indonesia.
Tutorial ini menggunakan metode kinematik: mengestimasi \(\omega\) dari divergensi horizontal angin ERA5 via persamaan kontinuitas, kemudian mengonversi ke \(w\) menggunakan pendekatan hidrostatik. Metode ini memiliki nilai pedagogis tinggi karena mengajarkan fisika di balik hubungan angin horizontal–gerakan vertikal.
Konvensi Tanda dan Persamaan Kontinuitas
Berikut adalah pipeline lengkap dari data angin horizontal ERA5 hingga kecepatan vertikal geometrik:
Pipeline kinematik: dari angin horizontal ERA5 hingga kecepatan vertikal geometrik w.
Persamaan kontinuitas dalam koordinat tekanan menyatakan:
$$\frac{\partial \omega}{\partial p} = -\nabla_p \cdot \mathbf{V} = -\left(\frac{\partial u}{\partial x} + \frac{\partial v}{\partial y}\right)$$
Artinya, gradien vertikal omega sama dengan negatif divergensi horizontal. Di lapisan yang divergen (\(\nabla \cdot \mathbf{V} > 0\), udara menyebar), \(\omega\) harus berkurang ke atas — ciri khas gerakan turun. Di lapisan yang konvergen (\(\nabla \cdot \mathbf{V} < 0\)), \(\omega\) meningkat ke atas — ciri gerakan naik.
Dengan mengintegrasikan dari tekanan referensi \(p_{\text{top}}\) ke \(p\):
$$\omega(p) = \omega(p_{\text{top}}) - \int_{p_{\text{top}}}^{p} (\nabla \cdot \mathbf{V})\, dp'$$
Dalam tutorial ini, kita gunakan dua level tekanan: 500 hPa (batas atas integrasi, dengan kondisi batas \(\omega = 0\)) dan 850 hPa (target estimasi). Aproksimasi diskrit satu layer:
$$\omega_{850} \approx -\overline{\nabla \cdot \mathbf{V}} \times \Delta p$$
dengan \(\overline{\nabla \cdot \mathbf{V}}\) adalah rata-rata divergensi antara 500 dan 850 hPa, dan \(\Delta p = 350\ \text{hPa} = 35000\ \text{Pa}\).
Konversi ke \(w\) menggunakan pendekatan hidrostatik (\(\omega \approx -\rho g w\)):
$$w \approx -\frac{\omega}{\rho g}$$
Di 850 hPa tropis, \(\rho \approx 1{,}0\ \text{kg/m}^3\); di 500 hPa, \(\rho \approx 0{,}6\ \text{kg/m}^3\). Dengan \(g = 9{,}81\ \text{m/s}^2\), nilai \(\omega = -0{,}1\ \text{Pa/s}\) menghasilkan \(w \approx 0{,}01\ \text{m/s} = 1\ \text{cm/s}\) — masuk akal untuk skala sinoptik.
Mempersiapkan Data ERA5 via cdsapi
Kita butuh komponen angin u dan v pada level tekanan 500 dan 850 hPa untuk wilayah Indonesia sepanjang 2024. ERA5 menyediakan variabel ini dalam dataset reanalysis-era5-pressure-levels melalui CDS (Copernicus Data Store). Kita download satu kali, lalu iterasi lokal.
Snippet di bawah mengunduh kedua file — era5_u_pl500-850_indonesia_2024_d.nc dan era5_v_pl500-850_indonesia_2024_d.nc — lalu membuka keduanya dengan xarray dan mencetak dimensinya. Guard if not os.path.exists(OUT) memastikan download hanya terjadi sekali; saat file sudah ada, baris cdsapi dilewati.
import os
import cdsapi
import xarray as xr
OUT_U = "era5_u_pl500-850_indonesia_2024_d.nc"
OUT_V = "era5_v_pl500-850_indonesia_2024_d.nc"
_cds_params_base = {
"product_type": "reanalysis",
"year": "2024",
"month": [f"{m:02d}" for m in range(1, 13)],
"day": [f"{d:02d}" for d in range(1, 32)],
"time": ["00:00"],
"pressure_level": ["500", "850"],
"area": [6, 95, -11, 141], # N, W, S, E — Indonesia
"format": "netcdf",
}
if not os.path.exists(OUT_U):
c = cdsapi.Client(quiet=True)
c.retrieve(
"reanalysis-era5-pressure-levels",
{**_cds_params_base, "variable": ["u_component_of_wind"]},
OUT_U,
)
if not os.path.exists(OUT_V):
c = cdsapi.Client(quiet=True)
c.retrieve(
"reanalysis-era5-pressure-levels",
{**_cds_params_base, "variable": ["v_component_of_wind"]},
OUT_V,
)
ds_u = xr.open_dataset(OUT_U)
ds_v = xr.open_dataset(OUT_V)
# CDS-new menggunakan 'valid_time'; normalisasi ke 'time' agar kode hilir tetap bersih
def _normalize_dims(ds):
rename_map = {}
if "valid_time" in ds.dims:
rename_map["valid_time"] = "time"
if rename_map:
ds = ds.rename(rename_map)
return ds
ds_u = _normalize_dims(ds_u)
ds_v = _normalize_dims(ds_v)
# Deteksi nama koordinat tekanan (bisa 'pressure_level' atau 'level')
plev_coord = "pressure_level" if "pressure_level" in ds_u.dims else "level"
u = ds_u["u"]
v = ds_v["v"]
print("=== Dataset u ===")
print(ds_u.sizes)
print("Koordinat tekanan:", plev_coord, "->", u[plev_coord].values, "hPa")
print("\n=== Dataset v ===")
print(ds_v.sizes)
print("Waktu pertama:", str(u.time.values[0])[:10])
print("Waktu terakhir:", str(u.time.values[-1])[:10])
=== Dataset u ===
Frozen({'time': 366, 'pressure_level': 2, 'latitude': 69, 'longitude': 185})
Koordinat tekanan: pressure_level -> [850. 500.] hPa
=== Dataset v ===
Frozen({'time': 366, 'pressure_level': 2, 'latitude': 69, 'longitude': 185})
Waktu pertama: 2024-01-01
Waktu terakhir: 2024-12-31
Dataset berdimensi (time, pressure_level, latitude, longitude) — 366 hari 00Z di 2024, dua level (500 dan 850 hPa), resolusi 0,25°.
Menghitung Divergensi Horizontal
Divergensi horizontal \(\nabla \cdot \mathbf{V} = \partial u/\partial x + \partial v/\partial y\) harus menghitung turunan pada grid bola bumi, bukan grid Cartesian datar. Pada latitude \(\phi\), jarak zonal per derajat longitude adalah \(\Delta x = R_{\text{Earth}} \cos\phi \cdot \Delta\lambda\) (dengan \(\Delta\lambda\) dalam radian). Jarak meridional konstan: \(\Delta y = R_{\text{Earth}} \cdot \Delta\phi\).
xarray memiliki metode .differentiate() yang menghitung turunan numerik terhadap koordinat bernilai. Kita konversi koordinat lat/lon ke meter terlebih dahulu sebagai data array bantu, lalu bagi turunan u (terhadap lon) dengan faktor \(R \cos\phi\) dan turunan v (terhadap lat) dengan \(R\).
import numpy as np
R_EARTH = 6_371_000.0 # meter
lat_rad = np.deg2rad(u.latitude)
cos_lat = np.cos(lat_rad)
# ∂u/∂x: turunan u terhadap longitude, dibagi (R cos φ)
# .differentiate('longitude') memberi ∂u/∂λ (per derajat); konversi ke per meter
du_dx = u.differentiate("longitude") / (np.deg2rad(1.0) * R_EARTH * cos_lat)
# ∂v/∂y: turunan v terhadap latitude, dibagi R
dv_dy = v.differentiate("latitude") / (np.deg2rad(1.0) * R_EARTH)
# Divergensi total (s⁻¹)
div = du_dx + dv_dy
div.name = "divergence"
div.attrs["units"] = "s-1"
# Statistik untuk satu hari contoh (hari ke-0 = 1 Januari 2024)
div0 = div.isel(time=0)
print("=== Divergensi 1 Jan 2024 ===")
for lv in div[plev_coord].values:
d = div0.sel({plev_coord: lv})
print(f" {int(lv)} hPa | min={float(d.min()):.2e} max={float(d.max()):.2e} "
f"mean={float(d.mean()):.2e} s⁻¹")
print("\nDivergence positif = udara menyebar (gerakan turun)")
print("Divergence negatif = udara konvergen (gerakan naik)")
=== Divergensi 1 Jan 2024 ===
850 hPa | min=-2.11e-04 max=6.33e-05 mean=-9.50e-07 s⁻¹
500 hPa | min=-2.10e-04 max=3.56e-04 mean=-4.75e-07 s⁻¹
Divergence positif = udara menyebar (gerakan turun)
Divergence negatif = udara konvergen (gerakan naik)
Output menunjukkan dua rentang yang berbeda. Rata-rata domain \(\approx 10^{-6}\ \text{s}^{-1}\) — masuk akal untuk skala sinoptik. Namun puncak grid mencapai \(\approx -2{,}1 \times 10^{-4}\ \text{s}^{-1}\) di 850 hPa dan \(+3{,}6 \times 10^{-4}\ \text{s}^{-1}\) di 500 hPa — satu titik grid 0,25° di atas pusat konveksi aktif. Konvergensi (negatif) dominan di 850 hPa mencerminkan angin musim masuk ke kepulauan Indonesia, konsisten dengan profil ascending.
Integrasi Vertikal dan Estimasi Omega
Dengan divergensi tersedia di kedua level, kita terapkan integrasi kinematik. Kondisi batas: \(\omega = 0\) di 500 hPa (asumsi tidak ada gerakan vertikal di batas atas integrasi). Lalu:
$$\omega_{850} \approx -\overline{\text{div}} \times \Delta p$$
dengan \(\overline{\text{div}}\) adalah rata-rata sederhana divergensi di 500 dan 850 hPa, dan \(\Delta p = 35000\ \text{Pa}\).
Snippet berikut menghitung estimasi kinematik \(\omega\) di 850 hPa untuk semua hari di 2024, lalu merender peta spasial untuk satu tanggal sampel menggunakan cartopy. Kita pilih 15 Januari 2024 (pertengahan musim hujan DJF) yang biasanya menampilkan pola ascending yang jelas di atas Indonesia barat.
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import os
# --- Integrasi kinematik ---
DP = 35_000.0 # Pa (500 → 850 hPa)
div_500 = div.sel({plev_coord: 500})
div_850 = div.sel({plev_coord: 850})
div_mean = 0.5 * (div_500 + div_850)
# ω_850 = ω_500 − div_mean × Δp ; ω_500 = 0 (kondisi batas)
omega_850 = -div_mean * DP
omega_850.name = "omega_850"
omega_850.attrs["units"] = "Pa s-1"
# --- Peta untuk 15 Januari 2024 ---
date_idx = 14 # indeks ke-14 = 15 Jan 2024 (00Z)
omega_plot = omega_850.isel(time=date_idx)
date_str = str(omega_850.time.values[date_idx])[:10]
fig, ax = plt.subplots(
figsize=(12, 6),
subplot_kw={"projection": ccrs.PlateCarree()},
)
ax.set_extent([95, 141, -11, 6], crs=ccrs.PlateCarree())
# Diverging colormap: biru = naik (ω < 0), merah = turun (ω > 0)
vmax = 0.3
norm = mcolors.TwoSlopeNorm(vmin=-vmax, vcenter=0, vmax=vmax)
cmap = "RdBu_r"
cf = ax.contourf(
omega_plot.longitude,
omega_plot.latitude,
omega_plot.values,
levels=20,
cmap=cmap,
norm=norm,
transform=ccrs.PlateCarree(),
)
ax.add_feature(cfeature.COASTLINE, linewidth=0.8, color="black")
ax.add_feature(cfeature.BORDERS, linewidth=0.5, color="gray", linestyle="--")
ax.gridlines(draw_labels=True, linewidth=0.4, linestyle=":", color="gray")
cbar = plt.colorbar(cf, ax=ax, orientation="vertical", pad=0.02, shrink=0.85)
cbar.set_label("Kinematic ω at 850 hPa (Pa s⁻¹)", fontsize=11)
cbar.ax.axhline(0, color="black", linewidth=0.8)
ax.set_title(
f"Estimasi Kinematik Omega 850 hPa — {date_str}\n"
"Biru = ascending (ω < 0) | Merah = descending (ω > 0)",
fontsize=12,
)
plt.tight_layout()
plt.savefig("omega_850.png", dpi=110, bbox_inches="tight")
print("Peta omega 850 hPa tersimpan.")
Peta menampilkan estimasi \(\omega\) di 850 hPa untuk 15 Januari 2024 — pertengahan musim hujan Indonesia barat. Biru (negatif) menandai ascending aktif di atas Sumatera, Kalimantan, dan Jawa barat, tempat konvergensi angin musim bertemu topografi. Merah menandai subsidence. Pola ini konsisten dengan mekanisme island convection yang didokumentasikan NASA. Gambar satelit MODIS di bawah memberikan validasi visual:
Sumber: NASA Earth Observatory — Menara konveksi tropis di atas Flores, Indonesia, Desember 2013. Ascending motion kuat (ω sangat negatif) terlihat dari pembentukan awan cumulonimbus yang menjulang. (halaman sumber)
Konversi ke Kecepatan Vertikal w (m/s)
Nilai \(\omega\) dalam Pa/s berguna untuk analisis sinoptik, tetapi \(w\) dalam m/s lebih intuitif saat membandingkan dengan pengamatan radar atau profiler angin. Konversi menggunakan pendekatan hidrostatik:
$$w \approx -\frac{\omega}{\rho g}$$
Densitas udara \(\rho\) bervariasi dengan tekanan dan suhu. Untuk estimasi praktis pada kondisi tropis Indonesia: \(\rho_{850} \approx 1{,}0\ \text{kg/m}^3\) dan \(\rho_{500} \approx 0{,}6\ \text{kg/m}^3\).
G = 9.81 # m/s²
# Densitas tipikal tropis (estimasi konstan per level)
rho = {850: 1.0, 500: 0.6}
# Kita hitung w dari omega_850 yang sudah ada
# Juga buat omega_500 sebagai referensi (seharusnya mendekati 0 karena kondisi batas)
omega_500_check = -div_500 * 0.0 # = 0 by definition (boundary condition)
print("=== Konversi ω → w untuk 15 Jan 2024 ===")
omega_sample = omega_850.isel(time=14)
w_850 = -omega_sample / (rho[850] * G)
print(f" Level 850 hPa | ρ = {rho[850]} kg/m³")
print(f" ω min = {float(omega_sample.min()):.4f} Pa/s → w max = {float((-omega_sample / (rho[850]*G)).max())*100:.2f} cm/s (ascending)")
print(f" ω max = {float(omega_sample.max()):.4f} Pa/s → w min = {float((-omega_sample / (rho[850]*G)).min())*100:.2f} cm/s (descending)")
print(f" ω mean = {float(omega_sample.mean()):.4f} Pa/s → w mean = {float(w_850.mean())*100:.3f} cm/s")
print()
print("=== Referensi skala sinoptik (NWS/literatur) ===")
print(" Skala sinoptik tipikal : w = 1–30 cm/s (updraft front, siklogenesis)")
print(" Rata-rata jangka panjang: w = ±0.3–0.6 cm/s (Uma et al. 2021, Kototabang)")
print(" ω = −0.1 Pa/s → w ≈", round(0.1 / (1.0 * 9.81) * 100, 2), "cm/s (850 hPa)")
print(" ω = −0.1 Pa/s → w ≈", round(0.1 / (0.6 * 9.81) * 100, 2), "cm/s (500 hPa)")
=== Konversi ω → w untuk 15 Jan 2024 ===
Level 850 hPa | ρ = 1.0 kg/m³
ω min = -3.4092 Pa/s → w max = 34.75 cm/s (ascending)
ω max = 3.6270 Pa/s → w min = -36.97 cm/s (descending)
ω mean = 0.0538 Pa/s → w mean = -0.549 cm/s
=== Referensi skala sinoptik (NWS/literatur) ===
Skala sinoptik tipikal : w = 1–30 cm/s (updraft front, siklogenesis)
Rata-rata jangka panjang: w = ±0.3–0.6 cm/s (Uma et al. 2021, Kototabang)
ω = −0.1 Pa/s → w ≈ 1.02 cm/s (850 hPa)
ω = −0.1 Pa/s → w ≈ 1.7 cm/s (500 hPa)
Output menunjukkan kontras penting. Puncak grid \(\omega_{\min} \approx -3{,}4\) Pa/s → \(w_{\max} \approx 34{,}8\) cm/s adalah artefak metode: aproksimasi dua-level dengan \(\Delta p = 35000\) Pa mengamplifikasi puncak divergensi di satu titik grid 0,25°, bukan kolom udara nyata yang naik 35 cm/s. Sebaliknya rata-rata domain \(w_{\text{mean}} \approx -0{,}55\) cm/s klop dengan radar VHF Kototabang (±0,3–0,6 cm/s, Uma et al. 2021). Aturan praktis: estimasi kinematik harus dirata-ratakan secara spasial sebelum dibandingkan literatur.
Keterbatasan Metode Kinematik dan Langkah Berikutnya
Estimasi kinematik yang kita buat adalah aproksimasi, bukan \(\omega\) yang "sesungguhnya" dari ERA5. Ada beberapa sumber perbedaan yang penting:
Resolusi vertikal. Kita hanya punya dua level (500 dan 850 hPa). Model IFS di balik ERA5 menggunakan 137 hybrid sigma/pressure levels secara internal; nilai yang diinterpolasi ke grid tekanan kasar kehilangan detail struktur vertikal penting, terutama di dekat tropopause dan boundary layer.
Efek diabatik. Persamaan kontinuitas kinematik \(\partial\omega/\partial p = -\nabla \cdot \mathbf{V}\) mengasumsikan bahwa semua gerakan vertikal tercermin dalam divergensi horizontal. Dalam kenyataannya, pemanasan diabatik (latent heat release, radiasi) menginduksi gerakan vertikal yang tidak sepenuhnya terekam dalam divergensi angin. ERA5's native \(\omega\) dari assimilation 4D-Var memperhitungkan faktor ini.
Bias berlawanan arah. Metode kinematik dua-level kita melebih-estimasi puncak grid (\(w_{\max} \approx 35\) cm/s di atas), sedangkan ERA5 native meremehkan magnitudo 10–50% dibanding radar VHF (Uma et al. 2021), dan hampir tidak menangkap downdraft. Raw grid-point dari keduanya tidak dapat dipercaya tanpa spatial averaging — keduanya konvergen saat dirata-ratakan.
Kapan menggunakan metode kinematik vs. omega ERA5 langsung. ERA5 menyediakan variabel vertical_velocity (short name w, GRIB paramId 135) secara native di semua 37 level tekanan standar — termasuk 500 dan 850 hPa. Untuk keperluan operasional atau riset serius, gunakan variabel itu langsung. Metode kinematik dalam tutorial ini memiliki nilai utama sebagai alat belajar: membuat hubungan antara divergensi horizontal dan gerakan vertikal menjadi konkret dan terukur.
Langkah berikutnya yang bisa dicoba:
- Hitung time series \(\omega\) rata-rata area Indonesia dan plot siklus musiman untuk melihat sinyal musim hujan (DJF) vs. musim kering (JJA).
- Overlay peta \(\omega\) dengan cloud-top pressure dari data MODIS atau Himawari untuk validasi visual terhadap area konveksi aktif.
- Bandingkan estimasi kinematik dari tutorial ini dengan \(\omega\) ERA5 yang diunduh langsung menggunakan
variable: ["vertical_velocity"]— perbedaannya mengajarkan kontribusi efek diabatik. - Perluas ke lebih banyak level tekanan (200, 300, 500, 700, 850, 925 hPa) untuk profil \(\omega\) yang lebih lengkap.
Eksplorasi artikel meteorologi lainnya di meteo.my.id — kunjungi situs di https://meteo.my.id.
Referensi
- Omega (Vertical Velocity) – NWS Houston Training Page — Penjelasan operasional NOAA NWS tentang omega sebagai kecepatan vertikal dalam koordinat tekanan, konvensi tanda, dan hubungannya dengan curah hujan.
- ERA5: Data Documentation – Copernicus Knowledge Base (ECMWF) — Dokumentasi resmi ERA5 yang menjelaskan variabel
vertical_velocity(GRIB paramId 135) tersedia di semua 37 level tekanan standar. - Vertical Velocity in the Atmosphere – ESS 227, UC Irvine — Slide kuliah atmosferik dinamik yang mendefinisikan omega, konvensi tanda, persamaan kontinuitas, dan metode kinematik.
- Uma et al. (2021): Assessment of vertical air motion among reanalyses – Atmospheric Chemistry and Physics — Studi peer-reviewed yang membandingkan ERA5 dan reanalysis lain dengan radar VHF di Kototabang, Indonesia, menunjukkan ERA5 meremehkan magnitudo kecepatan vertikal 10–50%.
- Cloud Towers Over Flores, Indonesia – NASA Earth Observatory — Dokumentasi NASA tentang konveksi pulau tropis di atas Flores sebagai contoh nyata ascending motion kuat (ω sangat negatif) yang dipacu konvergensi dan orografi.
Tidak ada komentar:
Posting Komentar