-
Notifications
You must be signed in to change notification settings - Fork 181
Description
Treating velocities at z=0
The u-component of velocity is initialized with a shear profile that enforces a no slip condition at the ground (when z_sorted is 0, the shear profile is 0):
wind_profile_plane = (grid.z_sorted / self.reference_wind_height) ** self.wind_shearHowever, the integration of the wake deficit with the background flow simply subtracts the two:
flow_field.u_sorted = flow_field.u_initial_sorted - wake_fieldGiven this solver structure, the wake models themselves are responsible for handing the velocity at the ground. This separation of concerns is valid since the solver should not contain the physical models but instead orchestrate the coupling between the models.
Additionally, the Gauss-Curl Hybrid model contains methods for calculating the transverse velocity components (v and w in addition to u) in floris.simulation.wake_deflection.gauss.calculate_transverse_velocity, but a no slip condition at the ground is not enforced.
This was found in #699 since @vallbog noted that the derivative of the streamwise velocity component (du/dz) initialized in the FlowField results in a divide-by-zero at z=0 and the wind shear exponent is less than 1 (discussed in #699 (comment)). In that case, a runtime warning is issued and the transverse velocity components should be undefined (though I haven't tested that this is what FLORIS produces). #699 instead sets the derivative to 0 when the wind shear is 0 to avoid the divide by zero. This change is relevant to this issue because the ultimate question is how to treat this derivate at the ground since it's actually more appropriate to be undefined.
Proposed solution
- All velocity components should always be 0 at a point where z=0
- Tests of the wake models at z=0 should show 0 velocity
- Tests of the transverse velocity components should show 0 velocity
Additional information
Here's the beginning of a test for this:
# What happens when the wind shear and height are 0?
tdict = turbine_grid_fixture.as_dict()
tdict["grid_resolution"] = 3 # Use an odd number to put a point at the origin
coords = np.array(tdict["turbine_coordinates"]).T # Transpose to get (x, y, z)
coords[2, :] = 0.0 # Set all z coordinates to 0.0
tdict["turbine_coordinates"] = coords.T.tolist() # Transpose back to (N, 3)
turbine_grid = TurbineGrid.from_dict(tdict)
flow_field_fixture.wind_shear = 0.0
flow_field_fixture.initialize_velocity_field(turbine_grid)
print(flow_field_fixture.u_initial_sorted)