|
824 | 824 | " title=\"Regional Delaunay Regions\",\n", |
825 | 825 | ")" |
826 | 826 | ] |
| 827 | + }, |
| 828 | + { |
| 829 | + "cell_type": "markdown", |
| 830 | + "id": "560212c8", |
| 831 | + "metadata": {}, |
| 832 | + "source": [ |
| 833 | + "### Creating a Regional Unstructured Grid from Points\n", |
| 834 | + "UXarray allows users to create unstructured grids from scattered (lon, lat) point coordinates using Delaunay triangulation. When constructing regional unstructured grids with the method=\"regional_delaunay\" option, it is critical to explicitly specify boundary points to avoid mesh artifacts and ensure accurate face bounds." |
| 835 | + ] |
| 836 | + }, |
| 837 | + { |
| 838 | + "cell_type": "code", |
| 839 | + "execution_count": null, |
| 840 | + "id": "45780c35", |
| 841 | + "metadata": {}, |
| 842 | + "outputs": [], |
| 843 | + "source": [ |
| 844 | + "import numpy as np\n", |
| 845 | + "\n", |
| 846 | + "import uxarray as ux\n", |
| 847 | + "\n", |
| 848 | + "# Define a regular grid of longitude and latitude points over [0, 60] x [0, 60]\n", |
| 849 | + "lon, lat = np.meshgrid(\n", |
| 850 | + " np.linspace(0, 60.0, 10, dtype=np.float32),\n", |
| 851 | + " np.linspace(0, 60.0, 10, dtype=np.float32),\n", |
| 852 | + ")\n", |
| 853 | + "lon_flat = lon.ravel()\n", |
| 854 | + "lat_flat = lat.ravel()\n", |
| 855 | + "\n", |
| 856 | + "# Identify points along the domain boundary\n", |
| 857 | + "mask = (\n", |
| 858 | + " np.isclose(lon_flat, 0.0)\n", |
| 859 | + " | np.isclose(lon_flat, 60.0)\n", |
| 860 | + " | np.isclose(lat_flat, 0.0)\n", |
| 861 | + " | np.isclose(lat_flat, 60.0)\n", |
| 862 | + ")\n", |
| 863 | + "boundary_points = np.flatnonzero(mask)\n", |
| 864 | + "\n", |
| 865 | + "# Create the unstructured grid using the regional Delaunay method\n", |
| 866 | + "uxgrid = ux.Grid.from_points(\n", |
| 867 | + " (lon_flat, lat_flat), method=\"regional_delaunay\", boundary_points=boundary_points\n", |
| 868 | + ")" |
| 869 | + ] |
| 870 | + }, |
| 871 | + { |
| 872 | + "cell_type": "markdown", |
| 873 | + "id": "9ce1fb8d", |
| 874 | + "metadata": {}, |
| 875 | + "source": [ |
| 876 | + "#### Why Specify `boundary_points`?\n", |
| 877 | + "The internal triangulation algorithm assumes a **spherical domain**. Without user-defined constraints, it may attempt to \"wrap\" the grid edges to form a closed surface, which is inappropriate for bounded regional domains. This can cause:\n", |
| 878 | + "\n", |
| 879 | + "* Element bounds that exceed the expected coordinate extents.\n", |
| 880 | + "* Spatial hash errors in downstream workflows.\n", |
| 881 | + "* Unexpected overlaps or distortions in edge geometry.\n", |
| 882 | + "\n", |
| 883 | + "By supplying `boundary_points`, you ensure:\n", |
| 884 | + "\n", |
| 885 | + "* Proper triangulation only within the region of interest.\n", |
| 886 | + "* Accurate `face_bounds_lat` and `face_bounds_lon`.\n", |
| 887 | + "* Stable behavior for spatial indexing and remapping." |
| 888 | + ] |
827 | 889 | } |
828 | 890 | ], |
829 | 891 | "metadata": { |
|
0 commit comments