Plugin WindLab: Difference between revisions
No edit summary |
No edit summary |
||
(13 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
|Version=1.0 | |Version=1.0 | ||
|Date=2024-04-15 | |Date=2024-04-15 | ||
|Features= [[#Cholesky_Decomposition|Cholesky Decomposition]], [[#Horizontal_Uniform_Distribution|Horizontal Uniform Distribution]], [[#Vertical_Uniform_Distribution|Vertical Uniform Distribution]], [[#Uniform_Distribution|Uniform Distribution]], [[#Grid_Points|Grid Points]], [[#Power_Law_Profile|Power Law Profile]], [[#Logarithmic_Law_Profile|Logarithmic Law Profile]], [[#Deaves_and_Harris_Profile|Deaves and Harris Profile]] | |||
|RPSVersion=All | |RPSVersion=All | ||
}} | }} | ||
You can find the source code on the following Github repository: | You can find the source code of this plugin on the following Github repository: [https://github.com/LabRPS/LabRPS-plugins/tree/master/WindLab/WindLabPlugin Get the code here!]. This plugin is one of the official plugins provided by LabRPS. It provides very useful features (tools) for the simulation of random wind velocity. Plugins are very easy to create in LabRPS, therefore, anyone can develop plugin for any random phenomenon in LabRPS. Go to this [[Plugin_Creation|page]] to see how to create new plugin for LabRPS. You can get quick assistance from LabRPS community by sending your concern to the [https://labrps.com/boards community forum]. | ||
[https://github.com/LabRPS/LabRPS-plugins/tree/master/WindLab/WindLabPlugin Get the code here!] | |||
{{ | == Cholesky Decomposition == | ||
This feature performs the [https://en.wikipedia.org/wiki/Cholesky_decomposition Cholesky decomposition] of a positive Hermitian power spectrum matrix and returns the lower triangular matrix (L) of the decomposition. The Cholesky decomposition is a numerical method used to decompose a positive-definite matrix into the product of a lower triangular matrix and its conjugate transpose. Specifically, for a matrix | |||
A, the decomposition is given by: | |||
<math display=block>\mathbf{A} = \mathbf{L L}^{*},</math> | |||
<math display=block> L_{j,j} = \sqrt{ A_{j,j} - \sum_{k=1}^{j-1} L_{j,k}^*L_{j,k} }, </math> | |||
<math display=block> L_{i,j} = \frac{1}{L_{j,j}} \left( A_{i,j} - \sum_{k=1}^{j-1} L_{j,k}^* L_{i,k} \right) \quad \text{for } i>j. </math> | |||
where <math>L</math> is a [https://en.wikipedia.org/wiki/Triangular_matrix lower triangular matrix] with real and positive diagonal entries, and <math>L^*</math> denotes the [https://en.wikipedia.org/wiki/Conjugate_transpose conjugate transpose] of <math>L</math>. | |||
The feature is optimized for performance and can handle large matrices efficiently using <math>O(n^3)</math> computational complexity in the worst case. It checks if the input matrix is indeed positive-definite and Hermitian before performing the decomposition and raises an error if the matrix does not meet these conditions. The feature belong to the [[RPS_Feature_Group#PSD_Decomposition_Method|PSD Decomposition Method]] feature group. | |||
=== Scripting === | |||
The feature can be used from the python console as follows: | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "Cholesky Decomposition" | |||
featureGroup = "Spectrum Decomposition Method" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
decomposedPSD = WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not decomposedPSD : | |||
LabRPS.Console.PrintError("Error on creating the spectrum decomposition method.\n") | |||
# abord the computation | |||
# get the active simulation points feature and compute the simulation points coordinates | |||
simPoints = sim.computeLocationCoordinateMatrixP3() | |||
# use a vector to represent a simulation point based on its coordinates | |||
v1 = vec(simPoints[0][1], simPoints[0][2], simPoints[0][3]) | |||
v2 = vec(simPoints[1][1], simPoints[1][2], simPoints[1][3]) | |||
v3 = vec(simPoints[2][1], simPoints[2][2], simPoints[2][3]) | |||
# This feature is used to decompose power spectrum matrices which may vary in time. Let's assume that | |||
# the active power spectrun density function in this example is stationary. Meanning it is not varying in time. | |||
#Then, we use time instant of 0 second. | |||
time = 0.0 | |||
# compute the decomposed cross spectrum between points 1 and 3, at time instant of 0 second and for all frequency | |||
# increments. Note that when the following code is run, WindLab will try to identify the active frequency distribution, | |||
# the active power spectrum feature, the active coherence function feature and others. If WindLab fails to find any | |||
# of these dependency features, the computation will fails and specific error messages will be sent to the report view. | |||
# The following function is only one of its functions. There are some other two. | |||
psd13 = sim.computeDecomposedCrossSpectrumVectorF(v1, v3, time) | |||
# psd13 can be converted to numpy vector and be used for some other purposes. | |||
arr = numpy.asarray(psd13) | |||
}} | |||
== Horizontal Uniform Distribution == | |||
This feature provides an efficient method to distribute random wind simulation points uniformly in space. It allows users to generate a set of points within a 3D spatial domain, ensuring that the points are evenly distributed along a horizontal line that is parallel to one of the coordinate system axis. This uniform distribution is critical in certain simulation methods. For <math>n</math> simulation points <math>(P_1,P_2,P_3,...,P_n)</math>, the distance <math>d_{jk}</math> between points <math>P_j</math> and <math>P_k</math> must be given by the following formula: | |||
<math>d_{jk} = s\times|j-k|</math> | |||
where <math>s</math> is the even space between any two adjacent points. | |||
=== Properties === | |||
* {{PropertyData|FirstPoint}}: This is a point in 3D space representing the first point the distribution will start from. | |||
* {{PropertyData|Spacing}}: This is the even space between any two adjacent points in the distribution. | |||
=== Scripting === | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "Horizontal Distribution" | |||
featureGroup = "Location Distribution" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not unifSimPoints: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
# let's set the first point of the distribution (x =0, y = 0, z = 80m) | |||
simPoints.FirstPoint = vec(0,0,80000) | |||
# let's set the spacing (s = 10m) | |||
simPoints.Spacing = '10m' | |||
# compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. | |||
simPoints = sim.computeLocationCoordinateMatrixP3() | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(simPoints) | |||
}} | |||
[[#top| Back to the Top ]] | |||
== Vertical Uniform Distribution == | |||
This feature provides an efficient method to distribute random wind simulation points uniformly in space. It allows users to generate a set of points within a 3D spatial domain, ensuring that the points are evenly distributed along a vertical line. This uniform distribution is critical in certain simulation methods. For <math>n</math> simulation points <math>(P_1,P_2,P_3,...,P_n)</math>, the distance <math>d_{jk}</math> between points <math>P_j</math> and <math>P_k</math> must be given by the following formula: | |||
<math>d_{jk} = s\times|j-k|</math> | |||
where <math>s</math> is the even space between any two adjacent points. | |||
=== Properties === | |||
* {{PropertyData|LowestPoint}}: This is a point in 3D space representing the lowest point the distribution will start from. In many applications, this point should not be lower than 10 meters. | |||
* {{PropertyData|Spacing}}: This is the even space between any two adjacent points in the distribution. | |||
=== Scripting === | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "VerticalDistribution" | |||
featureGroup = "Location Distribution" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not unifSimPoints: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
# let's set the first point of the distribution (x =0, y = 0, z = 30m) | |||
simPoints.LowestPoint = vec(0,0,30000) | |||
# let's set the spacing (s = 10m) | |||
simPoints.Spacing = '10m' | |||
# compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. | |||
simPoints = sim.computeLocationCoordinateMatrixP3() | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(simPoints) | |||
}} | |||
[[#top| Back to the Top ]] | |||
== Uniform Distribution == | |||
This feature may be seen as a general form of the horizontal and the vertical distribution features. It allows users to generate a set of points within a 3D spatial domain, ensuring that the points are evenly distributed along a line parallel to one of the coordinate system axis. For <math>n</math> simulation points <math>(P_1,P_2,P_3,...,P_n)</math>, the distance <math>d_{jk}</math> between points <math>P_j</math> and <math>P_k</math> must be given by the following formula: | |||
<math>d_{jk} = s\times|j-k|</math> | |||
where <math>s</math> is the even space between any two adjacent points. | |||
=== Properties === | |||
* {{PropertyData|FirstPoint}}: This is a point in 3D space representing the first point the distribution will start from. This should be the lowest point in case the distribution is parallel to the vertical axis and should not be lower than 10 meters in many application. | |||
* {{PropertyData|Spacing}}: This is the even space between any two adjacent points in the distribution. | |||
* {{PropertyData|Direction}}: Its value can be X, Y or Z. This is the axis the points distribution is parallel to. | |||
=== Scripting === | |||
This feature can be used to produce vertical distribution as we did before in the Vertical Distribution feature. | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "UniformDistribution" | |||
featureGroup = "Location Distribution" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not unifSimPoints: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
# set the direction of the distribution to be vertical | |||
simPoints.Direction= 'Z' | |||
# let's set the first point of the distribution (x =0, y = 0, z = 30m) | |||
simPoints.FirstPoint = vec(0,0,30000) # This is the lowest point in this case (Direction = 'Z') | |||
# let's set the spacing (s = 10m) | |||
simPoints.Spacing = '10m' | |||
# compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. | |||
simPoints = sim.computeLocationCoordinateMatrixP3() | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(simPoints) | |||
}} | |||
[[#top| Back to the Top ]] | |||
== Grid Points == | |||
This feature allows users to generate a set of grid points within a 3D spatial domain, ensuring that the points are evenly distributed in a plane parallel to one of the coordinate system planes (XY Plane, YZ Plane, XZ Plane). | |||
=== Properties === | |||
* {{PropertyData|Spacing1}}: This is the points spacing along one of the axis forming the plane. | |||
* {{PropertyData|Spacing2}}: This is the points spacing along the second axis. | |||
* {{PropertyData|Length1}}: This is the length within points are distributed along one of the axis forming the plane. | |||
* {{PropertyData|Length2}}: This is the length within points are distributed along the second axis. | |||
* {{PropertyData|CenterPoint}}: This is the center of the grid around which the points are generated. It is a 3D point. | |||
* {{PropertyData|NumberOfPoints}}: This is the resulting total number of points in the grid. This is a read only property for internal use. User cannot change its value directly. | |||
=== Scripting === | |||
The following script shows how this feature can be created and used. | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "Grid Points" | |||
featureGroup = "Location Distribution" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not unifSimPoints: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
# set the plan the points grid is parallel to | |||
simPoints.LocationPlan= 'YZ Plane' | |||
# let's set the center point of the distribution (x =0, y = 0, z = 0) | |||
simPoints.CenterPoint = vec(0,0,0) | |||
# let's set the spacing1 (s1 = 10m) | |||
simPoints.Spacing1 = '10m' | |||
# let's set the spacing2 (s2 = 10m) | |||
simPoints.Spacing2 = '10m' | |||
# let's set the length1 (l1 = 200m) | |||
simPoints.Length1= '200m' | |||
# let's set the length2 (l2 = 200m) | |||
simPoints.Length2= '200m' | |||
# compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. | |||
simPoints = sim.computeLocationCoordinateMatrixP3() | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(simPoints) | |||
}} | |||
[[#top| Back to the Top ]] | |||
== General Distribution == | |||
When the simulation points distribution is more general and does not follow any of the previous uniform distribution, this feature can be used. This feature allows users to input simulation points one by one using their coordinates based on the vector dialog shown below: | |||
[[Image:WindLab_Tutorial001_Pic005_WindLab_Feat_Locations_2.png|400px]] | |||
=== Properties === | |||
* {{PropertyData|Locations}}: This is a list holding the simulation points | |||
=== Scripting === | |||
The following script shows how this feature can be created and used. | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "General Distribution" | |||
featureGroup = "Location Distribution" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
genSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not genSimPoints: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
# create the simulation points by their coordinates | |||
v1 = vec(0, 0, 35000) | |||
v2 = vec(0, 0, 40000) | |||
v3 = vec(0, 0, 140000) | |||
# add the points to the locations | |||
loc.Locations = [v1, v2, v3] | |||
# compute the simulation points coordinates. WindLab will internally use the "genSimPoints" feature | |||
simPoints = sim.computeLocationCoordinateMatrixP3() | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(simPoints) | |||
}} | |||
[[#top| Back to the Top ]] | |||
== Power Law Profile == | |||
This feature is designed to compute the wind speed at a given height based on the power law mean wind profile, which is commonly used to model the variation of wind speed with height in the atmospheric boundary layer. This model is essential in fields such as wind energy, structural engineering, and environmental science. The power law formula that governs the relationship between wind speed and height is expressed as: | |||
<math>U(z) = U(z_0)\times\left( \frac{{z-\phi}}{z_0} \right)^\alpha</math> | |||
where: | |||
* <math>U(z)</math> is the wind speed at height <math>z</math>, | |||
* <math>U(z_0)</math> is the reference wind speed at a known reference height <math>z_0</math>, | |||
* <math>\alpha</math> is the power law exponent, a dimensionless constant that varies depending on terrain and atmospheric conditions, | |||
* <math>\phi</math> is the zero plan displacement, | |||
* <math>z</math> is the height at which the wind speed is to be calculated. | |||
=== Properties === | |||
* {{PropertyData|ReferenceHeight}}: This is a reference height. | |||
* {{PropertyData|ReferenceSpeed}}: This is the reference wind speed at the reference height. | |||
* {{PropertyData|DimensionlessPower}}: This is the power law exponent. | |||
* {{PropertyData|ZeroPlanDisplacement}}: This is the zero plan displacement. | |||
=== Scripting === | |||
The following script shows how this feature can be created and used. | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "Power Law Profile" | |||
featureGroup = "Mean Wind Profile" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
meanSpeed= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not meanSpeed: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
meanSpeed.ReferenceHeight = '10.00 m' | |||
meanSpeed.ReferenceSpeed = '30.00 m/s' | |||
meanSpeed.DimensionlessPower = 0.12 | |||
meanSpeed.ZeroPlanDisplacement = '0.0 m' | |||
# In WindLab, mean wind velocity can vary with time. In case the user desires a time dependent mean wind speed, | |||
# a modulation function can be used for this purpose. The feature account for this. When the Stationarity property of the parent | |||
# simulation of this feature is false, the feature identify the active modulation function and use it to produce non-stationary | |||
# mean wind speed. But for this example we shall use time instant of 0 second. | |||
time = 0.0 | |||
# compute the mean wind speeds at time instant of 0 second and for all simulation points | |||
# Note that when the following code is run, WindLab will try to identify the active locations distribution, | |||
# it will also try to identity the active modulation function in case the parent simulation is non-stationary. | |||
# If WindLab fails to find these dependency features, the computation will fails and specific error messages will be sent to the report view. | |||
meanValues = sim.computeMeanWindSpeedVectorP(time) | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(meanValues ) | |||
}} | |||
[[#top| Back to the Top ]] | |||
== Logarithmic Law Profile == | |||
This feature is designed to compute the wind speed at a given height based on the logarithmic law mean wind profile. The logarithmic law is commonly used to model the variation of wind speed with height in the atmospheric boundary layer, especially in cases where the wind profile is influenced by surface roughness, such as over flat terrain, forests, or urban environments. The logarithmic law for wind speed variation is given by the following equation: | |||
<math>U(z) =\left( \frac{u_*}{k} \right)\times\ln{\left( \frac{{z-\phi}}{z_0} \right)}</math> | |||
where: | |||
* <math>U(z)</math> is the wind speed at height <math>z</math>, | |||
* <math>u_*</math> is the friction velocity, which is a measure of the turbulence intensity, | |||
* <math>k</math> is the von Kármán constant (approximately 0.4), | |||
* <math>\phi</math> is the zero plan displacement, | |||
* <math>z_0</math> is the roughness length, which characterizes the roughness of the surface, | |||
* <math>z</math> is the height at which the wind speed is to be calculated. | |||
=== Properties === | |||
* {{PropertyData|TerrainRoughness}}: This is the terrain roughness value. | |||
* {{PropertyData|ShearVelocity}}: This is the shear velocity of the flow. | |||
* {{PropertyData|vonKarmanConstant}}: This is the von karman constant. | |||
* {{PropertyData|ZeroPlanDisplacement}}: This is the zero plan displacement value. | |||
=== Scripting === | |||
The following script shows how this feature can be created and used. | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "Logarithmic Law Profile" | |||
featureGroup = "Mean Wind Profile" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
meanSpeed= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not meanSpeed: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
meanSpeed.TerrainRoughness = '0.001266 m' | |||
meanSpeed.ShearVelocity = '1.76 m/s' | |||
# In WindLab, mean wind velocity can vary with time. In case the user desires a time dependent mean wind speed, | |||
# a modulation function can be used for this purpose. The feature account for this. When the Stationarity property of the parent | |||
# simulation of this feature is false, the feature identify the active modulation function and use it to produce non-stationary | |||
# mean wind speed. But for this example we shall use time instant of 0 second. | |||
time = 0.0 | |||
# compute the mean wind speeds at time instant of 0 second and for all simulation points | |||
# Note that when the following code is run, WindLab will try to identify the active locations distribution, | |||
# it will also try to identity the active modulation function in case the parent simulation is non-stationary. | |||
# If WindLab fails to find these dependency features, the computation will fails and specific error messages will be sent to the report view. | |||
meanValues = sim.computeMeanWindSpeedVectorP(time) | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(meanValues ) | |||
}} | |||
[[#top| Back to the Top ]] | |||
== Deaves and Harris Profile == | |||
This feature is designed to compute the wind speed at a given height based on the logarithmic law mean wind profile. The logarithmic law is commonly used to model the variation of wind speed with height in the atmospheric boundary layer, especially in cases where the wind profile is influenced by surface roughness, such as over flat terrain, forests, or urban environments. The logarithmic law for wind speed variation is given by the following equation: | |||
<math>U(z) =\left( \frac{u_*}{k} \right)\times\left [\ln{\left( \frac{{z-z_d}}{z_0} \right)} + 5.75\left( \frac{{z-z_d}}{h} \right) - 1.88\left( \frac{{z-z_d}}{h} \right)^2 - 1.33\left( \frac{{z-z_d}}{h} \right)^3 + 0.25\left( \frac{{z-z_d}}{h} \right)^4\right ]</math> | |||
where: | |||
* <math>U(z)</math> is the wind speed at height <math>z</math>, | |||
* <math>u_*</math> is the friction velocity, which is a measure of the turbulence intensity, | |||
* <math>k</math> is the von Kármán constant (approximately 0.4), | |||
* <math>z_d</math> is the zero plan displacement, | |||
* <math>z_0</math> is the roughness length, which characterizes the roughness of the surface, | |||
* <math>h</math> is the gradient height, defined as the height where atmospheric flow is free from surface stresses and becomes geostrophic, | |||
* <math>z</math> is the height at which the wind speed is to be calculated. | |||
=== Properties === | |||
* {{PropertyData|TerrainRoughness}}: The terrain roughness length. | |||
* {{PropertyData|ShearVelocity}}: The shear velocity of the flow. | |||
* {{PropertyData|ZeroPlanDisplacement}}: The zero plan displacement. | |||
* {{PropertyData|Latitude}}: The latitude. | |||
* {{PropertyData|EarthAngularVelocity}}: The earth angular velocity. | |||
* {{PropertyData|Betta}}: The coefficient beta. | |||
=== Scripting === | |||
The following script shows how this feature can be created and used. | |||
{{Code|code= | |||
import WindLab | |||
import WindLabObjects | |||
from LabRPS import Vector as vec | |||
import numpy | |||
# get an existing WindLab simulation called "Simulation" | |||
sim = WindLab.getSimulation("Simulation") | |||
# check if the simulation does really exist | |||
if not sim: | |||
LabRPS.Console.PrintError("The simulation does not exist.\n") | |||
# abord the computation | |||
featureType = "Deaves and Harris Profile" | |||
featureGroup = "Mean Wind Profile" | |||
# create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in | |||
# case you don't understand the next line) | |||
meanSpeed= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) | |||
# check if the created feature is good | |||
if not meanSpeed: | |||
LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") | |||
# abord the computation | |||
meanSpeed.TerrainRoughness = '0.001266 m' | |||
meanSpeed.ShearVelocity = '1.76 m/s' | |||
# In WindLab, mean wind velocity can vary with time. In case the user desires a time dependent mean wind speed, | |||
# a modulation function can be used for this purpose. The feature account for this. When the Stationarity property of the parent | |||
# simulation of this feature is false, the feature identify the active modulation function and use it to produce non-stationary | |||
# mean wind speed. But for this example we shall use time instant of 0 second. | |||
time = 0.0 | |||
# compute the mean wind speeds at time instant of 0 second and for all simulation points | |||
# Note that when the following code is run, WindLab will try to identify the active locations distribution, | |||
# it will also try to identity the active modulation function in case the parent simulation is non-stationary. | |||
# If WindLab fails to find these dependency features, the computation will fails and specific error messages will be sent to the report view. | |||
meanValues = sim.computeMeanWindSpeedVectorP(time) | |||
# now you can convert the coordinate matrix to numpy array and use it for any other purposes | |||
arr = numpy.asarray(meanValues ) | |||
}} | |||
[[#top| Back to the Top ]] |
Latest revision as of 13:24, 20 November 2024
Description |
---|
This plugin implement various WindLab features. Plugin version: 1.0 Last modified: 2024-04-15 LabRPS version: All Author: Koffi Daniel |
Author |
Koffi Daniel |
Download |
None |
Features |
Cholesky Decomposition, Horizontal Uniform Distribution, Vertical Uniform Distribution, Uniform Distribution, Grid Points, Power Law Profile, Logarithmic Law Profile, Deaves and Harris Profile |
Plugin Version |
1.0 |
Date last modified |
2024-04-15 |
LabRPS Version(s) |
All |
Default shortcut |
None |
See also |
None |
You can find the source code of this plugin on the following Github repository: Get the code here!. This plugin is one of the official plugins provided by LabRPS. It provides very useful features (tools) for the simulation of random wind velocity. Plugins are very easy to create in LabRPS, therefore, anyone can develop plugin for any random phenomenon in LabRPS. Go to this page to see how to create new plugin for LabRPS. You can get quick assistance from LabRPS community by sending your concern to the community forum.
Cholesky Decomposition
This feature performs the Cholesky decomposition of a positive Hermitian power spectrum matrix and returns the lower triangular matrix (L) of the decomposition. The Cholesky decomposition is a numerical method used to decompose a positive-definite matrix into the product of a lower triangular matrix and its conjugate transpose. Specifically, for a matrix A, the decomposition is given by:
[math]\displaystyle{ \mathbf{A} = \mathbf{L L}^{*}, }[/math]
[math]\displaystyle{ L_{j,j} = \sqrt{ A_{j,j} - \sum_{k=1}^{j-1} L_{j,k}^*L_{j,k} }, }[/math]
[math]\displaystyle{ L_{i,j} = \frac{1}{L_{j,j}} \left( A_{i,j} - \sum_{k=1}^{j-1} L_{j,k}^* L_{i,k} \right) \quad \text{for } i\gt j. }[/math]
where [math]\displaystyle{ L }[/math] is a lower triangular matrix with real and positive diagonal entries, and [math]\displaystyle{ L^* }[/math] denotes the conjugate transpose of [math]\displaystyle{ L }[/math].
The feature is optimized for performance and can handle large matrices efficiently using [math]\displaystyle{ O(n^3) }[/math] computational complexity in the worst case. It checks if the input matrix is indeed positive-definite and Hermitian before performing the decomposition and raises an error if the matrix does not meet these conditions. The feature belong to the PSD Decomposition Method feature group.
Scripting
The feature can be used from the python console as follows:
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "Cholesky Decomposition" featureGroup = "Spectrum Decomposition Method" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) decomposedPSD = WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not decomposedPSD : LabRPS.Console.PrintError("Error on creating the spectrum decomposition method.\n") # abord the computation # get the active simulation points feature and compute the simulation points coordinates simPoints = sim.computeLocationCoordinateMatrixP3() # use a vector to represent a simulation point based on its coordinates v1 = vec(simPoints[0][1], simPoints[0][2], simPoints[0][3]) v2 = vec(simPoints[1][1], simPoints[1][2], simPoints[1][3]) v3 = vec(simPoints[2][1], simPoints[2][2], simPoints[2][3]) # This feature is used to decompose power spectrum matrices which may vary in time. Let's assume that # the active power spectrun density function in this example is stationary. Meanning it is not varying in time. #Then, we use time instant of 0 second. time = 0.0 # compute the decomposed cross spectrum between points 1 and 3, at time instant of 0 second and for all frequency # increments. Note that when the following code is run, WindLab will try to identify the active frequency distribution, # the active power spectrum feature, the active coherence function feature and others. If WindLab fails to find any # of these dependency features, the computation will fails and specific error messages will be sent to the report view. # The following function is only one of its functions. There are some other two. psd13 = sim.computeDecomposedCrossSpectrumVectorF(v1, v3, time) # psd13 can be converted to numpy vector and be used for some other purposes. arr = numpy.asarray(psd13)
Horizontal Uniform Distribution
This feature provides an efficient method to distribute random wind simulation points uniformly in space. It allows users to generate a set of points within a 3D spatial domain, ensuring that the points are evenly distributed along a horizontal line that is parallel to one of the coordinate system axis. This uniform distribution is critical in certain simulation methods. For [math]\displaystyle{ n }[/math] simulation points [math]\displaystyle{ (P_1,P_2,P_3,...,P_n) }[/math], the distance [math]\displaystyle{ d_{jk} }[/math] between points [math]\displaystyle{ P_j }[/math] and [math]\displaystyle{ P_k }[/math] must be given by the following formula:
[math]\displaystyle{ d_{jk} = s\times|j-k| }[/math]
where [math]\displaystyle{ s }[/math] is the even space between any two adjacent points.
Properties
- DataFirstPoint: This is a point in 3D space representing the first point the distribution will start from.
- DataSpacing: This is the even space between any two adjacent points in the distribution.
Scripting
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "Horizontal Distribution" featureGroup = "Location Distribution" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not unifSimPoints: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation # let's set the first point of the distribution (x =0, y = 0, z = 80m) simPoints.FirstPoint = vec(0,0,80000) # let's set the spacing (s = 10m) simPoints.Spacing = '10m' # compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. simPoints = sim.computeLocationCoordinateMatrixP3() # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(simPoints)
Vertical Uniform Distribution
This feature provides an efficient method to distribute random wind simulation points uniformly in space. It allows users to generate a set of points within a 3D spatial domain, ensuring that the points are evenly distributed along a vertical line. This uniform distribution is critical in certain simulation methods. For [math]\displaystyle{ n }[/math] simulation points [math]\displaystyle{ (P_1,P_2,P_3,...,P_n) }[/math], the distance [math]\displaystyle{ d_{jk} }[/math] between points [math]\displaystyle{ P_j }[/math] and [math]\displaystyle{ P_k }[/math] must be given by the following formula:
[math]\displaystyle{ d_{jk} = s\times|j-k| }[/math]
where [math]\displaystyle{ s }[/math] is the even space between any two adjacent points.
Properties
- DataLowestPoint: This is a point in 3D space representing the lowest point the distribution will start from. In many applications, this point should not be lower than 10 meters.
- DataSpacing: This is the even space between any two adjacent points in the distribution.
Scripting
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "VerticalDistribution" featureGroup = "Location Distribution" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not unifSimPoints: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation # let's set the first point of the distribution (x =0, y = 0, z = 30m) simPoints.LowestPoint = vec(0,0,30000) # let's set the spacing (s = 10m) simPoints.Spacing = '10m' # compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. simPoints = sim.computeLocationCoordinateMatrixP3() # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(simPoints)
Uniform Distribution
This feature may be seen as a general form of the horizontal and the vertical distribution features. It allows users to generate a set of points within a 3D spatial domain, ensuring that the points are evenly distributed along a line parallel to one of the coordinate system axis. For [math]\displaystyle{ n }[/math] simulation points [math]\displaystyle{ (P_1,P_2,P_3,...,P_n) }[/math], the distance [math]\displaystyle{ d_{jk} }[/math] between points [math]\displaystyle{ P_j }[/math] and [math]\displaystyle{ P_k }[/math] must be given by the following formula:
[math]\displaystyle{ d_{jk} = s\times|j-k| }[/math]
where [math]\displaystyle{ s }[/math] is the even space between any two adjacent points.
Properties
- DataFirstPoint: This is a point in 3D space representing the first point the distribution will start from. This should be the lowest point in case the distribution is parallel to the vertical axis and should not be lower than 10 meters in many application.
- DataSpacing: This is the even space between any two adjacent points in the distribution.
- DataDirection: Its value can be X, Y or Z. This is the axis the points distribution is parallel to.
Scripting
This feature can be used to produce vertical distribution as we did before in the Vertical Distribution feature.
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "UniformDistribution" featureGroup = "Location Distribution" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not unifSimPoints: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation # set the direction of the distribution to be vertical simPoints.Direction= 'Z' # let's set the first point of the distribution (x =0, y = 0, z = 30m) simPoints.FirstPoint = vec(0,0,30000) # This is the lowest point in this case (Direction = 'Z') # let's set the spacing (s = 10m) simPoints.Spacing = '10m' # compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. simPoints = sim.computeLocationCoordinateMatrixP3() # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(simPoints)
Grid Points
This feature allows users to generate a set of grid points within a 3D spatial domain, ensuring that the points are evenly distributed in a plane parallel to one of the coordinate system planes (XY Plane, YZ Plane, XZ Plane).
Properties
- DataSpacing1: This is the points spacing along one of the axis forming the plane.
- DataSpacing2: This is the points spacing along the second axis.
- DataLength1: This is the length within points are distributed along one of the axis forming the plane.
- DataLength2: This is the length within points are distributed along the second axis.
- DataCenterPoint: This is the center of the grid around which the points are generated. It is a 3D point.
- DataNumberOfPoints: This is the resulting total number of points in the grid. This is a read only property for internal use. User cannot change its value directly.
Scripting
The following script shows how this feature can be created and used.
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "Grid Points" featureGroup = "Location Distribution" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) unifSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not unifSimPoints: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation # set the plan the points grid is parallel to simPoints.LocationPlan= 'YZ Plane' # let's set the center point of the distribution (x =0, y = 0, z = 0) simPoints.CenterPoint = vec(0,0,0) # let's set the spacing1 (s1 = 10m) simPoints.Spacing1 = '10m' # let's set the spacing2 (s2 = 10m) simPoints.Spacing2 = '10m' # let's set the length1 (l1 = 200m) simPoints.Length1= '200m' # let's set the length2 (l2 = 200m) simPoints.Length2= '200m' # compute the simulation points coordinates. WindLab will internally use the "unifSimPoints" feature. simPoints = sim.computeLocationCoordinateMatrixP3() # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(simPoints)
General Distribution
When the simulation points distribution is more general and does not follow any of the previous uniform distribution, this feature can be used. This feature allows users to input simulation points one by one using their coordinates based on the vector dialog shown below:
Properties
- DataLocations: This is a list holding the simulation points
Scripting
The following script shows how this feature can be created and used.
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "General Distribution" featureGroup = "Location Distribution" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) genSimPoints= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not genSimPoints: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation # create the simulation points by their coordinates v1 = vec(0, 0, 35000) v2 = vec(0, 0, 40000) v3 = vec(0, 0, 140000) # add the points to the locations loc.Locations = [v1, v2, v3] # compute the simulation points coordinates. WindLab will internally use the "genSimPoints" feature simPoints = sim.computeLocationCoordinateMatrixP3() # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(simPoints)
Power Law Profile
This feature is designed to compute the wind speed at a given height based on the power law mean wind profile, which is commonly used to model the variation of wind speed with height in the atmospheric boundary layer. This model is essential in fields such as wind energy, structural engineering, and environmental science. The power law formula that governs the relationship between wind speed and height is expressed as:
[math]\displaystyle{ U(z) = U(z_0)\times\left( \frac{{z-\phi}}{z_0} \right)^\alpha }[/math]
where:
- [math]\displaystyle{ U(z) }[/math] is the wind speed at height [math]\displaystyle{ z }[/math],
- [math]\displaystyle{ U(z_0) }[/math] is the reference wind speed at a known reference height [math]\displaystyle{ z_0 }[/math],
- [math]\displaystyle{ \alpha }[/math] is the power law exponent, a dimensionless constant that varies depending on terrain and atmospheric conditions,
- [math]\displaystyle{ \phi }[/math] is the zero plan displacement,
- [math]\displaystyle{ z }[/math] is the height at which the wind speed is to be calculated.
Properties
- DataReferenceHeight: This is a reference height.
- DataReferenceSpeed: This is the reference wind speed at the reference height.
- DataDimensionlessPower: This is the power law exponent.
- DataZeroPlanDisplacement: This is the zero plan displacement.
Scripting
The following script shows how this feature can be created and used.
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "Power Law Profile" featureGroup = "Mean Wind Profile" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) meanSpeed= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not meanSpeed: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation meanSpeed.ReferenceHeight = '10.00 m' meanSpeed.ReferenceSpeed = '30.00 m/s' meanSpeed.DimensionlessPower = 0.12 meanSpeed.ZeroPlanDisplacement = '0.0 m' # In WindLab, mean wind velocity can vary with time. In case the user desires a time dependent mean wind speed, # a modulation function can be used for this purpose. The feature account for this. When the Stationarity property of the parent # simulation of this feature is false, the feature identify the active modulation function and use it to produce non-stationary # mean wind speed. But for this example we shall use time instant of 0 second. time = 0.0 # compute the mean wind speeds at time instant of 0 second and for all simulation points # Note that when the following code is run, WindLab will try to identify the active locations distribution, # it will also try to identity the active modulation function in case the parent simulation is non-stationary. # If WindLab fails to find these dependency features, the computation will fails and specific error messages will be sent to the report view. meanValues = sim.computeMeanWindSpeedVectorP(time) # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(meanValues )
Logarithmic Law Profile
This feature is designed to compute the wind speed at a given height based on the logarithmic law mean wind profile. The logarithmic law is commonly used to model the variation of wind speed with height in the atmospheric boundary layer, especially in cases where the wind profile is influenced by surface roughness, such as over flat terrain, forests, or urban environments. The logarithmic law for wind speed variation is given by the following equation:
[math]\displaystyle{ U(z) =\left( \frac{u_*}{k} \right)\times\ln{\left( \frac{{z-\phi}}{z_0} \right)} }[/math]
where:
- [math]\displaystyle{ U(z) }[/math] is the wind speed at height [math]\displaystyle{ z }[/math],
- [math]\displaystyle{ u_* }[/math] is the friction velocity, which is a measure of the turbulence intensity,
- [math]\displaystyle{ k }[/math] is the von Kármán constant (approximately 0.4),
- [math]\displaystyle{ \phi }[/math] is the zero plan displacement,
- [math]\displaystyle{ z_0 }[/math] is the roughness length, which characterizes the roughness of the surface,
- [math]\displaystyle{ z }[/math] is the height at which the wind speed is to be calculated.
Properties
- DataTerrainRoughness: This is the terrain roughness value.
- DataShearVelocity: This is the shear velocity of the flow.
- DatavonKarmanConstant: This is the von karman constant.
- DataZeroPlanDisplacement: This is the zero plan displacement value.
Scripting
The following script shows how this feature can be created and used.
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "Logarithmic Law Profile" featureGroup = "Mean Wind Profile" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) meanSpeed= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not meanSpeed: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation meanSpeed.TerrainRoughness = '0.001266 m' meanSpeed.ShearVelocity = '1.76 m/s' # In WindLab, mean wind velocity can vary with time. In case the user desires a time dependent mean wind speed, # a modulation function can be used for this purpose. The feature account for this. When the Stationarity property of the parent # simulation of this feature is false, the feature identify the active modulation function and use it to produce non-stationary # mean wind speed. But for this example we shall use time instant of 0 second. time = 0.0 # compute the mean wind speeds at time instant of 0 second and for all simulation points # Note that when the following code is run, WindLab will try to identify the active locations distribution, # it will also try to identity the active modulation function in case the parent simulation is non-stationary. # If WindLab fails to find these dependency features, the computation will fails and specific error messages will be sent to the report view. meanValues = sim.computeMeanWindSpeedVectorP(time) # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(meanValues )
Deaves and Harris Profile
This feature is designed to compute the wind speed at a given height based on the logarithmic law mean wind profile. The logarithmic law is commonly used to model the variation of wind speed with height in the atmospheric boundary layer, especially in cases where the wind profile is influenced by surface roughness, such as over flat terrain, forests, or urban environments. The logarithmic law for wind speed variation is given by the following equation:
[math]\displaystyle{ U(z) =\left( \frac{u_*}{k} \right)\times\left [\ln{\left( \frac{{z-z_d}}{z_0} \right)} + 5.75\left( \frac{{z-z_d}}{h} \right) - 1.88\left( \frac{{z-z_d}}{h} \right)^2 - 1.33\left( \frac{{z-z_d}}{h} \right)^3 + 0.25\left( \frac{{z-z_d}}{h} \right)^4\right ] }[/math]
where:
- [math]\displaystyle{ U(z) }[/math] is the wind speed at height [math]\displaystyle{ z }[/math],
- [math]\displaystyle{ u_* }[/math] is the friction velocity, which is a measure of the turbulence intensity,
- [math]\displaystyle{ k }[/math] is the von Kármán constant (approximately 0.4),
- [math]\displaystyle{ z_d }[/math] is the zero plan displacement,
- [math]\displaystyle{ z_0 }[/math] is the roughness length, which characterizes the roughness of the surface,
- [math]\displaystyle{ h }[/math] is the gradient height, defined as the height where atmospheric flow is free from surface stresses and becomes geostrophic,
- [math]\displaystyle{ z }[/math] is the height at which the wind speed is to be calculated.
Properties
- DataTerrainRoughness: The terrain roughness length.
- DataShearVelocity: The shear velocity of the flow.
- DataZeroPlanDisplacement: The zero plan displacement.
- DataLatitude: The latitude.
- DataEarthAngularVelocity: The earth angular velocity.
- DataBetta: The coefficient beta.
Scripting
The following script shows how this feature can be created and used.
import WindLab import WindLabObjects from LabRPS import Vector as vec import numpy # get an existing WindLab simulation called "Simulation" sim = WindLab.getSimulation("Simulation") # check if the simulation does really exist if not sim: LabRPS.Console.PrintError("The simulation does not exist.\n") # abord the computation featureType = "Deaves and Harris Profile" featureGroup = "Mean Wind Profile" # create the feature and add it to the existing simulation (you may refer to the WindLab Workbench page in # case you don't understand the next line) meanSpeed= WindLabObjects.makeFeature("MyNewFeature", sim.Name, featureType, featureGroup) # check if the created feature is good if not meanSpeed: LabRPS.Console.PrintError("Error on creating the uniform points feature.\n") # abord the computation meanSpeed.TerrainRoughness = '0.001266 m' meanSpeed.ShearVelocity = '1.76 m/s' # In WindLab, mean wind velocity can vary with time. In case the user desires a time dependent mean wind speed, # a modulation function can be used for this purpose. The feature account for this. When the Stationarity property of the parent # simulation of this feature is false, the feature identify the active modulation function and use it to produce non-stationary # mean wind speed. But for this example we shall use time instant of 0 second. time = 0.0 # compute the mean wind speeds at time instant of 0 second and for all simulation points # Note that when the following code is run, WindLab will try to identify the active locations distribution, # it will also try to identity the active modulation function in case the parent simulation is non-stationary. # If WindLab fails to find these dependency features, the computation will fails and specific error messages will be sent to the report view. meanValues = sim.computeMeanWindSpeedVectorP(time) # now you can convert the coordinate matrix to numpy array and use it for any other purposes arr = numpy.asarray(meanValues )