{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": "# LES Intercomparison Study for Neutral Boundary Layers: Description", "id": "e9fbf882ec1770d" }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Last updated: May 2026*\n" ], "id": "2c3fd71902db52f9" }, { "metadata": {}, "cell_type": "markdown", "source": [ "**References**\n", "\n", "Andrén, A., Brown, A. R., Graf, J., Mason, P. J., Moeng, C.-H., Nieuwstadt, F. T. M., & Schumann, U. (1994). Large-eddy simulation of a neutrally stratified boundary layer: a comparison of four codes. Quart. J. Roy. Meteorol. Soc., 120, 1457–1484.\n", "\n", "Anderson, W. C., Basu, S., & Letchford, C. W. (2007). Comparison of dynamic subgrid-scale models for simulations of neutrally buoyant shear-driven atmospheric boundary layer flows. Environmental Fluid Mechanics, 7, 195-215." ], "id": "65fa3dd23a466e43" }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Case Description**\n\nThe NBL_A94 case simulates a (truly) neutrally stratified Ekman layer with zero surface heat flux. The flow is driven by a constant geostrophic wind. The original intercomparison case is slightly modified to have realistic simulated boundary layer height.\n\n| Parameter | Value |\n| --- | --- |\n| Reference run | `examples/NBL_A94/runs/128x128x128_LASDD_SM_SP` |\n| Domain | 4000 m x 4000 m x 4000 m |\n| Reference grid | $128^3$ |\n| Run matrix | $64^3$, $128^3$, $256^3$, $384^3$ x LASDD-SM, LASDD-WL, LAD-SM, LAD-WL x SP, DP |\n| Simulation time | 300000 s (83.3333 h) |\n| Reference time step | 1 s |\n| Geostrophic wind | $U_g = 5$ m s$^{-1}$, $V_g = 0$ m s$^{-1}$ |\n| Coriolis parameter | $f = 1.0 \\times 10^{-4}$ s$^{-1}$ |\n| Roughness lengths | $z_{0m} = 0.01$ m, $z_{0T} = 0.01$ m |\n| Thermal surface option | `optSurfBC = 0` |\n| Sensible heat flux | 0 K m s$^{-1}$ |\n| Reference temperature | $T_0 = 300$ K |\n| Inversion strength | 0 / 1000 K m$^{-1}$ |\n| SGS model | LASDD-SM (`optSgs = 1`) |\n| Filter-to-grid ratio | `FGR = 2` |\n| Damping layer | above $z = 2500$ m |\n| Output statistics interval | 60 s |\n| 3D output interval | SimTime s |\n| Geostrophic forcing option | `optGeoWind = 0` |\n| Advection forcing option | `optAdvection = 0` |\n| Moisture option | `optMoisture = 0` |\n| Boundary-layer type | Neutral Ekman layer |\n| Reference averaging window | hours 75-83.3 |\n\nThe representative configuration below is copied from `examples/NBL_A94/runs/128x128x128_LASDD_SM_SP/Config.py`." ], "id": "3d8f0d8c0f4fa932" }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reference Configuration\n" ], "id": "8a5c88217b322749" }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-05-29T13:46:52.310204Z", "start_time": "2026-05-29T13:46:52.294096Z" } }, "source": [ "# Copyright (C) 2025 Sukanta Basu\n", "#\n", "# This program is free software: you can redistribute it and/or modify\n", "# it under the terms of the GNU General Public License as published by\n", "# the Free Software Foundation, either version 3 of the License, or\n", "# (at your option) any later version.\n", "#\n", "# This program is distributed in the hope that it will be useful,\n", "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n", "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n", "# GNU General Public License for more details.\n", "#\n", "# You should have received a copy of the GNU General Public License\n", "# along with this program. If not, see .\n", "\n", "\"\"\"\n", "File: Config.py\n", "===============\n", "\n", ":Author: Sukanta Basu\n", ":AI Assistance: Claude.AI (Anthropic) is used for documentation,\n", " code restructuring, and performance optimization\n", ":Date: 2026-05-20\n", ":Description: Neutral BL benchmark after Andren et al. (1994).\n", " Grid: 128x128x128, SGS: LASDD-SM,\n", " Precision: single.\n", "\"\"\"\n", "\n", "\n", "# ============================================================\n", "# Imports\n", "# ============================================================\n", "\n", "import numpy as np\n", "\n", "\n", "# ============================================================\n", "# User Input\n", "# ============================================================\n", "\n", "# ------------------------------------------------------------\n", "# Platform options\n", "# ------------------------------------------------------------\n", "use_double_precision = False\n", "# 0: use CPU, 1: use GPU\n", "optGPU = 1\n", "GPU_ID = 0\n", "\n", "# ------------------------------------------------------------\n", "# Domain configuration\n", "# ------------------------------------------------------------\n", "\n", "# Domain size (m)\n", "l_x = 4000\n", "l_y = 4000\n", "l_z = 4000\n", "\n", "# Number of grid points\n", "nx = 128\n", "ny = 128\n", "nz = 128\n", "\n", "# ------------------------------------------------------------\n", "# Time integration configuration\n", "# ------------------------------------------------------------\n", "\n", "# Change this if it is a restart run\n", "istep = 1\n", "\n", "# Time stepping and simulation time\n", "dt = 1.0 # unit: sec\n", "SimTime = 300000 # unit: sec\n", "\n", "# Galilean transformation (m/s)\n", "Ugal = 3\n", "\n", "# ------------------------------------------------------------\n", "# Surface configuration\n", "# ------------------------------------------------------------\n", "\n", "# optSurfFlux: 0 = homogeneous, 1 = heterogeneous\n", "optSurfFlux = 0\n", "\n", "# optSurfBC: 0 = constant flux\n", "# 1 = time-varying flux (from SurfaceBCFile)\n", "# 2 = time-varying surface temperature (from SurfaceBCFile)\n", "optSurfBC = 0\n", "\n", "# Roughness lengths (m)\n", "z0m = 0.01\n", "z0T = 0.01\n", "\n", "# Screen-level temperature reference height (m); 0 = use z0T\n", "zTemperature = 0.0\n", "\n", "# SensibleHeatFlux: not used when optSurfBC >= 1; set to 0 as placeholder\n", "SensibleHeatFlux = 0.0 # K m/s\n", "\n", "# Path to surface BC file (relative to run directory)\n", "SurfaceBCFile = 'input/SurfaceBC.npz'\n", "\n", "# ------------------------------------------------------------\n", "# Forcing configuration\n", "# ------------------------------------------------------------\n", "\n", "# Geostrophic wind option:\n", "# 0 = constant Ug2, Vg2 from Config\n", "# 1 = time + height varying, loaded from GeoWindFile\n", "optGeoWind = 0\n", "\n", "# Constant geostrophic wind (m/s)\n", "Ug2 = 5\n", "Vg2 = 0\n", "\n", "# Path to geostrophic wind file (relative to run directory)\n", "GeoWindFile = 'input/GeoWind.npz'\n", "\n", "# Coriolis parameter (1/s)\n", "f_coriolis = 0.0001\n", "\n", "# Potential temperature lapse rate above domain top (K/m)\n", "inversion = 0/1000\n", "\n", "# Buoyancy calculation: 0 = use reference T_0, 1 = use local THv\n", "optBuoyancy = 1\n", "\n", "# Reference temperature (K)\n", "T_0 = 300\n", "\n", "# ------------------------------------------------------------\n", "# Subgrid-scale configuration\n", "# ------------------------------------------------------------\n", "\n", "# SGS model: 1 = LASDD-SM, 2 = LASDD-WL, 3 = LAD-SM, 4 = LAD-WL\n", "optSgs = 1\n", "\n", "# Dynamic SGS update frequency (every N steps)\n", "dynamicSGS_call_time = 1\n", "\n", "# Filter to grid ratio (FGR=1: implicit + dealiasing; FGR>=2: explicit)\n", "FGR = 2\n", "\n", "# Initial SGS coefficients (used before first dynamic update)\n", "Cs2 = 0.1 ** 2 # SM models: initial Cs^2\n", "Cwl = 0.1 ** 2 # WL models: initial C_WL\n", "Cs2PrRatio = Cs2 / 1.0\n", "CwlPrRatio = Cwl / 1.0\n", "\n", "# ------------------------------------------------------------\n", "# Damping layer configuration\n", "# ------------------------------------------------------------\n", "\n", "optDamping = 1 # 1: activate Rayleigh damping\n", "z_damping = 2500 # unit: m\n", "RelaxTime = 300 # unit: s\n", "\n", "# ------------------------------------------------------------\n", "# Statistics computation\n", "# ------------------------------------------------------------\n", "\n", "SampleInterval_sec = 10.0 # collect a sample every N s\n", "OutputInterval_sec = 60.0 # output averaged stats every N s\n", "Output3DInterval_sec = SimTime # output 3D fields only at the end of the run\n", "\n", "# ------------------------------------------------------------\n", "# Large-scale advection forcing\n", "# ------------------------------------------------------------\n", "# 0: none, 1: time/height-varying (from AdvectionFile)\n", "optAdvection = 0\n", "AdvectionFile = 'input/AdvForcing.npz'\n", "\n", "# ------------------------------------------------------------\n", "# Moisture configuration\n", "# ------------------------------------------------------------\n", "# 0: dry run, 1: prognostic specific humidity Q\n", "optMoisture = 0\n", "# Screen-level moisture reference height (m); 0 = use z0T\n", "zMoisture = 0.0\n", "# Surface moisture flux (kg/kg m/s); used when optMoistureSurfBC = 0\n", "MoistureFlux = 0.0\n", "# 0: constant flux, 1: time-varying flux, 2: time-varying surface Q\n", "optMoistureSurfBC = 0\n", "MoistureSurfaceBCFile = 'input/MoistureSurfaceBC.npz'\n", "# Specific humidity lapse rate above domain top (kg/kg/m); 0 = zero gradient\n", "q_inversion = 0.0\n", "\n", "# Pressure solver: 0 = LU (original), 1 = Thomas (tridiagonal, faster)\n", "optPressureSolver = 1" ], "id": "5c144fff89d0b53a", "outputs": [], "execution_count": 1 } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }