AMR-Wind ABL Boundary I/O
Wind farm simulations typically require ABL inflow conditions. As such, a precursor ABL simulation is often performed to collect inflow conditions for the wind farm. AMR-Wind leverages NetCDF to collect ABL inflow variables at each time step and write the data to a file. This file can then be read during a wind farm simulation to populate the inflow.
Note
Inflow conditions are linearly interpolated between output times.
The time for the simulation that is reading the inflow file must be entirely contained within the inflow times.
The simulation reading the inflow file must have the same grid resolution at the boundaries.
Generating the inflow file from an ABL simulation
The following section can be added to the input file to generate an inflow file during an ABL simulation:
ABL.bndry_file = "bndry_file.nc"
ABL.bndry_io_mode = 0
ABL.bndry_planes = ylo xlo
ABL.bndry_output_start_time = 2.0
ABL.bndry_var_names = velocity temperature
In the case of using the OneEqKsgsM84 model the tke field is also needed.
ABL.bndry_var_names = velocity temperature tke
Using an inflow file in an ABL simulation
The following section can be added to the input file to read an inflow file to populate the boundary conditions:
ABL.bndry_file = "../orig/bndry_file.nc"
ABL.bndry_io_mode = 1
ABL.bndry_var_names = velocity temperature
Again, In the case of using the OneEqKsgsM84 model the tke field is also needed.
ABL.bndry_var_names = velocity temperature tke
The boundary conditions need to be adjusted from periodic to inflow/outflow. The following lines show the changes that need to be made to the input file for the x coordinate (similar change for y coordinate when needed):
geometry.is_periodic = 0 1 0 # Periodicity x y z (0/1)
xlo.type = "mass_inflow"
xlo.density = 1.0
xhi.type = "pressure_outflow"
Inflow file structure (NetCDF)
The inflow file is written by the NetCDF library in the following structure:
Top level contains the data common to all the groups (title, dimensions, time)
Mid level contains the groups of planes: Each plane (e.g.
xlo
) is assigned a group at this level. It contains variables such as the plane normal and perpendicular directions.Bottom levels contains groups of AMR levels, i.e. the levels associated with each plane: Each AMR level is assigned a group (e.g. “level_0”, “level_1”, etc) containing the variable dimensions and the inflow variables (e.g. velocity) associated with that level.
For a multi-level file, ncdump -h <file> provides:
1netcdf bndry_file {
2dimensions:
3 sdim = 1 ;
4 pdim = 2 ;
5 vdim = 3 ;
6 nt = UNLIMITED ; // (7 currently)
7variables:
8 double time(nt) ;
9
10// global attributes:
11 :title = "ABL boundary planes" ;
12
13group: xlo {
14 variables:
15 int normal ;
16 int side ;
17 int perpendicular(pdim) ;
18
19 group: level_0 {
20 dimensions:
21 nx = 48 ;
22 ny = 48 ;
23 nz = 48 ;
24 variables:
25 double lengths(pdim) ;
26 double lo(pdim) ;
27 double hi(pdim) ;
28 double dx(pdim) ;
29 double velocity(nt, ny, nz, vdim) ;
30 double temperature(nt, ny, nz) ;
31 } // group level_0
32
33 group: level_1 {
34 dimensions:
35 nx = 96 ;
36 ny = 96 ;
37 nz = 56 ;
38 variables:
39 double lengths(pdim) ;
40 double lo(pdim) ;
41 double hi(pdim) ;
42 double dx(pdim) ;
43 double velocity(nt, ny, nz, vdim) ;
44 double temperature(nt, ny, nz) ;
45 } // group level_1
46 } // group xlo
47
48group: ylo {
49 variables:
50 int normal ;
51 int side ;
52 int perpendicular(pdim) ;
53
54 group: level_0 {
55 dimensions:
56 nx = 48 ;
57 ny = 48 ;
58 nz = 48 ;
59 variables:
60 double lengths(pdim) ;
61 double lo(pdim) ;
62 double hi(pdim) ;
63 double dx(pdim) ;
64 double velocity(nt, nx, nz, vdim) ;
65 double temperature(nt, nx, nz) ;
66 } // group level_0
67
68 group: level_1 {
69 dimensions:
70 nx = 96 ;
71 ny = 96 ;
72 nz = 56 ;
73 variables:
74 double lengths(pdim) ;
75 double lo(pdim) ;
76 double hi(pdim) ;
77 double dx(pdim) ;
78 double velocity(nt, nx, nz, vdim) ;
79 double temperature(nt, nx, nz) ;
80 } // group level_1
81 } // group ylo
82}
The inflow file can be inspected with Python as such:
from netCDF4 import Dataset
import matplotlib.pyplot as plt
Load the file and inspect the top level
rg = Dataset("bndry_file.nc", "r")
print(rg)
Looping through the planes
for grp in rg.groups:
print(f"""Accessing {grp}:""")
print(rg.groups[grp])
Inspect the output times
print(rg.variables["time"][:])
Looping through the AMR levels in a given plane
plane = "ylo"
for grp in rg.groups[plane].groups:
print(f"""Accessing {grp} in plane {plane}:""")
print(rg.groups[plane].groups[grp])
An example of plotting the data in the different planes and levels
def plot_field(plane, name):
nlevels = len(plane.groups)
shp = (plane.groups["level_0"].variables[name][:]).shape
if len(shp) == 4:
ncomp = shp[-1]
else:
ncomp = 1
fig, axs = plt.subplots(nrows=nlevels, ncols=ncomp, sharex=True, figsize=(8*ncomp,6*nlevels), squeeze=False)
fig.suptitle(f"{name}_{plane.name}", fontsize=20)
for component in range(ncomp):
for i, lev in enumerate(plane.groups):
fld = plane.groups[lev].variables[name][:]
lo = plane.groups[lev].variables["lo"][:]
hi = plane.groups[lev].variables["hi"][:]
if ncomp == 1:
arr = fld[0, :, :].T
else:
arr = fld[0, :, :, component].T
axs[i, component].imshow(
arr,
extent=[lo[0], hi[0], lo[1], hi[1]],
origin="lower",
aspect="auto",
)
axs[i, component].set_title(lev)
plt.savefig(f"{name}_{plane.name}.png")
for plane in ["ylo", "xlo"]:
plot_field(rg.groups[plane], "velocity")
plot_field(rg.groups[plane], "temperature")
Inflow file structure (native)
These are the files generated by ABL.bndry_output_format =
native
. It is possible to visualize the native boundary files with
the usual data visualizers (e.g., VisIt). Because of limitations with
the visualizers, it is possible to see only one plane and one variable
at a time. The different Header*
files must be linked to
Header
. This can be done with the following command for the
velocity
field at the xlo
boundary, from the run directory:
$ find . \( -name "Header_0_velocity" \) -exec bash -c 'ln -s $(basename {}) $(dirname {})/Header' \;
The different boundaries are counted as xlo = 0
, ylo = 1
,
zlo = 2
, xhi = 3
, yhi = 4
, and zhi = 5
. The boundary
files can now be loaded into the visualizers.
AMR-Wind provides Python tools for reading and manipulating boundary
file data. These are located in the tools
folder of Python
scripts. One of the provided examples,
refine_native_boundary_plane.py
, is a utility to refine boundary
planes. Another, generate_native_boundary_plane.py
can be used to
generate arbitrary temporal and spatially varying boundary conditions.