{ "cells": [ { "cell_type": "markdown", "id": "title", "metadata": {}, "source": [ "# Global-to-local validation of multiscale HEALPix divergence and curl\n", "\n", "This notebook uses ERA5 10-m eastward/northward wind (`u`, `v`) to validate `HealPixDivCurl` and `HealPixMultiScaleDivCurl`. It first computes a physical full-sphere spectral reference with ALM, then masks the same wind on a coastal NESTED HEALPix domain and checks whether the local multiscale diagnostic preserves the meaningful divergence/curl structures. Input channel zero is eastward velocity `u`; channel one is northward velocity `v`." ] }, { "cell_type": "code", "execution_count": 1, "id": "imports", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "device: cuda\n" ] } ], "source": [ "import healpix_geo\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import torch\n", "\n", "from healpix_analyse import (\n", " HealPixDecomp,\n", " HealPixDivCurl,\n", " HealPixMultiScaleDivCurl,\n", ")\n", "\n", "torch.manual_seed(3)\n", "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", "dtype = torch.float64\n", "RADIUS_M = 6_371_008.8\n", "print(\"device:\", device)" ] }, { "cell_type": "markdown", "id": "domain-header", "metadata": {}, "source": [ "## Coastal masked domain\n", "\n", "We use a coastal HEALPix footprint as an irregular missing-data mask. The mask is not a physical wind boundary condition: ERA5 wind remains a global field and does not follow the coastline. This makes the experiment a controlled test of local derivatives with incomplete stencils, rather than a test of coastal wind dynamics." ] }, { "cell_type": "code", "execution_count": 2, "id": "03d3a630-178f-4abc-bbb0-b9838779dd68", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<xarray.Dataset> Size: 90MB\n",
"Dimensions: (time: 24, depth: 8, latitude: 180, longitude: 324)\n",
"Coordinates:\n",
" * time (time) datetime64[ns] 192B 2025-03-20 ... 2025-03-20T23:00:00\n",
" * depth (depth) float32 32B 0.494 1.541 2.646 3.819 ... 6.441 7.93 9.573\n",
" * latitude (latitude) float32 720B 46.03 46.05 46.08 ... 50.94 50.97 51.0\n",
" * longitude (longitude) float32 1kB -7.999 -7.971 -7.944 ... 0.9456 0.9733\n",
"Data variables:\n",
" thetao (time, depth, latitude, longitude) float64 90MB dask.array<chunksize=(1, 1, 180, 324), meta=np.ndarray>\n",
"Attributes:\n",
" Conventions: CF-1.8\n",
" comment: \n",
" contact: https://marine.copernicus.eu/contact\n",
" institution: NOW Systems (Spain)\n",
" references: http://marine.copernicus.eu/\n",
" source: NEMO3.6\n",
" title: Ocean 3D hourly mean fields for the Iberia-Biscay-Ireland (...<xarray.Dataset> Size: 47MB\n",
"Dimensions: (number: 10, values: 348528)\n",
"Coordinates:\n",
" * number (number) int64 80B 0 1 2 3 4 5 6 7 8 9\n",
" latitude (values) float64 3MB ...\n",
" longitude (values) float64 3MB ...\n",
" time datetime64[ns] 8B ...\n",
" step timedelta64[ns] 8B ...\n",
" surface float64 8B ...\n",
" valid_time datetime64[ns] 8B ...\n",
"Dimensions without coordinates: values\n",
"Data variables:\n",
" u10 (number, values) float32 14MB ...\n",
" v10 (number, values) float32 14MB ...\n",
" sst (number, values) float32 14MB ...\n",
"Attributes:\n",
" GRIB_edition: 1\n",
" GRIB_centre: ecmf\n",
" GRIB_centreDescription: European Centre for Medium-Range Weather Forecasts\n",
" GRIB_subCentre: 0\n",
" Conventions: CF-1.7\n",
" institution: European Centre for Medium-Range Weather Forecasts\n",
" history: 2026-08-04T10:05 GRIB to CDM+CF via cfgrib-0.9.1...