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
Currently, it is only possible to write xlo and ylo boundaries.
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
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")