diff --git a/cmake/OpenfastCmakeUtils.cmake b/cmake/OpenfastCmakeUtils.cmake index 4837582412..1a490e7453 100644 --- a/cmake/OpenfastCmakeUtils.cmake +++ b/cmake/OpenfastCmakeUtils.cmake @@ -42,13 +42,11 @@ function(generate_f90_types regfile outfile) get_filename_component(input ${regfile} ABSOLUTE) get_filename_component(outdir ${outfile} DIRECTORY) - add_custom_command( OUTPUT ${outfile} DEPENDS openfast_registry ${input} - COMMAND ${CMAKE_BINARY_DIR}/modules/openfast-registry/openfast_registry ${input} "-O" "${outdir}" ${OPENFAST_REGISTRY_INCLUDES} ${ARGN} + COMMAND ${CMAKE_BINARY_DIR}/modules/openfast-registry/openfast_registry ${input} "-O" ${outdir} ${OPENFAST_REGISTRY_INCLUDES} ${ARGN} ) - set_source_files_properties(${output} PROPERTIES GENERATED TRUE) endfunction(generate_f90_types) # diff --git a/docs/OtherSupporting/OutListParameters.xlsx b/docs/OtherSupporting/OutListParameters.xlsx index 98006d67b0..03146fa76a 100644 Binary files a/docs/OtherSupporting/OutListParameters.xlsx and b/docs/OtherSupporting/OutListParameters.xlsx differ diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 0dc720369c..a6427fc9d1 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -20,24 +20,25 @@ Modified in OpenFAST `dev` Module Line Flag Name Example Value ============================================= ==== ==================== ======================================================================================================================================================================================================== ServoDyn-StructCtrl 6 StC_DOF_MODE 2 StC_DOF_MODE - DOF mode (switch) {0: No StC or TLCD DOF; 1: StC_X_DOF, StC_Y_DOF, and/or StC_Z_DOF (three independent StC DOFs); 2: StC_XY_DOF (Omni-Directional StC); 3: TLCD; 4: Prescribed force/moment time series; 5: Force determined by external DLL} -InflowWind 50 ================== LIDAR Parameters =========================================================================== -InflowWind 51 SensorType 0 SensorType - Switch for lidar configuration (0 = None, 1 = Single Point Beam(s), 2 = Continuous, 3 = Pulsed) -InflowWind 52 NumPulseGate 0 NumPulseGate - Number of lidar measurement gates (used when SensorType = 3) -InflowWind 53 PulseSpacing 30 PulseSpacing - Distance between range gates (m) (used when SensorType = 3) -InflowWind 54 NumBeam 0 NumBeam - Number of lidar measurement beams (0-5)(used when SensorType = 1) -InflowWind 55 FocalDistanceX -200 FocalDistanceX - Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) -InflowWind 56 FocalDistanceY 0 FocalDistanceY - Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) -InflowWind 57 FocalDistanceZ 0 FocalDistanceZ - Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) -InflowWind 58 RotorApexOffsetPos 0.0 0.0 0.0 RotorApexOffsetPos - Offset of the lidar from hub height (m) -InflowWind 59 URefLid 17 URefLid - Reference average wind speed for the lidar[m/s] -InflowWind 50 MeasurementInterval 0.25 MeasurementInterval - Time between each measurement [s] -InflowWind 61 LidRadialVel False LidRadialVel - TRUE => return radial component, FALSE => return 'x' direction estimate -InflowWind 62 ConsiderHubMotion 1 ConsiderHubMotion - Flag whether to consider the hub motion's impact on Lidar measurements +InflowWind 8 VelInterpCubic true VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] +InflowWind 51 ================== LIDAR Parameters =========================================================================== +InflowWind 52 SensorType 0 SensorType - Switch for lidar configuration (0 = None, 1 = Single Point Beam(s), 2 = Continuous, 3 = Pulsed) +InflowWind 53 NumPulseGate 0 NumPulseGate - Number of lidar measurement gates (used when SensorType = 3) +InflowWind 54 PulseSpacing 30 PulseSpacing - Distance between range gates (m) (used when SensorType = 3) +InflowWind 55 NumBeam 0 NumBeam - Number of lidar measurement beams (0-5)(used when SensorType = 1) +InflowWind 56 FocalDistanceX -200 FocalDistanceX - Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +InflowWind 57 FocalDistanceY 0 FocalDistanceY - Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +InflowWind 58 FocalDistanceZ 0 FocalDistanceZ - Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +InflowWind 59 RotorApexOffsetPos 0.0 0.0 0.0 RotorApexOffsetPos - Offset of the lidar from hub height (m) +InflowWind 60 URefLid 17 URefLid - Reference average wind speed for the lidar[m/s] +InflowWind 61 MeasurementInterval 0.25 MeasurementInterval - Time between each measurement [s] +InflowWind 62 LidRadialVel False LidRadialVel - TRUE => return radial component, FALSE => return 'x' direction estimate +InflowWind 63 ConsiderHubMotion 1 ConsiderHubMotion - Flag whether to consider the hub motion's impact on Lidar measurements ============================================= ==== ==================== ======================================================================================================================================================================================================== -OpenFAST v3.4.1 to OpenFAST v3.4.1 +OpenFAST v3.4.0 to OpenFAST v3.4.1 ---------------------------------- Restored the AeroDyn channel names with `Aero` in the name. These had be diff --git a/docs/source/user/inflowwind/driver.rst b/docs/source/user/inflowwind/driver.rst index fd322a5b1f..f436f2203a 100644 --- a/docs/source/user/inflowwind/driver.rst +++ b/docs/source/user/inflowwind/driver.rst @@ -13,23 +13,24 @@ Command-line syntax for InflowWind driver: options: /ifw -- treat as name of InflowWind input file (no driver input file) The following options will override values in the driver input file: - /DT[#] -- timestep - /TStart[#] -- start time - /TSteps[#] -- number of timesteps - /xrange[#:#] -- range of x (#'s are reals) - /yrange[#:#] -- range of y - /zrange[#:#] -- range in z (ground = 0.0) - /Dx[#] -- spacing in x - /Dy[#] -- spacing in y - /Dz[#] -- spacing in z - /points[FILE] -- calculates at x,y,z coordinates specified in a white space delimited FILE - /v -- verbose output - /vv -- very verbose output - /hawc -- convert wind file specified in InflowWind to HAWC format - /bladed -- convert wind file specified in InflowWind to Bladed format - /uniform -- convert wind file specified in InflowWind to Uniform-wind format - /vtk -- convert wind file specified in InflowWind to VTK format - /help -- print this help menu and exit + /DT[#] -- timestep + /TStart[#] -- start time + /TSteps[#] -- number of timesteps + /xrange[#:#] -- range of x (#'s are reals) + /yrange[#:#] -- range of y + /zrange[#:#] -- range in z (ground = 0.0) + /Dx[#] -- spacing in x + /Dy[#] -- spacing in y + /Dz[#] -- spacing in z + /points[FILE] -- calculates at x,y,z coordinates specified in a white space delimited FILE + /v -- verbose output + /vv -- very verbose output + /hawc -- convert wind file specified in InflowWind to HAWC format + /bladed -- convert wind file specified in InflowWind to Bladed format + /vtk -- convert wind file specified in InflowWind to VTK format + /accel -- output acceleration when processing a points file + /BoxExceedAllow -- set flag to extrapolate values of points outside FF wind box + /help -- print this help menu and exit :: @@ -137,4 +138,100 @@ When converting from a full-field wind format to a uniform wind file, the follow - The power law exponent is either 1. The power-law exponent specified in InflowWind (if a power law wind profile is used to add to the turbulence with native-Bladed or HAWC2 files), or - 2. Calculated by using the mean wind speeds at two points: the reference (hub) height and the uppermost height on the grid. \ No newline at end of file + 2. Calculated by using the mean wind speeds at two points: the reference (hub) height and the uppermost height on the grid. + +accel flag +------------------- + +The ability to calculate the acceleration of the flow field was added to InflowWind +to support the analysis of MHK, underwater, turbines. The acceleration is needed +to calculate the mass effects of the fluid interacting with the rotor. Calculation of the +acceleration is supported for Uniform/Steady Wind and grid based wind profiles (Turbsim, +HAWC, and Bladed files). Enabling this flag causes the driver to output the flow field +acceleration for points defined in the Points file in addition to the velocities at those +same points. + + +BoxExceedAllow flag +------------------- + +A feature was added to InflowWind to all for some requested points to lie +outside the full field wind grid. This allows for a continuous exptrapolation of +values beyond the grid that approaches an average level. + +Purpose +~~~~~~~ + +When InflowWind is coupled to OpenFAST, wind points corresponding to the free +vortex wake module (OLAF) in AeroDyn 15 and LidarSim module may be outside the +full-field wind data. No other wind data points may be outside the grid +(AeroDyn15 blades must be within the wind box). The wake from OLAF may over +time stray outside the full-field wind box, in which case it should be +sufficiently far from the turbine that any inacuracies in the reported wind +value should have little to no effect on the turbine. The method employed here +should allow the wake to continue evolving without flow reversals or other +oddities due to a discontinuity at the wind grid boundary. However, to limit +the impact of the approximation used, the wake should not be allowed to exit the +box until far from the turbine. + +The other use case is when the LidarSim requests data far from the turbine that +may lie outside the wind box, such as a yawed, or floating turbine where the +sensing beam periodically exits the wind box. + +Method +~~~~~~ + +During initialization, a flag and corresponding index are passed to tell IfW to +allow points in the requested position array to lie outside the full-field wind +and tower grids starting at this index. The values for these points are then +extrapolated using the data from the full-field wind as follows: + + 1. The average wind value at each Z height at each timestep is calculated and + stored during initialization (averaged across the Y dimension). + 2. Wind above the full field wind grid is linearly interpolated between the + value at the top of the grid the average of the top of the grid. This + linear interpolation zone extends from the top of grid to the top of the + grid + one half grid height (``FFZHWid``). Values beyond that are held + constant. + 3. Values beyond the +/-Y grid edges are linearly interpolated between the + value at the edge of the grid and the average for that Z elevation in the + grid. The interpolation zone is between the edge of the grid and one half + grid width further along Y at ``+/-2*FFYHWid``. + 4. When no tower data is present, the values below the grid are linearly + interpolated between the bottom of the grid and 0 at the ground. + 5. When tower data is present, points below the grid are interpolated between + the tower and grid and the ground (0 value at ``+/-2*FFYHWid``). Linear + interpolation is then used beyond the edge of the grid. + + +Testing with driver +~~~~~~~~~~~~~~~~~~~ + +To test this feature, the driver accepts the flag ``BoxExceedAllow`` and will +signal to InflowWind that all windgrid points may be beyond the edge of the +grid. To use this, setup a driver input file with an output wind grid that is +larger than the full-field grid from the wind file referenced in the +corresponding InflowWind input file. Then the following command can be used +(Linux syntax, Windows is slightly different): + +.. code-block:: bash + + > inflowwind_driver -BoxExceedAllow MyDriverFile.inp + +For a single YZ plane from the resulting wind grid output file at time T, the +results for extrapolated data points can be plotted and should show +characteristics similar to the following plots. + + +.. figure:: figs/FFWindExtrap--NoTower.png + :width: 90% + + Extrapolation of wind values beyond the full field wind grid when no tower data is present. The semi-transparent red planes indicate the edges of the full-field wind grid, and the red points are the locations of wind grid data in this example case. All other points shown on the surface are interpolated/extrapolated. + + +.. figure:: figs/FFWindExtrap--Tower.png + :width: 90% + + Extrapolation of wind values beyond the full field wind grid when tower data is present. The semi-transparent red planes indicate the edges of th e full-field wind grid, blue semi-transparent plane indicates the tower grid, and the red points indcate the data points from the wind grid and tower. All other points shown on the surface are interpolated/extrapolated. + + diff --git a/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp b/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp index b82594c65a..ada6a15427 100644 --- a/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp +++ b/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp @@ -14,9 +14,11 @@ InflowWind driver input file. DEFAULT DT -- timestep size for driver to take (s, or DEFAULT for what the file contains) t Summary -- Summarize the data extents in the windfile (flag) t SummaryFile -- Write summary to file (.dvr.sum) (flag) + f BoxExceedAllow -- Allow point sampling outside grid ---- Points file input (output given as POINTSFILENAME.Velocity.dat) -------- f PointsFile -- read in a list of output points from a file (flag) "Test005.txt" PointsFileName -- name of points file (-) (comma separated x,y,z coordinates, # symbol for comments) + f CalcAccel -- calculate and output acceleration at points in addition to velocity ---- Output grid (Points below ground will simply be ignored) --------------- t WindGrid -- report wind data at set of X,Y,Z coordinat (flag) 6,0,15 GridCtrCoord -- coordinate of center of grid (m) diff --git a/docs/source/user/inflowwind/examples/inflowwind_example.dat b/docs/source/user/inflowwind/examples/inflowwind_example.dat index 1f7ee25be6..9a9aa62f59 100644 --- a/docs/source/user/inflowwind/examples/inflowwind_example.dat +++ b/docs/source/user/inflowwind/examples/inflowwind_example.dat @@ -6,6 +6,7 @@ False Echo - Echo input data to .ech (flag) 0 PropagationDir - Direction of wind propagation (meteorological rotation from aligned with X (positive rotates towards -Y) -- degrees) (not used for native Bladed format WindType=7) 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) 1 NWindVel - Number of points to output the wind velocity (0 to 9) + False VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] 0 WindVxiList - List of coordinates in the inertial X direction (m) 0 WindVyiList - List of coordinates in the inertial Y direction (m) 90 WindVziList - List of coordinates in the inertial Z direction (m) @@ -46,7 +47,20 @@ False TowerFile - Have tower file (.twr) (flag) ignored when WindTy 2 WindProfile - Wind profile type (0=constant;1=logarithmic,2=power law) 0.2 PLExp_HAWC - Power law exponent (-) (used for PL wind profile type only) 0.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) - 0 XOffset - Initial offset in +x direction (shift of wind box) + 0 XOffset - Initial offset in +x direction (shift of wind box) +================== LIDAR Parameters =========================================================================== + 0 SensorType - Switch for lidar configuration (0 = None, 1 = Single Point Beam(s), 2 = Continuous, 3 = Pulsed) + 0 NumPulseGate - Number of lidar measurement gates (used when SensorType = 3) + 30 PulseSpacing - Distance between range gates (m) (used when SensorType = 3) + 0 NumBeam - Number of lidar measurement beams (0-5)(used when SensorType = 1) + -200 FocalDistanceX - Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) + 0 FocalDistanceY - Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) + 0 FocalDistanceZ - Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +0.0 0.0 0.0 RotorApexOffsetPos - Offset of the lidar from hub height (m) + 17 URefLid - Reference average wind speed for the lidar[m/s] + 0.25 MeasurementInterval - Time between each measurement [s] + False LidRadialVel - TRUE => return radial component, FALSE => return 'x' direction estimate + 1 ConsiderHubMotion - Flag whether to consider the hub motion's impact on Lidar measurements ====================== OUTPUT ================================================== False SumPrint - Print summary data to .IfW.sum (flag) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) diff --git a/docs/source/user/inflowwind/figs/FFWindExtrap--NoTower.png b/docs/source/user/inflowwind/figs/FFWindExtrap--NoTower.png new file mode 100644 index 0000000000..8d1746de8e Binary files /dev/null and b/docs/source/user/inflowwind/figs/FFWindExtrap--NoTower.png differ diff --git a/docs/source/user/inflowwind/figs/FFWindExtrap--Tower.png b/docs/source/user/inflowwind/figs/FFWindExtrap--Tower.png new file mode 100644 index 0000000000..1e871c3d1f Binary files /dev/null and b/docs/source/user/inflowwind/figs/FFWindExtrap--Tower.png differ diff --git a/glue-codes/fast-farm/src/FASTWrapper.f90 b/glue-codes/fast-farm/src/FASTWrapper.f90 index 6ad986e75b..903666cb48 100644 --- a/glue-codes/fast-farm/src/FASTWrapper.f90 +++ b/glue-codes/fast-farm/src/FASTWrapper.f90 @@ -184,7 +184,7 @@ SUBROUTINE FWrap_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init return end if - call move_alloc(m%Turbine%IfW%m%FDext%V, u%Vdist_High) + call move_alloc(m%Turbine%IfW%p%FlowField%Grid4D%Vel, u%Vdist_High) !................. @@ -556,7 +556,7 @@ SUBROUTINE FWrap_CalcOutput(p, u, y, m, ErrStat, ErrMsg) ErrMsg = '' ! put this back! - call move_alloc(m%Turbine%IfW%m%FDext%V, u%Vdist_High) + call move_alloc(m%Turbine%IfW%p%FlowField%Grid4D%Vel, u%Vdist_High) ! Turbine-dependent commands to the super controller: @@ -712,8 +712,8 @@ SUBROUTINE FWrap_SetInputs(u, m, t) REAL(DbKi), INTENT(IN ) :: t !< current simulation time ! set the 4d-wind-inflow input array (a bit of a hack [simplification] so that we don't have large amounts of data copied in multiple data structures): - call move_alloc(u%Vdist_High, m%Turbine%IfW%m%FDext%V) - m%Turbine%IfW%m%FDext%TgridStart = t + call move_alloc(u%Vdist_High, m%Turbine%IfW%p%FlowField%Grid4D%Vel) + m%Turbine%IfW%p%FlowField%Grid4D%TimeStart = t ! do something with the inputs from the super-controller: if ( m%Turbine%p_FAST%UseSC ) then diff --git a/modules/aerodyn/src/AeroDyn.f90 b/modules/aerodyn/src/AeroDyn.f90 index 7d45a4a65c..81640ba3d1 100644 --- a/modules/aerodyn/src/AeroDyn.f90 +++ b/modules/aerodyn/src/AeroDyn.f90 @@ -62,6 +62,7 @@ module AeroDyn PUBLIC :: AD_GetOP !< Routine to pack the operating point values (for linearization) into arrays PUBLIC :: AD_NumWindPoints !< Routine to return then number of windpoints required by AeroDyn + PUBLIC :: AD_BoxExceedPointsIdx !< Routine to set the start of the OLAF wind points PUBLIC :: AD_GetExternalWind !< Set the external wind into AeroDyn inputs PUBLIC :: AD_SetExternalWindPositions !< Set the external wind points needed by AeroDyn inputs @@ -7073,6 +7074,22 @@ integer(IntKi) function AD_NumWindPoints(u_AD, o_AD) result(n) end if end function AD_NumWindPoints !---------------------------------------------------------------------------------------------------------------------------------- +!> Start index of the OLAF wind points for this turbine +!! Should respect the order of AD_GetExternalWind and AD_SetExternalWindPositions +integer(IntKi) function AD_BoxExceedPointsIdx(u_AD, o_AD) result(n) + type(AD_InputType), intent(in ) :: u_AD ! AeroDyn data + type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data + ! locals + integer(IntKi) :: k + integer(IntKi) :: TotPts ! call AD_NumWindPts, then subtract + TotPts = AD_NumWindPoints(u_AD, o_AD) + if (allocated(o_AD%WakeLocationPoints)) then + n = TotPts - size(o_AD%WakeLocationPoints, dim=2) + 1 ! start index of the olaf points + else ! No OLAF, so return -1 to indicate not used + n = -1 + endif +end function AD_BoxExceedPointsIdx +!---------------------------------------------------------------------------------------------------------------------------------- !> Sets the wind calculated by InflowWind into the AeroDyn arrays ("InputSolve_IfW") !! Should respect the order of AD_NumWindPoints and AD_SetExternalWindPositions subroutine AD_GetExternalWind(u_AD, VelUVW, node, errStat, errMsg) diff --git a/modules/inflowwind/CMakeLists.txt b/modules/inflowwind/CMakeLists.txt index 3584020202..ec987c89c9 100644 --- a/modules/inflowwind/CMakeLists.txt +++ b/modules/inflowwind/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2016 National Renewable Energy Laboratory +# Copyright 2023 National Renewable Energy Laboratory # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,40 +15,22 @@ # if (GENERATE_TYPES) - generate_f90_types(src/InflowWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_Types.f90) + generate_f90_types(src/IfW_FlowField.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_FlowField_Types.f90 -noextrap) + generate_f90_types(src/InflowWind_IO.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_IO_Types.f90 -noextrap) generate_f90_types(src/Lidar.txt ${CMAKE_CURRENT_LIST_DIR}/src/Lidar_Types.f90) - generate_f90_types(src/IfW_BladedFFWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_BladedFFWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_4Dext.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_4Dext_Types.f90 -noextrap) - generate_f90_types(src/IfW_HAWCWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_HAWCWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_TSFFWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_TSFFWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_UniformWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_UniformWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_UserWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_UserWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_FFWind_Base.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_FFWind_Base_Types.f90 -noextrap) + generate_f90_types(src/InflowWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_Types.f90) endif() -set(IFW_SOURCES - src/IfW_BladedFFWind.f90 - src/IfW_4Dext.f90 - src/IfW_HAWCWind.f90 - src/IfW_TSFFWind.f90 - src/IfW_UserWind.f90 - src/IfW_UniformWind.f90 +add_library(ifwlib_obj OBJECT + src/IfW_FlowField_Types.f90 + src/IfW_FlowField.f90 + src/InflowWind_IO_Types.f90 + src/InflowWind_IO.f90 src/InflowWind_Subs.f90 - src/InflowWind.f90 - src/Lidar.f90 - src/IfW_FFWind_Base.f90 - src/IfW_FFWind_Base_Types.f90 - src/IfW_BladedFFWind_Types.f90 - src/IfW_4Dext_Types.f90 - src/IfW_HAWCWind_Types.f90 - src/IfW_TSFFWind_Types.f90 - src/IfW_UserWind_Types.f90 - src/IfW_UniformWind_Types.f90 src/InflowWind_Types.f90 + src/InflowWind.f90 src/Lidar_Types.f90 -) - -add_library(ifwlib_obj OBJECT ${IFW_SOURCES}) + src/Lidar.f90) target_link_libraries(ifwlib_obj nwtclibs_obj) add_library(ifwlib $) @@ -69,7 +51,7 @@ set(IFW_DRIVER_SOURCES ) add_executable(inflowwind_driver ${IFW_DRIVER_SOURCES}) -target_link_libraries(inflowwind_driver ifwlib versioninfolib ${CMAKE_DL_LIBS}) +target_link_libraries(inflowwind_driver ifwlib versioninfolib) install(TARGETS inflowwind_driver ifwlib ifw_c_binding ifwlib_obj EXPORT "${CMAKE_PROJECT_NAME}Libraries" diff --git a/modules/inflowwind/src/CTWind.f90 b/modules/inflowwind/src/CTWind.f90 deleted file mode 100644 index b0adc411c7..0000000000 --- a/modules/inflowwind/src/CTWind.f90 +++ /dev/null @@ -1,1345 +0,0 @@ -MODULE CTWind -! This module uses reads coherent turbulence parameter (CTP) files and processes the data in them -! to get coherent turbulence which is later superimposed on a background wind field (the super- -! positioning occurs elsewhere). The turbulence in this module is part of the KH billow, which -! can be read using FDWind. As a result, the scaling here should be similiar to FDWind. -! -! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -! and that all units are specified in the metric system (using meters and seconds). -! Data is shifted by half the grid width when used with FFWind. -! -! Created 25-Sept-2009 by B. Jonkman, National Renewable Energy Laboratory -! using subroutines and modules from AeroDyn v12.58 -! -! Modified Jan-2013 by A. Platt, National Renewable Energy Laboratory -! to fit the modularization framework used by FAST -! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2013 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** -! File last committed: $Date: 2014-07-29 13:30:04 -0600 (Tue, 29 Jul 2014) $ -! (File) Revision #: $Rev: 125 $ -! URL: $HeadURL$ -!********************************************************************************************************************************** - - USE NWTC_Library - USE SharedInflowDefs - USE InflowWind_Module_Types - - IMPLICIT NONE - PRIVATE - - -!fixme: this invokes SAVE - INTEGER, PARAMETER :: NumComps = 3 ! number of components - - ! CT_Wind - REAL(ReKi) :: DelYCTgrid ! The nondimensional distance between grid points in the y direction. - REAL(ReKi) :: DelZCTgrid ! The nondimensional distance between grid points in the z direction. - REAL(ReKi) :: CTDistSc ! Disturbance scale (ratio of wave height to rotor diameter). - REAL(ReKi) :: CTOffset (NumComps) ! Offsets to convert integer data to actual wind speeds. - REAL(ReKi) :: CTScale (NumComps) ! Scaling factors to convert integer data to actual wind speeds. - - - REAL(ReKi), ALLOCATABLE :: CTvelU (:,:,:) ! The y-z grid velocity data (U components) for the lower- and upper-bound time slices - REAL(ReKi), ALLOCATABLE :: CTvelV (:,:,:) ! The y-z grid velocity data (V components) for the lower- and upper-bound time slices - REAL(ReKi), ALLOCATABLE :: CTvelW (:,:,:) ! The y-z grid velocity data (W components) for the lower- and upper-bound time slices - REAL(ReKi) :: CTLy ! Fractional location of tower centerline from right (looking downwind) to left side of the dataset. - REAL(ReKi) :: CTLz ! Fractional location of hub height from bottom to top of dataset. - REAL(ReKi) :: CTScaleVel ! Scaling velocity, U0. 2*U0 is the difference in wind speed between the top and bottom of the wave. - REAL(ReKi), ALLOCATABLE :: Tdata (:) ! The list of times for the CT-wind input files. - - REAL(ReKi) :: CT_Zref ! The reference height for the CT file (the bottom of the billow) - REAL(ReKi) :: CTYHWid ! The half the width of the background dataset, used to compute the CTwind time offset - REAL(ReKi) :: CTYmax ! The dimensional lateral width of the dataset. - REAL(ReKi) :: CTYt ! Distance of the tower from the right side of the dataset (looking downwind). - REAL(ReKi) :: CTZmax ! The dimensional vertical height of the dataset. - REAL(ReKi) :: InvMCTWS ! The multiplicative inverse of the mean hub height wind speed for the CT wind data - - INTEGER :: CT_DF_Y ! The decimation factor for the CT wind data in the y direction. - INTEGER :: CT_DF_Z ! The decimation factor for the CT wind data in the z direction. - INTEGER :: CTvel_files(2) ! Times for the CT wind files stored in CTvel arrays. - - INTEGER :: IndCT_hi ! An index into the 3rd dimension of the CTvel arrays, indicating the upper time slice (allows us to avoid copying array) - INTEGER :: IndCT_lo ! An index into the 3rd dimension of the CTvel arrays, indicating the lower time slice (allows us to avoid copying array) - - INTEGER :: NumCTt ! The number of CT wind grids, no more than one grid per time step. - INTEGER :: NumCTy ! The number of CT wind grid points in the y direction. - INTEGER :: NumCTyD ! The decimated number of CT wind grid points in the y direction. - INTEGER :: NumCTyD1 ! The decimated number of CT wind grid points in the y direction minus 1. - INTEGER :: NumCTz ! The number of CT wind grid points in the z direction. - INTEGER :: NumCTzD ! The decimated number of CT wind grid points in the z direction. - INTEGER :: NumCTzD1 ! The decimated number of CT wind grid points in the z direction minus 1. -!FIXME: move to otherstate - INTEGER, SAVE :: TimeIndx = 0 ! Index into the time array - INTEGER, ALLOCATABLE :: TimeStpCT (:) ! The list of time steps from the original LE simulation, associated with the CT-wind times. - - INTEGER :: CTWindUnit ! unit number used to read the wind files at each call to CT_GetWindSpeed() - - LOGICAL :: CTVertShft ! Flag to indicate whether or not to shift the z values for the w component. - - CHARACTER(3) :: CText ! The extension used for coherent turbulence data files. (usually "les" or "dns") - CHARACTER(1024) :: CTSpath ! The path to the CT wind files. - -!FIXME: move this to types -- parameters! - TYPE :: CTWindFiles - CHARACTER(1024) :: CTfile ! The name of the file containing the time-step history of the wind files. - CHARACTER(1024) :: CTbackgr ! The name of the background wind data - END TYPE CTWindFiles - -!FIXME: this should be moved to parameters. - TYPE, PUBLIC :: CT_Backgr -! TYPE :: CT_Backgr - CHARACTER(1024) :: WindFile ! The name of the background wind file - INTEGER :: WindFileType ! The type of background wind file (currently only FF) - LOGICAL :: CoherentStr ! If the coherent time step file is blank or doesn't exist, this is FALSE (use the background only) - END TYPE CT_Backgr - - - PUBLIC :: CT_Init - PUBLIC :: CT_GetWindSpeed - PUBLIC :: CT_SetRefVal - PUBLIC :: CT_Terminate - -CONTAINS -!==================================================================================================== -SUBROUTINE CT_Init(UnWind, WindFile, BackGrndValues, ErrStat, ErrMsg) -! This subroutine is called at the beginning of a simulation. It reads the CTP file to obtain -! the name of the CTS file, the path locating the binary KH files, and decimation factors. -! It returns the background wind file and type; it also returns a flag that determines if CT wind -! files are ACTUALLY to be used (e.g., if the CTS file is blank or there is one line of zero in the -! CTS time array). -!---------------------------------------------------------------------------------------------------- - - ! Passed Variables: - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: WindFile ! Name of the CTP (.ctp) wind file - TYPE(CT_Backgr), INTENT(OUT) :: BackGrndValues ! output background values - INTEGER, INTENT(OUT) :: ErrStat ! return ErrID_None if no errors - CHARACTER(*), INTENT(OUT) :: ErrMsg ! message if there was an error - - ! Local Variables: - - TYPE(CTWindFiles) :: CTP_files - CHARACTER(3) :: CT_SC_ext ! extension of the scaling file - LOGICAL :: EmptyFileStat ! temporary variable indicating the CT file was empty / non-existent - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - - - !------------------------------------------------------------------------------------------------- - ! Initialize temporary variables - !------------------------------------------------------------------------------------------------- - - TmpErrStat = ErrID_None - TmpErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Check that the module hasn't already been initialized. - !------------------------------------------------------------------------------------------------- - - IF ( TimeIndx /= 0 ) THEN - ErrMsg = ' CTWind has already been initialized.' - ErrStat = ErrID_Fatal - RETURN - ELSE - ErrMsg = '' - ErrStat = ErrID_None - END IF - - - !------------------------------------------------------------------------------------------------- - ! Read the CTP file and set the background data info to be returned later - !------------------------------------------------------------------------------------------------- - - CALL ReadCTP( UnWind, WindFile, CTP_files, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - BackGrndValues%WindFile = CTP_files%CTbackgr - BackGrndValues%WindFileType = FF_Wind !bjj: perhaps we should check the wind type here - - - !------------------------------------------------------------------------------------------------- - ! Read the CT file to get the time step and file number arrays - !------------------------------------------------------------------------------------------------- - - CALL ReadCT( UnWind, CTP_files%CTfile, CT_SC_ext, EmptyFileStat, TmpErrStat, TmpErrMsg ) - - ! Errors check - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! If the CTP_files%CTfile was empty or non-existent, we continue on without it. - - IF ( EmptyFileStat ) THEN - - ! The file is missing, blank (or possibly incomplete), or has only 1 time step line (which - ! is zero); Go on without the CT file, using just the background - - ErrMsg = TRIM(ErrMsg)//' '//'Coherent turbulence wind file will be turned off.' - - BackGrndValues%CoherentStr = .FALSE. - CALL CT_Terminate( TmpErrStat, TmpErrMsg ) - - ! Error check - ErrStat = MAX( ErrStat, TmpErrStat ) - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - IF ( ErrStat >= AbortErrLev ) RETURN - - - RETURN - - ELSEIF ( (ErrStat < AbortErrLev) .AND. NumCTt > 1) THEN - BackGrndValues%CoherentStr = .TRUE. - - !------------------------------------------------------------------------------------------------- - ! Read file containing scaling for the binary large-eddy files - !------------------------------------------------------------------------------------------------- - CALL ReadCTScales( UnWind, TRIM( CTSpath )//'\Scales.'//TRIM( CT_SC_ext ), TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CTScale(:) = CTScaleVel*CTScale(:) - CTOffset(:) = CTScaleVel*CTOffset(:) - - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set some values that don't change during the run - !------------------------------------------------------------------------------------------------- - - CTYHWid = 0.0 ! This value is used to perform a time shift (the equivalent distance of FFYHWid [approx. rotor radius]) - CT_Zref = -1.0 ! This value needs to be set after the corresponding background turbulence has been read (or the CTS file should be changed) - - NumCTyD = ( NumCTy + CT_DF_Y - 1 )/CT_DF_Y ! The decimated number of CT wind grid points in the y direction. - NumCTzD = ( NumCTz + CT_DF_Z - 1 )/CT_DF_Z ! The decimated number of CT wind grid points in the z direction. - NumCTyD1 = NumCTyD - 1 ! The decimated number of CT wind grid points in the y direction minus 1. - NumCTzD1 = NumCTzD - 1 ! The decimated number of CT wind grid points in the z direction minus 1. - - CTYt = CTYmax*CTLy ! Distance of the tower from the right side of the dataset (looking downwind). -! CTZt = CTZmax*CTLz ! Distance of the hub from the bottom of the dataset. - DelYCTgrid = 1.0/NumCTyD1 ! The nondimensional distance between grid points in the y direction. - DelZCTgrid = 1.0/NumCTzD1 ! The nondimensional distance between grid points in the z direction. - - - - !------------------------------------------------------------------------------------------------- - ! Allocate the wind array and initialize it - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(CTvelU) ) THEN - ALLOCATE ( CTvelU(NumCTyD,NumCTzD,2), STAT=TmpErrStat ) - - IF ( TmpErrStat /= 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the CTvelU array.' - ErrStat = ErrID_Fatal - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(CTvelV) ) THEN -! CALL AllocAry( CTvelV, NumCTyD, NumCTzD, 2, 'CTvelV', ErrStat ) !AllRAry3 AllocAry - ALLOCATE ( CTvelV(NumCTyD,NumCTzD,2), STAT=TmpErrStat ) - - IF ( TmpErrStat /= 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the CTvelV array.' - ErrStat = ErrID_Fatal - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(CTvelW) ) THEN -! CALL AllocAry( CTvelW, NumCTyD, NumCTzD, 2, 'CTvelW', ErrStat ) !AllRAry3 AllocAry - ALLOCATE ( CTvelW(NumCTyD,NumCTzD,2), STAT=TmpErrStat ) - - IF ( TmpErrStat /= 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the CTvelW array.' - ErrStat = ErrID_Fatal - RETURN - END IF - END IF - - CTvelU(:,:,:) = 0.0 ! the original velocity data - CTvelV(:,:,:) = 0.0 ! the original velocity data - CTvelW(:,:,:) = 0.0 ! the original velocity data - - !------------------------------------------------------------------------------------------------- - ! Initialize the arrays and set the initialization flag - !------------------------------------------------------------------------------------------------- - CTvel_files(:) = 0 ! the name of the files currently in the CTvel array - CTWindUnit = UnWind ! This unit is needed to open the binary files at each step - TimeIndx = 1 - - RETURN - -END SUBROUTINE CT_Init -!==================================================================================================== -SUBROUTINE CT_SetRefVal(Height, HWidth, ErrStat, ErrMsg) - - REAL(ReKi), INTENT(IN) :: Height ! a reference height (should be hub height) - REAL(ReKi), INTENT(IN), OPTIONAL :: HWidth ! a reference offset (should be half grid width [~rotor radius]) - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no errors, nonzero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message to return about the error - - - !------------------------------------------------------------------------------------------------- - ! Check that we've initialized everything first - !------------------------------------------------------------------------------------------------- - - IF ( TimeIndx == 0 ) THEN - ErrMsg = ' Initialialize the CTWind module before calling its subroutines.' - ErrStat = ErrID_Fatal - RETURN - ELSE IF ( CT_Zref >= 0 ) THEN - ErrMsg = ' Cannot reset the CTWind reference height in the middle of a simulation.' - ErrStat = ErrID_Fatal - RETURN - ELSE - ErrStat = ErrID_None - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the grid shift using the half-width - !------------------------------------------------------------------------------------------------- - IF ( PRESENT( HWidth ) ) THEN - CTYHWid = HWidth - - IF ( CTYHWid < 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Reference width in CTWind cannot be negative.' - CTYHWid = 0 - ErrStat = ErrID_Fatal - END IF - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the reference height (bottom of the KH billow) using the input hub-height - !------------------------------------------------------------------------------------------------- - ! CTZt = CTZmax*CTLz ! the distance between the hub and the bottom of the dataset - - CT_Zref = Height - CTZmax*CTLz ! the height of the bottom of the KH billow - - IF ( CT_Zref < 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Reference height in CTWind cannot be negative.' - CT_Zref = 0 - ErrStat = ErrID_Fatal - END IF - - -END SUBROUTINE CT_SetRefVal -!==================================================================================================== -FUNCTION CT_GetWindSpeed(Time, InputPosition, ErrStat, ErrMsg) -! This function receives time and position (in InputInfo) where (undisturbed) velocities are are -! requested. It returns the velocities at the specified time and space that are superimposed on -! a background wind flow. This function interpolates into the full-field CT wind arrays, performing -! a time shift based on the average windspeed. The modified time is used to decide which pair of time -! slices to interpolate within and between. After finding the two time slices, it decides which four -! grid points bound the (Y,Z) pair. It does a bilinear interpolation for (Y,Z) on each bounding time -! slice, then linearly interpolates between the 2 time slices. This routine assumes that X is downwind, -! Y is to the left when looking downwind and Z is up. In the time (X) and Z directions, steady winds -! are used when extrapolation is required. The dataset is assumed to be periodic in the Y direction. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables: - - REAL(DbKi), INTENT(IN) :: Time ! the time - REAL(ReKi), INTENT(IN) :: InputPosition(3) ! the position (X,Y,Z) - INTEGER, INTENT(OUT):: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about the error - REAL(ReKi) :: CT_GetWindSpeed ! the resultant wind speed - - - ! Local Variables: - - REAL(ReKi) :: Iyz_th ! Temporary interpolated value. (time hi, all y, all z) - REAL(ReKi) :: Iyz_tl ! Temporary interpolated value. (time lo, all y, all z) - REAL(ReKi) :: Iyhz ! Temporary interpolated value. (y hi, all z) - REAL(ReKi) :: Iylz ! Temporary interpolated value. (y lo, all z) - REAL(ReKi) :: TimeShifted ! Shifted time (necessary because we're keeping x constant) - REAL(ReKi) :: Tgrid ! Fractional distance between time grids. - REAL(ReKi) :: Ygrid ! Fractional distance between grids in the y direction. - REAL(ReKi) :: Ynorm ! Nondimensional lateral distance of the analysis point from right side of dataset (looking downwind). - REAL(ReKi) :: Zgrid(3) ! Fractional distance between grids in the z direction. - REAL(ReKi) :: Znorm ! Nondimensional vertical distance of the analysis point from bottom of dataset. - - INTEGER :: I - INTEGER :: IYHi - INTEGER :: IYLo - INTEGER :: IZHi(3) - INTEGER :: IZLo(3) - - ! Temporary error handling - INTEGER :: TmpErrStat - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg - - - !------------------------------------------------------------------------------------------------- - ! Check that we've initialized everything first - !------------------------------------------------------------------------------------------------- - - IF ( TimeIndx == 0 ) THEN - ErrMsg = ' Initialialize the CTWind module before calling its subroutines.' - ErrStat = ErrID_Fatal - RETURN - ELSE IF ( CT_Zref < 0 ) THEN - ErrMsg = ' Set the reference height in the CTWind module before calling CT_GetWindSpeed.' - ErrStat = ErrID_Fatal - RETURN - ELSE - ErrStat = ErrID_None - END IF - - - !------------------------------------------------------------------------------------------------- - ! Perform the time shift. At time=0, a point half the grid width downstream will index into the zero - ! time slice. CTYHWid is used to shift the CT wind the same as FF wind is shifted. - ! This assumes that the coherent turbulence events are moving at MCTWS - !------------------------------------------------------------------------------------------------- - - TimeShifted = TIME + ( CTYHWid - InputPosition(1) )*InvMCTWS - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding time slices: - ! Linearly interpolate in time (or set to 0 before and/or after) - ! (compare with NWTC_Num.f90\InterpStpReal) - !------------------------------------------------------------------------------------------------- - - ! Let's check the limits first. - - IF ( TimeShifted <= Tdata(1) ) THEN - - TimeIndx = 1 - Tgrid = 0.0 - -! CT_GetWindSpeed%Velocity(:) = 0.0 -! RETURN - - ELSE IF ( TimeShifted >= Tdata(NumCTt) ) THEN - - TimeIndx = NumCTt - 1 - Tgrid = 1.0 - -! CT_GetWindSpeed%Velocity(:) = 0.0 -! RETURN - - ELSE - - ! Let's interpolate! - - TimeIndx = MAX( MIN( TimeIndx, NumCTt-1 ), 1 ) - - - DO - - IF ( TimeShifted < Tdata(TimeIndx) ) THEN - - TimeIndx = TimeIndx - 1 - - ELSE IF ( TimeShifted >= Tdata(TimeIndx+1) ) THEN - - TimeIndx = TimeIndx + 1 - - ELSE - - Tgrid = MIN( MAX( ( TimeShifted - Tdata(TimeIndx) )/( Tdata(TimeIndx+1) - Tdata(TimeIndx) ), 0.0 ), 1.0 ) - EXIT - - END IF - - END DO - - END IF - - - !------------------------------------------------------------------------------------------------- - ! Read the data at the two time steps, if necessary - !------------------------------------------------------------------------------------------------- - - IF ( TimeStpCT(TimeIndx) == CTvel_files(2) ) THEN - IndCT_lo = 2 - IndCT_hi = 1 - - ELSE - IndCT_lo = 1 - IndCT_hi = 2 - - IF ( TimeStpCT(TimeIndx) /= CTvel_files(IndCT_lo) ) THEN - CTvel_files(IndCT_lo) = TimeStpCT(TimeIndx) - CALL ReadCTData ( CTWindUnit, CTvel_files(IndCT_lo), IndCT_lo, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - END IF - - - IF ( CTvel_files(IndCT_hi) /= TimeStpCT(TimeIndx+1) ) THEN - - CTvel_files(IndCT_hi) = TimeStpCT(TimeIndx+1) - CALL ReadCTData ( CTWindUnit, CTvel_files(IndCT_hi), IndCT_hi, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! Calculate the y values; The lower-right corner is (1,1) when looking downwind. - ! note that the KH data is periodic in this direction - !------------------------------------------------------------------------------------------------- - - Ynorm = ( CTYt + InputPosition(2) )/CTYmax - - ! Ensure Ynorm is not negative. The wave is periodic in y. - - IF ( Ynorm < 0.0 ) THEN - Ynorm = 1.0 + MOD(Ynorm, 1.0) - ENDIF - - Ygrid = MIN( MAX( MOD( Ynorm, DelYCTgrid ), 0.0 ), 1.0 ) - IYLo = MAX( MOD( INT( Ynorm*NumCTyD1 ) + 1, NumCTyD1 ), 1 ) - IYHi = MOD( IYLo, NumCTyD ) + 1 - - - !------------------------------------------------------------------------------------------------- - ! Calculate the z values The lower-right corner is (1,1) when looking downwind. - ! Note: the equivalent Znorm for the w-component may be shifted vertically by half the original - ! grid spacing. (the K-H data staggers w differently than u & v). We store IZLo, IZHi, and - ! Zgrid in an array to account for this difference. - !------------------------------------------------------------------------------------------------- - - Znorm = MIN( MAX( ( InputPosition(3) - CT_Zref )/CTZmax, 0.0 ), 1.0 ) ! non-dimensional height (CT_Zref is the bottom of the billow) - - ! Find out fractionally how far we are between grids in time and between grid points in each direction. - ! Limit values to avoid extrapolation. We need this for interpolation later on. - - Zgrid(1:2) = MIN( MAX( MOD( Znorm, DelZCTgrid ), 0.0 ), 1.0 ) - IZLo(1:2) = MAX( INT( Znorm*NumCTzD1 ) + 1, 1 ) ! Make sure the lowest possible value is 1. - - ! If we are located at the upper end of the z dimension, decrement the index by one and set the grid coordinate to 1. - - IF ( IZLo(1) == NumCTzD ) THEN - IZLo(1:2) = NumCTzD1 - Zgrid(1:2) = 1.0 - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Find the equivalent Znorm for the w-component, which may be shifted vertically by half - ! the original grid spacing. (This is necessary due to the fact that the K-H data staggers w - ! differently than u & v). LES and DNS scale differently. - !------------------------------------------------------------------------------------------------- - - IF ( CTVertShft ) THEN - Znorm = MAX( Znorm - 0.5*DelZCTgrid/CT_DF_Z, 0.0 ) - - Zgrid(3) = MIN( MAX( MOD( Znorm, DelZCTgrid ), 0.0 ), 1.0 ) - IZLo(3) = MAX( INT( Znorm*NumCTzD1 ) + 1, 1 ) ! Make sure the lowest possible value is 1. - - - ! If we are located at the upper end of the z dimension, decrement the index by one and set the grid coordinate to 1. - - IF ( IZLo(3) == NumCTzD ) THEN - IZLo(3) = NumCTzD1 - Zgrid(3) = 1.0 - ENDIF - - ELSE - IZLo(3) = IZLo(1) - Zgrid(3)= Zgrid(1) - ENDIF - - IZHi(:) = IZLo(:) + 1 - -!bjj: old versions used Zgrid(3) = Zgrid(1) without regard to CTVertShft. It seemed wrong to me so I changed it. - - !------------------------------------------------------------------------------------------------- - ! Interpolate for U component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - I = 1 - ! linearaly interpolate in the lower time slice - Iylz = ( CTvelU(IYLo,IZHi(I),IndCT_lo) - CTvelU(IYLo,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelU(IYLo,IZLo(I),IndCT_lo) - Iyhz = ( CTvelU(IYHi,IZHi(I),IndCT_lo) - CTvelU(IYHi,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelU(IYHi,IZLo(I),IndCT_lo) - Iyz_tl = ( Iyhz - Iylz )*Ygrid + Iylz - - ! linearaly interpolate in the upper time slice - Iylz = ( CTvelU(IYLo,IZHi(I),IndCT_hi) - CTvelU(IYLo,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelU(IYLo,IZLo(I),IndCT_hi) - Iyhz = ( CTvelU(IYHi,IZHi(I),IndCT_hi) - CTvelU(IYHi,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelU(IYHi,IZLo(I),IndCT_hi) - Iyz_th = ( Iyhz - Iylz )*Ygrid + Iylz - - CT_GetWindSpeed = ( Iyz_th - Iyz_tl )*Tgrid + Iyz_tl - - - !------------------------------------------------------------------------------------------------- - ! Interpolate for V component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - I = 2 - - ! linearaly interpolate in the lower time slice - Iylz = ( CTvelV(IYLo,IZHi(I),IndCT_lo) - CTvelV(IYLo,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelV(IYLo,IZLo(I),IndCT_lo) - Iyhz = ( CTvelV(IYHi,IZHi(I),IndCT_lo) - CTvelV(IYHi,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelV(IYHi,IZLo(I),IndCT_lo) - Iyz_tl = ( Iyhz - Iylz )*Ygrid + Iylz - - ! linearaly interpolate in the upper time slice - Iylz = ( CTvelV(IYLo,IZHi(I),IndCT_hi) - CTvelV(IYLo,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelV(IYLo,IZLo(I),IndCT_hi) - Iyhz = ( CTvelV(IYHi,IZHi(I),IndCT_hi) - CTvelV(IYHi,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelV(IYHi,IZLo(I),IndCT_hi) - Iyz_th = ( Iyhz - Iylz )*Ygrid + Iylz - - CT_GetWindSpeed = ( Iyz_th - Iyz_tl )*Tgrid + Iyz_tl - - - !------------------------------------------------------------------------------------------------- - ! Interpolate for W component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - I = 3 - - ! linearaly interpolate in the lower time slice - Iylz = ( CTvelW(IYLo,IZHi(I),IndCT_lo) - CTvelW(IYLo,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelW(IYLo,IZLo(I),IndCT_lo) - Iyhz = ( CTvelW(IYHi,IZHi(I),IndCT_lo) - CTvelW(IYHi,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelW(IYHi,IZLo(I),IndCT_lo) - Iyz_tl = ( Iyhz - Iylz )*Ygrid + Iylz - - ! linearaly interpolate in the upper time slice - Iylz = ( CTvelW(IYLo,IZHi(I),IndCT_hi) - CTvelW(IYLo,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelW(IYLo,IZLo(I),IndCT_hi) - Iyhz = ( CTvelW(IYHi,IZHi(I),IndCT_hi) - CTvelW(IYHi,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelW(IYHi,IZLo(I),IndCT_hi) - Iyz_th = ( Iyhz - Iylz )*Ygrid + Iylz - - CT_GetWindSpeed = ( Iyz_th - Iyz_tl )*Tgrid + Iyz_tl - - - RETURN - -END FUNCTION CT_GetWindSpeed -!==================================================================================================== -SUBROUTINE ReadCTData ( UnWind, CTFileNo, Itime, ErrStat, ErrMsg ) -! This subroutine is used to read one time-step's worth of large-eddy -! zero-mean wind data for each wind component from a file. -!---------------------------------------------------------------------------------------------------- - - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - INTEGER, INTENT(IN) :: CTFileNo ! The number of the file to read - INTEGER, INTENT(IN) :: Itime ! The index of the time slice - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message to return about the error - - ! Local variables. - -! CHARACTER(1),PARAMETER :: Comp(NumComps) = (/'u', 'v', 'w' /) ! the wind components - CHARACTER(5) :: CTnum ! string equivalent of input variable CTFileNo - CHARACTER(1024) :: FileName ! The name of the input data file - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - - !------------------------------------------------------------------------ - ! Initialize the error handling - !------------------------------------------------------------------------ - ErrStat = ErrID_None - ErrMsg = '' - - - IF ( CTFileNo == 0 ) THEN - - CTvelU(:,:,Itime) = 0.0 - CTvelV(:,:,Itime) = 0.0 - CTvelW(:,:,Itime) = 0.0 - - ELSE - ! Loop through the components - - WRITE( CTnum, '(I5.5)' ) CTFileNo - - - FileName = TRIM( CTSpath )//'\u\u_16i_'//CTnum//'.'//TRIM( CText ) - CALL LoadCTData( UnWind, TRIM(FileName), Itime, 1, CTvelU, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - FileName = TRIM( CTSpath )//'\v\v_16i_'//CTnum//'.'//TRIM( CText ) - CALL LoadCTData( UnWind, TRIM(FileName), Itime, 2, CTvelV, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - FileName = TRIM( CTSpath )//'\w\w_16i_'//CTnum//'.'//TRIM( CText ) - CALL LoadCTData( UnWind, TRIM(FileName), Itime, 3, CTvelW, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - END IF - - RETURN - -END SUBROUTINE ReadCTData -!==================================================================================================== -SUBROUTINE LoadCTData( UnWind, FileName, ITime, IComp, Vel, ErrStat, ErrMsg ) -! This function is used to read the input parameters for the coherent turbulence events, -! based on the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the file to open - INTEGER, INTENT(IN) :: Itime ! The index of the time slice - INTEGER, INTENT(IN) :: IComp ! The index of the component - REAL(ReKi), INTENT(INOUT) :: Vel (NumCTyD,NumCTzD,2) ! returns the velocity array (don't use INTENT OUT!) - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! A message abouth the error - - - ! Local Variables - - INTEGER(B2Ki) :: Com (NumCTy) ! Temporary array to hold component's integer values for a given Z. - INTEGER :: IY ! A DO index for indexing the arrays in the y direction. - INTEGER :: IYK ! An index for the decimated arrays in the y direction. - INTEGER :: IZ ! A DO index for indexing the arrays in the z direction. - INTEGER :: IZK ! An index for the decimated arrays in the z direction. - - ! Temporary error handling - INTEGER :: TmpErrStat - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg - - - !------------------------------------------------------------------------------------------------- - ! Set temporary Error info - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' -!FIXME: remove with add ErrMsg - TmpErrMsg = '' - - - !------------------------------------------------------------------------------------------------- - ! Open the input file - !------------------------------------------------------------------------------------------------- - - CALL OpenUInBEFile( UnWind, TRIM(FileName), 2*NumCTy, TmpErrStat ) ! add ErrMsg - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - RETURN - ELSE - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Read the data and fill the arrays - !------------------------------------------------------------------------------------------------- - - IZK = 0 ! the Z index into the array (necessary b/c of decimation factor) - DO IZ=1,NumCTz,CT_DF_Z - - READ (UnWind,REC=IZ,IOSTAT=TmpErrStat) Com - - IF ( TmpErrStat /= 0 ) THEN - - ErrMsg = TRIM(ErrMsg)//' Error reading record '//TRIM( Num2LStr( IZ ) )//' of the binary CT wind file, "' & - //TRIM( FileName )//'."' - ErrStat=ErrID_Fatal - RETURN - - ENDIF - - IZK = IZK + 1 - IYK = 0 ! the Y index into the array (necessary b/c of decimation factor) - - DO IY=1,NumCTy,CT_DF_Y - IYK = IYK + 1 - Vel(IYK,IZK,ITime) = CTScale(IComp)*Com(IY) + CTOffset(IComp) - ENDDO ! IY - - ENDDO ! IZ - - - !------------------------------------------------------------------------------------------------- - ! Close the file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnWind ) - - RETURN - - -END SUBROUTINE LoadCTData -!==================================================================================================== -SUBROUTINE ReadCTP( UnWind, FileName, CTPscaling, ErrStat, ErrMsg ) -! This function is used to read the input parameters for the coherent turbulence events, -! based on the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the input data file - TYPE(CTWindFiles), INTENT(OUT) :: CTPscaling ! The file names contained in the CTP file - INTEGER, INTENT(OUT) :: ErrStat ! returns 0 if no error; non-zero otherwise' - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message to return - - - ! Local variables. - - CHARACTER(1024) :: HeaderLine ! The header text in the file - CHARACTER(1024) :: TmpPath - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - !------------------------------------------------------------------------------------------------- - ! Set temporary Error info - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - - !------------------------------------------------------------------------------------------------- - ! Open the CTP input file - !------------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnWind, TRIM( FileName ), TmpErrStat ) ! add ErrMsg - - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the CTP input file - !------------------------------------------------------------------------------------------------- - CALL ReadStr( UnWind, TRIM( FileName ), HeaderLine, 'Header line', 'The header line in the CTP file', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat > AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading header line of '//TRIM(FileName)//'.' - RETURN - ENDIF - CALL WrScr ( ' Heading of the CT-wind-parameter file: "'//TRIM(HeaderLine)//'"' ) - - - CALL ReadCom( UnWind, TRIM( FileName ), 'parameter header line', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading parameter header line of '//TRIM(FileName)//'.' - RETURN - ENDIF - - - CALL ReadVar( UnWind, TRIM( FileName ), CTSpath, 'CTSpath', & - 'Location (path) of the binary coherent turbulence dataset', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading location (path) of the binary coherent turbulence dataset '//TRIM(FileName)//'.' - RETURN - ENDIF - - - CALL ReadVar( UnWind, TRIM( FileName ), CTPscaling%CTfile, 'CTfile', & - 'File containing the time steps for the coherent turbulence events (.cts)', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading name of file containing time steps for the coherent turbulent events from ' & - //TRIM(FileName)//'.' - RETURN - ENDIF - - - IF ( PathIsRelative( CTPscaling%CTfile ) ) THEN - CALL GetPath( FileName, TmpPath ) - CTPscaling%CTfile = TRIM(TmpPath)//TRIM(CTPscaling%CTfile) - END IF - - - CALL ReadVar( UnWind, TRIM( FileName ), CTPscaling%CTbackgr, 'CTbackgr', 'File containing the background wind', TmpErrStat ) ! add ErrMsig - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading name of file containing the background wind from '//TRIM(FileName)//'.' - RETURN - ENDIF - - IF ( PathIsRelative( CTPscaling%CTbackgr ) ) THEN - CALL GetPath( FileName, TmpPath ) - CTPscaling%CTbackgr = TRIM(TmpPath)//TRIM(CTPscaling%CTbackgr) - END IF - - - CALL ReadVar( UnWind, TRIM( FileName ), CT_DF_Y, 'CT_DF_Y', 'Decimation factor for wind data in the Y direction', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading the decimation factor for wind data in the Y direction from ' & - //TRIM(FileName)//'.' - RETURN - ENDIF - - - CALL ReadVar( UnWind, TRIM( FileName ), CT_DF_Z, 'CT_DF_Z', 'Decimation factor for wind data in the Z direction', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading the decimation factor for wind data in the Z direction from ' & - //TRIM(FileName)//'.' - RETURN - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Close the CTP input file - !------------------------------------------------------------------------------------------------- - - CLOSE( UnWind ) - - -END SUBROUTINE ReadCTP -!==================================================================================================== -SUBROUTINE ReadCT ( UnWind, FileName, CT_SC_ext, EmptyFileStat, ErrStat, ErrMsg ) -! This subroutine is used to read the input parameters calculated in TurbSim for the scaling of -! coherent turbulence events. It reads the .cts file and saves the time step and file number arrays. -!---------------------------------------------------------------------------------------------------- - -! EmptyFileStat: The CT file may not be exist or may be empty. TurbSim will do this in certain conditions. -! This is not a problem for program execution and used to be handled by Errstat<0. Set a -! warning in this case. - - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the input data file - CHARACTER(3), INTENT(OUT) :: CT_SC_ext ! The extension used for coherent turbulence scale files.(usually "les", "dns", or "dat") - LOGICAL, INTENT(OUT) :: EmptyFileStat ! Special case for this file type. see note above - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_Warn if can't open the file - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about what happened - - ! Local variables - - INTEGER :: IT ! Loop counter - - ! Temporary error handling variables - - INTEGER :: TmpErrStat ! temporary ErrStat - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! temporary returned error message - - !------------------------------------------------------------------------------------------------- - ! Initialize variables - !------------------------------------------------------------------------------------------------- - - NumCTt = 0 - ErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Open the CTS input file -- can proceed if we can't open this file. - !------------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnWind, TRIM( FileName ), TmpErrStat ) ! add ErrMsg when available - IF (TmpErrStat /= 0) THEN - EmptyFileStat = .TRUE. - ErrMsg = ' Error opening '//TRIM(FileName)//', ignoring it.' - ErrStat = ErrID_Warn - RETURN - ELSE - EmptyFileStat = .FALSE. - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Read the header of the CTS input file - !------------------------------------------------------------------------------------------------- - - ! Check to see if the first value is numeric (old) or the file type (new) and start again - - READ ( UnWind, *, IOSTAT=TmpErrStat ) CTScaleVel - REWIND( UnWind ) - - IF ( TmpErrStat /= 0 ) THEN ! try again - - CALL ReadVar( UnWind, TRIM( FileName ), CText, 'CText', 'FileType ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? Can proceeed if the file is empty. - IF ( TmpErrStat < 0 ) THEN ! end of record / end of file condition - ErrMsg = TRIM(ErrMsg)//' File '//TRIM(FileName)//' is empty; ignoring it' - ErrStat = ErrID_Warn - EmptyFileStat = .TRUE. - RETURN - ELSE ! positive, so something bad happened. - ErrMsg = TRIM(ErrMsg)//' Error reading from file '//TRIM(TmpErrMsg) - ErrStat = ErrID_Fatal - ENDIF - IF ( ErrStat >= AbortErrLev ) RETURN - - CT_SC_ext = CText - - CALL ReadVar( UnWind, TRIM( FileName ), CTScaleVel, 'CTScaleVel', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - ELSE ! assume LES files - - CALL ReadVar( UnWind, TRIM( FileName ), CTScaleVel, 'CTScaleVel', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - CText = 'les' - CT_SC_ext = 'dat' - END IF - - CALL ReadVar( UnWind, TRIM( FileName ), InvMCTWS, 'MeanCTWS', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - InvMCTWS = 1.0 / InvMCTWS - - - CALL ReadVar( UnWind, TRIM( FileName ), CTYmax, 'CTYmax', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTZmax, 'CTZmax', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTDistSc, 'CTDistSc', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTLy, 'CTLy', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTLz, 'CTLz', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), NumCTt, 'NumCTt', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Allocate space for the arrays - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(Tdata) ) THEN - ALLOCATE ( Tdata(NumCTt) , STAT=TmpErrStat ) - - ! Errors occured? - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the Tdata array.' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - END IF - - IF (.NOT. ALLOCATED(TimeStpCT) ) THEN - ALLOCATE ( TimeStpCT(NumCTt) , STAT=TmpErrStat ) - - ! Errors occured? - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the TimeStpCT array.' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - END IF - - - !------------------------------------------------------------------------------------------------- - ! Read the arrays from the CTS input file - !------------------------------------------------------------------------------------------------- - - DO IT=1,NumCTt - - READ (UnWind,*,IOSTAT=TmpErrStat) Tdata(IT), TimeStpCT(IT) - - ! Errors occured? - IF ( TmpErrStat /=0 ) THEN - ErrStat=ErrID_Fatal - ErrMsg = TRIM(ErrMsg)//' Error reading record '//TRIM( Num2LStr( IT ) )//' of the CT-wind time-steps file, "' & - //TRIM( FileName )//'."' - - NumCTt = IT - 1 - RETURN - ENDIF - - ENDDO ! IT - - - !------------------------------------------------------------------------------------------------- - ! Close the CTS input file - !------------------------------------------------------------------------------------------------- - CLOSE( UnWind ) - - - RETURN - -END SUBROUTINE ReadCT -!==================================================================================================== -SUBROUTINE ReadCTScales ( UnWind, FileName, ErrStat, ErrMsg ) -! This subroutine is used to read the input parameters for the coherent turbulence events, based -! on the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the input data file - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about the error - - - ! Local variables - - INTEGER :: I ! Array counter - - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - !------------------------------------------------------------------------------------------------- - ! Open the file with the scales (les or dns) - !------------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnWind, TRIM( FileName ), ErrStat) ! add ErrMsg - IF (ErrStat /= 0) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the file with the scales (les or dns) - !------------------------------------------------------------------------------------------------- - - CALL ReadCom( UnWind, TRIM( FileName ), 'First line', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTVertShft, 'CTVertShft', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - DO I = 1,3 - CALL ReadVar( UnWind, TRIM( FileName ), CTScale(I), 'CTScale('//TRIM(Num2LStr(I))//')', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTOffset(I), 'CTOffset('//TRIM(Num2LStr(I))//')', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - END DO !I - - - CALL ReadVar( UnWind, TRIM( FileName ), NumCTy, 'NumCTy', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), NumCTz, 'NumCTz', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Close the file with the scales (les or dns) - !------------------------------------------------------------------------------------------------- - - CLOSE( UnWind ) - - - RETURN - -END SUBROUTINE ReadCTScales -!==================================================================================================== -SUBROUTINE CT_Terminate( ErrStat, ErrMsg ) -! This subroutine closes files, deallocates memory, and un-sets the initialization flag -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(OUT) :: ErrStat ! return ErrID_None if no errors, ErrID level otherwise. - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about the error that occurred. - - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary Error Message - - - ! Initialize variables - ErrStat = ErrID_None - ErrMsg = '' - TmpErrMsg = '' - TmpErrStat = 0 - - - CLOSE( CTWindUnit ) - - IF ( ALLOCATED( CTvelU ) ) DEALLOCATE( CTvelU, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of CTvelU.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( CTvelV ) ) DEALLOCATE( CTvelV, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of CTvelV.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( CTvelW ) ) DEALLOCATE( CTvelW, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of CTvelW.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( Tdata ) ) DEALLOCATE( Tdata, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of Tdata.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( TimeStpCT ) ) DEALLOCATE( TimeStpCT, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of TimeStpCT.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - TimeIndx = 0 - -END SUBROUTINE CT_Terminate -!==================================================================================================== -END MODULE CTWind diff --git a/modules/inflowwind/src/FDWind.f90 b/modules/inflowwind/src/FDWind.f90 deleted file mode 100644 index c8accae528..0000000000 --- a/modules/inflowwind/src/FDWind.f90 +++ /dev/null @@ -1,1300 +0,0 @@ -MODULE FDWind -! This module reads and processes 4-dimensional wind fields. -! The subroutines were originally created by Marshall Buhl to read LES data provided by researchers -! at NCAR. It was later updated by Bonnie Jonkman to read DNS data provided by researchers at CoRA. -! -! Data are assumed to be in units of meters and seconds. -! -! 7 Oct 2009 B. Jonkman, NREL/NWTC using subroutines from AeroDyn 12.57 -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2013 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** -! File last committed: $Date: 2014-07-29 13:30:04 -0600 (Tue, 29 Jul 2014) $ -! (File) Revision #: $Rev: 125 $ -! URL: $HeadURL$ -!********************************************************************************************************************************** - - USE NWTC_Library - USE SharedInflowDefs - USE InflowWind_Module_Types - - IMPLICIT NONE - PRIVATE - - ! FD_Wind - - REAL(ReKi) :: DelXgrid ! The nondimensional distance between grid points in the x direction. - REAL(ReKi) :: DelYgrid ! The nondimensional distance between grid points in the y direction. - REAL(ReKi) :: DelZgrid ! The nondimensional distance between grid points in the z direction. - REAL(ReKi) :: FDper ! Total time in dataset. - REAL(ReKi) :: FDTime (2) ! Times for the 4D wind files. - REAL(ReKi), ALLOCATABLE :: FDu (:,:,:,:) ! The u-component array of 4D wind data. - REAL(ReKi), ALLOCATABLE :: FDv (:,:,:,:) ! The v-component array of 4D wind data. - REAL(ReKi), ALLOCATABLE :: FDw (:,:,:,:) ! The w-component array of 4D wind data. - REAL(ReKi), ALLOCATABLE :: FDuData (:,:,:,:) ! The u-component array of all 4D wind data when used with advection. - REAL(ReKi), ALLOCATABLE :: FDvData (:,:,:,:) ! The v-component array of all 4D wind data when used with advection. - REAL(ReKi), ALLOCATABLE :: FDwData (:,:,:,:) ! The w-component array of all 4D wind data when used with advection. - REAL(ReKi) :: Lx ! Fractional location of tower centerline from upwind end to downwind end of the dataset. - REAL(ReKi) :: Ly ! Fractional location of tower centerline from right (looking downwind) to left side of the dataset. - REAL(ReKi) :: Lz ! Fractional location of hub height from bottom to top of dataset. - REAL(ReKi) :: Offsets (3) ! Offsets to convert integer data to actual wind speeds. -!FIXME: move to otherstates - REAL(ReKi), SAVE :: PrevTime ! The previous time this was called -- so we can go back in time if necessary - REAL(ReKi) :: RotDiam ! Rotor diameter. - REAL(ReKi) :: ScalFact (3) ! Scaling factors to convert integer data to actual wind speeds. - REAL(ReKi) :: ScaleVel ! Scaling velocity, U0. 2*U0 is the difference in wind speed between the top and bottom of the wave. - REAL(ReKi), ALLOCATABLE :: Times4D (:) ! The list of times for the 4D-wind input files. - REAL(ReKi) :: Tm_max ! The total nondimensional time of the dataset. - REAL(ReKi) :: TSclFact ! Scale factor for time (h/U0). - REAL(ReKi) :: T_4D_En ! Time at which the wave event ends. - REAL(ReKi) :: T_4D_St ! Time at which the wave event starts. - REAL(ReKi) :: Xmax ! The dimensional downwind length of the dataset. - REAL(ReKi) :: Xt ! Distance of the tower from the upwind end of the dataset. - REAL(ReKi) :: Ymax ! The dimensional lateral width of the dataset. - REAL(ReKi) :: Yt ! Distance of the tower from the right side of the dataset (looking downwind). - REAL(ReKi) :: Zmax ! The dimensional vertical height of the dataset. - REAL(ReKi) :: Zt ! Distance of the hub from the bottom of the dataset. - REAL(ReKi) :: Zref ! The reference height (hub height) - - INTEGER :: FD_DF_X ! The decimation factor for the 4D wind data in the x direction. - INTEGER :: FD_DF_Y ! The decimation factor for the 4D wind data in the y direction. - INTEGER :: FD_DF_Z ! The decimation factor for the 4D wind data in the z direction. - INTEGER :: FDFileNo ! The 4D wind file number. - INTEGER :: FDRecL ! The length, in bytes, of the LE binary records. - INTEGER :: Ind4DAdv ! Index of the file to be used in advection - INTEGER :: Ind4Dnew ! Index of the newest 4D wind file. - INTEGER :: Ind4Dold ! Index of the older 4D wind file. - INTEGER :: Num4Dt ! The number of 4D wind grids, one grid per time step. - INTEGER, PARAMETER :: Num4DtD = 2 ! The number of 4D wind grids stored in memory, normally 2 - INTEGER :: Num4Dx ! The number of 4D wind grid points in the x direction. - INTEGER :: Num4DxD ! The decimated number of 4D wind grid points in the x direction. - INTEGER :: Num4DxD1 ! The decimated number of 4D wind grid points in the x direction minus 1. - INTEGER :: Num4Dy ! The number of 4D wind grid points in the y direction. - INTEGER :: Num4DyD ! The decimated number of 4D wind grid points in the y direction. - INTEGER :: Num4DyD1 ! The decimated number of 4D wind grid points in the y direction minus 1. - INTEGER :: Num4Dz ! The number of 4D wind grid points in the z direction. - INTEGER :: Num4DzD ! The decimated number of 4D wind grid points in the z direction. - INTEGER :: Num4DzD1 ! The decimated number of 4D wind grid points in the z direction minus 1. - INTEGER :: NumAdvect ! Number of frozen timesteps to advect past the turbine - INTEGER :: Shft4Dnew ! Number of times the x-data needs to be shifted for advection - INTEGER, ALLOCATABLE :: Times4DIx (:) ! Index number of the 4D time files (used for advection) - - INTEGER :: FDUnit ! Unit number for reading wind files - - LOGICAL :: Advect ! Flag to indicate whether or not to advect a given data set or to just use the time step files - LOGICAL :: VertShft ! Flag to indicate whether or not to shift the z values for the w component. - -!FIXME: move to parameters or otherstates - LOGICAL, SAVE :: Initialized = .FALSE. - - CHARACTER(5), ALLOCATABLE :: AdvFiles (:) - CHARACTER(1024) :: FDSpath ! The path to the 4D wind files. - - - PUBLIC :: FD_Init - PUBLIC :: FD_GetWindSpeed - PUBLIC :: FD_Terminate - PUBLIC :: FD_GetValue - - -CONTAINS -!==================================================================================================== -SUBROUTINE FD_Init(UnWind, WindFile, RefHt, ErrStat) -! This subroutine is called at the beginning of a simulation to initialize the module. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: WindFile ! Name of the 4D wind parameter file (.fdp) - REAL(ReKi), INTENT(IN) :: RefHt ! The reference height for the billow (should be hub height) - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors; non-zero otherwise - - ! Local variables - - CHARACTER(1024) :: FDTSfile ! name of the 4D time step file - REAL(ReKi) :: FDTimStp ! Average time step for 4D wind data. - INTEGER :: IT - - !------------------------------------------------------------------------------------------------- - ! Check that the module hasn't already been initialized. - !------------------------------------------------------------------------------------------------- - - IF ( Initialized ) THEN - CALL WrScr( ' FDWind has already been initialized.' ) - ErrStat = 1 - RETURN - ELSE - ErrStat = 0 -! CALL NWTC_Init() ! Initialized in IfW_Init - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the reference height for the wind file (this takes the place of HH that was used earlier) - !------------------------------------------------------------------------------------------------- - - ZRef = RefHt - - !------------------------------------------------------------------------------------------------- - ! Read the main 4D input file - !------------------------------------------------------------------------------------------------- - - CALL ReadFDP( UnWind, WindFile, FDTSfile, ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - !------------------------------------------------------------------------------------------------- - ! Get the times array, which must be scaled and shifted later using TSclFact and T_4D_St - !------------------------------------------------------------------------------------------------- - - CALL Read4Dtimes ( UnWind, FDTSfile, ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Calculate some values that don't change during the run. - !------------------------------------------------------------------------------------------------- - - FDRecL = 2*Num4Dx*Num4Dy ! The length, in bytes, of the 4D binary records. - Num4DxD = ( Num4Dx + FD_DF_X - 1 )/FD_DF_X ! The decimated number of 4D wind grid points in the x direction. - Num4DyD = ( Num4Dy + FD_DF_Y - 1 )/FD_DF_Y ! The decimated number of 4D wind grid points in the y direction. - Num4DzD = ( Num4Dz + FD_DF_Z - 1 )/FD_DF_Z ! The decimated number of 4D wind grid points in the z direction. - Num4DxD1 = Num4DxD - 1 ! The decimated number of 4D wind grid points in the x direction minus 1. - Num4DyD1 = Num4DyD - 1 ! The decimated number of 4D wind grid points in the y direction minus 1. - Num4DzD1 = Num4DzD - 1 ! The decimated number of 4D wind grid points in the z direction minus 1. - - Tm_max = Times4D(Num4Dt) ! Time of end of dataset. - IF ( ADVECT ) THEN - FDTimStp = Xmax / ( ( Num4Dx - 1 )*( ScaleVel )*Num4Dt ) ! The timestep is calculated by the approximation dx/dt ~= U0 (divide by num4dt to get delta for a full timestep). - FDper = FDTimStp * Num4Dt ! Total time in dataset. (We have periodic time, so multiply by number of time steps, without subtracting 1) - TSclFact = FDper / Tm_max ! Equivalent scale factor for time. - ELSE - FDper = TSclFact*Tm_max ! Total time in dataset. - FDTimStp = FDper/( Num4Dt - 1 ) ! Average time step. - ENDIF - - T_4D_En = T_4D_St + FDper ! Time for the end of the dataset. - Xt = Xmax*Lx ! Distance of the tower from the upwind end of the dataset. - Yt = Ymax*Ly ! Distance of the tower from the right side of the dataset (looking downwind). - Zt = Zmax*Lz ! Distance of the hub from the bottom of the dataset. - DelXgrid = 1.0/Num4DxD1 ! The nondimensional distance between grid points in the x direction. - DelYgrid = 1.0/Num4DyD1 ! The nondimensional distance between grid points in the y direction. - DelZgrid = 1.0/Num4DzD1 ! The nondimensional distance between grid points in the z direction. - - - !------------------------------------------------------------------------------------------------- - ! Scale and shift the times array using TSclFact and T_4D_St - !------------------------------------------------------------------------------------------------- - - DO IT=1,Num4Dt - - Times4D(IT) = TSclFact*Times4D(IT) + T_4D_St - - ENDDO ! IT - - - !------------------------------------------------------------------------------------------------- - ! Allocate velocity arrays and fill Data arrays for advection (DNS files) - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(FDu) ) THEN -! CALL AllocAry ( FDu, Num4DxD, Num4DyD, Num4DzD, 2, 'U-component velocity array (FDu)', ErrStat) - ALLOCATE ( FDu(Num4DxD,Num4DyD,Num4DzD,2), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the U-component velocity array (FDu) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDv) ) THEN -! CALL AllocAry ( FDv, Num4DxD, Num4DyD, Num4DzD, 2, 'V-component velocity array (FDv)', ErrStat) - ALLOCATE ( FDv(Num4DxD,Num4DyD,Num4DzD,2), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the V-component velocity array (FDv) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDw) ) THEN -! CALL AllocAry ( FDw, Num4DxD, Num4DyD, Num4DzD, 2, 'W-component velocity array (FDw)', ErrStat) - ALLOCATE ( FDw(Num4DxD,Num4DyD,Num4DzD,2), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the W-component velocity array (FDw) array.' ) - RETURN - END IF - END IF - - IF ( ADVECT ) THEN - - IF (.NOT. ALLOCATED(FDuData) ) THEN -! CALL AllocAry ( FDuData, Num4DxD, Num4DyD, Num4DzD, Num4Dt, 'U-component velocity array (FDuData)', ErrStat) - ALLOCATE ( FDuData(Num4DxD,Num4DyD,Num4DzD,Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the U-component velocity array (FDuData) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDvData) ) THEN -! CALL AllocAry ( FDvData, Num4DxD, Num4DyD, Num4DzD, Num4Dt, 'V-component velocity array (FDvData)', ErrStat) - ALLOCATE ( FDvData(Num4DxD,Num4DyD,Num4DzD,Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the V-component velocity array (FDvData) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDwData) ) THEN -! CALL AllocAry ( FDwData, Num4DxD, Num4DyD, Num4DzD, Num4Dt, 'W-component velocity array (FDwData)', ErrStat) - ALLOCATE ( FDwData(Num4DxD,Num4DyD,Num4DzD,Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the W-component velocity array (FDwData) array.' ) - RETURN - END IF - END IF - - CALL ReadAll4DData(UnWind, ErrStat) !This needs AdvFiles(:), which was is read in ReadFDP() - IF ( ErrStat /= 0 ) RETURN - - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Determine the first file needed for this simulation. - !------------------------------------------------------------------------------------------------- - Ind4Dold = 1 ! Put the old stuff in the first part of the array. - Ind4Dnew = 2 ! Put the new stuff in the second part of the array. - - Shft4Dnew = 0 - - - IF ( T_4D_St >= 0.0 ) THEN - FDFileNo = 1 - ELSE - FDFileNo = Num4Dt - DO IT=1,Num4Dt - IF ( Times4D(IT) > 0.0 ) THEN - FDFileNo = IT - 1 - EXIT - END IF - END DO ! IT - END IF - - !------------------------------------------------------------------------------------------------- - ! Open, read, and close the first set of files. - !------------------------------------------------------------------------------------------------- - FDTime(Ind4Dold) = Times4D(FDFileNo) ! Set the time for this file. - - IF ( ADVECT ) THEN - CALL Load4DData(Ind4Dold) ! load data stored in FDuData, FDvData, and FDwData arrays - ELSE - CALL LoadLESData( UnWind, FDFileNo, Ind4Dold, ErrStat ) - END IF - - - !------------------------------------------------------------------------------------------------- - ! Open, read, and close the second set of files. - !------------------------------------------------------------------------------------------------- - FDFileNo = FDFileNo + 1 - - - IF ( ADVECT ) THEN - FDFileNo = MOD(FDFileNo-1,Num4Dt) + 1 - - IF (FDFileNo == 1) THEN - Shft4Dnew = Shft4Dnew + 1 - - IF (Ind4DAdv <= NumAdvect) THEN ! Ind4DAdv was set in ReadFDP - IF ( MOD( Shft4Dnew, Num4Dx ) == 0 ) THEN - CALL ReadAll4DData(UnWind, ErrStat) - IF ( ErrStat /= 0 ) RETURN - END IF - END IF - - ENDIF - - FDTime(Ind4Dnew) = Times4D(FDFileNo) + Shft4Dnew*FDPer ! Set the time for this file. - - CALL Load4DData( Ind4Dnew ) ! shift the data - - ELSE - FDTime(Ind4Dnew) = Times4D(FDFileNo) ! Set the time for this file. - - CALL LoadLESData( UnWind, FDFileNo, Ind4Dnew, ErrStat ) - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Set the initialization flag - !------------------------------------------------------------------------------------------------- - FDUnit = UnWind - PrevTime = 0.0 - - Initialized = .TRUE. - - RETURN - -END SUBROUTINE FD_Init -!==================================================================================================== -SUBROUTINE ReadFDP ( UnWind, FileName, FDTSfile, ErrStat ) -! This subroutine is used to read the input parameters for the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: FileName ! Then name of the LE data file. - CHARACTER(*), INTENT(OUT) :: FDTSfile ! The name of the file containing the time-step history of the wind files. - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors encountered; non-zero otherwise - - - ! Local variables - - CHARACTER(1024) :: HeaderLine -!FIXME: this invokes SAVE - CHARACTER(1),PARAMETER :: Comp(3) = (/'U', 'V', 'W' /) ! the wind components - - REAL(ReKi) :: CoefTE ! Coefficient of thermal expansion. - REAL(ReKi) :: DistScal ! Disturbance scale (ratio of wave height to rotor diameter) from input file. - REAL(ReKi) :: Grav ! Gravitational acceleration. - REAL(ReKi) :: LenScale ! Length scale (h). - REAL(ReKi) :: Ri ! Richardson number. - REAL(ReKi) :: Ubot ! Steady u-component wind speed at the bottom of the wave. - REAL(ReKi) :: Zm_maxo ! The nondimensional vertical height of the untrimmed dataset. - - REAL(ReKi) :: Xm_max ! The nondimensional downwind length of the dataset. - REAL(ReKi) :: Ym_max ! The nondimensional lateral width of the dataset. - REAL(ReKi) :: Zm_max ! The nondimensional vertical height of the dataset. - - INTEGER :: I - - !------------------------------------------------------------------------------------------------- - ! Open the 4D parameter file for reading - !------------------------------------------------------------------------------------------------- - CALL OpenFInpFile ( UnWind, TRIM( FileName ), ErrStat) - IF (ErrStat /= 0) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the 4D parameter input file - !------------------------------------------------------------------------------------------------- - - !.............................................................................................. - ! Read the 4D wind parameters specific to this turbine simulation. - !.............................................................................................. - - CALL ReadStr( UnWind, TRIM( FileName ), HeaderLine, 'Header line', 'The header line in the FTP file', ErrStat ) - IF (ErrStat /= 0) RETURN - CALL WrScr ( ' Heading of the 4D-wind-parameter file: "'//TRIM(HeaderLine)//'"' ) - - - CALL ReadCom( UnWind, TRIM( FileName ), 'Header line', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FDSpath, 'FDSpath', 'Location (path) of the binary dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FDTSfile, 'FDTSfile', & - 'Name of the file containing the time-step history of the wind files', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ubot, 'Ubot', 'Steady u-component wind speed at the bottom of the wave', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), DistScal, 'DistScal', 'Disturbance scale', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Lx, 'Lx', & - 'Fractional location of tower centerline from upwind end to downwind end of the dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ly, 'Ly', & - 'Fractional location of tower centerline from right (looking downwind) to left side of the dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Lz, 'Lz', & - 'Fractional location of hub height from bottom to top of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), T_4D_St, 'T_4D_St', 'Time at which the wave event starts', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), ScaleVel, 'ScaleVel', & - 'Scaling velocity, U0: half the difference in wind speed between the top and bottom of the billow.', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), RotDiam, 'RotDiam', 'Rotor diameter', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FD_DF_X, 'FD_DF_X', 'Decimation factor in X direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FD_DF_Y, 'FD_DF_Y', 'Decimation factor in Y direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FD_DF_Z, 'FD_DF_Z', 'Decimation factor in Z direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadCom( UnWind, TRIM( FileName ), 'blank line', ErrStat ) - IF (ErrStat /= 0) RETURN - - !.............................................................................................. - ! Read the 4D wind parameters specific to the K-H billow simulation being used. - !.............................................................................................. - - CALL ReadCom( UnWind, TRIM( FileName ), 'LES parameters specific to the K-H billow simulation being used', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), VertShft, 'VertShft', & - 'Flag to indicate whether or not to shift the z values for the w component', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Xm_max, 'Xm_max', & - 'Maximum nondimensional downwind distance from center of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ym_max, 'Ym_max', & - 'Maximum nondimensional lateral distance from center of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Zm_max, 'Zm_max', & - 'Maximum nondimensional vertical distance from center of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Zm_maxo, 'Zm_maxo', & - 'Maximum nondimensional vertical distance from center of untrimmed dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - DO I = 1,3 - - CALL ReadVar( UnWind, TRIM( FileName ), ScalFact(I), Comp(I)//'Scl', & - Comp(I)//'-component scale factor for converting from integers to reals', ErrStat ) - IF (ErrStat /= 0) RETURN - ScalFact(I) = ScalFact(I) * ScaleVel - - - CALL ReadVar( UnWind, TRIM( FileName ), Offsets(I), Comp(I)//'Off', & - Comp(I)//'-component offset for converting from integers to reals', ErrStat ) - IF (ErrStat /= 0) RETURN - Offsets(I) = Offsets(I) * ScaleVel - - END DO - Offsets (1) = Offsets (1) + ScaleVel + Ubot ! u-component offset to convert integer data to actual wind speeds. - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dt, 'Num4Dt', 'The number of LE grids, one grid per time step', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dx, 'Num4Dx', 'The number of LE grid points in the x direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dy, 'Num4Dy', 'The number of LE grid points in the y direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dz, 'Num4Dz', 'The number of LE grid points in the z direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ri, 'Ri', 'Richardson number', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CoefTE, 'CoefTE', 'Coefficient of thermal expansion', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Grav, 'Grav', 'Gravitational acceleration', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Advect, 'Advect', 'Advection flag', ErrStat ) - - IF (ErrStat /= 0) THEN - - Advect = .FALSE. - Ind4DAdv = 0 - ErrStat = 0 - CALL WrScr( ' Advection will not be used.') - - ELSE - - IF (Advect) THEN - IF ( FD_DF_X /= 1 ) THEN - CALL WrScr( ' FD_DF_X must be 1 when using advection. ' ) - FD_DF_X = 1 - ENDIF - - CALL ReadVar( UnWind, TRIM( FileName ), NumAdvect, 'NumAdvect', 'Number of 4D files for advection', ErrStat ) - IF (ErrStat /= 0) RETURN - - - IF ( NumAdvect < 1 ) THEN - CALL WrScr( ' NumAdvect in 4D-wind-parameter file, "'//TRIM( FileName )//'," must be at least 1.' ) - ErrStat = 1 - RETURN - ENDIF - - IF ( .NOT. ALLOCATED( AdvFiles ) ) THEN -! CALL AllocAry( AdvFiles, NumAdvect, 'AdvFiles array', ErrStat ) - ALLOCATE ( AdvFiles(NumAdvect), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the AdvFiles array.' ) - RETURN - END IF - ENDIF - - CALL ReadAryLines( UnWind, TRIM( FileName ), AdvFiles, NumAdvect, 'AdvFiles', 'Advection file names', ErrStat ) - IF (ErrStat /= 0) RETURN - Ind4DAdv = 1 - - ELSE - Ind4DAdv = 0 - ENDIF !Advect == .TRUE. - - END IF - - !------------------------------------------------------------------------------------------------- - ! Close the 4D parameter input file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnWind ) - - !------------------------------------------------------------------------------------------------- - ! Close the 4D parameter input file - !------------------------------------------------------------------------------------------------- - - LenScale = RotDiam*DistScal/Zm_max ! Length scale (h). - Xmax = Xm_max*LenScale ! The dimensional length of the dataset. - Ymax = Ym_max*LenScale ! The dimensional width of the dataset - Zmax = Zm_max*LenScale ! The dimensional vertical height of the dataset. - TSclFact = LenScale/ScaleVel ! Scale factor for time (h/U0). - - - - RETURN - -END SUBROUTINE ReadFDP -!==================================================================================================== -SUBROUTINE Read4Dtimes ( UnWind, FileName, ErrStat ) -! This subroutine is used to read the time array for the 4D data. The times in the file are -! non-dimensional and non-uniformly spaced. They are scaled using TSclFact to obtain units of seconds -! and T_4D_St is added to allow the billow to start at non-zero time. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: FileName ! Then name of the LE data file. - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors encountered; non-zero otherwise - - - ! Local variables - - INTEGER :: I ! Loop counter - - !------------------------------------------------------------------------------------------------- - ! Allocate arrays to store the data in - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED( Times4D) ) THEN -! CALL AllocAry( Times4D, Num4Dt, '4D time array', ErrStat) - ALLOCATE ( Times4D(Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the Times4D array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED( Times4DIx) ) THEN -! CALL AllocAry( Times4DIx, Num4Dt, '4D time array', ErrStat) - ALLOCATE ( Times4DIx(Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the Times4DIx array.' ) - RETURN - END IF - END IF - - - !------------------------------------------------------------------------------------------------- - ! Open the 4D times file - !------------------------------------------------------------------------------------------------- - CALL OpenFInpFile ( UnWind, TRIM( FileName ), ErrStat) - IF ( ErrStat /= 0 ) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the 4D times file - !------------------------------------------------------------------------------------------------- - CALL ReadCom( UnWind, TRIM( FileName ), 'first line', ErrStat) - IF ( ErrStat /= 0 ) RETURN - - DO I=1,Num4Dt - - READ (UnWind,*,IOSTAT=ErrStat) Times4DIx(I), Times4D(I) - - IF ( ErrStat /= 0 ) THEN - - CALL WrScr( ' Error reading line '//TRIM( Num2LStr( I+1 ) )// & - ' of the 4D-wind time-steps file, "'//TRIM( FileName )//'."') - RETURN - - ENDIF - - ENDDO ! I - - - !------------------------------------------------------------------------------------------------- - ! Close the 4D times file - !------------------------------------------------------------------------------------------------- - - CLOSE ( UnWind ) - - RETURN - -END SUBROUTINE Read4Dtimes -!==================================================================================================== -SUBROUTINE ReadAll4DData(UnWind, ErrStat) -! This subroutine reads the data into one array to be accessed later when ADVECT=.TRUE. Since there -! are just a few time steps, we'll load them into memory to (hopefully) save I/O time. -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(IN) :: UnWind - INTEGER, INTENT(OUT) :: ErrStat ! - INTEGER :: IT - - CHARACTER(1) :: FDNum - CHARACTER(20) :: DNSFileName ! String containing part of the current file name. - - - DO IT = 1,Num4Dt - - WRITE(FDNum,'(I1.1)') Times4DIx(IT) - DNSFileName = TRIM(AdvFiles(Ind4DAdv))//'_'//TRIM(FDNum)//'.dns' - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\u\u_16i_'//TRIM(DNSFileName), FDuData, IT, ScalFact(1), Offsets(1), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\v\v_16i_'//TRIM(DNSFileName), FDvData, IT, ScalFact(2), Offsets(2), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\w\w_16i_'//TRIM(DNSFileName), FDwData, IT, ScalFact(3), Offsets(3), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - ENDDO ! IT - - Ind4DAdv = Ind4DAdv + 1 - - RETURN - -END SUBROUTINE ReadAll4DData -!==================================================================================================== -SUBROUTINE LoadLESData( UnWind, FileNo, Indx, ErrStat ) -! This subroutine reads binary data from the U, V, and W files and stores them in the arrays FDu, -! FDv, and FDw (by calling Read4DData). -!---------------------------------------------------------------------------------------------------- - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - INTEGER, INTENT(IN) :: FileNo ! current file number to read - INTEGER, INTENT(IN) :: Indx ! index into the data arrays - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors encountered; non-zero otherwise - - ! local variables - CHARACTER(5) :: FDNum - CHARACTER(20) :: LESFileName ! String containing part of the current file name. - - - ! get the file name for the file number - - WRITE(FDNum,'(I5.5)', IOStat=ErrStat) FileNo - IF ( ErrStat /= 0 ) RETURN - - LESFileName = TRIM(FDNum)//'.les' - - - ! set the paths and read the data for each component - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\u\u_16i_'//TRIM(LESFileName), FDu, Indx, ScalFact(1), Offsets(1), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\v\v_16i_'//TRIM(LESFileName), FDv, Indx, ScalFact(2), Offsets(2), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\w\w_16i_'//TRIM(LESFileName), FDw, Indx, ScalFact(3), Offsets(3), ErrStat ) - - -END SUBROUTINE LoadLESData -!==================================================================================================== -SUBROUTINE Read4DData ( UnWind, FileName, Comp, Indx4, Scale, Offset, ErrStat) -! This subroutine is used to read one time-step's worth of large-eddy wind data for one component -! from a file. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the LE file. - CHARACTER(*),INTENT(IN) :: FileName ! Then name of the LE data file. - - REAL(ReKi), INTENT(INOUT) :: Comp (:,:,:,:) ! The velocity array [do NOT make this INTENT(OUT): other parts of the array may become undefined] - INTEGER, INTENT(IN) :: Indx4 ! The index of the 4th dimension of Comp, which is to be read. - REAL(ReKi), INTENT(IN) :: Scale ! The scale factor for converting from intergers to non-normalized reals. - REAL(ReKi), INTENT(IN) :: Offset ! The offset for converting from intergers to non-normalized reals. - - INTEGER, INTENT(OUT) :: ErrStat ! The returned status of a READ. - - ! Local variables - - INTEGER :: IX ! A DO index for indexing the arrays in the x direction. - INTEGER :: IXK ! An index for the decimated arrays in the x direction. - INTEGER :: IY ! A DO index for indexing the arrays in the y direction. - INTEGER :: IYK ! An index for the decimated arrays in the y direction. - INTEGER :: IZ ! A DO index for indexing the arrays in the z direction. - INTEGER :: IZK ! An index for the decimated arrays in the z direction. - - INTEGER(B2Ki) :: Com (Num4Dx,Num4Dy) ! Temporary array to hold component's integer values for a given Z. - - - !------------------------------------------------------------------------------------------------- - ! Open the binary input file - !------------------------------------------------------------------------------------------------- - CALL OpenUInBEFile( UnWind, TRIM( FileName ), FDRecL, ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the input file - !------------------------------------------------------------------------------------------------- - - IZK = 0 - DO IZ=1,Num4Dz,FD_DF_Z - - READ (UnWind,REC=IZ,IOSTAT=ErrStat) Com - - IF ( ErrStat /= 0 ) THEN - - CALL WrScr( ' Error reading record '//TRIM( Num2LStr( IZ ) )// & - ' of the binary 4D wind file, "'//TRIM( FileName )//'".') - RETURN - - ENDIF - - IZK = IZK + 1 ! IZK = ( IZ - 1 + FD_DF_Z )/FD_DF_Z - IYK = 0 - - DO IY=1,Num4Dy,FD_DF_Y - - IYK = IYK + 1 ! IYK = ( IY - 1 + FD_DF_Y )/FD_DF_Y - - DO IX=1,Num4Dx,FD_DF_X - - ! shift the x-index, if necessary, to perform Advection - - !IXK = ( IX + FD_DF_X - 1 )/FD_DF_X - IXK = ( MOD(IX+Shft4Dnew-1,Num4Dx) + FD_DF_X )/FD_DF_X - - Comp(IXK,IYK,IZK,Indx4) = Scale*Com(IX,IY) + Offset - - ENDDO ! IX - - ENDDO ! IY - - ENDDO ! IZ - - - !------------------------------------------------------------------------------------------------- - ! Close the file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnWind ) - - RETURN - -END SUBROUTINE Read4DData -!==================================================================================================== -SUBROUTINE Load4DData( InpIndx ) -! This subroutine takes the data from the storage array (used when ADVECT=.TRUE., shifts it if necessary, -! and loads it into the array for the time slice indexed by InpIndx. -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(IN) :: InpIndx - - INTEGER :: IX - INTEGER :: IXK - - - DO IX=1,Num4Dx,FD_DF_X - - ! shift the x-index, if necessary, to perform Advection - IXK = ( MOD(IX+Shft4Dnew-1,Num4Dx) + FD_DF_X )/FD_DF_X - - FDu(IXK,:,:,InpIndx) = FDuData(IX,:,:,FDFileNo) - FDv(IXK,:,:,InpIndx) = FDvData(IX,:,:,FDFileNo) - FDw(IXK,:,:,InpIndx) = FDwData(IX,:,:,FDFileNo) - - ENDDO ! IX - - - RETURN - -END SUBROUTINE Load4DData -!==================================================================================================== -FUNCTION FD_GetValue(RVarName, ErrStat) -! This function returns a real scalar value whose name is listed in the RVarName input argument. -! If the name is not recognized, an error is returned in ErrStat. -!---------------------------------------------------------------------------------------------------- - - CHARACTER(*), INTENT(IN) :: RVarName - INTEGER, INTENT(OUT) :: ErrStat - REAL(ReKi) :: FD_GetValue - - - CHARACTER(20) :: VarNameUC - - - !------------------------------------------------------------------------------------------------- - ! Check that the module has been initialized. - !------------------------------------------------------------------------------------------------- - - IF ( .NOT. Initialized ) THEN - CALL WrScr( ' Initialialize the FDWind module before calling its subroutines.' ) - ErrStat = 1 - RETURN - ELSE - ErrStat = 0 - END IF - - - !------------------------------------------------------------------------------------------------- - ! Return the requested values. - !------------------------------------------------------------------------------------------------- - - VarNameUC = RVarName - CALL Conv2UC( VarNameUC ) - - SELECT CASE ( TRIM(VarNameUC) ) - - CASE ('ROTDIAM' ) - FD_GetValue = RotDiam - - CASE DEFAULT - CALL WrScr( ' Invalid variable name in FD_GetRValue().' ) - ErrStat = 1 - - END SELECT - -END FUNCTION FD_GetValue -!==================================================================================================== -FUNCTION FD_GetWindSpeed(Time, InputPosition, ErrStat) -! This function is used to interpolate into the 4D wind arrays. It receives X, Y, Z and TIME from the -! calling routine. The time since the start of the 4D data is used to decide which pair of time slices -! to interpolate within and between. After finding the two time slices, it decides which eight grid -! points bound the (X,Y,Z) pair. It does a trilinear interpolation for each time slice. Linear -! interpolation is then used to interpolate between time slices. This routine assumes that X is -! downwind, Y is to the left when looking downwind and Z is up. It also assumes that no -! extrapolation will be needed except in time and the Z direction. In those cases, the appropriate -! steady winds are used. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables: - - REAL(DbKi), INTENT(IN) :: Time ! the time - REAL(ReKi), INTENT(IN) :: InputPosition(3) ! structure that contains the position - INTEGER, INTENT(OUT):: ErrStat ! returns 0 if no error; non-zero otherwise -!FIXME:delete -! TYPE(InflIntrpOut) :: FD_GetWindSpeed ! the resultant wind speed - REAL(ReKi) :: FD_GetWindSpeed(3) ! the resultant wind speed - - - ! Local Variables: - - REAL(ReKi) :: Ixhyz ! Temporary interpolated value. - REAL(ReKi) :: Ixlyz ! Temporary interpolated value. - REAL(ReKi) :: Ixyzo ! Temporary interpolated value. - REAL(ReKi) :: Iyhz ! Temporary interpolated value. - REAL(ReKi) :: Iylz ! Temporary interpolated value. - REAL(ReKi) :: Ixyzn ! Temporary interpolated value. - REAL(ReKi) :: Tgrid ! Fractional distance between time grids. - REAL(ReKi) :: Xgrid ! Fractional distance between grids in the x direction. - REAL(ReKi) :: Xnorm ! Nondimensional downwind distance of the analysis point from upwind end of dataset. - REAL(ReKi) :: Ygrid ! Fractional distance between grids in the y direction. - REAL(ReKi) :: Ynorm ! Nondimensional lateral distance of the analysis point from right side of dataset (looking downwind). - REAL(ReKi) :: Zgrid ! Fractional distance between grids in the z direction. - REAL(ReKi) :: Zgrid_w ! Fractional distance between grids in the z direction for the w component. - REAL(ReKi) :: Znorm ! Nondimensional vertical distance of the analysis point from bottom of dataset. - REAL(ReKi) :: Znorm_w ! Nondimensional vertical distance of the analysis point from bottom of dataset for the w component. - - INTEGER :: IT ! Index for do loop - INTEGER :: IXHI ! Index for the more-positive x value. - INTEGER :: IXLO ! Index for the more-negative x value. - INTEGER :: IYHI ! Index for the more-positive y value. - INTEGER :: IYLO ! Index for the more-negative y value. - INTEGER :: IZHI ! Index for the more-positive z value. - INTEGER :: IZHI_w ! Index for the more-positive z value for the w component. - INTEGER :: IZLO ! Index for the more-negative z value. - INTEGER :: IZLO_w ! Index for the more-negative z value for the w component. - - REAL(ReKi) :: TempWindSpeed(3) ! Temporary variable to hold the windspeed before returning - - !------------------------------------------------------------------------------------------------- - ! Check that we've initialized everything first - !------------------------------------------------------------------------------------------------- - - IF ( .NOT. Initialized ) THEN - CALL WrScr( ' Initialialize the FDWind module before calling its subroutines.' ) - ErrStat = 1 - RETURN - ELSE - ErrStat = 0 - END IF - - !------------------------------------------------------------------------------------------------- - ! If the TIME is greater than the time for the last file read, read another set of files until we straddle the current time. - ! Stick with the last file if we've exhausted the data. - ! We're assuming here that the simulation time step is smaller than the wind-file time step. - !------------------------------------------------------------------------------------------------- - - IF ( Time < PrevTime .AND. Time < FDTime(Ind4Dold) ) THEN ! bjj: GET THE CORRECT TIME if we're going backward! - - !---------------------------------------------------------------------------------------------- - ! Determine the first file needed for this simulation. - !---------------------------------------------------------------------------------------------- - Ind4Dold = 1 ! Put the old stuff in the first part of the array. - Ind4Dnew = 2 ! Put the new stuff in the second part of the array. - - FDFileNo = Num4Dt - DO IT=1,Num4Dt - IF ( Times4D(IT) > Time ) THEN - FDFileNo = IT - 1 - EXIT - END IF - END DO ! IT - - !---------------------------------------------------------------------------------------------- - ! Open, read, and close the first set of files. - !---------------------------------------------------------------------------------------------- - FDTime(Ind4Dold) = Times4D(FDFileNo) ! Set the time for this file. - - IF ( ADVECT ) THEN - CALL Load4DData(Ind4Dold) ! load data stored in FDuData, FDvData, and FDwData arrays - ELSE - CALL LoadLESData( FDUnit, FDFileNo, Ind4Dold, ErrStat ) - END IF - - !---------------------------------------------------------------------------------------------- - ! Open, read, and close the second set of files. - !---------------------------------------------------------------------------------------------- - FDFileNo = MIN(FDFileNo + 1, Num4Dt) - Shft4Dnew = 0 - - IF ( ADVECT ) THEN - FDFileNo = MOD(FDFileNo-1,Num4Dt) + 1 - - IF (FDFileNo == 1) THEN - Shft4Dnew = Shft4Dnew + 1 - - IF (Ind4DAdv <= NumAdvect) THEN ! Ind4DAdv was set in ReadFDP - IF ( MOD( Shft4Dnew, Num4Dx ) == 0 ) THEN - CALL ReadAll4DData(FDUnit, ErrStat) - IF ( ErrStat /= 0 ) RETURN - END IF - END IF - - ENDIF - - FDTime(Ind4Dnew) = Times4D(FDFileNo) + Shft4Dnew*FDPer ! Set the time for this file. - - CALL Load4DData( Ind4Dnew ) ! shift the data - - ELSE - FDTime(Ind4Dnew) = Times4D(FDFileNo) ! Set the time for this file. -! - CALL LoadLESData( FDUnit, FDFileNo, Ind4Dnew, ErrStat ) - ENDIF - - END IF - - !------------------------------------------------------------------------------------------------- - ! Move forward in time - !------------------------------------------------------------------------------------------------- - - DO WHILE ( Time > FDTime(Ind4Dnew) .AND. ( Time < T_4D_En .OR. ADVECT ) ) - - Ind4Dnew = Ind4Dold ! Reverse array indices (1 or 2). - Ind4Dold = 3 - Ind4Dnew - FDFileNo = FDFileNo + 1 ! Increment file number. - - - IF ( ADVECT ) THEN - FDFileNo = MOD(FDFileNo-1,Num4Dt) + 1 - - IF (FDFileNo == 1) THEN - Shft4Dnew = Shft4Dnew + 1 - - IF (Ind4DAdv <= NumAdvect) THEN - IF ( MOD( Shft4Dnew, Num4Dx ) == 0 ) THEN - CALL ReadAll4DData(FDUnit, ErrStat) - IF ( ErrStat /= 0 ) RETURN - END IF - ENDIF - - ENDIF - - FDTime(Ind4Dnew) = Times4D(FDFileNo) + Shft4Dnew*FDPer - - CALL Load4DData( Ind4Dnew ) ! shift the data - ELSE - FDTime(Ind4Dnew) = Times4D(FDFileNo) - - CALL LoadLESData( FDUnit, FDFileNo, Ind4Dnew, ErrStat ) - ENDIF - - ENDDO - - - !................................................................................................. - ! Find the bounding rows, columns, and planes for the X,Y,Z position. The near, lower-right - ! corner is (1,1,1) when looking downwind. Make sure the lowest possible value is 1. - !................................................................................................. - - - !------------------------------------------------------------------------------------------------- - ! get values of Time for interpolation. Linear interpolation; Nearest-neighbor extrapolation. - !------------------------------------------------------------------------------------------------- - - ! Find out fractionally how far we are between grids in time and between grid points in each direction. - ! Limit values to avoid extrapolation. We need this for interpolation later on. - - Tgrid = MIN( MAX( ( Time - FDTime(Ind4Dold) )/( FDTime(Ind4Dnew) - FDTime(Ind4Dold) ), 0.0 ), 1.0 ) - - - !------------------------------------------------------------------------------------------------- - ! get values of X for interpolation. Grid is periodic in X. - !------------------------------------------------------------------------------------------------- - Xnorm = ( Xt + InputPosition(1) )/Xmax - - DO WHILE ( Xnorm < 0.0 ) ! Ensure Xnorm is not negative. The wave is periodic in x. - Xnorm = Xnorm + 1.0 - ENDDO - - Xgrid = MIN( MAX( MOD( Xnorm, DelXgrid ), 0.0 ), 1.0 ) - IXLo = MAX( MOD( INT( Xnorm*Num4DxD1 ) + 1, Num4DxD1 ), 1 ) - IXHi = MOD( IXLo, Num4DxD ) + 1 - - !------------------------------------------------------------------------------------------------- - ! get values of Y for interpolation. Grid is periodic in Y. - !------------------------------------------------------------------------------------------------- - Ynorm = ( Yt + InputPosition(2) )/Ymax - - DO WHILE ( Ynorm < 0.0 ) ! Ensure Ynorm is not negative. The wave is periodic in y. - Ynorm = Ynorm + 1.0 - ENDDO - - Ygrid = MIN( MAX( MOD( Ynorm, DelYgrid ), 0.0 ), 1.0 ) - IYLo = MAX( MOD( INT( Ynorm*Num4DyD1 ) + 1, Num4DyD1 ), 1 ) - IYHi = MOD( IYLo, Num4DyD ) + 1 - - !------------------------------------------------------------------------------------------------- - ! get values of Z for interpolation. Linear interpolation; Nearest-neighbor extrapolation. - !------------------------------------------------------------------------------------------------- - Znorm = MIN( MAX( ( Zt + InputPosition(3) - ZRef )/Zmax, 0.0 ), 1.0 ) !bjj: define ZRef - - Zgrid = MIN( MAX( MOD( Znorm, DelZgrid ), 0.0 ), 1.0 ) - IZLo = MAX( INT( Znorm*Num4DzD1 ) + 1, 1 ) - - ! If we are located at the upper end of the z dimension, decrement the index by one and set the grid coordinate to 1. - - IF ( IZLo == Num4DzD ) THEN - IZLo = Num4DzD1 - Zgrid = 1.0 - ENDIF - IZHi = IZLo + 1 - - !.............................................................................................. - ! Find the equivalent Znorm (Znorm_w) for the w-component, which may be shifted vertically - ! by half the original grid spacing. - !.............................................................................................. - - IF ( VertShft ) THEN - Znorm_w = MAX( Znorm - 0.5*DelZgrid/FD_DF_Z, 0.0 ) - ELSE - Znorm_w = Znorm - ENDIF - - Zgrid_w = MIN( MAX( MOD( Znorm_w, DelZgrid ), 0.0 ), 1.0 ) - IZLo_w = MAX( INT( Znorm_w*Num4DzD1 ) + 1, 1 ) - - IF ( IZLo_w == Num4DzD ) THEN - IZLo_w = Num4DzD1 - Zgrid_w = 1.0 - ENDIF - - IZHi_w = IZLo_w + 1 - - - !------------------------------------------------------------------------------------------------- - ! Interpolate for u component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - Iylz = ( FDu(IXLo,IYLo,IZHi,Ind4Dold) - FDu(IXLo,IYLo,IZLo,Ind4Dold) )*Zgrid + FDu(IXLo,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDu(IXLo,IYHi,IZHi,Ind4Dold) - FDu(IXLo,IYHi,IZLo,Ind4Dold) )*Zgrid + FDu(IXLo,IYHi,IZLo,Ind4Dold) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDu(IXHi,IYLo,IZHi,Ind4Dold) - FDu(IXHi,IYLo,IZLo,Ind4Dold) )*Zgrid + FDu(IXHi,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDu(IXHi,IYHi,IZHi,Ind4Dold) - FDu(IXHi,IYHi,IZLo,Ind4Dold) )*Zgrid + FDu(IXHi,IYHi,IZLo,Ind4Dold) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzo = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - - Iylz = ( FDu(IXLo,IYLo,IZHi,Ind4Dnew) - FDu(IXLo,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDu(IXLo,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDu(IXLo,IYHi,IZHi,Ind4Dnew) - FDu(IXLo,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDu(IXLo,IYHi,IZLo,Ind4Dnew) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDu(IXHi,IYLo,IZHi,Ind4Dnew) - FDu(IXHi,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDu(IXHi,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDu(IXHi,IYHi,IZHi,Ind4Dnew) - FDu(IXHi,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDu(IXHi,IYHi,IZLo,Ind4Dnew) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzn = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - -! FD_GetWindSpeed%Velocity(1) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - TempWindSpeed(1) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - - !------------------------------------------------------------------------------------------------- - ! Interpolate for v component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - Iylz = ( FDv(IXLo,IYLo,IZHi,Ind4Dold) - FDv(IXLo,IYLo,IZLo,Ind4Dold) )*Zgrid + FDv(IXLo,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDv(IXLo,IYHi,IZHi,Ind4Dold) - FDv(IXLo,IYHi,IZLo,Ind4Dold) )*Zgrid + FDv(IXLo,IYHi,IZLo,Ind4Dold) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDv(IXHi,IYLo,IZHi,Ind4Dold) - FDv(IXHi,IYLo,IZLo,Ind4Dold) )*Zgrid + FDv(IXHi,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDv(IXHi,IYHi,IZHi,Ind4Dold) - FDv(IXHi,IYHi,IZLo,Ind4Dold) )*Zgrid + FDv(IXHi,IYHi,IZLo,Ind4Dold) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzo = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - - Iylz = ( FDv(IXLo,IYLo,IZHi,Ind4Dnew) - FDv(IXLo,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDv(IXLo,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDv(IXLo,IYHi,IZHi,Ind4Dnew) - FDv(IXLo,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDv(IXLo,IYHi,IZLo,Ind4Dnew) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDv(IXHi,IYLo,IZHi,Ind4Dnew) - FDv(IXHi,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDv(IXHi,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDv(IXHi,IYHi,IZHi,Ind4Dnew) - FDv(IXHi,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDv(IXHi,IYHi,IZLo,Ind4Dnew) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzn = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - -!FIXME:delete -! FD_GetWindSpeed%Velocity(2) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - TempWindSpeed(2) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - - !------------------------------------------------------------------------------------------------- - ! Interpolate for w component of wind within the grid. - !------------------------------------------------------------------------------------------------- - !bjj: should Zgrid actually be Zgrid_w here? I changed it so that it's consistent - - Iylz = ( FDw(IXLo,IYLo,IZHi_w,Ind4Dold) - FDw(IXLo,IYLo,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXLo,IYLo,IZLo_w,Ind4Dold) - Iyhz = ( FDw(IXLo,IYHi,IZHi_w,Ind4Dold) - FDw(IXLo,IYHi,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXLo,IYHi,IZLo_w,Ind4Dold) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDw(IXHi,IYLo,IZHi_w,Ind4Dold) - FDw(IXHi,IYLo,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXHi,IYLo,IZLo_w,Ind4Dold) - Iyhz = ( FDw(IXHi,IYHi,IZHi_w,Ind4Dold) - FDw(IXHi,IYHi,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXHi,IYHi,IZLo_w,Ind4Dold) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzo = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - - Iylz = ( FDw(IXLo,IYLo,IZHi_w,Ind4Dnew) - FDw(IXLo,IYLo,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXLo,IYLo,IZLo_w,Ind4Dnew) - Iyhz = ( FDw(IXLo,IYHi,IZHi_w,Ind4Dnew) - FDw(IXLo,IYHi,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXLo,IYHi,IZLo_w,Ind4Dnew) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDw(IXHi,IYLo,IZHi_w,Ind4Dnew) - FDw(IXHi,IYLo,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXHi,IYLo,IZLo_w,Ind4Dnew) - Iyhz = ( FDw(IXHi,IYHi,IZHi_w,Ind4Dnew) - FDw(IXHi,IYHi,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXHi,IYHi,IZLo_w,Ind4Dnew) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzn = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - -!FIXME:delete -! FD_GetWindSpeed%Velocity(3) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - TempWindSpeed(3) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - - ! Copy the windspeed info to the output - FD_GetWindSpeed = TempWindSpeed - - !------------------------------------------------------------------------------------------------- - ! Set the previous time here to compare with later... - !------------------------------------------------------------------------------------------------- - PrevTime = Time - - RETURN - -END FUNCTION FD_GetWindSpeed -!==================================================================================================== -SUBROUTINE FD_Terminate( ErrStat ) -! This subroutine deallocates arrays, closes files, and un-sets the initialization flag. -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors; non-zero otherwise - - - CLOSE( FDunit ) - - ErrStat = 0 - - IF ( ALLOCATED( FDu ) ) DEALLOCATE( FDu, STAT=ErrStat ) - IF ( ALLOCATED( FDv ) ) DEALLOCATE( FDv, STAT=ErrStat ) - IF ( ALLOCATED( FDw ) ) DEALLOCATE( FDw, STAT=ErrStat ) - IF ( ALLOCATED( FDuData ) ) DEALLOCATE( FDuData, STAT=ErrStat ) - IF ( ALLOCATED( FDvData ) ) DEALLOCATE( FDvData, STAT=ErrStat ) - IF ( ALLOCATED( FDwData ) ) DEALLOCATE( FDwData, STAT=ErrStat ) - IF ( ALLOCATED( Times4D ) ) DEALLOCATE( Times4D, STAT=ErrStat ) - IF ( ALLOCATED( Times4DIx ) ) DEALLOCATE( Times4DIx, STAT=ErrStat ) - IF ( ALLOCATED( AdvFiles ) ) DEALLOCATE( AdvFiles, STAT=ErrStat ) - - Initialized = .FALSE. - -END SUBROUTINE FD_Terminate -!==================================================================================================== -END MODULE FDWind diff --git a/modules/inflowwind/src/IfW_4Dext.f90 b/modules/inflowwind/src/IfW_4Dext.f90 deleted file mode 100644 index dea5bd8e44..0000000000 --- a/modules/inflowwind/src/IfW_4Dext.f90 +++ /dev/null @@ -1,369 +0,0 @@ -!> This module is a placeholder for any user defined wind types. The end user can use this as a template for their code. -!! @note This module does not need to exactly conform to the FAST Modularization Framework standards. Three routines are required -!! though: -!! -- IfW_4Dext_Init -- Load or create any wind data. Only called at the start of FAST. -!! -- IfW_4Dext_CalcOutput -- This will be called at each timestep with a series of data points to give wind velocities at. -!! -- IfW_4Dext_End -- clear out any stored stuff. Only called at the end of FAST. -MODULE IfW_4Dext -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_4Dext_Types - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_4Dext_Ver = ProgDesc( 'IfW_4Dext', '', '' ) - - PUBLIC :: IfW_4Dext_Init - PUBLIC :: IfW_4Dext_End - PUBLIC :: IfW_4Dext_CalcOutput - -CONTAINS - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> A subroutine to initialize the UserWind module. This routine will initialize the module. -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_4Dext_Init(InitInp, p, m, Interval, InitOut, ErrStat, ErrMsg) - - - IMPLICIT NONE - - ! Passed Variables - - TYPE(IfW_4Dext_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization - TYPE(IfW_4Dext_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(IfW_4Dext_MiscVarType), INTENT( OUT) :: m !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_4Dext_InitOutputType), INTENT( OUT) :: InitOut !< Initial output - - REAL(DbKi), INTENT(IN ) :: Interval !< Do not change this!! - - - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error. See NWTC_Library info for ErrID_* levels. - - ! local variables - ! Put local variables used during initializing your wind here. DO NOT USE GLOBAL VARIABLES EVER! - INTEGER(IntKi) :: UnitWind ! Use this unit number if you need to read in a file. - - ! Temporary variables for error handling - INTEGER(IntKi) :: ErrStat2 ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_Init' - - !------------------------------------------------------------------------------------------------- - ! Set the Error handling variables - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData. - !------------------------------------------------------------------------------------------------- - p%n = InitInp%n ! number of points on the evenly-spaced grid (in each direction) - p%delta = InitInp%delta ! distance between consecutive grid points in each direction - p%pZero = InitInp%pZero ! fixed location of first XYZ grid point (i.e., XYZ coordinates of m%V(:,1,1,1,:)) - - - !------------------------------------------------------------------------------------------------- - ! Set the MiscVars: - ! Note that these could be considered inputs, but that would mean many extra copies of potentially - ! large arrays. I am using misc vars to avoid unnecessary duplication. The external code must - ! set values for m%TgridStart and m%V. - !------------------------------------------------------------------------------------------------- - m%TgridStart = 0.0_ReKi ! (time) location of first time grid point (i.e., XYZ coordinates of m%V(:,:,:,:,1)) - should be set with m%V - - call AllocAry( m%V, 3, p%n(1), p%n(2), p%n(3), p%n(4), 'V', ErrStat2, ErrMsg2 ) !uvw at x,y,z,t coordinate - call SetErrStat(ErrStat, ErrMsg, ErrStat2, ErrMsg2, RoutineName) - if (ErrStat >= AbortErrLev) return - m%V = 0.0_SiKi - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information. Set any outputs here. - !------------------------------------------------------------------------------------------------- - - InitOut%Ver = IfW_4Dext_Ver - - RETURN - -END SUBROUTINE IfW_4Dext_Init - -!==================================================================================================== - -!------------------------------------------------------------------------------------------------- -!> This routine and its subroutines calculate the wind velocity at a set of points given in -!! PositionXYZ. The UVW velocities are returned in OutData%Velocity -!------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_4Dext_CalcOutput(Time, PositionXYZ, p, Velocity, m, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_4Dext_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_4Dext_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - TYPE(IfW_4Dext_MiscVarType), INTENT(IN ) :: m !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! local counters - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points passed in - - ! temporary variables - INTEGER(IntKi) :: ErrStat2 ! temporary error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - - - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,DIM=2) - - - ! Step through all the positions and get the velocities - DO PointNum = 1, NumPoints - - - ! Calculate the velocity for the position - Velocity(:,PointNum) = Interp4D(Time, PositionXYZ(:,PointNum), p, m, ErrStat2, ErrMsg2 ) - - - ! Error handling - IF (ErrStat2 /= ErrID_None) THEN ! adding this so we don't have to convert numbers to strings every time - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//" [position=("// & - TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in wind-file coordinates]" ) - IF (ErrStat >= AbortErrLev) RETURN - END IF - - - ENDDO - - RETURN - -END SUBROUTINE IfW_4Dext_CalcOutput - -!==================================================================================================== -!> This routine interpolates a 4-d dataset. -!! This method is described here: http://rjwagner49.com/Mathematics/Interpolation.pdf -FUNCTION Interp4D( Time, Position, p, m, ErrStat, ErrMsg ) - - ! I/O variables - - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: Position(3) !< Array of XYZ coordinates, 3 - TYPE(IfW_4Dext_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_4Dext_MiscVarType), INTENT(IN ) :: m !< Misc variables for optimization (not copied in glue code) - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - REAL(SiKi) :: Interp4D(3) !< The interpolated UVW from m%V - - CHARACTER(*), PARAMETER :: RoutineName = 'Interp4D' - - ! Local variables - - INTEGER(IntKi) :: i ! loop counter - INTEGER(IntKi) :: ic ! wind-component counter - - INTEGER(IntKi) :: Indx_Lo(4) ! index associated with lower bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) - INTEGER(IntKi) :: Indx_Hi(4) ! index associated with upper bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) - - REAL(SiKi) :: isopc(4) ! isoparametric coordinates - REAL(SiKi) :: N(16) ! size 2^n - REAL(SiKi) :: u(16) ! size 2^n - REAL(ReKi) :: Tmp ! temporary fraction of distance between two grid points - - - Interp4D = 0.0_ReKi - ErrStat = ErrID_None - ErrMsg = "" - - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding indices for XYZ position - !------------------------------------------------------------------------------------------------- - do i=1,3 - Tmp = (Position(i) - p%pZero(i)) / p%delta(i) - Indx_Lo(i) = INT( Tmp ) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 - isopc(i) = 2.0_ReKi * (Tmp - REAL(Indx_Lo(i) - 1_IntKi, ReKi)) - 1.0_ReKi ! convert to value between -1 and 1 - enddo - - !------------------------------------------------------------------------------------------------- - ! Find the bounding indices for time - !------------------------------------------------------------------------------------------------- - i=4 - Tmp = (Time - m%TgridStart) / p%delta(i) - Indx_Lo(i) = INT( Tmp ) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 - isopc(i) = 2.0_ReKi * (Tmp - REAL(Indx_Lo(i) - 1_IntKi, ReKi)) - 1.0_ReKi ! convert to value between -1 and 1 - IF ( ( Indx_Lo(i) == p%n(i) ) ) then - if ( abs(isopc(i) + 1.0_SiKi) < 0.001_SiKi ) THEN ! Allow for the special case where Time = TgridStart + deltat*( n_high_low - 1 ) - Indx_Lo(i) = Indx_Lo(i) - 1 - isopc(i) = 1.0_SiKi - end if - END IF - - !------------------------------------------------------------------------------------------------- - ! to verify that we don't extrapolate, make sure isopc is bound between -1 and 1 (effectively nearest neighbor) - !------------------------------------------------------------------------------------------------- - DO i=1,size(isopc) - isopc(i) = min( 1.0_SiKi, isopc(i) ) - isopc(i) = max(-1.0_SiKi, isopc(i) ) - END DO - - !------------------------------------------------------------------------------------------------- - ! also make sure we're not outside the bounds - !------------------------------------------------------------------------------------------------- - DO i=1,size(p%n) - IF (Indx_Lo(i) <= 0) THEN - Indx_Lo(i) = 1 - CALL SetErrStat(ErrID_Fatal,'Outside the grid bounds.',ErrStat,ErrMsg,RoutineName) !error out if x,y,z, or time is outside the lower bounds - RETURN - ELSEIF (Indx_Lo(i) >= p%n(i) ) THEN - Indx_Lo(i) = max( p%n(i) - 1, 1 ) ! make sure it's a valid index - CALL SetErrStat(ErrID_Fatal,'Outside the grid bounds.',ErrStat,ErrMsg,RoutineName) !error out if x,y,z, or time is outside the upper bounds - RETURN - END IF - Indx_Hi(i) = min( Indx_Lo(i) + 1, p%n(i) ) ! make sure it's a valid index - END DO - - !------------------------------------------------------------------------------------------------- - ! compute weighting factors - !------------------------------------------------------------------------------------------------- - - N( 1) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 2) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 3) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 4) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 5) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 6) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 7) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 8) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 9) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(10) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N(11) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(12) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N(13) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(14) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N(15) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(16) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N = N / REAL( SIZE(N), SiKi ) ! normalize - - !------------------------------------------------------------------------------------------------- - ! interpolate - !------------------------------------------------------------------------------------------------- - - do ic=1,3 - - u( 1) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4) ) - u( 2) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4) ) - u( 3) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4) ) - u( 4) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4) ) - u( 5) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4) ) - u( 6) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4) ) - u( 7) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4) ) - u( 8) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4) ) - u( 9) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4) ) - u(10) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4) ) - u(11) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4) ) - u(12) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4) ) - u(13) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4) ) - u(14) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4) ) - u(15) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4) ) - u(16) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4) ) - - Interp4D(ic) = SUM ( N * u ) - - end do - -END FUNCTION Interp4D - -!---------------------------------------------------------------------------------------------------- -!> This routine deallocates any memory in the FDext module. -SUBROUTINE IfW_4Dext_End( ParamData, MiscVars, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_4Dext_End" - - - ! Passed Variables - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_4Dext_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the misc data - - CALL IfW_4Dext_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - -END SUBROUTINE IfW_4Dext_End -!==================================================================================================== -END MODULE IfW_4Dext diff --git a/modules/inflowwind/src/IfW_4Dext.txt b/modules/inflowwind/src/IfW_4Dext.txt deleted file mode 100644 index 5a4543981e..0000000000 --- a/modules/inflowwind/src/IfW_4Dext.txt +++ /dev/null @@ -1,39 +0,0 @@ -################################################################################################################################### -# Registry for IfW_UserWind, creates MODULE IfW_UserWind_Types -# Module IfW_UserWind_Types contains all of the user-defined types needed in IfW_UserWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt - - -######################### - -typedef IfW_4Dext/IfW_4Dext InitInputType IntKi n 4 - - "number of grid points in the x, y, z, and t directions" - -typedef ^ InitInputType ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" -typedef ^ InitInputType ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information of this submodule" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType SiKi V ::::: - - "this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt]; it is stored as a miscVar instead of an input so that we don't have 4 copies of a very large field" - -typedef ^ MiscVarType ReKi TgridStart - - - "this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1))" s - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IntKi n 4 - - "number of evenly-spaced grid points in the x, y, z, and t directions" - -typedef ^ ParameterType ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" -typedef ^ ParameterType ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" - - - - diff --git a/modules/inflowwind/src/IfW_4Dext_Types.f90 b/modules/inflowwind/src/IfW_4Dext_Types.f90 deleted file mode 100644 index a764d703ad..0000000000 --- a/modules/inflowwind/src/IfW_4Dext_Types.f90 +++ /dev/null @@ -1,879 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_4Dext_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_4Dext_Types -!................................................................................................................................. -! This file is part of IfW_4Dext. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_4Dext. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_4Dext_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_4Dext_InitInputType ======= - TYPE, PUBLIC :: IfW_4Dext_InitInputType - INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of grid points in the x, y, z, and t directions [-] - REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] - REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] - END TYPE IfW_4Dext_InitInputType -! ======================= -! ========= IfW_4Dext_InitOutputType ======= - TYPE, PUBLIC :: IfW_4Dext_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information of this submodule [-] - END TYPE IfW_4Dext_InitOutputType -! ======================= -! ========= IfW_4Dext_MiscVarType ======= - TYPE, PUBLIC :: IfW_4Dext_MiscVarType - REAL(SiKi) , DIMENSION(:,:,:,:,:), ALLOCATABLE :: V !< this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt]; it is stored as a miscVar instead of an input so that we don't have 4 copies of a very large field [-] - REAL(ReKi) :: TgridStart !< this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1)) [s] - END TYPE IfW_4Dext_MiscVarType -! ======================= -! ========= IfW_4Dext_ParameterType ======= - TYPE, PUBLIC :: IfW_4Dext_ParameterType - INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of evenly-spaced grid points in the x, y, z, and t directions [-] - REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] - REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] - END TYPE IfW_4Dext_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_4Dext_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_4Dext_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%n = SrcInitInputData%n - DstInitInputData%delta = SrcInitInputData%delta - DstInitInputData%pZero = SrcInitInputData%pZero - END SUBROUTINE IfW_4Dext_CopyInitInput - - SUBROUTINE IfW_4Dext_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_4Dext_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyInitInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_4Dext_DestroyInitInput - - SUBROUTINE IfW_4Dext_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + SIZE(InData%n) ! n - Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta - Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) - IntKiBuf(Int_Xferred) = InData%n(i1) - Int_Xferred = Int_Xferred + 1 - END DO - DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) - ReKiBuf(Re_Xferred) = InData%delta(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) - ReKiBuf(Re_Xferred) = InData%pZero(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_PackInitInput - - SUBROUTINE IfW_4Dext_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - i1_l = LBOUND(OutData%n,1) - i1_u = UBOUND(OutData%n,1) - DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) - OutData%n(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - i1_l = LBOUND(OutData%delta,1) - i1_u = UBOUND(OutData%delta,1) - DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) - OutData%delta(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%pZero,1) - i1_u = UBOUND(OutData%pZero,1) - DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) - OutData%pZero(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_UnPackInitInput - - SUBROUTINE IfW_4Dext_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_4Dext_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_4Dext_CopyInitOutput - - SUBROUTINE IfW_4Dext_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_4Dext_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyInitOutput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_4Dext_DestroyInitOutput - - SUBROUTINE IfW_4Dext_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_4Dext_PackInitOutput - - SUBROUTINE IfW_4Dext_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_4Dext_UnPackInitOutput - - SUBROUTINE IfW_4Dext_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcMiscData%V)) THEN - i1_l = LBOUND(SrcMiscData%V,1) - i1_u = UBOUND(SrcMiscData%V,1) - i2_l = LBOUND(SrcMiscData%V,2) - i2_u = UBOUND(SrcMiscData%V,2) - i3_l = LBOUND(SrcMiscData%V,3) - i3_u = UBOUND(SrcMiscData%V,3) - i4_l = LBOUND(SrcMiscData%V,4) - i4_u = UBOUND(SrcMiscData%V,4) - i5_l = LBOUND(SrcMiscData%V,5) - i5_u = UBOUND(SrcMiscData%V,5) - IF (.NOT. ALLOCATED(DstMiscData%V)) THEN - ALLOCATE(DstMiscData%V(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%V = SrcMiscData%V -ENDIF - DstMiscData%TgridStart = SrcMiscData%TgridStart - END SUBROUTINE IfW_4Dext_CopyMisc - - SUBROUTINE IfW_4Dext_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyMisc' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - -IF (ALLOCATED(MiscData%V)) THEN - DEALLOCATE(MiscData%V) -ENDIF - END SUBROUTINE IfW_4Dext_DestroyMisc - - SUBROUTINE IfW_4Dext_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! V allocated yes/no - IF ( ALLOCATED(InData%V) ) THEN - Int_BufSz = Int_BufSz + 2*5 ! V upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%V) ! V - END IF - Re_BufSz = Re_BufSz + 1 ! TgridStart - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%V) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,3) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,4) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,4) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,5) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,5) - Int_Xferred = Int_Xferred + 2 - - DO i5 = LBOUND(InData%V,5), UBOUND(InData%V,5) - DO i4 = LBOUND(InData%V,4), UBOUND(InData%V,4) - DO i3 = LBOUND(InData%V,3), UBOUND(InData%V,3) - DO i2 = LBOUND(InData%V,2), UBOUND(InData%V,2) - DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) - ReKiBuf(Re_Xferred) = InData%V(i1,i2,i3,i4,i5) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END DO - END IF - ReKiBuf(Re_Xferred) = InData%TgridStart - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_4Dext_PackMisc - - SUBROUTINE IfW_4Dext_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i4_l = IntKiBuf( Int_Xferred ) - i4_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i5_l = IntKiBuf( Int_Xferred ) - i5_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%V)) DEALLOCATE(OutData%V) - ALLOCATE(OutData%V(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i5 = LBOUND(OutData%V,5), UBOUND(OutData%V,5) - DO i4 = LBOUND(OutData%V,4), UBOUND(OutData%V,4) - DO i3 = LBOUND(OutData%V,3), UBOUND(OutData%V,3) - DO i2 = LBOUND(OutData%V,2), UBOUND(OutData%V,2) - DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) - OutData%V(i1,i2,i3,i4,i5) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END DO - END IF - OutData%TgridStart = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_4Dext_UnPackMisc - - SUBROUTINE IfW_4Dext_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%n = SrcParamData%n - DstParamData%delta = SrcParamData%delta - DstParamData%pZero = SrcParamData%pZero - END SUBROUTINE IfW_4Dext_CopyParam - - SUBROUTINE IfW_4Dext_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyParam' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_4Dext_DestroyParam - - SUBROUTINE IfW_4Dext_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + SIZE(InData%n) ! n - Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta - Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) - IntKiBuf(Int_Xferred) = InData%n(i1) - Int_Xferred = Int_Xferred + 1 - END DO - DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) - ReKiBuf(Re_Xferred) = InData%delta(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) - ReKiBuf(Re_Xferred) = InData%pZero(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_PackParam - - SUBROUTINE IfW_4Dext_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - i1_l = LBOUND(OutData%n,1) - i1_u = UBOUND(OutData%n,1) - DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) - OutData%n(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - i1_l = LBOUND(OutData%delta,1) - i1_u = UBOUND(OutData%delta,1) - DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) - OutData%delta(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%pZero,1) - i1_u = UBOUND(OutData%pZero,1) - DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) - OutData%pZero(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_UnPackParam - -END MODULE IfW_4Dext_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_BladedFFWind.f90 b/modules/inflowwind/src/IfW_BladedFFWind.f90 deleted file mode 100644 index c2e54892a4..0000000000 --- a/modules/inflowwind/src/IfW_BladedFFWind.f90 +++ /dev/null @@ -1,1925 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is shifted by half the grid width to account for turbine yaw (so that data in the X -!! direction actually starts at -1*ParamData%FFYHWid meters). -MODULE IfW_BladedFFWind -!! -!! Created 25-Sep-2009 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Modified to use NWTC_Library v. 2.0 -!! -- Note: Jacobians are not included in this version. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_BladedFFWind_Types - USE IfW_FFWind_Base - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_BladedFFWind_Ver = ProgDesc( 'IfW_BladedFFWind', '', '' ) - - PUBLIC :: IfW_BladedFFWind_Init - PUBLIC :: IfW_BladedFFWind_End - PUBLIC :: IfW_BladedFFWind_CalcOutput - - - - -CONTAINS -!==================================================================================================== -!> This routine is used read the full-field turbulence data. -!! 09/25/1997 - Created by M. Buhl from GETFILES in ViewWind. -!! 09/23/2009 - modified by B. Jonkman: this subroutine was split into several subroutines (was ReadFF) -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_BladedFFWind_Init(InitInp, ParamData, MiscVars, InitOutData, ErrStat, ErrMsg) - - CHARACTER(*), PARAMETER :: RoutineName="IfW_BladedFFWind_Init" - - ! Passed Variables - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization data passed to the module - TYPE(IfW_BladedFFWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - TYPE(IfW_BladedFFWind_MiscVarType), INTENT( OUT) :: MiscVars !< misc/optimization data (storage for the main data) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - REAL(ReKi) :: TI(3) - REAL(ReKi) :: ScaleFactors(3) - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - TYPE(IfW_FFWind_InitInputType) :: FF_InitInp ! Initialization input data for FF scaling - - - - ErrMsg = '' - ErrStat = ErrID_None - - - CALL ReadFiles(InitInp, FF_InitInp, InitOutData, ParamData, TI, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - !------------------------------------------------------------------------------------------------- - ! If the wind file has zero-mean and unit standard deviation (native Bladed format), scale the data: - !------------------------------------------------------------------------------------------------- - ParamData%FF%AddMeanAfterInterp = .false. - ParamData%FF%Z0 = FF_InitInp%Z0 - ParamData%FF%PLExp = FF_InitInp%PLExp - ParamData%FF%VLinShr = FF_InitInp%VLinShr - ParamData%FF%HLinShr = FF_InitInp%HLinShr - ParamData%FF%RefLength = FF_InitInp%RefLength - - if (InitInp%NativeBladedFmt) then - ParamData%FF%InterpTower = .true. - ParamData%FF%AddMeanAfterInterp = .true. - ParamData%FF%WindProfileType = FF_InitInp%WindProfileType - - - ! Validate scaling data if we've got native-Bladed format - CALL FFWind_ValidateInput(FF_InitInp, ParamData%FF%NFFComp, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! scale to requested TI (or use requested scale factors) - call ScaleTurbulence(FF_InitInp, ParamData%FF%FFData(:,:,:,1:ParamData%FF%NFFSteps), ScaleFactors, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - ! Add the mean wind speed to the u component. - if (.not. ParamData%FF%AddMeanAfterInterp) call AddMeanVelocity(FF_InitInp, ParamData%FF%GridBase, 1.0_ReKi/ParamData%FF%InvFFZD, 1.0_ReKi/ParamData%FF%InvFFYD, ParamData%FF%FFData) - else - ParamData%FF%InterpTower = .false. - ParamData%FF%WindProfileType = WindProfileType_None - end if - - - IF (ParamData%FF%Periodic) THEN - ParamData%FF%InitXPosition = 0 ! start at the hub - ParamData%FF%TotalTime = ParamData%FF%NFFSteps*ParamData%FF%FFDTime - ELSE - ParamData%FF%InitXPosition = ParamData%FF%FFYHWid ! start half the grid width ahead of the turbine - ParamData%FF%TotalTime = (ParamData%FF%NFFSteps-1)*ParamData%FF%FFDTime - ENDIF - - ! overwrite the offset - IF (InitInp%NativeBladedFmt) THEN - ParamData%FF%InitXPosition = FF_InitInp%XOffset - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_BladedFFWind_Ver - InitOutdata%TI = TI - - - - !------------------------------------------------------------------------------------------------- - ! Write to the summary file - !------------------------------------------------------------------------------------------------- - - IF ( InitInp%SumFileUnit > 0 ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'Bladed-style wind type. Read by InflowWind sub-module '// & - TRIM(IfW_BladedFFWind_Ver%Name)//' '//TRIM(IfW_BladedFFWind_Ver%Ver) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) TRIM(TmpErrMsg) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' FileName: '//TRIM(InitInp%WindFileName) - WRITE(InitInp%SumFileUnit,'(A34,I3)', IOSTAT=TmpErrStat) ' Binary file format id: ',ParamData%FF%WindFileFormat - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',ParamData%FF%RefHt - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Timestep (s): ',ParamData%FF%FFDTime - WRITE(InitInp%SumFileUnit,'(A34,I12)', IOSTAT=TmpErrStat) ' Number of timesteps: ',ParamData%FF%NFFSteps - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Mean windspeed (m/s): ',ParamData%FF%MeanFFWS - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Characteristic TI: [ '// & - TRIM(Num2LStr(TI(1)))//', '//TRIM(Num2LStr(TI(2)))//', '//TRIM(Num2LStr(TI(3)))//' ] ' - WRITE(InitInp%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile is periodic: ',ParamData%FF%Periodic - WRITE(InitInp%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile includes tower: ',ParamData%FF%NTGrids > 0 - - IF ( ParamData%FF%Periodic ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%TotalTime))//' ]' - ELSE ! Shift the time range to compensate for the shifting of the wind grid - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' : '// & - TRIM(Num2LStr(ParamData%FF%TotalTime-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' ]' - ENDIF - - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Y range (m): [ '// & - TRIM(Num2LStr(-ParamData%FF%FFYHWid))//' : '//TRIM(Num2LStr(ParamData%FF%FFYHWid))//' ]' - - IF ( ParamData%FF%NTGrids > 0 ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ELSE - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(ParamData%FF%RefHt - ParamData%FF%FFZHWid))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ENDIF - - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - ENDIF - - - - - RETURN - -END SUBROUTINE IfW_BladedFFWind_Init -!======================================================================================================== -SUBROUTINE ReadFiles(InitInp, FF_InitInp, InitOut, ParamData, TI, ErrStat, ErrMsg) - - CHARACTER(*), PARAMETER :: RoutineName="ReadFiles" - - ! Passed Variables - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization data passed to the module - TYPE(IfW_FFWind_InitInputType), INTENT( OUT) :: FF_InitInp !< Initialization data for scaling - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: InitOut !< Initial output - TYPE(IfW_BladedFFWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - REAL(ReKi) , INTENT( OUT) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ! Local Variables: - - REAL(ReKi) :: BinTI (3) ! turbulence intensities of the wind components as defined in the FF binary file, not necessarially the actual TI - REAL(ReKi) :: NatTI (3) ! turbulence intensities of the wind components as defined in the native FF summary file - REAL(ReKi) :: UBar - REAL(ReKi) :: ZCenter - - INTEGER(IntKi) :: UnitWind ! Unit number for the InflowWind input file - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(IntKi) :: I - LOGICAL :: CWise - LOGICAL :: LHR ! Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) - - LOGICAL :: Exists - CHARACTER( 1028 ) :: SumFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. - CHARACTER( 1028 ) :: TwrFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. - - CHARACTER(1024) :: BinFileName - CHARACTER(1024) :: PriPath - - - ErrMsg = '' - ErrStat = ErrID_None - - - if (InitInp%NativeBladedFmt) then - call Read_NativeBladedSummary(InitInp%WindFileName, FF_InitInp%PLExp, FF_InitInp%VLinShr, FF_InitInp%HLinShr, FF_InitInp%RefLength, & - NatTI, ParamData%FF%MeanFFWS, ParamData%FF%RefHt, InitOut%PropagationDir, InitOut%VFlowAngle, & - BinFileName, FF_InitInp%XOffset, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - if (pathIsRelative(BinFileName)) then - CALL GetPath( InitInp%WindFileName, PriPath ) ! Binary file will be relative to the path where the primary input file is located. - BinFileName = TRIM(PriPath)//TRIM(BinFileName) - end if - - IF ( InitInp%FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data - IF ( InitInp%TurbineID == 0 ) THEN ! .TRUE. for the FAST.Farm low-resolution domain - BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'Low' - ELSE ! FAST.Farm high-resolution domain(s) - BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) - ENDIF - ENDIF - - ! default values for Bladed Format - CWise = .false. - ZCenter = ParamData%FF%RefHt - ParamData%FF%Periodic = .true. - - FF_InitInp%ScaleMethod = ScaleMethod_StdDev - FF_InitInp%SigmaF = NatTI * ParamData%FF%MeanFFWS - FF_InitInp%sf = FF_InitInp%SigmaF -! FF_InitInp%ScaleMethod = ScaleMethod_Direct ! Bladed files should have std of 1, so we'll just multiply (closer to what Bladed does) - - FF_InitInp%RefHt = ParamData%FF%RefHt - FF_InitInp%URef = ParamData%FF%MeanFFWS - FF_InitInp%WindProfileType = WindProfileType_PL ! it could also have logarithmic, but I'm going to leave that off for now - - TI = 100.0_ReKi - UBar = 0.0_ReKi - LHR = .true. - - else - InitOut%PropagationDir = 0.0_ReKi - InitOut%VFlowAngle = 0.0_ReKi - FF_InitInp%VLinShr = 0.0_ReKi - FF_InitInp%HLinShr = 0.0_ReKi - FF_InitInp%RefLength = 1.0_ReKi - - BinFileName = InitInp%WindFileName - end if - - - ! Get a unit number to use - - CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !---------------------------------------------------------------------------------------------- - ! Open the binary file, read its "header" (first 2-byte integer) to determine what format - ! binary file it is, and close it. - !---------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! Read the first binary integer from the file to get info on the type. - ! Cannot use library read routines since this is a 2-byte integer. - READ ( UnitWind, IOSTAT=TmpErrStat ) Dum_Int2 - CLOSE( UnitWind ) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat(ErrID_Fatal,' Error reading first binary integer from file "'//TRIM(BinFileName)//'."', & - ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - - - !---------------------------------------------------------------------------------------------- - ! Read the files to get the required FF data. - !---------------------------------------------------------------------------------------------- - - ! Store the binary format information so the InflowWind code can use it. - ! Also changes to IntKi from INT(2) to compare in the SELECT below - ParamData%FF%WindFileFormat = Dum_Int2 - - - SELECT CASE (ParamData%FF%WindFileFormat) - - CASE ( -1, -2, -3, -99 ) ! Bladed-style binary format - - IF (.not. InitInp%NativeBladedFmt) THEN - - !........................................................................................... - ! Create full-field summary file name from binary file root name. Also get tower file - ! name. - !........................................................................................... - - CALL GetRoot(BinFileName, SumFile) - - TwrFile = TRIM(SumFile)//'.twr' - SumFile = TRIM(SumFile)//'.sum' - - - !........................................................................................... - ! Read the summary file to get necessary scaling information - !........................................................................................... - - CALL Read_Summary_FF (UnitWind, TRIM(SumFile), CWise, ZCenter, TI, UBar, ParamData%FF%RefHt, ParamData%FF%Periodic, LHR, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - END IF - - - !........................................................................................... - ! Open the binary file and read its header - !........................................................................................... - - CALL OpenBInpFile (UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - IF ( Dum_Int2 == -99 ) THEN ! Newer-style BLADED format - CALL Read_Bladed_FF_Header1 (UnitWind, BinTI, ParamData%FF, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - ! If the TIs are also in the binary file (BinTI > 0), - ! use those numbers instead of ones from the summary file - - if (.not. InitInp%NativeBladedFmt) then - DO I =1,ParamData%FF%NFFComp - IF ( BinTI(I) > 0 ) TI(I) = BinTI(I) - ENDDO - end if - - - ELSE - CALL Read_Bladed_FF_Header0 (UnitWind, ParamData%FF, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) ! Older-style BLADED format - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - ENDIF - - - - !........................................................................................... - ! Let's see if the summary and binary FF wind files go together before continuing. - !........................................................................................... - - IF (.not. InitInp%NativeBladedFmt) THEN - IF ( ABS( UBar - ParamData%FF%MeanFFWS ) > 0.1 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error: Incompatible mean hub-height wind speeds in FF wind files. '//& - '(Check that the .sum and .wnd files were generated together.)', ErrStat, ErrMsg, RoutineName ) - CLOSE ( UnitWind ) - RETURN - ENDIF - - END IF - - !........................................................................................... - ! Calculate the height of the bottom of the grid - !........................................................................................... - - ParamData%FF%GridBase = ZCenter - ParamData%FF%FFZHWid ! the location, in meters, of the bottom of the grid - IF ( ParamData%FF%GridBase < 0.0_ReKi ) THEN - call SetErrStat( ErrID_Severe, 'WARNING: The bottom of the grid is located at a height of '//& - TRIM( Num2LStr(ParamData%FF%GridBase) )//' meters, which is below the ground.'//& - ' Winds below the ground will be set to 0.', ErrStat,ErrMsg, RoutineName) - END IF - - !........................................................................................... - ! Read the binary grids (converted to m/s) and close the file - !........................................................................................... - - CALL Read_Bladed_Grids( UnitWind, InitInp%NativeBladedFmt, CWise, LHR, TI, ParamData%FF, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - CLOSE ( UnitWind ) - if (InitInp%NativeBladedFmt) TI = NatTI*100.0_ReKi ! report these TI for the native Bladed format in percent - - IF ( ErrStat >= AbortErrLev ) RETURN - - !........................................................................................... - ! Read the tower points file - !........................................................................................... - - IF ( InitInp%TowerFileExist .AND. .NOT. InitInp%NativeBladedFmt) THEN ! If we specified a tower file - INQUIRE ( FILE=TRIM(TwrFile) , EXIST=Exists ) - - ! Double check that the tower file exists and read it. If it was requested but doesn't exist, - ! throw fatal error and exit. - IF ( Exists ) THEN - CALL Read_FF_Tower( UnitWind, ParamData%FF, TwrFile, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - ELSE - CALL SetErrStat( ErrID_Fatal, ' Tower file '//TRIM(TwrFile)//' specified for Bladed full-field '// & - 'wind files does not exist.', ErrStat, ErrMsg, RoutineName) - CLOSE ( UnitWind ) - RETURN - ENDIF - ELSE - ParamData%FF%NTGrids = 0_IntKi - ENDIF - - - CASE DEFAULT - CALL SetErrStat( ErrID_Fatal, ' This is not a bladed-style binary wind file (binary format identifier: '// & - TRIM(Num2LStr(ParamData%FF%WindFileFormat))//'. This might be a TurbSim binary wind file.', & - ErrStat, ErrMsg, RoutineName ) - RETURN - - END SELECT - -END SUBROUTINE ReadFiles - - !==================================================================================================== - !> This subroutine reads the text summary file to get normalizing parameters, the location of the - !! grid, and the direction the grid was written to the binary file - !! - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Summary_FF ( UnitWind, FileName, CWise, ZCenter, TI, UBar, RefHt, Periodic, LHR, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Summary_FF" - - - ! Passed variables - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number for the file to open - CHARACTER(*), INTENT(IN ) :: FileName !< name of the summary file - LOGICAL, INTENT( OUT) :: CWise !< rotation (for reading the order of the binary data) - REAL(ReKi), INTENT( OUT) :: ZCenter !< the height at the center of the grid - REAL(ReKi), INTENT( OUT) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - REAL(ReKi), INTENT( OUT) :: UBar !< mean (advection) wind speed - REAL(ReKi), INTENT( OUT) :: RefHt !< Reference height - LOGICAL, INTENT( OUT) :: Periodic !< rotation (for reading the order of the binary data) - LOGICAL, INTENT( OUT) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< returns 0 if no error encountered in the subroutine - CHARACTER(*), INTENT( OUT) :: ErrMsg !< holds the error messages - - ! Local variables - REAL(ReKi) :: ZGOffset ! The vertical offset of the turbine on rectangular grid (allows turbulence not centered on turbine hub) - - INTEGER, PARAMETER :: NumStrings = 7 ! number of strings to be looking for in the file - - INTEGER(IntKi) :: FirstIndx ! The first character of a line where data is located - INTEGER(IntKi) :: I ! A loop counter - INTEGER(IntKi) :: LastIndx ! The last character of a line where data is located - INTEGER(IntKi) :: LineCount ! Number of lines that have been read in the file - - LOGICAL :: StrNeeded(NumStrings) ! if the string has been found - - CHARACTER(1024) :: LINE ! temporary storage for reading a line from the file - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - !---------------------------------------------------------------------------------------------- - ! Initialize some variables - !---------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - LineCount = 0 - StrNeeded(:) = .TRUE. - ZGOffset = 0.0 - RefHt = 0.0 - Periodic = .FALSE. - LHR = .FALSE. - CWise = .FALSE. ! default value, in case it is not in this file - - !---------------------------------------------------------------------------------------------- - ! Open summary file. - !---------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnitWind, TRIM( FileName ), TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !---------------------------------------------------------------------------------------------- - ! Read the summary file. - !---------------------------------------------------------------------------------------------- - - ! Here are the strings we're looking for, in this order: - ! 1) 'CLOCKWISE' (optional) - ! 2) 'HUB HEIGHT' - ! 3) (unused; decided we didn't need to read data also stored in the binary file) - ! 4) 'UBAR' - ! 5) 'HEIGHT OFFSET' (optional) - ! 6) 'PERIODIC' (optional) - ! 7) 'BLADED LEFT-HAND RULE' (optional) - - - DO WHILE ( ( ErrStat == ErrID_None ) .AND. StrNeeded(NumStrings) ) - - LineCount = LineCount + 1 - - READ ( UnitWind, '(A)', IOSTAT=TmpErrStat ) LINE - IF ( TmpErrStat /= 0 ) THEN - - ! the "HEIGHT OFFSET", "PERIODIC", and "BLADED LEFT-HAND RULE" parameters are not necessary. We'll assume they are zero/false if we didn't find it. - ! We will also assume "CLOCKWISE" is false if we didn't find it. - IF ( StrNeeded(2) .OR. StrNeeded(4) ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'// & - TRIM(FileName)//'". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName ) - RETURN - ELSE - EXIT - ENDIF - - ENDIF - - CALL Conv2UC ( LINE ) - - - IF ( StrNeeded(2) ) THEN ! if "CLOCKWISE" (StrNeeded(1)) is in the file, we would have already read it. If not, it's not in this file. - - IF ( StrNeeded(1) ) THEN - - !------------------------------------------------------------------------------------------- - ! #1: Get the rotation direction, using the string "CLOCKWISE" - !------------------------------------------------------------------------------------------- - - IF ( INDEX( LINE, 'CLOCKWISE' ) > 0 ) THEN - - READ (LINE, *, IOSTAT = TmpErrStat) CWise ! Look for True/False values - - IF ( TmpErrStat /= 0 ) THEN ! Look for Yes/No values instead - - LINE = ADJUSTL ( LINE ) ! Remove leading spaces from input line - - SELECT CASE (LINE(1:1) ) - CASE ('Y') - CWise = .TRUE. - CASE ('N') - CWise = .FALSE. - CASE DEFAULT - CALL SetErrStat( ErrID_Fatal, ' Error reading rotation direction (CLOCKWISE) from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - END SELECT - CYCLE - - ENDIF ! TmpErrStat /= 0 - StrNeeded(1) = .FALSE. - - ENDIF ! INDEX for "CLOCKWISE" - - END IF - - !------------------------------------------------------------------------------------------- - ! #2: Get the hub height, using the strings "HUB HEIGHT" or "ZHUB" - !------------------------------------------------------------------------------------------- - - IF ( INDEX( LINE, 'HUB HEIGHT' ) > 0 .OR. INDEX( LINE, 'ZHUB' ) > 0 ) THEN - - READ (LINE, *, IOSTAT = TmpErrStat) RefHt - - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading hub height from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - StrNeeded(2) = .FALSE. - - ENDIF !INDEX for "HUB HEIGHT" or "ZHUB" - - ! ELSEIF ( StrNeeded(3) ) THEN - ! - ! !------------------------------------------------------------------------------------------- - ! ! #3: Get the grid width (& height, if available), using the strings "GRID WIDTH" or "RDIAM" - ! ! If GRID HEIGHT is specified, use it, too. -- THIS IS UNNECESSARY AS IT'S STORED IN THE BINARY FILE - ! !------------------------------------------------------------------------------------------- - - ELSEIF ( StrNeeded(4) ) THEN - - !------------------------------------------------------------------------------------------- - ! #4: Get the mean wind speed "UBAR" and turbulence intensities from following lines for - ! scaling Bladed-style FF binary files - !------------------------------------------------------------------------------------------- - - IF ( INDEX( LINE, 'UBAR') > 0 ) THEN - - FirstIndx = INDEX( LINE, '=' ) + 1 ! Look for the equal siqn to find the number we're looking for - - READ ( LINE( FirstIndx:LEN(LINE) ), *, IOSTAT=TmpErrStat ) UBar - - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading UBar binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - DO I = 1,3 - - LineCount = LineCount + 1 - - READ ( UnitWind, '(A)', IOSTAT=TmpErrStat ) LINE - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'//TRIM(FileName)//& - '". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - FirstIndx = INDEX( LINE, '=' ) + 1 ! Read the number between the = and % signs - LastIndx = INDEX( LINE, '%' ) - 1 - - IF ( LastIndx <= FirstIndx ) LastIndx = LEN( LINE ) ! If there's no % sign, read to the end of the line - - READ ( LINE( FirstIndx:LastIndx ), *, IOSTAT=TmpErrStat ) TI(I) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading TI('//TRIM(Num2LStr(I))// & - ') binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDDO !I - - StrNeeded(4) = .FALSE. - - ENDIF - - ELSEIF ( StrNeeded(5) ) THEN - - !------------------------------------------------------------------------------------------- - ! #5: Get the grid "HEIGHT OFFSET", if it exists (in TurbSim). Otherwise, assume it's zero - ! ZGOffset = HH - GridBase - ParamData%FF%FFZHWid - !------------------------------------------------------------------------------------------- - IF ( INDEX( LINE, 'HEIGHT OFFSET' ) > 0 ) THEN - - FirstIndx = INDEX ( LINE, '=' ) + 1 - - READ ( LINE( FirstIndx:LEN(LINE) ), *, IOSTAT=TmpErrStat ) ZGOffset - - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading height offset from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - StrNeeded(5) = .FALSE. - - ENDIF !INDEX for "HEIGHT OFFSET" - - ELSE - - IF ( StrNeeded(6) ) THEN - - !------------------------------------------------------------------------------------------- - ! #6: Get the grid "PERIODIC", if it exists (in TurbSim). Otherwise, assume it's - ! not a periodic file (would only show up if the HEIGHT OFFSET is in the file) - !------------------------------------------------------------------------------------------- - IF ( INDEX( LINE, 'PERIODIC' ) > 0 ) THEN - - Periodic = .TRUE. - StrNeeded(6) = .FALSE. - CYCLE - ENDIF !INDEX for "PERIODIC" - END IF - - IF ( StrNeeded(7) ) THEN - - IF ( INDEX( LINE, 'BLADED LEFT-HAND RULE') > 0 ) THEN - LHR = .TRUE. - StrNeeded(7) = .FALSE. - END IF ! INDEX for "BLADED LEFT-HAND RULE" - - END IF - - ENDIF ! StrNeeded - - ENDDO !WHILE - - !------------------------------------------------------------------------------------------------- - ! Close the summary file - !------------------------------------------------------------------------------------------------- - - CLOSE ( UnitWind ) - - - !------------------------------------------------------------------------------------------------- - ! Calculate the height of the grid center - !------------------------------------------------------------------------------------------------- - - ZCenter = RefHt - ZGOffset - - - END SUBROUTINE Read_Summary_FF - - !==================================================================================================== - !> Reads the binary headers from the turbulence files of the old Bladed variety. Note that - !! because of the normalization, neither ParamData%FF%NZGrids or ParamData%FF%NYGrids are larger than 32 points. - !! 21-Sep-2009 - B. Jonkman, NREL/NWTC. - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Bladed_FF_Header0 (UnitWind, p, NativeBladedFmt, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Bladed_FF_Header0" - - ! Passed Variables: - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number of already-opened wind file - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - LOGICAL, INTENT(IN ) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - - ! Local Variables: - REAL(ReKi) :: FFXDelt - REAL(ReKi) :: FFYDelt - REAL(ReKi) :: FFZDelt - - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(IntKi) :: I - - - ! Temporary Error Handling - INTEGER(IntKi) :: TmpErrStat ! for checking the IOSTAT from a READ or Open statement - - - !------------------------------------------------------------------------------------------------- - ! Initializations - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - - !------------------------------------------------------------------------------------------------- - ! Read the header (file has just been opened) - !------------------------------------------------------------------------------------------------- - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! -NFFC (file ID) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of wind components from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFComp = -1*Dum_Int2 - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! delta z (mm) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFZDelt = 0.001*Dum_Int2 - p%InvFFZD = 1.0/FFZDelt - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! delta y (mm) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dy from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFYDelt = 0.001*Dum_Int2 - p%InvFFYD = 1.0/FFYDelt - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! delta x (mm) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dx from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFXDelt = 0.001*Dum_Int2 - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! half the number of time steps - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of time steps from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFSteps = 2*Dum_Int2 - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! 10 times the mean full-field wind speed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading mean full-field wind speed from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - if (.not. NativeBladedFmt) p%MeanFFWS = 0.1*Dum_Int2 - p%InvMFFWS = 1.0/p%MeanFFWS - p%FFDTime = FFXDelt/p%MeanFFWS - p%FFRate = 1.0/p%FFDTime - - - DO I = 1,5 - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! unused variables: zLu, yLu, xLu, dummy, random seed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 2-byte integers from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - END DO - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! 1000*nz - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading nz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NZGrids = Dum_Int2/1000 - p%FFZHWid = 0.5*FFZDelt*( p%NZGrids - 1 ) ! half the vertical size of the grid - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! 1000*ny - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading ny from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NYGrids = Dum_Int2/1000 - p%FFYHWid = 0.5*FFYDelt*( p%NYGrids - 1 ) - - - IF (p%NFFComp == 3) THEN - - DO I=1,6 - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! unused variables: zLv, yLv, xLv, zLw, yLw, xLw - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 2-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - ENDIF !NFFComp - - - RETURN - - END SUBROUTINE Read_Bladed_FF_Header0 - !==================================================================================================== - !> Reads the binary headers from the turbulence files of the new Bladed variety. - !! 16-May-2002 - Windward Engineering. - !! 21-Sep-2009 - B. Jonkman, NREL. updated to trap errors and add extra parameters for MANN model - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Bladed_FF_Header1 (UnitWind, TI, p, NativeBladedFmt, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Bladed_FF_Header1" - - - ! Passed Variables: - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number of already-opened wind file - REAL(ReKi), INTENT( OUT) :: TI(3) !< turbulence intensity contained in file header - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - LOGICAL, INTENT(IN ) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - - ! Local Variables: - - REAL(ReKi) :: FFXDelt - REAL(ReKi) :: FFYDelt - REAL(ReKi) :: FFZDelt - - REAL(SiKi) :: Dum_Real4 - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(B4Ki) :: Dum_Int4 - - INTEGER(IntKi) :: I - INTEGER(IntKi) :: TurbType - - - ! Temporary Error Handling - INTEGER(IntKi) :: TmpErrStat - - - !------------------------------------------------------------------------------------------------- - ! Initializations - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - TI(:) = -1 !Initialize to -1 (not all models contain TI) - - !------------------------------------------------------------------------------------------------- - ! File reading - !------------------------------------------------------------------------------------------------- - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! -99 (file ID) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading integer from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! turbulence type - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading turbulence type from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - TurbType = Dum_Int2 - - - SELECT CASE (TurbType) - CASE(1, 2) - !---------------------------------------- - !1-component Von Karman (1) or Kaimal (2) - !---------------------------------------- - p%NFFComp = 1 - - CASE(3, 5) - !---------------------------------------- - !3-component Von Karman (3) or IEC-2 - ! Kaimal (5) - !---------------------------------------- - p%NFFComp = 3 - - CASE(4) - !---------------------------------------- - !improved Von Karman - !---------------------------------------- - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! number of components (should be 3) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of components from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFComp = Dum_Int4 - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Latitude (deg) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading latitude from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Roughness length (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading roughness length from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Reference height (m) = Z(1) + GridHeight / 2.0 - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading reference height from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - - DO I = 1,3 - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! TI(u, v, w) (%) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading TI('//'TRIM(Num2LStr(I))'//') from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - TI(I) = Dum_Real4 ! This overwrites the TI read in the summary file - - END DO !I - - - CASE (7, 8) - !---------------------------------------- - ! General Kaimal (7) or Mann model (8) - !---------------------------------------- - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! number of bytes in header - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of header records from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! number of components - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of data from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFComp = Dum_Int4 - - - CASE DEFAULT - - CALL SetErrStat( ErrID_Warn, ' InflowWind does not recognize the full-field turbulence file type ='// & - TRIM(Num2LStr(TurbType))//'.', ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - END SELECT !TurbType - - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! delta z (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFZDelt = Dum_Real4 - p%InvFFZD = 1.0/FFZDelt - - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! delta y (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dy from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFYDelt = Dum_Real4 - p%InvFFYD = 1.0/FFYDelt - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! delta x (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dx from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFXDelt = Dum_Real4 - - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! half the number of time steps - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of time steps from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFSteps = 2*Dum_Int4 - - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! mean full-field wind speed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading mean full-field wind speed from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - if (.not. NativeBladedFmt) p%MeanFFWS = Dum_Real4 - p%InvMFFWS = 1.0/p%MeanFFWS - p%FFDTime = FFXDelt/p%MeanFFWS - p%FFRate = 1.0/p%FFDTime - - - DO I = 1,3 - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: zLu, yLu, xLu - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - END DO - - - DO I = 1,2 - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! unused variables: dummy, random seed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte integers from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - END DO - - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! nz - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading nz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NZGrids = Dum_Int4 - p%FFZHWid = 0.5*FFZDelt*( p%NZGrids - 1 ) ! half the vertical size of the grid - - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! ny - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading ny from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NYGrids = Dum_Int4 - p%FFYHWid = 0.5*FFYDelt*( p%NYGrids - 1 ) - - - IF (p%NFFComp == 3) THEN - - DO I=1,6 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: zLv, yLv, xLv, zLw, yLw, xLw - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - ENDIF !NFFComp - - - - IF ( TurbType == 7 ) THEN ! General Kaimal model - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variable: coherence decay constant - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading coherence decay constant from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: coherence scale parameter in m - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading coherence scale parameter from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ELSE IF ( TurbType == 8 ) THEN ! Mann model - - DO I=1,2 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: shear parameter (gamma), scale length - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,4 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,3 - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,2 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,3 - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,2 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - - ENDIF !TurbType - - - RETURN - - END SUBROUTINE Read_Bladed_FF_Header1 - !==================================================================================================== - !> This subroutine continues reading UnitWind, starting after the headers have been read. - !! It reads the Grids and converts the data to un-normalized wind speeds in m/s. - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Bladed_Grids ( UnitWind, NativeBladedFmt, CWise, LHR, TI, p, ErrStat, ErrMsg ) - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Bladed_Grids" - - ! Passed variables - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number of already-opened wind file - LOGICAL, INTENT(IN ) :: NativeBladedFmt !< whether this data is in native Bladed format (scale to zero mean and unit standard deviation) - LOGICAL, INTENT(IN ) :: CWise !< clockwise flag (determines if y is increasing or decreasing in file) - LOGICAL, INTENT(IN ) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) - REAL(ReKi), INTENT(IN ) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - REAL(ReKi) :: FF_Scale(3) !< used for "un-normalizing" the data - REAL(ReKi) :: FF_Offset(3) !< used for "un-normalizing" the data - - INTEGER(IntKi) :: CFirst - INTEGER(IntKi) :: CLast - INTEGER(IntKi) :: CStep - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(IntKi) :: I - INTEGER(IntKi) :: IC - INTEGER(IntKi) :: IR - INTEGER(IntKi) :: IT - - INTEGER(IntKi) :: TmpNumSteps - - ! Temporary variables for error handling - - INTEGER(IntKi) :: TmpErrStat ! for checking the result of IOSTAT on READ or Open statements - CHARACTER(ErrMsgLen) :: TmpErrMsg - - IF (NativeBladedFmt) THEN - FF_Scale = 0.001_ReKi - FF_Offset = 0.0_ReKi - ELSE - FF_Scale = 0.001_ReKi*p%MeanFFWS*TI/100.0_ReKi - FF_Offset= (/ p%MeanFFWS, 0.0_ReKi, 0.0_ReKi /) ! used for "un-normalizing" the data - END IF - - ! Bladed convention has positive V pointed along negative Y - IF (LHR) THEN ! left-hand rule - FF_Scale(2) = -FF_Scale(2) - END IF - - - !------------------------------------------------------------------------------------------------- - ! Generate an informative message. Initialize the ErrStat. - !------------------------------------------------------------------------------------------------- - ! This could take a while, so we'll write a message to tell users what's going on: - - CALL WrScr( NewLine//' Reading a '//TRIM( Num2LStr(p%NYGrids) )//'x'//TRIM( Num2LStr(p%NZGrids) )// & - ' grid ('//TRIM( Num2LStr(p%FFYHWid*2) )//' m wide, '// & - TRIM( Num2LStr(p%GridBase) )//' m to '// & - TRIM( Num2LStr(p%GridBase+p%FFZHWid*2) )//& - ' m above ground) with a characteristic wind speed of '//TRIM( Num2LStr(p%MeanFFWS) )//' m/s. ' ) - ErrMsg = "" - ErrStat = ErrID_None - - - !------------------------------------------------------------------------------------------------- - ! Allocate space for the FF array - !------------------------------------------------------------------------------------------------- - - TmpNumSteps = p%NFFSteps + 1 ! add another step, just in case there is an odd number of steps. - - !bjj: should we reorganize this FFData array so we access the data faster? - - IF ( .NOT. ALLOCATED( p%FFData ) ) THEN - CALL AllocAry( p%FFData, p%NZGrids,p%NYGrids,p%NFFComp,TmpNumSteps, & - 'Full-field wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ELSE - IF (SIZE(p%FFData,1) /= p%NZGrids .OR. SIZE(p%FFData,2) /= p%NYGrids .OR. & - SIZE(p%FFData,3) /= p%NFFComp .OR. SIZE(p%FFData,3) /= TmpNumSteps ) THEN - - ! Let's make the array the correct size (we should never get here, but you never know) - - DEALLOCATE( p%FFData ) - - CALL AllocAry( p%FFData, p%NZGrids,p%NYGrids,p%NFFComp,TmpNumSteps, & - 'Full-field wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ENDIF !Incorrect size - ENDIF ! allocated - - !------------------------------------------------------------------------------------------------- - ! Initialize the data and set column indexing to account for direction of turbine rotation (CWise) - !------------------------------------------------------------------------------------------------- - - p%FFData(:,:,:,:) = 0.0 ! we may have only one component - - IF ( CWise ) THEN - CFirst = p%NYGrids - CLast = 1 - CStep = -1 - ELSE - CFirst = 1 - CLast = p%NYGrids - CStep = 1 - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Loop through all the time steps, reading the data and converting to m/s - !------------------------------------------------------------------------------------------------- - !bjj: should we reorganize this FFData array so we access the data faster? - - p%NFFSteps = TmpNumSteps - - TIME_LOOP: DO IT=1,TmpNumSteps ! time (add 1 to see if there is an odd number of grids) - - DO IR=1,p%NZGrids ! the rows (vertical) - - DO IC=CFirst,CLast,CStep ! the columns (lateral) - - DO I=1,p%NFFComp ! wind components (U, V, W) - - ! Get the next integer from the file. - ! This is a 2-byte integer, so we can't use the library read routines. - READ (UnitWind,IOStat=TmpErrStat) Dum_Int2 - IF (TmpErrStat /= 0) THEN - IF ( IT == TmpNumSteps ) THEN ! There really were an even number of steps - p%NFFSteps = TmpNumSteps - 1 - ErrStat = 0 - EXIT TIME_LOOP - ELSE - CALL SetErrStat( ErrID_Fatal, ' Error reading binary data file. '// & - 'ic = '//TRIM(Num2LStr(ic))// & - ', ir = '//TRIM(Num2LStr(ir))// & - ', it = '//TRIM(Num2LStr(it))// & - ', nffsteps = '//TRIM(Num2LStr(p%NFFSteps)), ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - ELSE - p%FFData(IR,IC,I,IT) = FF_Offset(I)+FF_Scale(I)*Dum_Int2 - ENDIF - - END DO !I - - END DO !IC - - END DO !IR - - END DO TIME_LOOP !IT - - IF ( p%Periodic ) THEN - TmpErrMsg = ' Processed '//TRIM( Num2LStr( p%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( p%FFRate ) )//'-Hz full-field data (period of '// & - TRIM( Num2LStr( p%FFDTime*p%NFFSteps ) )//' seconds).' - - ELSE - TmpErrMsg= ' Processed '//TRIM( Num2LStr( p%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( p%FFRate ) )//'-Hz full-field data ('// & - TRIM( Num2LStr( p%FFDTime*( p%NFFSteps - 1 ) ) )//' seconds).' - ENDIF - CALL WrScr( NewLine//TRIM(TmpErrMsg) ) - !CALL SetErrStat( ErrID_Info, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - - END SUBROUTINE Read_Bladed_Grids - !==================================================================================================== - !> This subroutine reads the binary tower file that corresponds with the Bladed-style FF binary file. - !! The FF grid must be read before this subroutine is called! (many checks are made to ensure the - !! files belong together) - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_FF_Tower( UnitWind, p, TwrFileName, ErrStat, ErrMsg ) - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_FF_Tower" - - - ! Passed Variables: - INTEGER(IntKi) :: UnitWind !< unit number of wind file to be opened - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - CHARACTER(*), INTENT(IN ) :: TwrFileName - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status return value (0=no error; non-zero is error) - CHARACTER(*), INTENT( OUT) :: ErrMsg !< a message for errors that occur - - ! Local Variables: - - REAL(SiKi) :: Dum_Real4 ! dummy 4-byte real number - INTEGER(B2Ki) :: Dum_Int2 ! dummy 2-byte integer - INTEGER(B4Ki) :: Dum_Int4 ! dummy 4-byte integer - - INTEGER(IntKi) :: IC ! loop counter for wind components - INTEGER(IntKi) :: IT ! loop counter for time - INTEGER(IntKi) :: IZ ! loop counter for z - - REAL(ReKi), PARAMETER :: TOL = 1E-4 ! tolerence for wind file comparisons - - REAL(ReKi), PARAMETER :: FF_Offset(3) = (/ 1.0, 0.0, 0.0 /) ! used for "un-normalizing" the data - REAL(SiKi) :: TI (3) ! scaling values for "un-normalizing the data" [approx. turbulence intensities of the wind components] - - - ! Temporary Error Handling - - INTEGER(IntKi) :: TmpErrStat ! IOSTAT value. - CHARACTER(ErrMsgLen) :: TmpErrMsg - - !------------------------------------------------------------------------------------------------- - ! Initialization - !------------------------------------------------------------------------------------------------- - - ErrMsg = '' - ErrStat = ErrID_None - - p%NTGrids = 0 - - IF ( p%NFFComp /= 3 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error: Tower binary files require 3 wind components.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Open the file - !------------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(TwrFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the header information and check that it's compatible with the FF Bladed-style binary - ! parameters already read. - !------------------------------------------------------------------------------------------------- - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! dz, in meters [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4*p%InvFFZD-1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Resolution in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! dx, in meters [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dx in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4*p%InvMFFWS/p%FFDTime-1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Time resolution in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Zmax, in meters [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading Zmax in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4/p%GridBase-1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Height in the FF binary file does not match the tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte integer, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! NumOutSteps [4-byte INTEGER] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading NumOutSteps in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( Dum_Int4 /= p%NFFSteps ) THEN - CALL SetErrStat( ErrID_Fatal, ' Number of time steps in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte integer, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! NumZ [4-byte INTEGER] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading NumZ in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - p%NTGrids = Dum_Int4 - - - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! UHub [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading UHub in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4*p%InvMFFWS - 1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Mean wind speed in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - p%NTGrids = 0 - RETURN - ENDIF - - - DO IC=1,3 - ! Read the TI values fromthe tower file: 4-byte reals. - - !bjj: not sure you can call this routine to read from a binary file... - !CALL ReadVar( UnitWind, TRIM(InitInp%WindFileName), TI(IC), 'TI('//TRIM(Num2LStr(IC))//')', 'TI value for u,v, or w', TmpErrStat, TmpErrMsg ) - !IF (TmpErrStat /= ErrID_None) THEN - ! p%NTGrids = 0 - ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - ! IF (ErrStat >= AbortErrLev) RETURN - !ENDIF - ! - READ (UnitWind, IOSTAT=TmpErrStat) TI(IC) ! TI(u), TI(v), TI(w) [4-byte REAL] - - IF (TmpErrStat /= 0) THEN - p%NTGrids = 0 - CALL SetErrStat( ErrID_Fatal, ' Error reading TI('//TRIM(Num2LStr(IC))//') in the binary tower file "' & - //TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - END DO - - !---------------------------------------------------------------------------------------------- - ! Allocate arrays for the tower points - !---------------------------------------------------------------------------------------------- - - IF ( p%NTGrids > 0 ) THEN - - IF ( .NOT. ALLOCATED( p%FFTower ) ) THEN - CALL AllocAry( p%FFTower, p%NFFComp, p%NTGrids, p%NFFSteps, & - 'Tower wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - - ELSE - ! Check sizes here! - ENDIF - - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Read the 16-bit time-series data and scale it to 32-bit reals - !------------------------------------------------------------------------------------------------- - - ! Loop through time. - - DO IT=1,p%NFFSteps - - DO IZ=1,p%NTGrids ! If NTGrids<1, there are no tower points & FFTower is not allocated - - ! Ytower = 0 ! Lateral location of the tower data point, in m relative to tower centerline - ! Ztower(IZ) = Z1 - (IZ-1)*dz ! Vertical location of tower data point, in m relative to ground - - DO IC=1,p%NFFComp ! number of wind components - - ! Read in the 2-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! normalized wind-component, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading binary tower data file. it = '//TRIM(Num2LStr(it))// & - ', nffsteps = '//TRIM(Num2LStr(p%NFFSteps)), ErrStat, ErrMsg, RoutineName ) - p%NTGrids = 0 - RETURN - ENDIF - - p%FFTower(IC,IZ,IT) = p%MeanFFWS*(FF_Offset(IC)+0.00001*TI(IC)*Dum_Int2) ! wind-component scaled to m/s - - ENDDO !IC - - ENDDO ! IZ - - - ENDDO ! IT - - !------------------------------------------------------------------------------------------------- - ! Close the file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnitWind ) - - TmpErrMsg = ' Processed '//TRIM( Num2LStr(p%NFFSteps) )//' time steps of '// & - TRIM( Num2LStr(p%NTGrids) )//'x1 tower data grids.' - - !CALL SetErrStat( ErrID_Info, ErrMsgLcl, ErrStat, ErrMsg, RoutineName ) - CALL WrScr( NewLine//TRIM(TmpErrMsg) ) - - RETURN - - END SUBROUTINE Read_FF_Tower -!==================================================================================================== -!> This subroutine reads the text summary file to get normalizing parameters, the location of the -!! grid, and the direction the grid was written to the binary file -SUBROUTINE Read_NativeBladedSummary ( FileName, PLExp, VLinShr, HLinShr, RefLength, TI, UBar, RefHt, PropagationDir, VFlowAngle, BinFileName, XOffset, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_NativeBladedSummary" - - - ! Passed variables - CHARACTER(*), INTENT(IN ) :: FileName !< name of the summary file - REAL(ReKi), INTENT( OUT) :: PLExp !< the power-law exponent for vertical wind shear - REAL(ReKi), INTENT( OUT) :: VLinShr !< the linear shape for vertical wind shear - REAL(ReKi), INTENT( OUT) :: HLinShr !< the linear shape for horizontal wind shear - REAL(ReKi), INTENT( OUT) :: RefLength !< Reference (rotor) diameter - REAL(ReKi), INTENT( OUT) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - REAL(ReKi), INTENT( OUT) :: UBar !< mean (advection) wind speed - REAL(ReKi), INTENT( OUT) :: RefHt !< Reference height - REAL(ReKi), INTENT( OUT) :: PropagationDir !< propagation direction - REAL(ReKi), INTENT( OUT) :: VFlowAngle !< vertical flow angle - CHARACTER(*), INTENT( OUT) :: BinFileName !< name of the binary file containing wind data - REAL(ReKi), INTENT( OUT) :: XOffset !< distance offset for start of wind files - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< returns 0 if no error encountered in the subroutine - CHARACTER(*), INTENT( OUT) :: ErrMsg !< holds the error messages - - ! Local variables - INTEGER(IntKi), PARAMETER :: UnEc= -1 ! echo file unit number (set to something else > 0 for debugging) - INTEGER(IntKi) :: CurLine ! Current line to parse in FileInfo data structure - INTEGER(IntKi) :: ErrStat2 ! temporary error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - - TYPE (FileInfoType) :: FileInfo ! The derived type for holding the file information. - - - !---------------------------------------------------------------------------------------------- - ! Initialize some variables - !---------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - !---------------------------------------------------------------------------------------------- - ! Open and read the summary file; store data in FileInfo structure. - !---------------------------------------------------------------------------------------------- - - CALL ProcessComFile ( FileName, FileInfo, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - !------------------------------------------------------------------------------------------------- - ! Process the lines stored in FileInfo - !------------------------------------------------------------------------------------------------- - - CurLine = 1 - - CALL ParseVar ( FileInfo, CurLine, 'UBAR', UBar, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'REFHT', RefHt, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'TI', TI(1), ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'TI_V', TI(2), ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'TI_W', TI(3), ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'WDIR', PropagationDir, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - PropagationDir = R2D*PropagationDir - - CALL ParseVar ( FileInfo, CurLine, 'FLINC', VFlowAngle, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - VFlowAngle = R2D*VFlowAngle ! convert to degrees - - CALL ParseVar ( FileInfo, CurLine, 'WINDF', BinFileName, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'WSHEAR', PLExp, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - CALL ParseVar ( FileInfo, CurLine, 'VLINSHEAR', VLinShr, ErrStat2, ErrMsg2, UnEc ) - if (ErrStat2/=ErrID_None) then - VLinShr = 0.0_ReKi ! this will be the default if VLINSHEAR is not in the file - end if - - CALL ParseVar ( FileInfo, CurLine, 'HLINSHEAR', HLinShr, ErrStat2, ErrMsg2, UnEc ) - if (ErrStat2/=ErrID_None) then - HLinShr = 0.0_ReKi ! this will be the default if HLINSHEAR is not in the file - end if - - CALL ParseVar ( FileInfo, CurLine, 'REFLENGTH', RefLength, ErrStat2, ErrMsg2, UnEc ) - if (ErrStat2/=ErrID_None) then - RefLength = 0.0_ReKi ! this will be the default if RefLength is not in the file; it will cause an error if either of the linear shears are non-zero - end if - - CALL ParseVar ( FileInfo, CurLine, 'XOffset', XOffset, ErrStat2, ErrMsg2, UnEc ) - if (ErrStat2/=ErrID_None) then - XOffset = 0.0_ReKi ! this will be the default if offset is not in the file - end if - - - !------------------------------------------------------------------------------------------------- - ! Get rid of the FileInfo data structure (including pointers and allocatable array): - !------------------------------------------------------------------------------------------------- - - call Cleanup ( ) - - -CONTAINS - - SUBROUTINE Cleanup () - CALL NWTC_Library_DestroyFileInfoType (FileInfo, ErrStat2, ErrMsg2) - END SUBROUTINE Cleanup - -END SUBROUTINE Read_NativeBladedSummary -!==================================================================================================== - - -!==================================================================================================== -!> This routine acts as a wrapper for the GetWindSpeed routine. It steps through the array of input -!! positions and calls the GetWindSpeed routine to calculate the velocities at each point. -!! -!! There are inefficiencies in how this set of routines is coded, but that is a problem for another -!! day. For now, it merely needs to be functional. It can be fixed up and made all pretty later. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_BladedFFWind_CalcOutput(Time, PositionXYZ, ParamData, Velocity, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_BladedFFWind_CalcOutput" - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_BladedFFWind_ParameterType), INTENT(IN ) :: ParamData !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: MiscVars !< misc/optimization data (storage for the main data) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - - CALL IfW_FFWind_CalcOutput(Time, PositionXYZ, ParamData%FF, Velocity, ErrStat, ErrMsg) - - - RETURN - -END SUBROUTINE IfW_BladedFFWind_CalcOutput - -!==================================================================================================== -!! This subroutine cleans up any data that is still allocated. The (possibly) open files are -!! closed in InflowWindMod. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_BladedFFWind_End( ParamData, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_BladedFFWind_End" - ! Passed Variables - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: MiscVars !< misc/optimization data (storage for the main data) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_BladedFFWind_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the state data - - CALL IfW_BladedFFWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - -END SUBROUTINE IfW_BladedFFWind_End - -!==================================================================================================== -END MODULE IfW_BladedFFWind diff --git a/modules/inflowwind/src/IfW_BladedFFWind.txt b/modules/inflowwind/src/IfW_BladedFFWind.txt deleted file mode 100644 index 76a57b1b5f..0000000000 --- a/modules/inflowwind/src/IfW_BladedFFWind.txt +++ /dev/null @@ -1,41 +0,0 @@ -################################################################################################################################### -# Registry for IfW_BladedFFWind, creates MODULE IfW_BladedFFWind_Types -# Module IfW_BladedFFWind_Types contains all of the user-defined types needed in IfW_BladedFFWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt -usefrom IfW_FFWind_Base.txt - - -######################### - -typedef IfW_BladedFFWind/IfW_BladedFFWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - -typedef ^ ^ Logical TowerFileExist - - - "Tower file exists" - -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - -typedef ^ ^ Logical NativeBladedFmt - - - "Whether this is native Bladed (needs wind profile and TI scaling) or not" - -typedef ^ ^ IntKi TurbineID - 0 - "Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm)" - -typedef ^ ^ LOGICAL FixedWindFileRootName - .FALSE. - "Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm)" - -#typedef ^ ^ IfW_FFWind_InitInputType FF - - - "scaling data (provided for native Bladed format)" - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off FFWind submodule" - -typedef ^ ^ ReKi TI {3} - - "Turbulence intensity given in the file" - -typedef ^ InitOutputType ReKi PropagationDir - - - "Propogation direction from native Bladed format" degrees -typedef ^ InitOutputType ReKi VFlowAngle - - - "Vertical flow angle from native Bladed format" degrees - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi dummy - 0 - "An Index into the TData array" - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IfW_FFWind_ParameterType FF - - - "Parameters used in all full-field wind types" - - diff --git a/modules/inflowwind/src/IfW_BladedFFWind_Types.f90 b/modules/inflowwind/src/IfW_BladedFFWind_Types.f90 deleted file mode 100644 index 4f0ea3b994..0000000000 --- a/modules/inflowwind/src/IfW_BladedFFWind_Types.f90 +++ /dev/null @@ -1,847 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_BladedFFWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_BladedFFWind_Types -!................................................................................................................................. -! This file is part of IfW_BladedFFWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_BladedFFWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_BladedFFWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_FFWind_Base_Types -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_BladedFFWind_InitInputType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - LOGICAL :: TowerFileExist !< Tower file exists [-] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - LOGICAL :: NativeBladedFmt !< Whether this is native Bladed (needs wind profile and TI scaling) or not [-] - INTEGER(IntKi) :: TurbineID = 0 !< Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm) [-] - LOGICAL :: FixedWindFileRootName = .FALSE. !< Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm) [-] - END TYPE IfW_BladedFFWind_InitInputType -! ======================= -! ========= IfW_BladedFFWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off FFWind submodule [-] - REAL(ReKi) , DIMENSION(1:3) :: TI !< Turbulence intensity given in the file [-] - REAL(ReKi) :: PropagationDir !< Propogation direction from native Bladed format [degrees] - REAL(ReKi) :: VFlowAngle !< Vertical flow angle from native Bladed format [degrees] - END TYPE IfW_BladedFFWind_InitOutputType -! ======================= -! ========= IfW_BladedFFWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_MiscVarType - INTEGER(IntKi) :: dummy = 0 !< An Index into the TData array [-] - END TYPE IfW_BladedFFWind_MiscVarType -! ======================= -! ========= IfW_BladedFFWind_ParameterType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_ParameterType - TYPE(IfW_FFWind_ParameterType) :: FF !< Parameters used in all full-field wind types [-] - END TYPE IfW_BladedFFWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_BladedFFWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_BladedFFWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%TowerFileExist = SrcInitInputData%TowerFileExist - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - DstInitInputData%NativeBladedFmt = SrcInitInputData%NativeBladedFmt - DstInitInputData%TurbineID = SrcInitInputData%TurbineID - DstInitInputData%FixedWindFileRootName = SrcInitInputData%FixedWindFileRootName - END SUBROUTINE IfW_BladedFFWind_CopyInitInput - - SUBROUTINE IfW_BladedFFWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyInitInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_BladedFFWind_DestroyInitInput - - SUBROUTINE IfW_BladedFFWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - Int_BufSz = Int_BufSz + 1 ! TowerFileExist - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - Int_BufSz = Int_BufSz + 1 ! NativeBladedFmt - Int_BufSz = Int_BufSz + 1 ! TurbineID - Int_BufSz = Int_BufSz + 1 ! FixedWindFileRootName - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%TowerFileExist, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%NativeBladedFmt, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%TurbineID - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%FixedWindFileRootName, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_PackInitInput - - SUBROUTINE IfW_BladedFFWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%TowerFileExist = TRANSFER(IntKiBuf(Int_Xferred), OutData%TowerFileExist) - Int_Xferred = Int_Xferred + 1 - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NativeBladedFmt = TRANSFER(IntKiBuf(Int_Xferred), OutData%NativeBladedFmt) - Int_Xferred = Int_Xferred + 1 - OutData%TurbineID = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%FixedWindFileRootName = TRANSFER(IntKiBuf(Int_Xferred), OutData%FixedWindFileRootName) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_UnPackInitInput - - SUBROUTINE IfW_BladedFFWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInitOutputData%TI = SrcInitOutputData%TI - DstInitOutputData%PropagationDir = SrcInitOutputData%PropagationDir - DstInitOutputData%VFlowAngle = SrcInitOutputData%VFlowAngle - END SUBROUTINE IfW_BladedFFWind_CopyInitOutput - - SUBROUTINE IfW_BladedFFWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyInitOutput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_BladedFFWind_DestroyInitOutput - - SUBROUTINE IfW_BladedFFWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Re_BufSz = Re_BufSz + SIZE(InData%TI) ! TI - Re_BufSz = Re_BufSz + 1 ! PropagationDir - Re_BufSz = Re_BufSz + 1 ! VFlowAngle - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) - ReKiBuf(Re_Xferred) = InData%TI(i1) - Re_Xferred = Re_Xferred + 1 - END DO - ReKiBuf(Re_Xferred) = InData%PropagationDir - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VFlowAngle - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_PackInitOutput - - SUBROUTINE IfW_BladedFFWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%TI,1) - i1_u = UBOUND(OutData%TI,1) - DO i1 = LBOUND(OutData%TI,1), UBOUND(OutData%TI,1) - OutData%TI(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%PropagationDir = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VFlowAngle = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_UnPackInitOutput - - SUBROUTINE IfW_BladedFFWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%dummy = SrcMiscData%dummy - END SUBROUTINE IfW_BladedFFWind_CopyMisc - - SUBROUTINE IfW_BladedFFWind_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyMisc' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_BladedFFWind_DestroyMisc - - SUBROUTINE IfW_BladedFFWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%dummy - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_PackMisc - - SUBROUTINE IfW_BladedFFWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_UnPackMisc - - SUBROUTINE IfW_BladedFFWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_CopyParam( SrcParamData%FF, DstParamData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_BladedFFWind_CopyParam - - SUBROUTINE IfW_BladedFFWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyParam' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL IfW_FFWind_DestroyParam( ParamData%FF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_BladedFFWind_DestroyParam - - SUBROUTINE IfW_BladedFFWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_BladedFFWind_PackParam - - SUBROUTINE IfW_BladedFFWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_BladedFFWind_UnPackParam - -END MODULE IfW_BladedFFWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_FFWind_Base.f90 b/modules/inflowwind/src/IfW_FFWind_Base.f90 deleted file mode 100644 index 365feed37d..0000000000 --- a/modules/inflowwind/src/IfW_FFWind_Base.f90 +++ /dev/null @@ -1,1205 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is shifted by half the grid width to account for turbine yaw (so that data in the X -!! direction actually starts at -1*p%FFYHWid meters). -MODULE IfW_FFWind_Base -!! -!! Created 25-Sep-2009 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Modified to use NWTC_Library v. 2.0 -!! -- Note: Jacobians are not included in this version. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_FFWind_Base_Types - - IMPLICIT NONE - - - INTEGER(IntKi), PARAMETER :: WindProfileType_None = -1 !< don't add a mean wind profile - INTEGER(IntKi), PARAMETER :: WindProfileType_Constant = 0 !< constant wind - INTEGER(IntKi), PARAMETER :: WindProfileType_Log = 1 !< logarithmic - INTEGER(IntKi), PARAMETER :: WindProfileType_PL = 2 !< power law - - INTEGER(IntKi), PARAMETER :: ScaleMethod_None = 0 !< no scaling - INTEGER(IntKi), PARAMETER :: ScaleMethod_Direct = 1 !< direct scaling factors - INTEGER(IntKi), PARAMETER :: ScaleMethod_StdDev = 2 !< requested standard deviation - - -CONTAINS -!==================================================================================================== - -!==================================================================================================== -!> This routine acts as a wrapper for the GetWindSpeed routine. It steps through the array of input -!! positions and calls the GetWindSpeed routine to calculate the velocities at each point. -SUBROUTINE IfW_FFWind_CalcOutput(Time, PositionXYZ, p, Velocity, ErrStat, ErrMsg) - - IMPLICIT NONE - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points specified by the PositionXYZ array - - ! local counters - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! temporary variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_CalcOutput' - - - !------------------------------------------------------------------------------------------------- - ! Check that the module has been initialized. - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,2) - - - ! Step through all the positions and get the velocities - !OMP PARALLEL default(shared) if(NumPoints>1000) - !OMP do private(PointNum, TmpErrStat, TmpErrMsg ) schedule(runtime) - DO PointNum = 1, NumPoints - - ! Calculate the velocity for the position - Velocity(:,PointNum) = FFWind_Interp(Time,PositionXYZ(:,PointNum),p,TmpErrStat,TmpErrMsg) - - ! Error handling - IF (TmpErrStat /= ErrID_None) THEN ! adding this so we don't have to convert numbers to strings every time - !OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg - ErrStat = ErrID_None - ErrMsg = "" - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName//" [position=("// & - TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in wind-file coordinates]" ) - !OMP END CRITICAL - END IF - - ENDDO - !OMP END DO - !OMP END PARALLEL - IF (ErrStat >= AbortErrLev) RETURN ! Return cannot be in parallel loop - - IF (p%AddMeanAfterInterp) THEN - DO PointNum = 1, NumPoints - Velocity(1,PointNum) = Velocity(1,PointNum) + CalculateMeanVelocity(p,PositionXYZ(3,PointNum),PositionXYZ(2,PointNum)) - ENDDO - END IF - - - RETURN - -END SUBROUTINE IfW_FFWind_CalcOutput -!+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -!> This function is used to interpolate into the full-field wind array or tower array if it has -!! been defined and is necessary for the given inputs. It receives X, Y, Z and -!! TIME from the calling routine. It then computes a time shift due to a nonzero X based upon -!! the average windspeed. The modified time is used to decide which pair of time slices to interpolate -!! within and between. After finding the two time slices, it decides which four grid points bound the -!! (Y,Z) pair. It does a bilinear interpolation for each time slice. Linear interpolation is then used -!! to interpolate between time slices. This routine assumes that X is downwind, Y is to the left when -!! looking downwind and Z is up. It also assumes that no extrapolation will be needed. -!! -!! If tower points are used, it assumes the velocity at the ground is 0. It interpolates between -!! heights and between time slices, but ignores the Y input. -!! -!! 11/07/1994 - Created by M. Buhl from the original TURBINT. -!! 09/25/1997 - Modified by M. Buhl to use f90 constructs and new variable names. Renamed to FF_Interp. -!! 09/23/2009 - Modified by B. Jonkman to use arguments instead of modules to determine time and position. -!! Height is now relative to the ground -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -FUNCTION FFWind_Interp(Time, Position, p, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="FFWind_Interp" - - REAL(DbKi), INTENT(IN ) :: Time !< time (s) - REAL(ReKi), INTENT(IN ) :: Position(3) !< takes the place of XGrnd, YGrnd, ZGrnd - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi) :: FFWind_Interp(3) !< The U, V, W velocities - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - ! Local Variables: - - REAL(ReKi) :: TimeShifted - REAL(ReKi),PARAMETER :: Tol = 1.0E-3 ! a tolerance for determining if two reals are the same (for extrapolation) - REAL(ReKi) :: T - REAL(ReKi) :: TGRID - REAL(ReKi) :: Y - REAL(ReKi) :: YGRID - REAL(ReKi) :: Z - REAL(ReKi) :: ZGRID - REAL(ReKi) :: N(8) ! array for holding scaling factors for the interpolation algorithm - REAL(ReKi) :: u(8) ! array for holding the corner values for the interpolation algorithm across a cubic volume - REAL(ReKi) :: M(4) ! array for holding scaling factors for the interpolation algorithm - REAL(ReKi) :: v(4) ! array for holding the corner values for the interpolation algorithm across an area - - INTEGER(IntKi) :: IDIM - INTEGER(IntKi) :: ITHI - INTEGER(IntKi) :: ITLO - INTEGER(IntKi) :: IYHI - INTEGER(IntKi) :: IYLO - INTEGER(IntKi) :: IZHI - INTEGER(IntKi) :: IZLO - - LOGICAL :: OnGrid - - !------------------------------------------------------------------------------------------------- - ! Initialize variables - !------------------------------------------------------------------------------------------------- - - FFWind_Interp(:) = 0.0_ReKi ! the output velocities (in case p%NFFComp /= 3 or error) - - ErrStat = ErrID_None - ErrMsg = "" - - - !------------------------------------------------------------------------------------------------- - ! By definition, wind below the ground is always zero (no turbulence, either). - !------------------------------------------------------------------------------------------------- - IF ( Position(3) <= 0.0_ReKi ) THEN - FFWind_Interp = 0.0_ReKi - RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding time slices. - !------------------------------------------------------------------------------------------------- - - ! Perform the time shift. At time=0, a point half the grid width downstream (p%FFYHWid) will index into the zero time slice. - ! If we did not do this, any point downstream of the tower at the beginning of the run would index outside of the array. - ! This all assumes the grid width is at least as large as the rotor. If it isn't, then the interpolation will not work. - - - TimeShifted = TIME + ( p%InitXPosition - Position(1) )*p%InvMFFWS ! in distance, X: InputInfo%Position(1) - p%InitXPosition - TIME*p%MeanFFWS - - - IF ( p%Periodic ) THEN ! translate TimeShifted to ( 0 <= TimeShifted < p%TotalTime ) - - TimeShifted = MODULO( TimeShifted, p%TotalTime ) - ! If TimeShifted is a very small negative number, modulo returns the incorrect value due to internal rounding errors. - ! See bug report #471 - IF (TimeShifted == p%TotalTime) TimeShifted = 0.0_ReKi - - TGRID = TimeShifted*p%FFRate - ITLO = INT( TGRID ) ! convert REAL to INTEGER (add 1 later because our grids start at 1, not 0) - T = 2.0_ReKi * ( TGRID - REAL(ITLO, ReKi) ) - 1.0_ReKi ! a value between -1 and 1 that indicates a relative position between ITLO and ITHI - - ITLO = ITLO + 1 - IF ( ITLO == p%NFFSteps ) THEN - ITHI = 1 - ELSE - IF (ITLO > p%NFFSteps) ITLO = 1 - ITHI = ITLO + 1 - ENDIF - - - ELSE - - TGRID = TimeShifted*p%FFRate - ITLO = INT( TGRID ) ! convert REAL to INTEGER (add 1 later because our grids start at 1, not 0) - T = 2.0_ReKi * ( TGRID - REAL(ITLO, ReKi) ) - 1.0_ReKi ! a value between -1 and 1 that indicates a relative position between ITLO and ITHI - - ITLO = ITLO + 1 ! add one since our grids start at 1, not 0 - ITHI = ITLO + 1 - - IF ( ITLO >= p%NFFSteps .OR. ITLO < 1 ) THEN - IF ( ITLO == p%NFFSteps ) THEN - ITHI = ITLO - IF ( T <= TOL ) THEN ! we're on the last point - T = -1.0_ReKi - ELSE ! We'll extrapolate one dt past the last value in the file - ITLO = ITHI - 1 - ENDIF - ELSE - ErrMsg = ' Error: FF wind array was exhausted at '//TRIM( Num2LStr( REAL( TIME, ReKi ) ) )// & - ' seconds (trying to access data at '//TRIM( Num2LStr( REAL( TimeShifted, ReKi ) ) )//' seconds).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - ENDIF - - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding rows for the Z position. [The lower-left corner is (1,1) when looking upwind.] - !------------------------------------------------------------------------------------------------- - - ZGRID = ( Position(3) - p%GridBase )*p%InvFFZD - - IF (ZGRID > -1*TOL) THEN - OnGrid = .TRUE. - - ! Index for start and end slices - IZLO = INT( ZGRID ) + 1 ! convert REAL to INTEGER, then add one since our grids start at 1, not 0 - IZHI = IZLO + 1 - - ! Set Z as a value between -1 and 1 for the relative location between IZLO and IZHI. - ! Subtract 1_IntKi from Z since the indices are starting at 1, not 0 - Z = 2.0_ReKi * (ZGRID - REAL(IZLO - 1_IntKi, ReKi)) - 1.0_ReKi - - IF ( IZLO < 1 ) THEN - IF ( IZLO == 0 .AND. Z >= 1.0-TOL ) THEN - Z = -1.0_ReKi - IZLO = 1 - ELSE - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction (Z='//& - TRIM(Num2LStr(Position(3)))//' m is below the grid).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - ELSEIF ( IZLO >= p%NZGrids ) THEN - IF ( IZLO == p%NZGrids .AND. Z <= TOL ) THEN - Z = -1.0_ReKi - IZHI = IZLO ! We're right on the last point, which is still okay - ELSE - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction (Z='//& - TRIM(Num2LStr(Position(3)))//' m is above the grid).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - ENDIF - - ELSE - - OnGrid = .FALSE. ! this is on the tower - - IF (p%InterpTower) then - - ! get Z between ground and bottom of grid - ZGRID = Position(3)/p%GridBase - Z = 2.0_ReKi * ZGRID - 1.0_ReKi - IZHI = 1 - IZLO = 0 - - IF ( ZGRID < 0.0_ReKi ) THEN - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction '// & - '(height (Z='//TRIM(Num2LStr(Position(3)))//' m) is below the ground).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - ELSE - - IF ( p%NTGrids < 1) THEN - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction '// & - '(height (Z='//TRIM(Num2LStr(Position(3)))//' m) is below the grid and no tower points are defined).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - IZLO = INT( -1.0*ZGRID ) + 1 ! convert REAL to INTEGER, then add one since our grids start at 1, not 0 - - - IF ( IZLO >= p%NTGrids ) THEN !our dz is the difference between the bottom tower point and the ground - IZLO = p%NTGrids - - ! Check that this isn't zero. Value between -1 and 1 corresponding to the relative position. - Z = 1.0_ReKi - 2.0_ReKi * (Position(3) / (p%GridBase - REAL(IZLO - 1_IntKi, ReKi)/p%InvFFZD)) - - ELSE - - ! Set Z as a value between -1 and 1 for the relative location between IZLO and IZHI. Used in the interpolation. - Z = 2.0_ReKi * (ABS(ZGRID) - REAL(IZLO - 1_IntKi, ReKi)) - 1.0_ReKi - - ENDIF - IZHI = IZLO + 1 - - ENDIF - - END IF - - IF ( OnGrid ) THEN ! The tower points don't use this - - CALL GetInterpValues(); if (ErrStat/=ErrID_None) return - - !------------------------------------------------------------------------------------------------- - ! Interpolate on the grid - !------------------------------------------------------------------------------------------------- - - DO IDIM=1,p%NFFComp ! all the components - - u(1) = p%FFData( IZHI, IYLO, IDIM, ITLO ) - u(2) = p%FFData( IZHI, IYHI, IDIM, ITLO ) - u(3) = p%FFData( IZLO, IYHI, IDIM, ITLO ) - u(4) = p%FFData( IZLO, IYLO, IDIM, ITLO ) - u(5) = p%FFData( IZHI, IYLO, IDIM, ITHI ) - u(6) = p%FFData( IZHI, IYHI, IDIM, ITHI ) - u(7) = p%FFData( IZLO, IYHI, IDIM, ITHI ) - u(8) = p%FFData( IZLO, IYLO, IDIM, ITHI ) - - FFWind_Interp(IDIM) = SUM ( N * u ) - - END DO !IDIM - - ELSE - - IF (p%InterpTower) THEN - - CALL GetInterpValues(); if (ErrStat >= AbortErrLev) return - - !------------------------------------------------------------------------------------------------- - ! Interpolate on the bottom of the grid to the ground - !------------------------------------------------------------------------------------------------- - - DO IDIM=1,p%NFFComp ! all the components - - u(1) = p%FFData( IZHI, IYLO, IDIM, ITLO ) - u(2) = p%FFData( IZHI, IYHI, IDIM, ITLO ) - u(3) = 0.0_ReKi !p%FFData( IZLO, IYHI, IDIM, ITLO ) - u(4) = 0.0_ReKi !p%FFData( IZLO, IYLO, IDIM, ITLO ) - u(5) = p%FFData( IZHI, IYLO, IDIM, ITHI ) - u(6) = p%FFData( IZHI, IYHI, IDIM, ITHI ) - u(7) = 0.0_ReKi !p%FFData( IZLO, IYHI, IDIM, ITHI ) - u(8) = 0.0_ReKi !p%FFData( IZLO, IYLO, IDIM, ITHI ) - - FFWind_Interp(IDIM) = SUM ( N * u ) - - END DO !IDIM - - ELSE - - !------------------------------------------------------------------------------------------------- - ! Interpolate on the tower array - !------------------------------------------------------------------------------------------------- - ! Setup the scaling factors. Set the unused portion of the array to zero - M(1) = ( 1.0_ReKi + Z )*( 1.0_ReKi - T ) - M(2) = ( 1.0_ReKi + Z )*( 1.0_ReKi + T ) - M(3) = ( 1.0_ReKi - Z )*( 1.0_ReKi - T ) - M(4) = ( 1.0_ReKi - Z )*( 1.0_ReKi + T ) - M = M / 4.0_ReKi ! normalize - - - DO IDIM=1,p%NFFComp ! all the components - - !---------------------------------------------------------------------------------------------- - ! Interpolate between the two times using an area interpolation. - !---------------------------------------------------------------------------------------------- - - IF (IZHI > p%NTGrids) THEN - v(1) = 0.0_ReKi ! on the ground - v(2) = 0.0_ReKi ! on the ground - ELSE - v(1) = p%FFTower( IDIM, IZHI, ITLO ) - v(2) = p%FFTower( IDIM, IZHI, ITHI ) - END IF - - v(3) = p%FFTower( IDIM, IZLO, ITLO ) - v(4) = p%FFTower( IDIM, IZLO, ITHI ) - - FFWind_Interp(IDIM) = SUM ( M * v ) - - - END DO !IDIM - - END IF ! Interpolate below the grid - - ENDIF ! OnGrid - RETURN - -CONTAINS - SUBROUTINE GetInterpValues() - - !------------------------------------------------------------------------------------------------- - ! Find the bounding columns for the Y position. [The lower-left corner is (1,1) when looking upwind.] - !------------------------------------------------------------------------------------------------- - - YGRID = ( Position(2) + p%FFYHWid )*p%InvFFYD ! really, it's (Position(2) - -1.0*p%FFYHWid) - - IYLO = INT( YGRID ) + 1 ! convert REAL to INTEGER, then add one since our grids start at 1, not 0 - IYHI = IYLO + 1 - - ! Set Y as a value between -1 and 1 for the relative location between IYLO and IYHI. Used in the interpolation. - ! Subtract 1_IntKi from IYLO since grids start at index 1, not 0 - Y = 2.0_ReKi * (YGRID - REAL(IYLO - 1_IntKi, ReKi)) - 1.0_ReKi - - IF ( IYLO >= p%NYGrids .OR. IYLO < 1 ) THEN - IF ( IYLO == 0 .AND. Y >= 1.0-TOL ) THEN - Y = -1.0_ReKi - IYLO = 1 - ELSE IF ( IYLO == p%NYGrids .AND. Y <= TOL ) THEN - Y = -1.0_ReKi - IYHI = IYLO ! We're right on the last point, which is still okay - ELSE - ErrMsg = ' FF wind array boundaries violated: Grid too small in Y direction. Y='// & - TRIM(Num2LStr(Position(2)))//'; Y boundaries = ['//TRIM(Num2LStr(-1.0*p%FFYHWid))// & - ', '//TRIM(Num2LStr(p%FFYHWid))//']' - ErrStat = ErrID_Fatal ! we don't return anything - RETURN - ENDIF - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Get normalization values for 3d-linear interpolation on the grid - !------------------------------------------------------------------------------------------------- - -!New Algorithm here - N(1) = ( 1.0_ReKi + Z )*( 1.0_ReKi - Y )*( 1.0_ReKi - T ) - N(2) = ( 1.0_ReKi + Z )*( 1.0_ReKi + Y )*( 1.0_ReKi - T ) - N(3) = ( 1.0_ReKi - Z )*( 1.0_ReKi + Y )*( 1.0_ReKi - T ) - N(4) = ( 1.0_ReKi - Z )*( 1.0_ReKi - Y )*( 1.0_ReKi - T ) - N(5) = ( 1.0_ReKi + Z )*( 1.0_ReKi - Y )*( 1.0_ReKi + T ) - N(6) = ( 1.0_ReKi + Z )*( 1.0_ReKi + Y )*( 1.0_ReKi + T ) - N(7) = ( 1.0_ReKi - Z )*( 1.0_ReKi + Y )*( 1.0_ReKi + T ) - N(8) = ( 1.0_ReKi - Z )*( 1.0_ReKi - Y )*( 1.0_ReKi + T ) - N = N / REAL( SIZE(N), ReKi ) ! normalize - - END SUBROUTINE GetInterpValues -END FUNCTION FFWind_Interp -!==================================================================================================== -!> This routine is used read scale the full-field turbulence data stored in HAWC format. -SUBROUTINE ScaleTurbulence(InitInp, FFData, ScaleFactors, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_FFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - REAL(SiKi), INTENT(INOUT) :: FFData(:,:,:,:) !< full-field wind inflow data - REAL(ReKi), INTENT( OUT) :: ScaleFactors(3) !< scaling factors that were used - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - ! Local Variables: - ! note that the variables used to compute statistics use double precision: - REAL(DbKi) :: v(3) ! instanteanous wind speed at target position - REAL(DbKi) :: vMean(3) ! average wind speeds over time at target position - REAL(DbKi) :: vSum(3) ! sum over time of wind speeds at target position - REAL(DbKi) :: vSum2(3) ! sum of wind speeds squared - REAL(ReKi) :: ActualSigma(3) ! computed standard deviation - - INTEGER :: ic ! Loop counter for wind component - INTEGER :: ix ! Loop counter for x or t - INTEGER :: iy ! Loop counter for y - INTEGER :: iz ! Loop counter for z - - INTEGER :: nc ! number of FF wind components - INTEGER :: nx ! size of x (or t) dimension of turbulence box - INTEGER :: ny ! size of y dimension of turbulence box - INTEGER :: nz ! size of z dimension of turbulence box - - CHARACTER(*), PARAMETER :: RoutineName = 'ScaleTurbulence' - - - - ErrStat = ErrID_None - ErrMsg = "" - - nz = size(FFData,1) - ny = size(FFData,2) - nc = size(FFData,3) - nx = size(FFData,4) - - if ( InitInp%ScaleMethod == ScaleMethod_None ) then - - ! don't scale FFWind: - ScaleFactors = 1.0_ReKi - - else ! ScaleMethod_Direct or ScaleMethod_StdDev - - !.............................. - ! determine the scaling factors: - !.............................. - - if ( InitInp%ScaleMethod == ScaleMethod_Direct ) then - ! Use the scaling factors specified in the input file: - ScaleFactors = InitInp%sf - - else !if ( InitInp%ScaleMethod == ScaleMethod_StdDev ) then - ! compute the scale factor to get requested sigma: - - ! find the center point of the grid (if we don't have an odd number of grid points, we'll pick the point closest to the center) - iz = (nz + 1) / 2 ! integer division - iy = (ny + 1) / 2 ! integer division - - ! compute the actual sigma at the point specified by (iy,iz). (This sigma should be close to 1.) - v = 0.0_ReKi - vSum = 0.0_ReKi - vSum2 = 0.0_ReKi - DO ix=1,nx - v(1:nc) = FFData(iz,iy,:,ix) - - vSum = vSum + v - vSum2 = vSum2 + v**2 - ENDDO ! IX - - vMean = vSum/nx - ActualSigma = SQRT( ABS( (vSum2/nx) - vMean**2 ) ) - - ! check that the ActualSigma isn't 0 - !InitOut%sf = InitInp%SigmaF / ActualSigma ! factor = Target / actual - do ic=1,nc - if ( EqualRealNos( ActualSigma(ic), 0.0_ReKi ) ) then - ScaleFactors(ic) = 0.0_ReKi - if ( .not. EqualRealNos( InitInp%SigmaF(ic), 0.0_ReKi ) ) then - call SetErrStat( ErrID_Fatal,"Computed standard deviation is zero; cannot scale to achieve target non-zero standard deviation.", ErrStat, ErrMsg, RoutineName ) - end if - else - ScaleFactors(ic) = InitInp%SigmaF(ic) / ActualSigma(ic) - end if - end do - - end if - - !.............................. - ! scale the data using our scaling factors: - !.............................. - - do ix=1,nx - do ic = 1,nc - FFData( :, :, ic, ix ) = ScaleFactors(ic) * FFData( :, :, ic, ix ) - end do !IC - end do - - end if - -END SUBROUTINE ScaleTurbulence -!==================================================================================================== -!> This routine is used to add a mean wind profile to the HAWC format turbulence data. -SUBROUTINE AddMeanVelocity(InitInp, GridBase, dz, dy, FFData) - - ! Passed Variables - TYPE(IfW_FFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - REAL(ReKi), INTENT(IN ) :: GridBase !< height of the lowest point on the grid - REAL(ReKi), INTENT(IN ) :: dz !< distance between two zertically consectutive grid points - REAL(ReKi), INTENT(IN ) :: dy !< distance between two horizontal consectutive grid points - REAL(SiKi), INTENT(INOUT) :: FFData(:,:,:,:) !< FF wind-inflow data - - ! Local Variables: - REAL(ReKi) :: Z ! height - REAL(ReKi) :: Y ! distance from centre in horizontal direction - REAL(ReKi) :: U ! mean wind speed - INTEGER(IntKi) :: iz ! loop counter - INTEGER(IntKi) :: iy ! loop counter - INTEGER(IntKi) :: nz ! number of points in the z direction - INTEGER(IntKi) :: ny ! number of points in the z direction - INTEGER(IntKi) :: centre_y ! index of centre in y direction - - - nz = size(FFData,1) - - DO iz = 1,nz - - Z = GridBase + ( iz - 1 )*dz - if (Z <= 0.0_ReKi) cycle - - SELECT CASE ( InitInp%WindProfileType ) - - CASE ( WindProfileType_PL ) - - U = InitInp%URef*( Z / InitInp%RefHt )**InitInp%PLExp ! [IEC 61400-1 6.3.1.2 (10)] - - CASE ( WindProfileType_Log ) - - IF ( .not. EqualRealNos( InitInp%RefHt, InitInp%Z0 ) .and. Z > 0.0_ReKi ) THEN - U = InitInp%URef*( LOG( Z / InitInp%Z0 ) )/( LOG( InitInp%RefHt / InitInp%Z0 ) ) - ELSE - U = 0.0_ReKi - ENDIF - - CASE ( WindProfileType_Constant ) - - U = InitInp%URef - - CASE DEFAULT - - U = 0.0_ReKi - - END SELECT - - IF (InitInp%VLinShr .NE. 0.0_ReKi) THEN ! Add vertical linear shear, if has - U = U + InitInp%URef * InitInp%VLinShr * (Z - InitInp%RefHt) / InitInp%RefLength - ENDIF - - FFData( iz, :, 1, : ) = FFData( iz, :, 1, : ) + U - - END DO ! iz - - IF (InitInp%HLinShr .NE. 0.0_ReKi) THEN ! Add horizontal linear shear, if has - ny = size(FFData,2) - ! find the center point of the grid (if we don't have an odd number of grid points, we'll pick the point closest to the center) - centre_y = (ny + 1) / 2 ! integer division - DO iy = 1,ny - - Y = (iy - centre_y) * dy - - U = InitInp%URef * InitInp%HLinShr * Y / InitInp%RefLength - - FFData( :, iy, 1, : ) = FFData( :, iy, 1, : ) + U - - END DO ! iy - ENDIF ! IF InitInp%HLinShr - - -END SUBROUTINE AddMeanVelocity -!==================================================================================================== -FUNCTION CalculateMeanVelocity(p,z,y) RESULT(u) - - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi) , INTENT(IN ) :: Z ! height - REAL(ReKi) , INTENT(IN ) :: y ! lateral location - REAL(ReKi) :: u ! mean wind speed at position (y,z) - - SELECT CASE ( p%WindProfileType ) - - CASE ( WindProfileType_PL ) - - U = p%MeanFFWS*( Z / p%RefHt )**p%PLExp ! [IEC 61400-1 6.3.1.2 (10)] - - CASE ( WindProfileType_Log ) - - IF ( .not. EqualRealNos( p%RefHt, p%Z0 ) .and. Z > 0.0_ReKi ) THEN - U = p%MeanFFWS*( LOG( Z / p%Z0 ) )/( LOG( p%RefHt / p%Z0 ) ) - ELSE - U = 0.0_ReKi - ENDIF - - CASE ( WindProfileType_Constant ) - - U = p%MeanFFWS - - CASE DEFAULT - - U = 0.0_ReKi - - END SELECT - - - IF (p%VLinShr .NE. 0.0_ReKi) THEN ! Add vertical linear shear, if has - U = U + p%MeanFFWS * p%VLinShr * (Z - p%RefHt) / p%RefLength - ENDIF - - - IF (p%HLinShr .NE. 0.0_ReKi) THEN ! Add horizontal linear shear, if has - U = U + p%MeanFFWS * p%HLinShr * y / p%RefLength - ENDIF - -END FUNCTION CalculateMeanVelocity -!==================================================================================================== -!> This routine is used to add a subtract the mean wind speed from turbulence data (so that the added mean can be added later). -!! Note that this does NOT scale using the length of the wind simulation, so there may be differences with the HAWC implementation. -SUBROUTINE SubtractMeanVelocity(FFData) - - ! Passed Variables - REAL(SiKi), INTENT(INOUT) :: FFData(:,:,:,:) !< FF wind-inflow data - - ! Local Variables: - REAL(ReKi) :: MeanVal ! computed mean wind speed - INTEGER(IntKi) :: ic ! loop counter - INTEGER(IntKi) :: iy ! loop counter - INTEGER(IntKi) :: iz ! loop counter - INTEGER(IntKi) :: nt ! number of points in the x (time) direction - - - nt = size(FFData,4) - - DO ic = 1,1 !size(FFData,3) - DO iy = 1,size(FFData,2) - DO iz = 1,size(FFData,1) - meanVal = sum(FFData(iz,iy,ic,:)) / nt - - FFData( iz,iy,ic,: ) = FFData( iz,iy,ic,: ) - meanVal - END DO ! iz - END DO ! iy - END DO ! ic - - -END SUBROUTINE SubtractMeanVelocity -!==================================================================================================== -!> This routine is used to make sure the initInp data is valid. -SUBROUTINE FFWind_ValidateInput(InitInp, nffc, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_FFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - INTEGER(IntKi), INTENT(IN ) :: nffc !< number of full-field wind components (normally 3) - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - character(*), parameter :: RoutineName = 'FFWind_ValidateInput' - - integer(intki) :: ic ! loop counter - - ErrStat = ErrID_None - ErrMsg = "" - - IF ( InitInp%RefHt < 0.0_ReKi .or. EqualRealNos( InitInp%RefHt, 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'The grid reference height must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - - if ( InitInp%ScaleMethod == ScaleMethod_Direct) then - do ic=1,nffc - if ( InitInp%sf(ic) < 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'Turbulence scaling factors must not be negative.', ErrStat, ErrMsg, RoutineName ) - end do - elseif ( InitInp%ScaleMethod == ScaleMethod_StdDev ) then - do ic=1,nffc - if ( InitInp%sigmaf(ic) < 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'Turbulence standard deviations must not be negative.', ErrStat, ErrMsg, RoutineName ) - end do -#ifdef UNUSED_INPUTFILE_LINES - if ( InitInp%TStart < 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'TStart for turbulence standard deviation calculations must not be negative.', ErrStat, ErrMsg, RoutineName ) - if ( InitInp%TEnd <= InitInp%TStart ) CALL SetErrStat( ErrID_Fatal, 'TEnd for turbulence standard deviation calculations must be after TStart.', ErrStat, ErrMsg, RoutineName ) -#endif - elseif ( InitInp%ScaleMethod /= ScaleMethod_None ) then - CALL SetErrStat( ErrID_Fatal, 'Turbulence scaling method must be 0 (none), 1 (direct scaling factors), or 2 (target standard deviation).', ErrStat, ErrMsg, RoutineName ) - end if - - - if (InitInp%WindProfileType == WindProfileType_Log) then - if ( InitInp%z0 < 0.0_ReKi .or. EqualRealNos( InitInp%z0, 0.0_ReKi ) ) & - call SetErrStat( ErrID_Fatal, 'The surface roughness length, Z0, must be greater than zero', ErrStat, ErrMsg, RoutineName ) - elseif ( InitInp%WindProfileType < WindProfileType_Constant .or. InitInp%WindProfileType > WindProfileType_PL) then - call SetErrStat( ErrID_Fatal, 'The WindProfile type must be 0 (constant), 1 (logarithmic) or 2 (power law).', ErrStat, ErrMsg, RoutineName ) - end if - - IF ( InitInp%URef < 0.0_ReKi ) call SetErrStat( ErrID_Fatal, 'The reference wind speed must not be negative.', ErrStat, ErrMsg, RoutineName ) - - IF ( EqualRealNos(InitInp%RefLength, 0.0_ReKi) .or. InitInp%RefLength < 0.0_ReKi ) THEN - IF (InitInp%VLinShr /= 0.0_ReKi .OR. InitInp%HLinShr /= 0.0_ReKi) THEN - call SetErrStat( ErrID_Fatal, 'The reference length must be a positive number when vertical or horizontal linear shear is used.', ErrStat, ErrMsg, RoutineName ) - END IF - END IF - -END SUBROUTINE FFWind_ValidateInput -!==================================================================================================== -SUBROUTINE ConvertFFWind_to_HAWC2(FileRootName, p, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - REAL(SiKi) :: delta(3) - - delta(1) = p%MeanFFWS * p%FFDTime - delta(2) = 1.0_SiKi / p%InvFFYD - delta(3) = 1.0_SiKi / p%InvFFZD - - CALL WrBinHAWC(FileRootName, p%FFData(:,:,:,1:p%NFFSteps), delta, ErrStat, ErrMsg) - - IF (.NOT. p%Periodic) THEN - call SetErrStat( ErrID_Severe, 'File converted to HAWC format is not periodic. Jumps may occur in resulting simulation.', & - ErrStat, ErrMsg, 'ConvertFFWind_to_HAWC2') - END IF - -END SUBROUTINE ConvertFFWind_to_HAWC2 -!==================================================================================================== -SUBROUTINE ConvertFFWind_to_Bladed(FileRootName, p, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - REAL(SiKi) :: delta(3) - - delta(1) = p%MeanFFWS * p%FFDTime - delta(2) = 1.0_SiKi / p%InvFFYD - delta(3) = 1.0_SiKi / p%InvFFZD - - CALL WrBinBladed(FileRootName, p%FFData(:,:,:,1:p%NFFSteps), delta, p%MeanFFWS, p%RefHt, p%GridBase, p%Periodic, p%AddMeanAfterInterp, ErrStat, ErrMsg) - -END SUBROUTINE ConvertFFWind_to_Bladed -!================================================================================================================================== -SUBROUTINE WrBinHAWC(FileRootName, FFWind, delta, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN) :: FileRootName !< Name of the file to write the output in - REAL(SiKi), INTENT(IN) :: FFWind(:,:,:,:) !< 4D wind speeds: index 1=z (height), 2=y (lateral), 3=dimension(u,v,w), 4=time or x - REAL(SiKi), INTENT(IN) :: delta(3) !< array containing dx, dy, dz in meters - INTEGER(IntKi), INTENT(OUT):: ErrStat !< Indicates whether an error occurred (see NWTC_Library) - CHARACTER(*), INTENT(OUT):: ErrMsg !< Error message associated with the ErrStat - - ! local variables - CHARACTER(*), PARAMETER :: Comp(3) = (/'u','v','w'/) - INTEGER(IntKi), PARAMETER :: AryDim(3) = (/4, 2, 1/) ! x,y,z dimensions of FFWind array - INTEGER(IntKi) :: nc - INTEGER(IntKi) :: IC, IX, IY, IZ - INTEGER(IntKi) :: UnWind - !REAL(SiKi) :: MeanVal(size(FFWind,1),size(FFWind,2)) - REAL(SiKi) :: MeanVal(size(FFWind,1)) - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'WrBinHAWC' - CHARACTER(1024) :: RootWithoutPathName - - ErrStat = ErrID_None - ErrMsg = "" - - CALL GetNewUnit( UnWind, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - nc = size(FFWind,3) ! check that nc == 3 ???? - - ! need to remove time-average value from DIM=1 - MeanVal = 0.0_SiKi - DO IX = 1,size(FFWind,4) - MeanVal = MeanVal + FFWind(:,1,1,ix) - END DO - MeanVal = MeanVal / size(FFWind,4) - - - ! write the summary file - CALL OpenFOutFile ( UnWind, trim(FileRootName)//'-HAWC.sum', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - WRITE( UnWind, '(A)' ) '; Wind file converted to HAWC format on '//CurDate()//' at '//CurTime() - - WRITE( UnWind, '()' ) - DO IZ = size(FFWind,AryDim(3)),1,-1 - WRITE( UnWind, '(A,I3,A,F15.5)' ) '; mean removed at z(', iz, ') = ', MeanVal(iz) - END DO - - WRITE( UnWind, '(A)' ) 'turb_format 1 ;' -! WRITE( UnWind, '(A)' ) 'center_pos0 0.0 0.0 '//trim(num2lstr( ';' - - WRITE( UnWind, '()' ) - WRITE( UnWind, '(A)' ) 'begin mann;' - - ic = INDEX( FileRootName, '\', BACK=.TRUE. ) - ic = MAX( ic, INDEX( FileRootName, '/', BACK=.TRUE. ) ) - RootWithoutPathName = FileRootName((ic+1):) - - - DO IC = 1,nc - WRITE( UnWind, '(2x,A, T30, A, " ;")' ) 'filename_'//Comp(IC), trim(RootWithoutPathName)//'-HAWC-'//Comp(IC)//'.bin' - END DO - DO IC = 1,nc - WRITE( UnWind, '(2x,A, T30, I8, 1x, F15.5, " ;")' ) 'box_dim_'//Comp(IC), size( FFWind, AryDim(ic) ), delta(ic) - END DO - WRITE( UnWind, '(2x,A)' ) 'dont_scale 1; converter did not rescale turbulence to unit standard deviation' - WRITE( UnWind, '(A)' ) 'end mann;' - CLOSE ( UnWind ) - - - ! write the binary files for each component - - DO IC = 1,nc - - CALL OpenBOutFile ( UnWind, trim(FileRootName)//'-HAWC-'//Comp(ic)//'.bin', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - DO IX = 1,size(FFWind,AryDim(1)) - DO IY = size(FFWind,AryDim(2)),1,-1 - WRITE( UnWind, IOSTAT=ErrStat2 ) FFWind(:,iy,ic,ix) - MeanVal(:) ! note that FFWind is SiKi (4-byte reals, not default kinds) - END DO - END DO - - CLOSE ( UnWind ) - - MeanVal = 0.0_SiKi - - END DO - -END SUBROUTINE WrBinHAWC -!================================================================================================================================== -SUBROUTINE WrBinBladed(FileRootName, FFWind, delta, MeanFFWS, HubHt, GridBase, Periodic, AddMeanAfterInterp, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN) :: FileRootName !< Name of the file to write the output in - REAL(SiKi), INTENT(IN) :: FFWind(:,:,:,:) !< 4D wind speeds: index 1=z (height), 2=y (lateral), 3=dimension(u,v,w), 4=time or x - REAL(SiKi), INTENT(IN) :: delta(3) !< array containing dx, dy, dz in meters - REAL(ReKi), INTENT(IN) :: MeanFFWS !< advection speed (mean wind speed at hub) - REAL(ReKi), INTENT(IN) :: HubHt !< hub height - REAL(ReKi), INTENT(IN) :: GridBase !< height of lowest grid point - LOGICAL, INTENT(IN) :: Periodic !< whether this wind file is periodic - LOGICAL, INTENT(IN) :: AddMeanAfterInterp !< whether this wind file contains a mean longditudinal wind speed - INTEGER(IntKi), INTENT(OUT):: ErrStat !< Indicates whether an error occurred (see NWTC_Library) - CHARACTER(*), INTENT(OUT):: ErrMsg !< Error message associated with the ErrStat - - ! local variables - INTEGER(IntKi), PARAMETER :: AryDim(3) = (/4, 2, 1/) ! x,y,z dimensions of FFWind array - INTEGER(IntKi) :: ic, it, iy, iz - INTEGER(IntKi) :: UnWind - REAL(SiKi) :: MeanVal(size(FFWind,1),size(FFWind,2)) - REAL(SiKi) :: SigmaGrid( size(FFWind,1),size(FFWind,2)) - REAL(SiKi) :: TI(3) !< array containing turbulence intensity (for scaling factors) - REAL(SiKi) :: Sigma(3) !< array containing standard deviations (for scaling factors) - REAL(SiKi) :: Scl(3) !< array containing scaling factors - REAL(SiKi) :: Off(3) !< array containing offsets - REAL(SiKi) :: Tmp - REAL(ReKi) :: MeanFFWS_nonZero !< advection speed (mean wind speed at hub) - - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'WrBinBladed' - - REAL(SiKi), PARAMETER :: Tolerance = 0.0001 ! The largest difference between two numbers that are assumed to be equal - - - ErrStat = ErrID_None - ErrMsg = "" - - !----------------------------------------------------- - ! Calculate the stats - !----------------------------------------------------- - - do ic=3,1,-1 - - ! mean values: - MeanVal = 0.0_SiKi - DO it = 1,size(FFWind,AryDim(1)) - MeanVal = MeanVal + FFWind(:,:,ic,it) - END DO - MeanVal = MeanVal / real( size(FFWind,AryDim(1)), SiKi) - - ! standard deviations (with 1/N scaling factor): - SigmaGrid = 0.0_SiKi - DO it = 1,size(FFWind,4) - SigmaGrid = SigmaGrid + FFWind(:,:,ic,it)**2 - END DO - SigmaGrid = SigmaGrid / size(FFWind,AryDim(1)) - SigmaGrid = SQRT( MAX( SigmaGrid - MeanVal**2, 0.0_SiKi ) ) - - ! now get the average standard deviation for each component: - Sigma(ic) = sum(SigmaGrid)/size(SigmaGrid) ! get the average sigma over the grid - Sigma(ic) = MAX(100.0_SiKi*Tolerance, Sigma(ic)) ! make sure this scaling isn't too small - - end do - - ! We need to take into account the shear across the grid in the sigma calculations for scaling the data, - ! and ensure that 32.767*sigma_u >= |V-UHub| so that we don't get values out of the range of our scaling values - ! in this BLADED-style binary output. Tmp is |V-UHub| - Tmp = MAX( ABS(MAXVAL(FFWind(:,:,1,:))-MeanFFWS), ABS(MINVAL(FFWind(:,:,1,:))-MeanFFWS) ) !Get the range of wind speed values for scaling in BLADED-format .wnd files - Sigma(1) = MAX(Sigma(1),0.05_SiKi*Tmp) - do ic=2,3 - Sigma(ic) = MAX( Sigma(ic), 0.05_SiKi*ABS(MAXVAL(FFWind(:,:,ic,:))), 0.05_SiKi*ABS(MINVAL(FFWind(:,:,ic,:))) ) ! put the abs() after the maxval() and minval() to avoid stack-overflow issues with large wind files - end do - - ! Put normalizing factors into the summary file. The user can use them to - ! tell a simulation program how to rescale the data. - - if ( abs(MeanFFWS) < 0.1_ReKi ) then - MeanFFWS_nonZero = sign( 0.1, MeanFFWS ) - else - MeanFFWS_nonZero = MeanFFWS - end if - - TI = Sigma / MeanFFWS_nonZero - - !----------------------------------------------------- - ! The summary file - !----------------------------------------------------- - CALL GetNewUnit( UnWind, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - CALL OpenFOutFile ( UnWind, trim(FileRootName)//'-Bladed.sum', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - !The string "TurbSim" needs to be in the 2nd line of the summary file if AeroDyn will read this. - WRITE( UnWind,"( / 'TurbSim - This summary file was generated by ', A, ' on ' , A , ' at ' , A , '.' / )") "NWTC_Library", CurDate(), CurTime() - WRITE( UnWind, '(/)' ) - WRITE( UnWind, '(/)' ) - WRITE( UnWind, '( L10, 2X, "Clockwise rotation when looking downwind?")' ) .FALSE. - WRITE( UnWind, '( F10.3, 2X, "Hub height [m]")' ) HubHt - WRITE( UnWind, '( F10.3, 2X, "Grid height [m]")' ) delta(3)*(size(FFWind,AryDim(3)) - 1) - WRITE( UnWind, '( F10.3, 2X, "Grid width [m]")' ) delta(2)*(size(FFWind,AryDim(2)) - 1) - WRITE( UnWind, '(/"BLADED-style binary scaling parameters:"/)' ) - WRITE( UnWind, '( 2X, "UBar = ", F9.4, " m/s")' ) MeanFFWS_nonZero - WRITE( UnWind, '( 2X, "TI(u) = ", F9.4, " %")' ) 100.0*TI(1) - WRITE( UnWind, '( 2X, "TI(v) = ", F9.4, " %")' ) 100.0*TI(2) - WRITE( UnWind, '( 2X, "TI(w) = ", F9.4, " %")' ) 100.0*TI(3) - WRITE( UnWind, '(/)' ) - WRITE( UnWind, '( 2X, "Height offset = ", F9.4, " m" )' ) HubHt - 0.5*delta(3)*(size(FFWind,AryDim(3)) - 1) - GridBase ! This will be zero for square grids - ! ZGOffset = ( HubHt - delta(3)*(size(FFWind,1) - 1) / 2.0 - Zbottom ) - WRITE( UnWind, '( 2X, "Grid Base = ", F9.4, " m" )' ) GridBase - if (Periodic) then - WRITE (UnWind,'()' ) - WRITE (UnWind,'( A)' ) 'Creating a PERIODIC output file.' - end if - WRITE (UnWind,'( A)' ) 'Creating a BLADED LEFT-HAND RULE output file.' - - - CLOSE (UnWind) - - !----------------------------------------------------- - ! The BINARY file - !----------------------------------------------------- - CALL OpenBOutFile ( UnWind, TRIM(FileRootName)//'-Bladed.wnd', ErrStat, ErrMsg ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - WRITE (UnWind) INT( -99 , B2Ki ) ! -99 = New Bladed format - WRITE (UnWind) INT( 4 , B2Ki ) ! 4 = improved von karman (not used, but needed for next 7 inputs) - WRITE (UnWind) INT( size(FFWind,3) , B4Ki ) ! size(FFWind,3) = 3 = number of wind components - WRITE (UnWind) REAL( 45.0_SiKi , SiKi ) ! Latitude (degrees) (informational, not used in FAST) - WRITE (UnWind) REAL( 0.03_SiKi , SiKi ) ! Roughness length (m) (informational, not used in FAST) - WRITE (UnWind) REAL( HubHt , SiKi ) ! Reference Height (m) (informational, not used in FAST) - WRITE (UnWind) REAL( 100.0*TI(1) , SiKi ) ! Longitudinal turbulence intensity (%) - WRITE (UnWind) REAL( 100.0*TI(2) , SiKi ) ! Lateral turbulence intensity (%) - WRITE (UnWind) REAL( 100.0*TI(3) , SiKi ) ! Vertical turbulence intensity (%) - - WRITE (UnWind) REAL( delta(3) , SiKi ) ! grid spacing in vertical direction, in m - WRITE (UnWind) REAL( delta(2) , SiKi ) ! grid spacing in lateral direction, in m - WRITE (UnWind) REAL( delta(1) , SiKi ) ! grid spacing in longitudinal direciton, in m - WRITE (UnWind) INT( size(FFWind,AryDim(1))/2 , B4Ki ) ! half the number of points in alongwind direction - WRITE (UnWind) REAL( MeanFFWS_nonZero , SiKi ) ! the mean wind speed in m/s - WRITE (UnWind) REAL( 0 , SiKi ) ! the vertical length scale of the longitudinal component in m - WRITE (UnWind) REAL( 0 , SiKi ) ! the lateral length scale of the longitudinal component in m - WRITE (UnWind) REAL( 0 , SiKi ) ! the longitudinal length scale of the longitudinal component in m - WRITE (UnWind) INT( 0 , B4Ki ) ! an unused integer - WRITE (UnWind) INT( 0 , B4Ki ) ! the random number seed - WRITE (UnWind) INT( size(FFWind,AryDim(3)) , B4Ki ) ! the number of grid points vertically - WRITE (UnWind) INT( size(FFWind,AryDim(2)) , B4Ki ) ! the number of grid points laterally - WRITE (UnWind) INT( 0 , B4Ki ) ! the vertical length scale of the lateral component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the lateral length scale of the lateral component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the longitudinal length scale of the lateral component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the vertical length scale of the vertical component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the lateral length scale of the vertical component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the longitudinal length scale of the vertical component, not used - - ! Scaling value to convert wind speeds to 16-bit integers - do ic = 1,3 - if (.not. EqualRealNos( Sigma(ic), 0.0_SiKi ) ) then - Scl(ic) = 1000.0/( Sigma(ic) ) - else - Scl(ic) = 1.0_SiKi - end if - end do - Scl(2) = -Scl(2) ! Bladed convention is positive V is pointed along negative Y (IEC turbine coordinate) - - ! Offset value to convert wind speeds to 16-bit integers - IF (AddMeanAfterInterp) THEN ! Note that this will not take into account any shear!!! - Off(1) = 0.0 - ELSE - Off(1) = MeanFFWS * Scl(1) - END IF - Off(2) = 0.0 - Off(3) = 0.0 - - DO it=1,size(FFWind,AryDim(1)) - DO iz=1,size(FFWind,AryDim(3)) ! 1=bottom of grid - DO iy=1,size(FFWind,AryDim(2)) ! 1=left of grid, i.e. y(1) = -GridWidth/2 - - ! Scale velocity for 16-bit integers: - WRITE ( UnWind ) NINT( FFWind(iz,iy,:,it) * Scl - Off , B2Ki ) ! scale to int16 - - ENDDO !IY - ENDDO !IZ - ENDDO !IT - - CLOSE( UnWind ) - - -END SUBROUTINE WrBinBladed -!==================================================================================================== -SUBROUTINE ConvertFFWind_toVTK(FileRootName, p, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - CHARACTER(1024) :: RootPathName - CHARACTER(1024) :: FileName - INTEGER :: UnWind - INTEGER :: i - INTEGER :: iy - INTEGER :: iz - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ConvertFFWind_toVTK' - - - CALL GetPath ( FileRootName, RootPathName ) - CALL GetNewUnit( UnWind, ErrStat, ErrMsg ) - - do i = 1,p%NFFSteps - - ! Create the output vtk file with naming /vtk/DisYZ.t.vtk - - RootPathName = trim(RootPathName)//PathSep//"vtk" - call MkDir( trim(RootPathName) ) ! make this directory if it doesn't already exist - - !FileName = trim(RootPathName)//PathSep//"vtk"//PathSep//"DisYZ.t"//trim(num2lstr(i))//".vtp" - FileName = trim(RootPathName)//PathSep//"DisYZ.t"//trim(num2lstr(i))//".vtp" - - ! see WrVTK_SP_header - CALL OpenFOutFile ( UnWind, TRIM(FileName), ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >= AbortErrLev) return - - WRITE(UnWind,'(A)') '# vtk DataFile Version 3.0' - WRITE(UnWind,'(A)') "InflowWind YZ Slice at T= "//trim(num2lstr((i-1)*p%FFDTime))//" s" - WRITE(UnWind,'(A)') 'ASCII' - WRITE(UnWind,'(A)') 'DATASET STRUCTURED_POINTS' - - ! Note: gridVals must be stored such that the left-most dimension is X and the right-most dimension is Z - ! see WrVTK_SP_vectors3D() - WRITE(UnWind,'(A,3(i5,1X))') 'DIMENSIONS ', 1, p%NYGrids, p%NZGrids - WRITE(UnWind,'(A,3(f10.2,1X))') 'ORIGIN ' , p%InitXPosition, -p%FFYHWid, p%GridBase - WRITE(UnWind,'(A,3(f10.2,1X))') 'SPACING ' , 0.0_ReKi, 1.0_SiKi / p%InvFFYD, 1.0_SiKi / p%InvFFZD - WRITE(UnWind,'(A,i5)') 'POINT_DATA ', p%NYGrids*p%NZGrids - WRITE(UnWind,'(A)') 'VECTORS DisYZ float' - - DO iz=1,p%NZGrids - DO iy=1,p%NYGrids - WRITE(UnWind,'(3(f10.2,1X))') p%FFData(iz,iy,:,i) - END DO - END DO - - CLOSE(UnWind) - - end do - - -END SUBROUTINE ConvertFFWind_toVTK - - -!==================================================================================================== - -END MODULE IfW_FFWind_Base diff --git a/modules/inflowwind/src/IfW_FFWind_Base.txt b/modules/inflowwind/src/IfW_FFWind_Base.txt deleted file mode 100644 index 1febd8d685..0000000000 --- a/modules/inflowwind/src/IfW_FFWind_Base.txt +++ /dev/null @@ -1,59 +0,0 @@ -################################################################################################################################### -# Registry for IfW_BladedFFWind, creates MODULE IfW_BladedFFWind_Types -# Module IfW_BladedFFWind_Types contains all of the user-defined types needed in IfW_BladedFFWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - - -typedef IfW_FFWind_Base/IfW_FFWind InitInputType IntKi ScaleMethod - 0 - "Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation]" - -typedef ^ ^ ReKi SF 3 0 - "Turbulence scaling factor for each direction [ScaleMethod=1]" - -typedef ^ ^ ReKi SigmaF 3 0 - "Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2]" - -#typedef ^ ^ ReKi TStart - 0 - "" - -#typedef ^ ^ ReKi TEnd - 0 - "" - -typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - -typedef ^ ^ ReKi RefHt - 0 - "Reference (hub) height of the grid" meters -typedef ^ ^ ReKi URef - 0 - "Mean u-component wind speed at the reference height" meters -typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - -typedef ^ ^ ReKi VLinShr - 0 - "Vertical linear wind shear coefficient (used for vertical linear wind profile type only)" - -typedef ^ ^ ReKi HLinShr - 0 - "Horizontal linear wind shear coefficient (used for horizontal wind profile type only)" - -typedef ^ ^ ReKi RefLength - 1.0_ReKi - "Reference (rotor) length of the grid (used for horizontal wind profile type only)" - -typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - -typedef ^ ^ ReKi XOffset - 0 - "distance offset for FF wind files" m - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType Logical Periodic - .FALSE. - "Flag to indicate if the wind file is periodic" - -typedef ^ ParameterType Logical InterpTower - .FALSE. - "Flag to indicate if we should interpolate wind speeds below the tower" - -typedef ^ ^ SiKi FFData :::: - - "Array of FF data" - -typedef ^ ^ SiKi FFTower ::: - - "Array of data along tower, below FF array" - -typedef ^ ^ ReKi FFDTime - 0 - "Delta time" seconds -typedef ^ ^ ReKi FFRate - 0 - "Data rate (1/FFDTime)" Hertz -typedef ^ ^ ReKi FFYHWid - 0 - "Half the grid width" meters -typedef ^ ^ ReKi FFZHWid - 0 - "Half the grid height" meters -typedef ^ ^ ReKi RefHt - 0 - "Reference (hub) height of the grid" meters -typedef ^ ^ ReKi GridBase - 0 - "the height of the bottom of the grid" meters -typedef ^ ^ ReKi InitXPosition - 0 - "the initial x position of grid (distance in FF is offset)" meters -typedef ^ ^ ReKi InvFFYD - 0 - "reciprocal of delta y" 1/meters -typedef ^ ^ ReKi InvFFZD - 0 - "reciprocal of delta z" 1/meters -typedef ^ ^ ReKi InvMFFWS - 0 - "reciprocal of mean wind speed (MeanFFWS)" seconds/meter -typedef ^ ^ ReKi MeanFFWS - 0 - "Mean wind speed (as defined in FF file), not necessarily of the portion used" meters/second -typedef ^ ^ ReKi TotalTime - 0 - "The total time of the simulation" seconds -typedef ^ ^ IntKi NFFComp - 3 - "Number of wind components" - -typedef ^ ^ IntKi NFFSteps - 0 - "Number of time steps in the FF array" - -typedef ^ ^ IntKi NYGrids - 0 - "Number of points in the lateral (y) direction of the grids" - -typedef ^ ^ IntKi NZGrids - 0 - "Number of points in the vertical (z) direction of the grids" - -typedef ^ ^ IntKi NTGrids - 0 - "Number of points in the vertical (z) direction on the tower (below the grids)" - -typedef ^ ^ IntKi WindFileFormat - - - "Binary file format description number" - -typedef ^ ^ Logical AddMeanAfterInterp - .FALSE. - "Add the mean wind speed after interpolating at a given height?" - -typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - -typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - -typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - -typedef ^ ^ ReKi VLinShr - 0 - "Vertical linear wind shear coefficient (used for vertical linear wind profile type only)" - -typedef ^ ^ ReKi HLinShr - 0 - "Horizontal linear wind shear coefficient (used for horizontal wind profile type only)" - -typedef ^ ^ ReKi RefLength - 1.0_ReKi - "Reference (rotor) length of the grid (used for horizontal wind profile type only)" - - diff --git a/modules/inflowwind/src/IfW_FFWind_Base_Types.f90 b/modules/inflowwind/src/IfW_FFWind_Base_Types.f90 deleted file mode 100644 index 9f5c55c5d2..0000000000 --- a/modules/inflowwind/src/IfW_FFWind_Base_Types.f90 +++ /dev/null @@ -1,777 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_FFWind_Base_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_FFWind_Base_Types -!................................................................................................................................. -! This file is part of IfW_FFWind_Base. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_FFWind_Base. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_FFWind_Base_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_FFWind_InitInputType ======= - TYPE, PUBLIC :: IfW_FFWind_InitInputType - INTEGER(IntKi) :: ScaleMethod = 0 !< Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation] [-] - REAL(ReKi) , DIMENSION(1:3) :: SF !< Turbulence scaling factor for each direction [ScaleMethod=1] [-] - REAL(ReKi) , DIMENSION(1:3) :: SigmaF !< Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2] [-] - INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] - REAL(ReKi) :: RefHt = 0 !< Reference (hub) height of the grid [meters] - REAL(ReKi) :: URef = 0 !< Mean u-component wind speed at the reference height [meters] - REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] - REAL(ReKi) :: VLinShr = 0 !< Vertical linear wind shear coefficient (used for vertical linear wind profile type only) [-] - REAL(ReKi) :: HLinShr = 0 !< Horizontal linear wind shear coefficient (used for horizontal wind profile type only) [-] - REAL(ReKi) :: RefLength = 1.0_ReKi !< Reference (rotor) length of the grid (used for horizontal wind profile type only) [-] - REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] - REAL(ReKi) :: XOffset = 0 !< distance offset for FF wind files [m] - END TYPE IfW_FFWind_InitInputType -! ======================= -! ========= IfW_FFWind_ParameterType ======= - TYPE, PUBLIC :: IfW_FFWind_ParameterType - LOGICAL :: Periodic = .FALSE. !< Flag to indicate if the wind file is periodic [-] - LOGICAL :: InterpTower = .FALSE. !< Flag to indicate if we should interpolate wind speeds below the tower [-] - REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: FFData !< Array of FF data [-] - REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: FFTower !< Array of data along tower, below FF array [-] - REAL(ReKi) :: FFDTime = 0 !< Delta time [seconds] - REAL(ReKi) :: FFRate = 0 !< Data rate (1/FFDTime) [Hertz] - REAL(ReKi) :: FFYHWid = 0 !< Half the grid width [meters] - REAL(ReKi) :: FFZHWid = 0 !< Half the grid height [meters] - REAL(ReKi) :: RefHt = 0 !< Reference (hub) height of the grid [meters] - REAL(ReKi) :: GridBase = 0 !< the height of the bottom of the grid [meters] - REAL(ReKi) :: InitXPosition = 0 !< the initial x position of grid (distance in FF is offset) [meters] - REAL(ReKi) :: InvFFYD = 0 !< reciprocal of delta y [1/meters] - REAL(ReKi) :: InvFFZD = 0 !< reciprocal of delta z [1/meters] - REAL(ReKi) :: InvMFFWS = 0 !< reciprocal of mean wind speed (MeanFFWS) [seconds/meter] - REAL(ReKi) :: MeanFFWS = 0 !< Mean wind speed (as defined in FF file), not necessarily of the portion used [meters/second] - REAL(ReKi) :: TotalTime = 0 !< The total time of the simulation [seconds] - INTEGER(IntKi) :: NFFComp = 3 !< Number of wind components [-] - INTEGER(IntKi) :: NFFSteps = 0 !< Number of time steps in the FF array [-] - INTEGER(IntKi) :: NYGrids = 0 !< Number of points in the lateral (y) direction of the grids [-] - INTEGER(IntKi) :: NZGrids = 0 !< Number of points in the vertical (z) direction of the grids [-] - INTEGER(IntKi) :: NTGrids = 0 !< Number of points in the vertical (z) direction on the tower (below the grids) [-] - INTEGER(IntKi) :: WindFileFormat !< Binary file format description number [-] - LOGICAL :: AddMeanAfterInterp = .FALSE. !< Add the mean wind speed after interpolating at a given height? [-] - INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] - REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] - REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] - REAL(ReKi) :: VLinShr = 0 !< Vertical linear wind shear coefficient (used for vertical linear wind profile type only) [-] - REAL(ReKi) :: HLinShr = 0 !< Horizontal linear wind shear coefficient (used for horizontal wind profile type only) [-] - REAL(ReKi) :: RefLength = 1.0_ReKi !< Reference (rotor) length of the grid (used for horizontal wind profile type only) [-] - END TYPE IfW_FFWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_FFWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_FFWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_FFWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%ScaleMethod = SrcInitInputData%ScaleMethod - DstInitInputData%SF = SrcInitInputData%SF - DstInitInputData%SigmaF = SrcInitInputData%SigmaF - DstInitInputData%WindProfileType = SrcInitInputData%WindProfileType - DstInitInputData%RefHt = SrcInitInputData%RefHt - DstInitInputData%URef = SrcInitInputData%URef - DstInitInputData%PLExp = SrcInitInputData%PLExp - DstInitInputData%VLinShr = SrcInitInputData%VLinShr - DstInitInputData%HLinShr = SrcInitInputData%HLinShr - DstInitInputData%RefLength = SrcInitInputData%RefLength - DstInitInputData%Z0 = SrcInitInputData%Z0 - DstInitInputData%XOffset = SrcInitInputData%XOffset - END SUBROUTINE IfW_FFWind_CopyInitInput - - SUBROUTINE IfW_FFWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_FFWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_DestroyInitInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_FFWind_DestroyInitInput - - SUBROUTINE IfW_FFWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_FFWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! ScaleMethod - Re_BufSz = Re_BufSz + SIZE(InData%SF) ! SF - Re_BufSz = Re_BufSz + SIZE(InData%SigmaF) ! SigmaF - Int_BufSz = Int_BufSz + 1 ! WindProfileType - Re_BufSz = Re_BufSz + 1 ! RefHt - Re_BufSz = Re_BufSz + 1 ! URef - Re_BufSz = Re_BufSz + 1 ! PLExp - Re_BufSz = Re_BufSz + 1 ! VLinShr - Re_BufSz = Re_BufSz + 1 ! HLinShr - Re_BufSz = Re_BufSz + 1 ! RefLength - Re_BufSz = Re_BufSz + 1 ! Z0 - Re_BufSz = Re_BufSz + 1 ! XOffset - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%ScaleMethod - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%SF,1), UBOUND(InData%SF,1) - ReKiBuf(Re_Xferred) = InData%SF(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%SigmaF,1), UBOUND(InData%SigmaF,1) - ReKiBuf(Re_Xferred) = InData%SigmaF(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%WindProfileType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%URef - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PLExp - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VLinShr - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%HLinShr - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefLength - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Z0 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%XOffset - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_PackInitInput - - SUBROUTINE IfW_FFWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_FFWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%ScaleMethod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%SF,1) - i1_u = UBOUND(OutData%SF,1) - DO i1 = LBOUND(OutData%SF,1), UBOUND(OutData%SF,1) - OutData%SF(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%SigmaF,1) - i1_u = UBOUND(OutData%SigmaF,1) - DO i1 = LBOUND(OutData%SigmaF,1), UBOUND(OutData%SigmaF,1) - OutData%SigmaF(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%WindProfileType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%URef = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PLExp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VLinShr = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%HLinShr = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefLength = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Z0 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%XOffset = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_UnPackInitInput - - SUBROUTINE IfW_FFWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_FFWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%Periodic = SrcParamData%Periodic - DstParamData%InterpTower = SrcParamData%InterpTower -IF (ALLOCATED(SrcParamData%FFData)) THEN - i1_l = LBOUND(SrcParamData%FFData,1) - i1_u = UBOUND(SrcParamData%FFData,1) - i2_l = LBOUND(SrcParamData%FFData,2) - i2_u = UBOUND(SrcParamData%FFData,2) - i3_l = LBOUND(SrcParamData%FFData,3) - i3_u = UBOUND(SrcParamData%FFData,3) - i4_l = LBOUND(SrcParamData%FFData,4) - i4_u = UBOUND(SrcParamData%FFData,4) - IF (.NOT. ALLOCATED(DstParamData%FFData)) THEN - ALLOCATE(DstParamData%FFData(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FFData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%FFData = SrcParamData%FFData -ENDIF -IF (ALLOCATED(SrcParamData%FFTower)) THEN - i1_l = LBOUND(SrcParamData%FFTower,1) - i1_u = UBOUND(SrcParamData%FFTower,1) - i2_l = LBOUND(SrcParamData%FFTower,2) - i2_u = UBOUND(SrcParamData%FFTower,2) - i3_l = LBOUND(SrcParamData%FFTower,3) - i3_u = UBOUND(SrcParamData%FFTower,3) - IF (.NOT. ALLOCATED(DstParamData%FFTower)) THEN - ALLOCATE(DstParamData%FFTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FFTower.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%FFTower = SrcParamData%FFTower -ENDIF - DstParamData%FFDTime = SrcParamData%FFDTime - DstParamData%FFRate = SrcParamData%FFRate - DstParamData%FFYHWid = SrcParamData%FFYHWid - DstParamData%FFZHWid = SrcParamData%FFZHWid - DstParamData%RefHt = SrcParamData%RefHt - DstParamData%GridBase = SrcParamData%GridBase - DstParamData%InitXPosition = SrcParamData%InitXPosition - DstParamData%InvFFYD = SrcParamData%InvFFYD - DstParamData%InvFFZD = SrcParamData%InvFFZD - DstParamData%InvMFFWS = SrcParamData%InvMFFWS - DstParamData%MeanFFWS = SrcParamData%MeanFFWS - DstParamData%TotalTime = SrcParamData%TotalTime - DstParamData%NFFComp = SrcParamData%NFFComp - DstParamData%NFFSteps = SrcParamData%NFFSteps - DstParamData%NYGrids = SrcParamData%NYGrids - DstParamData%NZGrids = SrcParamData%NZGrids - DstParamData%NTGrids = SrcParamData%NTGrids - DstParamData%WindFileFormat = SrcParamData%WindFileFormat - DstParamData%AddMeanAfterInterp = SrcParamData%AddMeanAfterInterp - DstParamData%WindProfileType = SrcParamData%WindProfileType - DstParamData%PLExp = SrcParamData%PLExp - DstParamData%Z0 = SrcParamData%Z0 - DstParamData%VLinShr = SrcParamData%VLinShr - DstParamData%HLinShr = SrcParamData%HLinShr - DstParamData%RefLength = SrcParamData%RefLength - END SUBROUTINE IfW_FFWind_CopyParam - - SUBROUTINE IfW_FFWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_DestroyParam' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - -IF (ALLOCATED(ParamData%FFData)) THEN - DEALLOCATE(ParamData%FFData) -ENDIF -IF (ALLOCATED(ParamData%FFTower)) THEN - DEALLOCATE(ParamData%FFTower) -ENDIF - END SUBROUTINE IfW_FFWind_DestroyParam - - SUBROUTINE IfW_FFWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_FFWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Periodic - Int_BufSz = Int_BufSz + 1 ! InterpTower - Int_BufSz = Int_BufSz + 1 ! FFData allocated yes/no - IF ( ALLOCATED(InData%FFData) ) THEN - Int_BufSz = Int_BufSz + 2*4 ! FFData upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FFData) ! FFData - END IF - Int_BufSz = Int_BufSz + 1 ! FFTower allocated yes/no - IF ( ALLOCATED(InData%FFTower) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! FFTower upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FFTower) ! FFTower - END IF - Re_BufSz = Re_BufSz + 1 ! FFDTime - Re_BufSz = Re_BufSz + 1 ! FFRate - Re_BufSz = Re_BufSz + 1 ! FFYHWid - Re_BufSz = Re_BufSz + 1 ! FFZHWid - Re_BufSz = Re_BufSz + 1 ! RefHt - Re_BufSz = Re_BufSz + 1 ! GridBase - Re_BufSz = Re_BufSz + 1 ! InitXPosition - Re_BufSz = Re_BufSz + 1 ! InvFFYD - Re_BufSz = Re_BufSz + 1 ! InvFFZD - Re_BufSz = Re_BufSz + 1 ! InvMFFWS - Re_BufSz = Re_BufSz + 1 ! MeanFFWS - Re_BufSz = Re_BufSz + 1 ! TotalTime - Int_BufSz = Int_BufSz + 1 ! NFFComp - Int_BufSz = Int_BufSz + 1 ! NFFSteps - Int_BufSz = Int_BufSz + 1 ! NYGrids - Int_BufSz = Int_BufSz + 1 ! NZGrids - Int_BufSz = Int_BufSz + 1 ! NTGrids - Int_BufSz = Int_BufSz + 1 ! WindFileFormat - Int_BufSz = Int_BufSz + 1 ! AddMeanAfterInterp - Int_BufSz = Int_BufSz + 1 ! WindProfileType - Re_BufSz = Re_BufSz + 1 ! PLExp - Re_BufSz = Re_BufSz + 1 ! Z0 - Re_BufSz = Re_BufSz + 1 ! VLinShr - Re_BufSz = Re_BufSz + 1 ! HLinShr - Re_BufSz = Re_BufSz + 1 ! RefLength - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = TRANSFER(InData%Periodic, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%InterpTower, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%FFData) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,3) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,4) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,4) - Int_Xferred = Int_Xferred + 2 - - DO i4 = LBOUND(InData%FFData,4), UBOUND(InData%FFData,4) - DO i3 = LBOUND(InData%FFData,3), UBOUND(InData%FFData,3) - DO i2 = LBOUND(InData%FFData,2), UBOUND(InData%FFData,2) - DO i1 = LBOUND(InData%FFData,1), UBOUND(InData%FFData,1) - ReKiBuf(Re_Xferred) = InData%FFData(i1,i2,i3,i4) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%FFTower) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFTower,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFTower,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFTower,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFTower,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFTower,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFTower,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%FFTower,3), UBOUND(InData%FFTower,3) - DO i2 = LBOUND(InData%FFTower,2), UBOUND(InData%FFTower,2) - DO i1 = LBOUND(InData%FFTower,1), UBOUND(InData%FFTower,1) - ReKiBuf(Re_Xferred) = InData%FFTower(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - ReKiBuf(Re_Xferred) = InData%FFDTime - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FFRate - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FFYHWid - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FFZHWid - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%GridBase - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InitXPosition - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InvFFYD - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InvFFZD - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InvMFFWS - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%MeanFFWS - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TotalTime - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NFFComp - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NFFSteps - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NYGrids - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NZGrids - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NTGrids - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%WindFileFormat - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%AddMeanAfterInterp, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%WindProfileType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PLExp - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Z0 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VLinShr - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%HLinShr - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefLength - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_PackParam - - SUBROUTINE IfW_FFWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%Periodic = TRANSFER(IntKiBuf(Int_Xferred), OutData%Periodic) - Int_Xferred = Int_Xferred + 1 - OutData%InterpTower = TRANSFER(IntKiBuf(Int_Xferred), OutData%InterpTower) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FFData not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i4_l = IntKiBuf( Int_Xferred ) - i4_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FFData)) DEALLOCATE(OutData%FFData) - ALLOCATE(OutData%FFData(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FFData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i4 = LBOUND(OutData%FFData,4), UBOUND(OutData%FFData,4) - DO i3 = LBOUND(OutData%FFData,3), UBOUND(OutData%FFData,3) - DO i2 = LBOUND(OutData%FFData,2), UBOUND(OutData%FFData,2) - DO i1 = LBOUND(OutData%FFData,1), UBOUND(OutData%FFData,1) - OutData%FFData(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FFTower not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FFTower)) DEALLOCATE(OutData%FFTower) - ALLOCATE(OutData%FFTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FFTower.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%FFTower,3), UBOUND(OutData%FFTower,3) - DO i2 = LBOUND(OutData%FFTower,2), UBOUND(OutData%FFTower,2) - DO i1 = LBOUND(OutData%FFTower,1), UBOUND(OutData%FFTower,1) - OutData%FFTower(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - OutData%FFDTime = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FFRate = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FFYHWid = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FFZHWid = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%GridBase = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InitXPosition = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InvFFYD = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InvFFZD = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InvMFFWS = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%MeanFFWS = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TotalTime = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%NFFComp = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NFFSteps = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NYGrids = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NZGrids = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NTGrids = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%WindFileFormat = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%AddMeanAfterInterp = TRANSFER(IntKiBuf(Int_Xferred), OutData%AddMeanAfterInterp) - Int_Xferred = Int_Xferred + 1 - OutData%WindProfileType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%PLExp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Z0 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VLinShr = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%HLinShr = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefLength = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_UnPackParam - -END MODULE IfW_FFWind_Base_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_FlowField.f90 b/modules/inflowwind/src/IfW_FlowField.f90 new file mode 100644 index 0000000000..5bcc3bfee4 --- /dev/null +++ b/modules/inflowwind/src/IfW_FlowField.f90 @@ -0,0 +1,2051 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2022 National Renewable Energy Laboratory +! +! This file is part of the NWTC Subroutine Library. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +!********************************************************************************************************************************** + +module IfW_FlowField + +use NWTC_Library +use IfW_FlowField_Types + +implicit none + +public IfW_FlowField_GetVelAcc +public IfW_UniformField_CalcAccel, IfW_Grid3DField_CalcAccel +public IfW_UniformWind_GetOP +public Grid3D_to_Uniform, Uniform_to_Grid3D + +integer(IntKi), parameter :: WindProfileType_None = -1 !< don't add wind profile; already included in input +integer(IntKi), parameter :: WindProfileType_Constant = 0 !< constant wind +integer(IntKi), parameter :: WindProfileType_Log = 1 !< logarithmic +integer(IntKi), parameter :: WindProfileType_PL = 2 !< power law + +real(ReKi), parameter :: GridTol = 1.0E-3 ! Tolerance for determining if position is within grid + +contains + +!> IfW_FlowField_GetVelAcc gets the velocities (and accelerations) at the given point positions. +!! Accelerations are only calculated if the AccelUVW array is allocated. +subroutine IfW_FlowField_GetVelAcc(FF, IStart, Time, PositionXYZ, VelocityUVW, AccelUVW, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< FlowField data structure + integer(IntKi), intent(in) :: IStart !< Start index for returning velocities for external field + real(DbKi), intent(in) :: Time !< Time to evaluate velocities/accelerations + real(ReKi), intent(in) :: PositionXYZ(:, :) !< Array of positions to evaluate velocites/accelerations + real(ReKi), intent(inout) :: VelocityUVW(:, :) !< Array of velocity outputs + real(ReKi), allocatable, intent(inout) :: AccelUVW(:, :) !< Array of acceleration outputs + integer(IntKi), intent(out) :: ErrStat !< Error status + character(*), intent(out) :: ErrMsg !< Error message + + character(*), parameter :: RoutineName = "IfW_FlowField_GetVelAcc" + integer(IntKi) :: i + integer(IntKi) :: NumPoints + logical :: OutputAccel + real(ReKi), allocatable :: Position(:, :) + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ! Uniform Field + type(UniformField_Interp) :: UFopVel, UFopAcc + + ! Grid3D Field + real(ReKi) :: Xi(3) + real(ReKi) :: VelCell(8, 3), AccCell(8, 3) + logical :: Is3D + logical :: GridExceedAllow ! is this point allowed to exceed bounds of wind grid + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get number of points to evaluate + NumPoints = size(PositionXYZ, dim=2) + + ! Determine if acceleration should be calculated and returned + OutputAccel = allocated(AccelUVW) + if (OutputAccel .and. .not. FF%AccFieldValid) then + call SetErrStat(ErrID_Fatal, "Accel output requested, but accel field is not valid", & + ErrStat, ErrMsg, RoutineName) + return + end if + + ! Allocate position array + call AllocAry(Position, 3, NumPoints, "Rotated position data", TmpErrStat, TmpErrMsg) + if (TmpErrStat >= AbortErrLev) then + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + + ! Copy positions or transform based on wind box rotation + if (FF%RotateWindBox) then + do i = 1, NumPoints + Position(:, i) = GetPrimePosition(PositionXYZ(:, i)) + end do + else + Position = PositionXYZ + end if + + !---------------------------------------------------------------------------- + ! Wind speed coordinate transforms from Wind file coordinates to global + !---------------------------------------------------------------------------- + + ! The VelocityUVW array data that has been returned from the sub-modules is + ! in the wind file (X'Y'Z') coordinates. These must be rotated to the global + ! XYZ coordinates if PropagationDir or UpflowAngle is nonzero. Apply the + ! coordinate transformation to the VelocityUVW(prime) coordinates + ! (in wind X'Y'Z' coordinate frame) returned from the submodules to the XYZ + ! coordinate frame, if PropagationDir is not zero. This is only a rotation + ! of the returned wind field, so UVW contains the direction components of + ! the wind at XYZ after translation from the U'V'W' wind velocity components + ! in the X'Y'Z' (wind file) coordinate frame. + ! NOTE: rotations are about the hub at [ 0 0 H ]. + + ! Switch based on flow type + select case (FF%FieldType) + case (Uniform_FieldType) + + !------------------------------------------------------------------------- + ! Uniform Flow Field + !------------------------------------------------------------------------- + + ! If cubic velocity interp requested, calculate operating point using + ! cubic interpolation. Otherwise, use linear interpolation + if (FF%VelInterpCubic) then + UFopVel = UniformField_InterpCubic(FF%Uniform, Time) + else + UFopVel = UniformField_InterpLinear(FF%Uniform, Time) + end if + + ! If velocity and acceleration output is requested + if (OutputAccel) then + + ! If cubic interpolation was used for the velocity, use same for accel + ! otherwise, calculate operating point via cubic interpolation + if (FF%VelInterpCubic) then + UFopAcc = UFopVel + else + UFopAcc = UniformField_InterpCubic(FF%Uniform, Time) + end if + + ! Loop throuh points and calcualate velocity and acceleration + do i = 1, NumPoints + if (Position(3, i) > 0.0_ReKi) then + VelocityUVW(:, i) = UniformField_GetVel(FF%Uniform, UFopVel, Position(:, i)) + AccelUVW(:, i) = UniformField_GetAcc(FF%Uniform, UFopAcc, Position(:, i)) + else + VelocityUVW(:, i) = 0.0_ReKi + AccelUVW(:, i) = 0.0_ReKi + end if + end do + + else ! Otherwise, only velocity requested + + ! Loop throuh points and calcualate velocity + do i = 1, NumPoints + if (Position(3, i) > 0.0_ReKi) then + VelocityUVW(:, i) = UniformField_GetVel(FF%Uniform, UFopVel, Position(:, i)) + else + VelocityUVW(:, i) = 0.0_ReKi + end if + end do + end if + + case (Grid3D_FieldType) + + !------------------------------------------------------------------------- + ! Grid3D Flow Field + !------------------------------------------------------------------------- + + ! Loop through points + do i = 1, NumPoints + + ! If height < zero, set velocity/acceleration to zero, continue + if (Position(3, i) <= 0.0_ReKi) then + VelocityUVW(:, i) = 0.0_ReKi + if (OutputAccel) AccelUVW(:, i) = 0.0_ReKi + cycle + end if + + ! Is this point allowed beyond the bounds of the wind box? + GridExceedAllow = FF%Grid3D%BoxExceedAllowF .and. (i >= FF%Grid3D%BoxExceedAllowIdx) + + ! Calculate grid cells for interpolation, returns velocity and acceleration + ! components at corners of grid cell containing time and position. Also + ! returns interpolation values Xi. + call Grid3DField_GetCell(FF%Grid3D, Time, Position(:, i), OutputAccel, GridExceedAllow, & + VelCell, AccCell, Xi, Is3D, TmpErrStat, TmpErrMsg) + if (TmpErrStat >= AbortErrLev) then + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + + ! Calculate velocity and acceleration + if (OutputAccel) then + if (FF%VelInterpCubic) then + ! Cubic velocity and cubic acceleration + call Grid3DField_GetVelAccCubic(FF%Grid3D%DTime, VelCell, AccCell, Xi, Is3D, & + Velocity=VelocityUVW(:, i), Accel=AccelUVW(:, i)) + else + ! Linear velocity and cubic acceleration + VelocityUVW(:, i) = Grid3DField_GetVelLinear(VelCell, Xi, Is3D) + call Grid3DField_GetVelAccCubic(FF%Grid3D%DTime, VelCell, AccCell, Xi, Is3D, & + Accel=AccelUVW(:, i)) + end if + else + if (FF%VelInterpCubic) then + ! Cubic velocity + call Grid3DField_GetVelAccCubic(FF%Grid3D%DTime, VelCell, AccCell, Xi, Is3D, & + Velocity=VelocityUVW(:, i)) + else + ! Linear velocity + VelocityUVW(:, i) = Grid3DField_GetVelLinear(VelCell, Xi, Is3D) + end if + end if + + end do + + ! Add mean wind speed after interpolation if flag is set + if (FF%Grid3D%AddMeanAfterInterp) then + do i = 1, NumPoints + VelocityUVW(1, i) = VelocityUVW(1, i) + GetMeanVelocity(FF%Grid3D, Position(3, i)) + end do + end if + + case (Grid4D_FieldType) + + !------------------------------------------------------------------------- + ! Grid4D Flow Field + !------------------------------------------------------------------------- + + ! If field is not allocated, return error + if (.not. allocated(FF%Grid4D%Vel)) then + call SetErrStat(ErrID_Fatal, "Grid4D Field not allocated", ErrStat, ErrMsg, RoutineName) + return + end if + + ! Loop through points + do i = 1, NumPoints + + ! If height less than or equal to zero, set velocity to zero + if (Position(3, i) <= 0.0_ReKi) then + VelocityUVW(:, i) = 0.0_ReKi + cycle + end if + + call Grid4DField_GetVel(FF%Grid4D, Time, Position(:, i), VelocityUVW(:, i), TmpErrStat, TmpErrMsg) + if (TmpErrStat >= AbortErrLev) then + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + end do + + case (Point_FieldType) + + !------------------------------------------------------------------------- + ! Point Flow Field + !------------------------------------------------------------------------- + + ! If points field is not allocated, return error + if (.not. allocated(FF%Points%Vel)) then + call SetErrStat(ErrID_Fatal, "Points Point Field not allocated", ErrStat, ErrMsg, RoutineName) + return + end if + + ! Set velocities directly from velocity array + VelocityUVW = FF%Points%Vel(:, IStart:IStart + NumPoints - 1) + + case (User_FieldType) + + !------------------------------------------------------------------------- + ! User Flow Field + !------------------------------------------------------------------------- + + call SetErrStat(ErrID_Fatal, "User Field not to be implemented", ErrStat, ErrMsg, RoutineName) + return + + case default + call SetErrStat(ErrID_Fatal, "Invalid FieldType "//trim(num2lstr(FF%FieldType)), ErrStat, ErrMsg, RoutineName) + return + end select + + !---------------------------------------------------------------------------- + ! If wind box was rotated, apply rotation to velocity/acceleration + !---------------------------------------------------------------------------- + + if (FF%RotateWindBox) then + if (.not. OutputAccel) then + do i = 1, NumPoints + VelocityUVW(:, i) = matmul(FF%RotFromWind, VelocityUVW(:, i)) + end do + else + do i = 1, NumPoints + VelocityUVW(:, i) = matmul(FF%RotFromWind, VelocityUVW(:, i)) + AccelUVW(:, i) = matmul(FF%RotFromWind, AccelUVW(:, i)) + end do + end if + end if + +contains + + pure function GetPrimePosition(Pos) result(PrimePos) + real(ReKi), dimension(3), intent(in) :: Pos + real(ReKi), dimension(3) :: PrimePos + PrimePos = matmul(FF%RotToWind, (Pos - FF%RefPosition)) + FF%RefPosition + end function + + function GetMeanVelocity(GF, PosZ) result(U) + type(Grid3DFieldType), intent(in) :: GF + real(ReKi), intent(in) :: PosZ + real(ReKi) :: U + select case (GF%WindProfileType) + case (WindProfileType_None) + U = 0.0_ReKi + case (WindProfileType_PL) + U = GF%MeanWS*(PosZ/GF%RefHeight)**GF%PLExp ! [IEC 61400-1 6.3.1.2 (10)] + case (WindProfileType_Log) + if (.not. EqualRealNos(GF%RefHeight, GF%Z0) .and. PosZ > 0.0_ReKi) then + U = GF%MeanWS*log(PosZ/GF%Z0)/log(GF%RefHeight/GF%Z0) + else + U = 0.0_ReKi + end if + case (WindProfileType_Constant) + U = GF%MeanWS + case default + U = 0.0_ReKi + end select + end function + +end subroutine + +pure function UniformField_GetVel(UF, op, Position) result(Velocity) + use, intrinsic :: ieee_arithmetic + + type(UniformFieldType), intent(in) :: UF + type(UniformField_Interp), intent(in) :: op + real(ReKi), dimension(3), intent(in) :: Position + real(ReKi), dimension(3) :: Velocity + + character(*), parameter :: RoutineName = "UniformField_GetVel" + real(ReKi) :: V1 + real(ReKi) :: V1_rotate, VZ_rotate + + ! Calculate horizontal velocity if position is above ground + V1 = op%VelH*((Position(3)/UF%RefHeight)**op%ShrV & ! power-law wind shear + + (op%ShrH*(Position(2)*op%CosAngleH + Position(1)*op%SinAngleH) & ! horizontal linear shear + + op%LinShrV*(Position(3) - UF%RefHeight))/UF%RefLength) & ! vertical linear shear + + op%VelGust ! gust speed + + ! Apply upflow angle + V1_rotate = op%CosAngleV*V1 - op%SinAngleV*op%VelV + VZ_rotate = op%SinAngleV*V1 + op%CosAngleV*op%VelV + + ! Apply wind direction + Velocity = [V1_rotate*op%CosAngleH, -V1_rotate*op%SinAngleH, VZ_rotate] + +end function + +function UniformField_GetAcc(UF, op, Position) result(Accel) + type(UniformFieldType), intent(in) :: UF + type(UniformField_Interp), intent(in) :: op + real(ReKi), dimension(3), intent(in) :: Position + real(ReKi), dimension(3) :: Accel + + character(*), parameter :: RoutineName = "UniformField_GetAcc" + real(ReKi) :: C1, C2, C3, C4, C5 + + C1 = (Position(3)/UF%RefHeight)**op%ShrV + & + (op%LinShrV*(Position(3) - UF%RefHeight) + & + op%ShrH*(Position(1)*op%SinAngleH + & + Position(2)*op%CosAngleH))/UF%RefLength + + C2 = op%CosAngleV*(op%VelGust + op%VelH*(C1)) + + C3 = op%AngleVDot*op%SinAngleV*(op%VelGust + op%VelH*(C1)) + + C4 = op%LinShrVDot*(Position(3) - UF%RefHeight) + & + op%ShrHDot*(Position(1)*op%SinAngleH + Position(2)*op%CosAngleH) + & + op%ShrH*(Position(1)*op%AngleHDot*op%CosAngleH - & + Position(2)*op%AngleHDot*op%SinAngleH) + + C5 = op%VelGustDot + op%VelHDot*C1 + & + op%VelH*(op%ShrVDot*(Position(3)/UF%RefHeight)**op%ShrV* & + log(Position(3)/UF%RefHeight) + C4/UF%RefLength) + + Accel(1) = -op%AngleHDot*op%SinAngleH*(C2 - op%SinAngleV*op%VelV) + & + op%CosAngleH*(-op%AngleVDot*op%CosAngleV*op%VelV - C3 - & + op%VelVDot*op%SinAngleV + op%CosAngleV*C5) + + Accel(2) = op%AngleHDot*op%CosAngleH*(-C2 + op%SinAngleV*op%VelV) + & + op%SinAngleH*(op%AngleVDot*op%CosAngleV*op%VelV + C3 + & + op%VelVDot*op%SinAngleV - op%CosAngleV*C5) + + Accel(3) = op%AngleVDot*C2 - op%AngleVDot*op%SinAngleV*op%VelV + & + op%VelVDot*op%CosAngleV + op%SinAngleV*C5 + +end function + +pure function UniformField_InterpLinear(UF, Time) result(op) + + type(UniformFieldType), intent(in) :: UF + real(DbKi), intent(in) :: Time + type(UniformField_Interp) :: op + integer(IntKi) :: i + real(ReKi) :: dt, alpha, OMalpha + + ! If only one data point or time is at or below first time, use first sample + if (UF%DataSize == 1 .or. Time < UF%Time(1)) then + + op%VelH = UF%VelH(1) + op%AngleH = UF%AngleH(1) + op%AngleV = UF%AngleV(1) + op%VelV = UF%VelV(1) + op%ShrH = UF%ShrH(1) + op%ShrV = UF%ShrV(1) + op%LinShrV = UF%LinShrV(1) + op%VelGust = UF%VelGust(1) + + ! If time is after end time, use last data point + else if (Time >= UF%Time(UF%DataSize)) then + + op%VelH = UF%VelH(UF%DataSize) + op%AngleH = UF%AngleH(UF%DataSize) + op%AngleV = UF%AngleV(UF%DataSize) + op%VelV = UF%VelV(UF%DataSize) + op%ShrH = UF%ShrH(UF%DataSize) + op%ShrV = UF%ShrV(UF%DataSize) + op%LinShrV = UF%LinShrV(UF%DataSize) + op%VelGust = UF%VelGust(UF%DataSize) + + else + + ! Find first index where current time is less than Time(i) + do i = 2, UF%DataSize + if (Time < UF%Time(i)) exit + end do + + ! Calculate interval delta time + dt = UF%Time(i) - UF%Time(i - 1) + + ! Calculate interpolation coefficient [0,1] + alpha = real((Time - UF%Time(i - 1))/dt, ReKi) + OMalpha = 1.0_ReKi - alpha + + ! Blend states before and after time based on alpha + op%VelH = UF%VelH(i - 1)*OMalpha + UF%VelH(i)*alpha + op%AngleH = UF%AngleH(i - 1)*OMalpha + UF%AngleH(i)*alpha + op%AngleV = UF%AngleV(i - 1)*OMalpha + UF%AngleV(i)*alpha + op%VelV = UF%VelV(i - 1)*OMalpha + UF%VelV(i)*alpha + op%ShrH = UF%ShrH(i - 1)*OMalpha + UF%ShrH(i)*alpha + op%ShrV = UF%ShrV(i - 1)*OMalpha + UF%ShrV(i)*alpha + op%LinShrV = UF%LinShrV(i - 1)*OMalpha + UF%LinShrV(i)*alpha + op%VelGust = UF%VelGust(i - 1)*OMalpha + UF%VelGust(i)*alpha + + end if + + op%CosAngleH = cos(op%AngleH) + op%SinAngleH = sin(op%AngleH) + op%CosAngleV = cos(op%AngleV) + op%SinAngleV = sin(op%AngleV) + +end function + +pure function UniformField_InterpCubic(UF, Time) result(op) + + type(UniformFieldType), intent(in) :: UF + real(DbKi), intent(in) :: Time + type(UniformField_Interp) :: op + + integer(IntKi) :: i + real(ReKi) :: C1, C2, C3, C4, h, t + + ! Initialize data index + i = 0 + + ! If time is outside of array + if (UF%DataSize == 1 .or. Time < UF%Time(1)) then + ! One data point or time is at or below first time, use first sample + i = 1 + else if (Time >= UF%Time(UF%DataSize)) then + ! Time is after end time, use last data point + i = UF%DataSize + end if + + ! If time was inside data array + if (i == 0) then + + ! Find first index where current time is less than Time(i) + do i = 2, UF%DataSize + if (Time < UF%Time(i)) exit + end do + + h = UF%Time(i) - UF%Time(i - 1) + t = real((Time - UF%Time(i - 1))/h, ReKi) + + C1 = 2.0_ReKi*t*t*t - 3.0_ReKi*t*t + 1.0_ReKi + C2 = (t*t*t - 2.0_ReKi*t*t + t)*h + C3 = -2.0_ReKi*t*t*t + 3.0_ReKi*t*t + C4 = (t*t*t - t*t)*h + + op%VelH = C1*UF%VelH(i - 1) + C2*UF%VelHDot(i - 1) + C3*UF%VelH(i) + C4*UF%VelHDot(i) + op%AngleH = C1*UF%AngleH(i - 1) + C2*UF%AngleHDot(i - 1) + C3*UF%AngleH(i) + C4*UF%AngleHDot(i) + op%AngleV = C1*UF%AngleV(i - 1) + C2*UF%AngleVDot(i - 1) + C3*UF%AngleV(i) + C4*UF%AngleVDot(i) + op%VelV = C1*UF%VelV(i - 1) + C2*UF%VelVDot(i - 1) + C3*UF%VelV(i) + C4*UF%VelVDot(i) + op%ShrH = C1*UF%ShrH(i - 1) + C2*UF%ShrHDot(i - 1) + C3*UF%ShrH(i) + C4*UF%ShrHDot(i) + op%ShrV = C1*UF%ShrV(i - 1) + C2*UF%ShrVDot(i - 1) + C3*UF%ShrV(i) + C4*UF%ShrVDot(i) + op%LinShrV = C1*UF%LinShrV(i - 1) + C2*UF%LinShrVDot(i - 1) + C3*UF%LinShrV(i) + C4*UF%LinShrVDot(i) + op%VelGust = C1*UF%VelGust(i - 1) + C2*UF%VelGustDot(i - 1) + C3*UF%VelGust(i) + C4*UF%VelGustDot(i) + + C1 = (6.0_ReKi*t*t - 6.0_ReKi*t)/h + C2 = (3.0_ReKi*t*t - 4.0_ReKi*t + 1.0_ReKi) + C3 = -C1 + C4 = (3.0_ReKi*t*t - 2.0_ReKi*t) + + op%VelHDot = C1*UF%VelH(i - 1) + C2*UF%VelHDot(i - 1) + C3*UF%VelH(i) + C4*UF%VelHDot(i) + op%AngleHDot = C1*UF%AngleH(i - 1) + C2*UF%AngleHDot(i - 1) + C3*UF%AngleH(i) + C4*UF%AngleHDot(i) + op%AngleVDot = C1*UF%AngleV(i - 1) + C2*UF%AngleVDot(i - 1) + C3*UF%AngleV(i) + C4*UF%AngleVDot(i) + op%VelVDot = C1*UF%VelV(i - 1) + C2*UF%VelVDot(i - 1) + C3*UF%VelV(i) + C4*UF%VelVDot(i) + op%ShrHDot = C1*UF%ShrH(i - 1) + C2*UF%ShrHDot(i - 1) + C3*UF%ShrH(i) + C4*UF%ShrHDot(i) + op%ShrVDot = C1*UF%ShrV(i - 1) + C2*UF%ShrVDot(i - 1) + C3*UF%ShrV(i) + C4*UF%ShrVDot(i) + op%LinShrVDot = C1*UF%LinShrV(i - 1) + C2*UF%LinShrVDot(i - 1) + C3*UF%LinShrV(i) + C4*UF%LinShrVDot(i) + op%VelGustDot = C1*UF%VelGust(i - 1) + C2*UF%VelGustDot(i - 1) + C3*UF%VelGust(i) + C4*UF%VelGustDot(i) + + else + + ! Set values based on first/last index + op%VelH = UF%VelH(i) + op%AngleH = UF%AngleH(i) + op%AngleV = UF%AngleV(i) + op%VelV = UF%VelV(i) + op%ShrH = UF%ShrH(i) + op%ShrV = UF%ShrV(i) + op%LinShrV = UF%LinShrV(i) + op%VelGust = UF%VelGust(i) + + op%VelHDot = 0.0_ReKi + op%AngleHDot = 0.0_ReKi + op%AngleVDot = 0.0_ReKi + op%VelVDot = 0.0_ReKi + op%ShrHDot = 0.0_ReKi + op%ShrVDot = 0.0_ReKi + op%LinShrVDot = 0.0_ReKi + op%VelGustDot = 0.0_ReKi + + end if + + op%CosAngleH = cos(op%AngleH) + op%SinAngleH = sin(op%AngleH) + op%CosAngleV = cos(op%AngleV) + op%SinAngleV = sin(op%AngleV) + +end function + +subroutine IfW_UniformField_CalcAccel(UF, ErrStat, ErrMsg) + type(UniformFieldType), intent(inout) :: UF + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "Uniform_CalcAccel" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + real(ReKi), allocatable :: b(:), u(:), dy2(:) + + ErrStat = ErrID_None + ErrMsg = "" + + !---------------------------------------------------------------------------- + ! Storage for spline fit arrays + !---------------------------------------------------------------------------- + + call AllocAry(B, UF%DataSize, "storage for B", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + call AllocAry(U, UF%DataSize, "storage for U", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + call AllocAry(dy2, UF%DataSize, "storage for dy2", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Storage for derivative arrays + !---------------------------------------------------------------------------- + + call AllocAry(UF%VelHDot, UF%DataSize, 'Uniform wind horizontal wind speed derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%AngleHDot, UF%DataSize, 'Uniform wind direction derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%AngleVDot, UF%DataSize, 'Uniform wind upflow angle derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%VelVDot, UF%DataSize, 'Uniform vertical wind speed derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%ShrHDot, UF%DataSize, 'Uniform horizontal linear shear derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%ShrVDot, UF%DataSize, 'Uniform vertical power-law shear exponent derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%LinShrVDot, UF%DataSize, 'Uniform vertical linear shear derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%VelGustDot, UF%DataSize, 'Uniform gust velocity derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Calculate derivatives + !---------------------------------------------------------------------------- + + call CalcCubicSplineDeriv(UF%Time, UF%VelH, UF%VelHDot) + call CalcCubicSplineDeriv(UF%Time, UF%AngleH, UF%AngleHDot) + call CalcCubicSplineDeriv(UF%Time, UF%AngleV, UF%AngleVDot) + call CalcCubicSplineDeriv(UF%Time, UF%VelV, UF%VelVDot) + call CalcCubicSplineDeriv(UF%Time, UF%ShrH, UF%ShrHDot) + call CalcCubicSplineDeriv(UF%Time, UF%ShrV, UF%ShrVDot) + call CalcCubicSplineDeriv(UF%Time, UF%LinShrV, UF%LinShrVDot) + call CalcCubicSplineDeriv(UF%Time, UF%VelGust, UF%VelGustDot) + +contains + + !> CalcCubicSplineDeriv fits a cubic spline through the y array with points + !! at x locations. It then calculates the corresponding derivative of y + !! with respect to x at the same x values and returns it in the dy array. + subroutine CalcCubicSplineDeriv(x, y, dy) + real(ReKi), intent(in) :: x(:) + real(ReKi), intent(in) :: y(:) + real(ReKi), intent(out) :: dy(:) + + integer(IntKi) :: i, n + real(ReKi) :: p, sig, un + + ! Get size of arrays + n = size(x) + + ! If 1 or 2 points, set derivatives to zero and return + if (n < 3) then + do i = 1, n + dy(i) = 0.0_ReKi + end do + return + end if + + ! Natural lower and upper boundaries (second derivative = 0) + ! u(1) = 0.0_ReKi + ! dy2(1) = 0.0_ReKi + ! dy2(n) = 0.0_ReKi + + ! First derivative is zero at lower boundary condition + dy2(1) = -0.5_ReKi + u(1) = 3.0_ReKi*(y(2) - y(1))/(x(2) - x(1))**2 + + ! Calculate slopes + do i = 1, n - 1 + b(i) = (y(i + 1) - y(i))/(x(i + 1) - x(i)) + end do + + ! Decomposition + do i = 2, n - 1 + sig = (x(i) - x(i - 1))/(x(i + 1) - x(i - 1)) + p = sig*dy2(i - 1) + 2.0_ReKi + dy2(i) = (sig - 1.0_ReKi)/p + u(i) = (6.*((y(i + 1) - y(i))/(x(i + 1) - x(i)) - (y(i) - y(i - 1))/(x(i) - x(i - 1)))/ & + (x(i + 1) - x(i - 1)) - sig*u(i - 1))/p + end do + + ! First derviative is zero at upper boundary condition + un = -3.0_ReKi*(y(n) - y(n - 1))/(x(n) - x(n - 1))**2 + dy2(n) = (un - 0.5_ReKi*u(n - 1))/(0.5_ReKi*dy2(n - 1) + 1.0_ReKi) + + ! Back substitution and derivative calculation + do i = n - 1, 1, -1 + dy2(i) = dy2(i)*dy2(i + 1) + u(i) + dy(i) = real(b(i) - (x(i + 1) - x(i))*(dy2(i)/3.0_ReKi + dy2(i + 1)/6.0_ReKi), SiKi) + end do + dy(n) = 0.0_ReKi + + end subroutine + +end subroutine + +!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial +!! derivative dY/du is returned. This submodule does not follow the modularization framework. +subroutine IfW_UniformWind_GetOP(UF, t, InterpCubic, OP_out) + type(UniformFieldType), intent(IN) :: UF !< Parameters + real(DbKi), intent(IN) :: t !< Current simulation time in seconds + logical, intent(in) :: InterpCubic !< flag for using cubic interpolation + real(ReKi), intent(OUT) :: OP_out(2) !< operating point (HWindSpeed and PLexp + + type(UniformField_Interp) :: op ! interpolated values of InterpParams + + ! Linearly interpolate parameters in time at operating point (or use nearest-neighbor to extrapolate) + if (InterpCubic) then + op = UniformField_InterpCubic(UF, t) + else + op = UniformField_InterpLinear(UF, t) + end if + + OP_out(1) = op%VelH + OP_out(2) = op%ShrV + +end subroutine + +subroutine Grid3DField_GetCell(G3D, Time, Position, CalcAccel, AllowExtrap, & + VelCell, AccCell, Xi, Is3D, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(in) :: G3D !< 3D Grid-Field data + real(DbKi), intent(in) :: Time !< time (s) + real(ReKi), intent(in) :: Position(3) !< position X,Y,Z to get value + logical, intent(in) :: CalcAccel !< flag to populat AccCell + logical, intent(in) :: AllowExtrap !< is this point allowed to exceed bounds of wind grid + real(ReKi), intent(out) :: VelCell(8, 3) !< Velocity components at corners of grid cell + real(ReKi), intent(out) :: AccCell(8, 3) !< Acceleration components at corners of grid cell + real(ReKi), intent(out) :: Xi(3) !< isoparametric coord of position in cell (y,z,t) [-1, +1] + logical, intent(out) :: Is3D !< flag indicating if interpolation is 3D or 2D + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + character(*), parameter :: RoutineName = "Grid3DField_GetCell" + integer(IntKi), parameter :: ExtrapNone = 0 + integer(IntKi), parameter :: ExtrapYmin = 1 + integer(IntKi), parameter :: ExtrapYmax = 2 + integer(IntKi), parameter :: ExtrapZmin = 4 + integer(IntKi), parameter :: ExtrapZmax = 8 + integer(IntKi) :: AllExtrap + integer(IntKi) :: IY_Lo, IY_Hi + integer(IntKi) :: IZ_Lo, IZ_Hi + integer(IntKi) :: IT_Lo, IT_Hi + logical :: InGrid + + ErrStat = ErrID_None + ErrMsg = "" + + ! Initialize to no extrapolation (modified in bounds routines) + AllExtrap = ExtrapNone + + !---------------------------------------------------------------------------- + ! Find grid bounds in Time and Z + !---------------------------------------------------------------------------- + + ! Get grid time bounds + call GetBoundsT(Position(1), Xi(3)) + if (ErrStat >= AbortErrLev) return + + ! Get grid Z bounds + call GetBoundsZ(Position(3), Xi(2)) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Extract interpolation cells from grids based on poisiont + !---------------------------------------------------------------------------- + + ! If position is inside grid + if (InGrid) then + + ! Set flag to use 3D interpolation + Is3D = .true. + + ! Get grid Y bounds + call GetBoundsY(Position(2), Xi(1)) + if (ErrStat >= AbortErrLev) return + + ! Interpolate within grid (or top, left, right if extrapolation enabled) + call GetCellInGrid(VelCell, G3D%Vel, G3D%VelAvg) + + ! If acceleration requested, get cell values + if (CalcAccel) then + call GetCellInGrid(AccCell, G3D%Acc, G3D%AccAvg) + end if + + else if (G3D%NTGrids > 0) then + + ! Interpolation is 2D + Is3D = .false. + + ! Tower grids present and position is below main grid + call GetCellInTower(VelCell, G3D%Vel, G3D%VelAvg, G3D%VelTower) + + ! If acceleration requested, get cell values + if (CalcAccel) then + call GetCellInTower(AccCell, G3D%Acc, G3D%AccAvg, G3D%AccTower) + end if + + else + + ! Set flag to use 3D interpolation + Is3D = .true. + + ! Get grid Y bounds + call GetBoundsY(Position(2), Xi(1)) + if (ErrStat >= AbortErrLev) return + + ! Tower interpolation without tower grids + call GetCellBelowGrid(VelCell, G3D%Vel) + + ! If acceleration requested, get cell values + if (CalcAccel) then + call GetCellBelowGrid(AccCell, G3D%Acc) + end if + + end if + +contains + + subroutine GetCellInGrid(cell, gridVal, gridAvg) + + real(ReKi), intent(out) :: cell(8, 3) + real(SiKi), intent(in) :: gridVal(:, :, :, :) + real(SiKi), intent(in), allocatable :: gridAvg(:, :, :) + + ! Select based on extrapolation flags + select case (AllExtrap) + + case (ExtrapNone) ! No extrapolation + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Hi) + + case (ior(ExtrapZmax, ExtrapYmax)) ! Extrapolate top right corner + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ior(ExtrapZmax, ExtrapYmin))! Extrapolate top left corner + + cell(1, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ExtrapZmax) ! Extrapolate above grid only + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ExtrapYmax) ! Extrapolate to the right of grid only + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(3, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(7, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ExtrapYmin) ! Extrapolate to the left of grid only + + cell(1, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Lo) + cell(5, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Hi) + + case (ExtrapZmin) ! Extrapolate below grid + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridVal(:, IY_Lo, 1, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, 1, IT_Lo) + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridVal(:, IY_Lo, 1, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, 1, IT_Hi) + + case (ior(ExtrapZmin, ExtrapYmin)) ! Extrapolate lower left of grid + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridAvg(:, 1, IT_Lo) ! Average + cell(4, :) = gridVal(:, 1, 1, IT_Lo) + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridAvg(:, 1, IT_Hi) ! Average + cell(8, :) = gridVal(:, 1, 1, IT_Hi) + + case (ior(ExtrapZmin, ExtrapYmax)) ! Extrapolate lower right of grid + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridVal(:, G3D%NYGrids, 1, IT_Lo) + cell(4, :) = gridAvg(:, 1, IT_Lo) ! Average + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridVal(:, G3D%NYGrids, 1, IT_Hi) + cell(8, :) = gridAvg(:, 1, IT_Hi) ! Average + + end select + + end subroutine + + !> GetCellBelowGrid interpolates between bottom of grid and ground. This + !! is only called if G3D%InterpTower == .true. + subroutine GetCellBelowGrid(cell, gridVal) + + real(ReKi), intent(out) :: cell(8, 3) + real(SiKi), intent(in) :: gridVal(:, :, :, :) + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Lo) + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Hi) + + end subroutine + + subroutine GetCellInTower(cell, gridVal, gridAvg, towerVal) + + real(ReKi), intent(out) :: cell(8, 3) + real(SiKi), intent(in) :: gridVal(:, :, :, :) + real(SiKi), intent(in), allocatable :: gridAvg(:, :, :) + real(SiKi), intent(in), allocatable :: towerVal(:, :, :) + + real(ReKi), dimension(2) :: P, P1, P2, P3, V0, V1, V2 + real(ReKi) :: d00, d01, d11, d20, d21 + real(ReKi) :: V(3, 3, 2), W(3) + real(ReKi) :: alpha, omalpha, denom + integer(IntKi) :: ic + + !------------------------------------------------------------------------- + ! If extrapolation is not allowed or Y is nearly zero, only interpolate + ! along the tower + !------------------------------------------------------------------------- + + if (.not. AllowExtrap) then + if (IZ_HI <= G3D%NTGrids) then ! In tower grid + cell(1, :) = towerVal(:, IZ_LO, IT_LO) + cell(2, :) = towerVal(:, IZ_HI, IT_LO) + cell(3, :) = towerVal(:, IZ_LO, IT_HI) + cell(4, :) = towerVal(:, IZ_HI, IT_HI) + else ! Between tower grid and ground + cell(1, :) = towerVal(:, IZ_LO, IT_LO) + cell(2, :) = 0.0_ReKi + cell(3, :) = towerVal(:, IZ_LO, IT_HI) + cell(4, :) = 0.0_ReKi + end if + return + end if + + !------------------------------------------------------------------------- + ! If Y is beyond grid width from the tower (clamped), + ! interp between ground and bottom of grid average + !------------------------------------------------------------------------- + + if (abs(Position(2)) >= 2.0_ReKi*G3D%YHWid) then + Xi(2) = 2.0_ReKi*Position(3)/G3D%GridBase - 1.0_ReKi + cell(1, :) = 0.0_ReKi + cell(2, :) = gridAvg(:, 1, IT_LO) + cell(3, :) = 0.0_ReKi + cell(4, :) = gridAvg(:, 1, IT_HI) + return + end if + + !------------------------------------------------------------------------- + ! Otherwise, position is below grid and within +- 2*GridWidth from tower + ! This section uses Barycentric interpolation of a triangle to get + ! the wind components at the desired Position. The components on the + ! bottom of the grid and on the tower are interpolated to get the first + ! two points. The third point is on the ground at the GridWidth away + ! from the tower. + !------------------------------------------------------------------------- + + ! Get grid Y bounds + call GetBoundsY(Position(2), Xi(1)) + if (ErrStat >= AbortErrLev) return + + ! Get interpolation point + P = [abs(Position(2)), Position(3)] + + ! Point 1 (grid bottom point) + P1 = [abs(Position(2)), G3D%GridBase] + select case (AllExtrap) + case (ExtrapNone) + ! Interpolate between grid points + alpha = (Xi(1) + 1.0_ReKi)/2.0_ReKi + omalpha = 1.0_ReKi - alpha + V(:, 1, 1) = omalpha*gridVal(:, IY_Lo, 1, IT_Lo) + & + alpha*gridVal(:, IY_Hi, 1, IT_Lo) + V(:, 1, 2) = omalpha*gridVal(:, IY_Lo, 1, IT_Hi) + & + alpha*gridVal(:, IY_Hi, 1, IT_Hi) + case (ExtrapYmin, ExtrapYmax) + ! Interpolate between edge of grid and grid average + alpha = abs(Position(2))/G3D%YHWid - 1.0_ReKi + omalpha = 1.0_ReKi - alpha + V(:, 1, 1) = omalpha*gridVal(:, IY_Lo, 1, IT_Lo) + & + alpha*gridAvg(:, 1, IT_Lo) + V(:, 1, 2) = omalpha*gridVal(:, IY_Lo, 1, IT_Hi) + & + alpha*gridAvg(:, 1, IT_Hi) + end select + + ! Point 2 (tower point) + P2 = [0.0_ReKi, Position(3)] + alpha = (Xi(2) + 1.0_ReKi)/2.0_ReKi + omalpha = 1.0_ReKi - alpha + if (IZ_HI <= G3D%NTGrids) then ! Lower point above ground + V(:, 2, 1) = omalpha*towerVal(:, IZ_Lo, IT_Lo) + & + alpha*towerVal(:, IZ_Hi, IT_Lo) + V(:, 2, 2) = omalpha*towerVal(:, IZ_Lo, IT_Hi) + & + alpha*towerVal(:, IZ_Hi, IT_Hi) + else ! Lower point on ground + V(:, 2, 1) = omalpha*towerVal(:, IZ_Lo, IT_Lo) + V(:, 2, 2) = omalpha*towerVal(:, IZ_Lo, IT_Hi) + end if + + ! Point 3 (ground @ grid width away from tower) + P3 = [2.0_ReKi*G3D%YHWid, 0.0_Reki] + ! V(:, 3, :) = 0.0_ReKi ! Not used + + ! Calculate Barycentric weights for triangle + V0 = P1 - P3 + V1 = P2 - P3 + V2 = P - P3 + d00 = dot_product(v0, v0) + d01 = dot_product(v0, v1) + d11 = dot_product(v1, v1) + d20 = dot_product(v2, v0) + d21 = dot_product(v2, v1) + denom = d00*d11 - d01*d01 + W(1) = (d11*d20 - d01*d21)/denom + W(2) = (d00*d21 - d01*d20)/denom + ! W(3) = 1.0_ReKi - W(1) - W(2) ! Not used + + ! Interpolate wind components based on weights + do ic = 1, 3 + cell(1, ic) = V(ic, 1, 1) * W(1) + V(ic, 2, 1) * W(2) + cell(3, ic) = V(ic, 1, 2) * W(1) + V(ic, 2, 2) * W(2) + end do + cell(2, :) = cell(1, :) + cell(4, :) = cell(3, :) + + end subroutine + + !> GetBoundsY populates IY_Lo, IY_Hi, and the interpolant [-1,1]. It also + !! adds ExtrapYmin or ExtrapYmax to AllExtrap if applicable. + subroutine GetBoundsY(PosY, DY) + + real(ReKi), intent(in) :: PosY + real(ReKi), intent(out) :: DY + + real(ReKi) :: Y_Grid + + ! Calculate position on Y grid + Y_Grid = (PosY + G3D%YHWid)*G3D%InvDY + 1 + + ! Calculate bounding grid indices + IY_LO = floor(Y_Grid, IntKi) + IY_HI = IY_LO + 1 + + ! Position location within interval [0,1] + DY = Y_Grid - aint(Y_Grid) + + if (IY_LO >= 1 .and. IY_HI <= G3D%NYGrids) then + DY = 2.0_ReKi*DY - 1.0_ReKi + else if (IY_LO == 0 .and. DY >= 1.0_ReKi - GridTol) then + IY_LO = 1 + IY_HI = 2 + DY = -1.0_ReKi + else if (IY_LO == G3D%NYGrids .and. DY <= GridTol) then + IY_LO = G3D%NYGrids - 1 + IY_HI = G3D%NYGrids + DY = 1.0_ReKi + else if (AllowExtrap) then + if (IY_LO <= 0) then + ! Clamp value at grid width below the low side of grid + DY = 2.0_ReKi*max(PosY/G3D%YHWid + 2.0_ReKi, 0.0_Reki) - 1.0_ReKi + IY_LO = 1 + IY_HI = 1 + AllExtrap = ior(AllExtrap, ExtrapYmin) + else if (IY_LO >= G3D%NYGrids) then + ! Clamp value at grid width above the high side of grid + DY = 2.0_ReKi*min(PosY/G3D%YHWid - 1.0_ReKi, 1.0_Reki) - 1.0_ReKi + IY_LO = G3D%NYGrids + IY_HI = G3D%NYGrids + AllExtrap = ior(AllExtrap, ExtrapYmax) + end if + else + ! Position outside + call SetErrStat(ErrID_Fatal, ' GF wind array boundaries violated: Grid too small in Y direction. Y='// & + TRIM(Num2LStr(PosY))//'; Y boundaries = ['//TRIM(Num2LStr(-1.0*G3D%YHWid))// & + ', '//TRIM(Num2LStr(G3D%YHWid))//']', & + ErrStat, ErrMsg, RoutineName) + end if + + end subroutine + + !> GetBoundsZ populates IZ_Lo, IZ_Hi, and the interpolant [-1,1]. It also + !! adds ExtrapZmin or ExtrapZmax to AllExtrap if applicable. + subroutine GetBoundsZ(PosZ, DZ) + + real(ReKi), intent(in) :: PosZ + real(ReKi), intent(out) :: DZ + + real(ReKi) :: Z_GRID + + ! Calculate position on Z grid + Z_GRID = (PosZ - G3D%GridBase)*G3D%InvDZ + 1 + + ! Calculate bounding grid indices + IZ_LO = floor(Z_GRID, IntKi) + IZ_HI = IZ_LO + 1 + + ! Position location within interval [-1,1] + DZ = Z_GRID - aint(Z_GRID) + + ! If indices are within grid, set in grid to true + if (IZ_LO >= 1 .and. IZ_HI <= G3D%NZGrids) then + InGrid = .true. + DZ = 2.0_ReKi*DZ - 1.0_ReKi + return + end if + + ! If below grid + if (IZ_LO < 1) then + if (IZ_LO == 0 .and. DZ >= 1.0_ReKi - GridTol) then + InGrid = .true. + IZ_LO = 1 + IZ_HI = 2 + DZ = -1.0_ReKi + else if (G3D%InterpTower) then + ! Interp from bottom of grid to ground (zero velocity) + InGrid = .false. + IZ_LO = 0 + IZ_HI = 1 + DZ = 2.0_ReKi*(PosZ/G3D%GridBase) - 1.0_ReKi + else if (G3D%NTGrids > 0) then + ! Interpolate with tower grid + InGrid = .false. + ! Tower grid is reversed (lowest index is top of tower) + IZ_LO = int(-(Z_GRID - 1)) + 1 + if (IZ_LO >= G3D%NTGrids) then + ! Between end of tower grid and ground (zero velocity) + IZ_LO = G3D%NTGrids + DZ = 1.0_ReKi - 2.0_ReKi*(PosZ/(G3D%GridBase - real(IZ_LO - 1, ReKi)/G3D%InvDZ)) + else + ! Within tower grid + DZ = 2.0_ReKi*(real(2 - IZ_LO, ReKi) - Z_GRID) - 1.0_ReKi + end if + IZ_HI = IZ_LO + 1 + else if (AllowExtrap) then + InGrid = .true. + IZ_LO = 1 + IZ_HI = 1 + DZ = 2.0_ReKi*max(PosZ/G3D%GridBase, 0.0_Reki) - 1.0_ReKi + AllExtrap = ior(AllExtrap, ExtrapZmin) + else + ! Position below grid + call SetErrStat(ErrID_Fatal, ' G3D wind array boundaries violated. '// & + 'Grid too small in Z direction '// & + '(height (Z='//TRIM(Num2LStr(Position(3)))// & + ' m) is below the grid and no tower points are defined).', & + ErrStat, ErrMsg, RoutineName) + end if + return + end if + + ! If above grid + if (IZ_HI > G3D%NZGrids) then + if (IZ_HI == G3D%NZGrids + 1 .and. DZ <= GridTol) then + InGrid = .true. + IZ_LO = G3D%NZGrids - 1 + IZ_HI = G3D%NZGrids + DZ = 1.0_ReKi + else if (AllowExtrap) then + InGrid = .true. + IZ_LO = G3D%NZGrids + IZ_HI = G3D%NZGrids + ! Calculate interpolation, limit to value at grid width above top of grid + DZ = 2.0_ReKi*min((Position(3) - (G3D%GridBase + 2*G3D%ZHWid))/G3D%ZHWid, 1.0_ReKi) - 1.0_ReKi + AllExtrap = ior(AllExtrap, ExtrapZmax) + else + ! Position above grid + call SetErrStat(ErrID_Fatal, ' G3D wind array boundaries violated. '// & + 'Grid too small in Z direction '// & + '(Z='//TRIM(Num2LStr(Position(3)))//' m is above grid.)', & + ErrStat, ErrMsg, RoutineName) + end if + return + end if + + end subroutine + + !> GetBoundsT populates IT_Lo, IT_Hi, and the interpolant [-1,1]. + subroutine GetBoundsT(PosX, DT) + + real(ReKi), intent(in) :: PosX + real(ReKi), intent(out) :: DT + + real(ReKi) :: TimeShifted + real(ReKi) :: T_GRID + + ! Perform the time shift. At time=0, a point half the grid width downstream + ! (p%YHWid) will index into the zero time slice. If we did not do this, + ! any point downstream of the tower at the beginning of the run would + ! index outside of the array. This all assumes the grid width is at least as + ! large as the rotor. If it isn't, then the interpolation will not work. + + ! In distance, X: InputInfo%PosX - p%InitXPosition - TIME*p%MeanWS + TimeShifted = real(Time, ReKi) + (G3D%InitXPosition - PosX)*G3D%InvMWS + + ! If field is periodic + if (G3D%Periodic) then + TimeShifted = MODULO(TimeShifted, G3D%TotalTime) + ! If TimeShifted is a very small negative number, + ! modulo returns the incorrect value due to internal rounding errors. + ! See bug report #471 + if (TimeShifted == G3D%TotalTime) TimeShifted = 0.0_ReKi + end if + + ! Get position on T grid + T_GRID = TimeShifted*G3D%Rate + 1 + + ! Calculate bounding grid indices + IT_LO = floor(T_GRID, IntKi) + IT_HI = ceiling(T_GRID, IntKi) + + ! Position location within interval [0,1] + DT = T_GRID - aint(T_GRID) + + ! Adjust indices and interpolant + if (IT_LO >= 1 .and. IT_HI <= G3D%NSteps) then + ! Point is within grid + DT = 2.0_ReKi*DT - 1.0_ReKi + else if (IT_LO == G3D%NSteps) then + if (G3D%Periodic) then + ! Time wraps back to beginning + IT_HI = 1 + DT = 2.0_ReKi*DT - 1.0_ReKi + else if (DT <= GridTol) then + ! Within tolerance of last time + IT_HI = IT_LO + DT = -1.0_Reki + else + ! Extrapolate + IT_LO = G3D%NSteps - 1 + IT_HI = G3D%NSteps + DT = DT + 1.0_ReKi + end if + else + ! Time exceeds array bounds + call SetErrStat(ErrID_Fatal, ' Error: GF wind array was exhausted at '// & + TRIM(Num2LStr(TIME))//' seconds (trying to access data at '// & + TRIM(Num2LStr(TimeShifted))//' seconds).', & + ErrStat, ErrMsg, RoutineName) + end if + + end subroutine + +end subroutine + +pure function Grid3DField_GetVelLinear(VelCell, Xi, Is3D) result(Velocity) + + real(ReKi), intent(in) :: VelCell(8, 3) !< velocities at corners of grid cell + real(ReKi), intent(in) :: Xi(3) !< isoparametric coordinates in cell (dy, dz, dt) [-1, +1] + logical, intent(in) :: Is3D !< flag for 3D or 2D grid + real(ReKi) :: Velocity(3) !< The U, V, W velocities + + real(ReKi) :: N(8) ! Shape function values + integer(IntKi) :: IC + + if (Is3D) then + + ! Get 3D interpolation weights + N(1) = (1.0_ReKi - Xi(1))*(1.0_ReKi - Xi(2)) + N(2) = (1.0_ReKi + Xi(1))*(1.0_ReKi - Xi(2)) + N(3) = (1.0_ReKi - Xi(1))*(1.0_ReKi + Xi(2)) + N(4) = (1.0_ReKi + Xi(1))*(1.0_ReKi + Xi(2)) + N(5) = (1.0_ReKi - Xi(1))*(1.0_ReKi - Xi(2)) + N(6) = (1.0_ReKi + Xi(1))*(1.0_ReKi - Xi(2)) + N(7) = (1.0_ReKi - Xi(1))*(1.0_ReKi + Xi(2)) + N(8) = (1.0_ReKi + Xi(1))*(1.0_ReKi + Xi(2)) + N(1:4) = N(1:4)*(1.0_ReKi - Xi(3))/8.0_ReKi + N(5:8) = N(5:8)*(1.0_ReKi + Xi(3))/8.0_ReKi + + ! Calculate velocity + do ic = 1, 3 + Velocity(ic) = dot_product(VelCell(:, ic), N) + end do + + else + + ! Get 2D interpolation weights + N(1) = (1.0_ReKi - Xi(2))*(1.0_ReKi - Xi(3))/4.0_ReKi + N(2) = (1.0_ReKi + Xi(2))*(1.0_ReKi - Xi(3))/4.0_ReKi + N(3) = (1.0_ReKi - Xi(2))*(1.0_ReKi + Xi(3))/4.0_ReKi + N(4) = (1.0_ReKi + Xi(2))*(1.0_ReKi + Xi(3))/4.0_ReKi + + ! Calculate velocity + do ic = 1, 3 + Velocity(ic) = dot_product(VelCell(1:4, ic), N(1:4)) + end do + + end if + +end function + +subroutine Grid3DField_GetVelAccCubic(DTime, VelCell, AccCell, Xi, Is3D, Velocity, Accel) + + real(ReKi), intent(in) :: DTime !< cell delta time + real(ReKi), intent(in) :: VelCell(8, 3) !< + real(ReKi), intent(in) :: AccCell(8, 3) !< + real(ReKi), intent(in) :: Xi(3) !< cell distance (dy, dz, dt) [-1, +1] + logical, intent(in) :: Is3D !< + real(ReKi), intent(out), optional :: Velocity(3) !< + real(ReKi), intent(out), optional :: Accel(3) !< + + character(*), parameter :: RoutineName = "Grid3DField_GetVelAccCubic" + integer(IntKi) :: IC + real(ReKi) :: N(4) + real(ReKi) :: P(3, 2), PP(3, 2) + real(ReKi) :: t, C1, C2, C3, C4 + + ! If 3D interpolation + if (Is3D) then + + ! Get interpolation weights + N(1) = (1.0_ReKi - Xi(1))*(1.0_ReKi - Xi(2))/4.0_ReKi + N(2) = (1.0_ReKi + Xi(1))*(1.0_ReKi - Xi(2))/4.0_ReKi + N(3) = (1.0_ReKi - Xi(1))*(1.0_ReKi + Xi(2))/4.0_ReKi + N(4) = (1.0_ReKi + Xi(1))*(1.0_ReKi + Xi(2))/4.0_ReKi + + ! Calculate velocity and acceleration at lo and hi time + do IC = 1, 3 + P(IC, 1) = dot_product(VelCell(1:4, IC), N) ! lo time + P(IC, 2) = dot_product(VelCell(5:8, IC), N) ! hi time + PP(IC, 1) = dot_product(AccCell(1:4, IC), N) ! lo time + PP(IC, 2) = dot_product(AccCell(5:8, IC), N) ! hi time + end do + + else ! 2D (Tower) + + ! Get interpolation weights + N(1) = (1.0_ReKi - Xi(2))/2.0_ReKi + N(2) = (1.0_ReKi + Xi(2))/2.0_ReKi + + ! Calculate velocity and acceleration at lo and hi time + do IC = 1, 3 + P(IC, 1) = dot_product(VelCell(1:2, IC), N(1:2)) ! lo time + P(IC, 2) = dot_product(VelCell(3:4, IC), N(1:2)) ! hi time + PP(IC, 1) = dot_product(AccCell(1:2, IC), N(1:2)) ! lo time + PP(IC, 2) = dot_product(AccCell(3:4, IC), N(1:2)) ! hi time + end do + + end if + + ! Calculate interval percent + t = (Xi(3) + 1)/2.0_ReKi + + ! If velocity requested + if (present(Velocity)) then + C1 = 2.0_ReKi*t*t*t - 3.0_ReKi*t*t + 1.0_ReKi + C2 = (t*t*t - 2.0_ReKi*t*t + t)*DTime + C3 = -2.0_ReKi*t*t*t + 3.0_ReKi*t*t + C4 = (t*t*t - t*t)*DTime + Velocity = C1*P(:, 1) + C2*PP(:, 1) + C3*P(:, 2) + C4*PP(:, 2) + end if + + ! If acceleration requested + if (present(Accel)) then + C1 = (6.0_ReKi*t*t - 6.0_ReKi*t)/DTime + C2 = 3.0_ReKi*t*t - 4.0_ReKi*t + 1.0_ReKi + C3 = -C1 + C4 = 3.0_ReKi*t*t - 2.0_ReKi*t + Accel = C1*P(:, 1) + C2*PP(:, 1) + C3*P(:, 2) + C4*PP(:, 2) + end if + +end subroutine + +subroutine IfW_Grid3DField_CalcAccel(G3D, ErrStat, ErrMsg) + type(Grid3DFieldType), intent(inout) :: G3D + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "Grid3DField_CalcAccel" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + integer(IntKi) :: ic, iy, iz + real(ReKi), allocatable :: u(:), dy2(:) + + ErrStat = ErrID_None + ErrMsg = "" + + ! Allocate storage for acceleration grid + call AllocAry(G3D%Acc, size(G3D%Vel, dim=1), size(G3D%Vel, dim=2), & + size(G3D%Vel, dim=3), size(G3D%Vel, dim=4), & + 'grid-field velocity data', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! If number of time grids is 1 or 2, set all accelerations to zero, return + if (G3D%NTGrids < 3) then + G3D%Acc = 0.0_SiKi + return + end if + + ! Allocate storage for U used in cubic spline derivative calc + call AllocAry(U, G3D%NSteps, "storage for U", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for V used in cubic spline derivative calc + call AllocAry(dy2, G3D%NSteps, "storage for V", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through grid points and calculate derivative using spline + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + do ic = 1, G3D%NComp + call CalcCubicSplineDeriv(G3D%NSteps, G3D%DTime, G3D%Vel(ic, iy, iz, :), G3D%Acc(ic, iy, iz, :)) + end do + end do + end do + + ! If grid field does not include tower grids, return + if (G3D%NTGrids == 0) return + + ! Allocate storage for tower acceleration + call AllocAry(G3D%AccTower, size(G3D%VelTower, dim=1), & + size(G3D%VelTower, dim=2), size(G3D%VelTower, dim=3), & + 'tower wind acceleration data.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! If number of time grids is 1 or 2, set all accelerations to zero + if (G3D%NTGrids < 3) then + G3D%Acc = 0.0_SiKi + else ! Otherwise, calculate acceleration at each grid point + do iz = 1, G3D%NTGrids + do ic = 1, G3D%NComp + call CalcCubicSplineDeriv(G3D%NSteps, G3D%DTime, G3D%VelTower(ic, iz, :), G3D%AccTower(ic, iz, :)) + end do + end do + end if + +contains + + !> CalcCubicSplineDeriv fits a cubic spline through the y array with points + !! spaced a constant 'h' apart. It then calculates the corresponding + !! derivative of y with respect to x at the same x values and returns it + !! in the dy array. + subroutine CalcCubicSplineDeriv(n, h, y, dy) + integer(IntKi), intent(in) :: n ! number of points + real(ReKi), intent(in) :: h ! delta time + real(SiKi), intent(in) :: y(:) ! value at each time + real(SiKi), intent(out) :: dy(:) ! value derivative at each time + + integer(IntKi) :: i + real(ReKi) :: p, un + + ! If periodic function, set beginning and end to have same slope + if (G3D%Periodic) then + dy(1) = real((y(2) - y(n - 1))/(2.0_ReKi*h), SiKi) + dy(n) = dy(1) + else + dy(1) = 0.0_ReKi + dy(n) = 0.0_ReKi + end if + + ! Apply first derivative at lower boundary condition + dy2(1) = -0.5_ReKi + u(1) = 3.0_ReKi*((y(2) - y(1))/h - dy(1))/h + + ! Decomposition + do i = 2, n - 1 + p = 0.5_ReKi*dy2(i - 1) + 2.0_ReKi + dy2(i) = -0.5_ReKi/p + u(i) = (6.*((y(i + 1) - 2.0_ReKi*y(i) + y(i - 1))/h)/(2.0_ReKi*h) - 0.5_ReKi*u(i - 1))/p + end do + + ! Apply first derviative at upper boundary condition + un = 3.0_ReKi*(dy(n) - (y(n) - y(n - 1))/h)/h + dy2(n) = (un - 0.5_ReKi*u(n - 1))/(0.5_ReKi*dy2(n - 1) + 1.0_ReKi) + + ! Back substitution and derivative calculation + do i = n - 1, 1, -1 + dy2(i) = dy2(i)*dy2(i + 1) + u(i) + dy(i) = real((y(i + 1) - y(i))/h - h*(dy2(i)/3.0_ReKi + dy2(i + 1)/6.0_ReKi), SiKi) + end do + + end subroutine + +end subroutine + +!> This subroutine generates the mean wind vector timeseries for each height above the ground. This +!! is essentially compressing the Y dimension of the wind box leaving a Z-T plane of vectors. The +!! resulting dimensions will be (NZGrids, NYGrids, NFFComp, NFFSteps) +subroutine IfW_Grid3DField_CalcVelAvgProfile(G3D, CalcAccel, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + logical, intent(inout) :: CalcAccel !< Flag to calculate acceleration + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = 'IfW_Grid3DField_CalcVelAvgProfile' + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Allocate velocity array + if (.not. allocated(G3D%VelAvg)) then + call AllocAry(G3D%VelAvg, G3D%NComp, G3D%NZGrids, G3D%NSteps, & + 'Full-field average wind velocity timeseries data array.', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + G3D%VelAvg = 0.0_SiKi + end if + + ! Calculate average velocity for each component across grid (Y) + G3D%VelAvg = sum(G3D%Vel, dim=2)/G3D%NYGrids + + ! If acceleration calculation not requested, return + if (.not. CalcAccel) return + + ! Allocate acceleration array + if (.not. allocated(G3D%AccAvg)) then + call AllocAry(G3D%AccAvg, G3D%NComp, G3D%NZGrids, G3D%NSteps, & + 'Full-field average wind acceleration timeseries data array.', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + G3D%AccAvg = 0.0_SiKi + end if + + ! Calculate average acceleration for each component across grid (Y) + G3D%AccAvg = sum(G3D%Acc, dim=2)/G3D%NYGrids + +end subroutine + +subroutine Grid4DField_GetVel(G4D, Time, Position, Velocity, ErrStat, ErrMsg) + + type(Grid4DFieldType), intent(in) :: G4D !< 4D grid-field data + real(DbKi), intent(in) :: Time !< time to get value + real(ReKi), intent(in) :: Position(3) !< position X,Y,Z to get value + real(ReKi), intent(out) :: Velocity(3) !< The U, V, W velocities + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "Grid4DField_GetVel" + + integer(IntKi) :: Indx_Lo(4) ! index associated with lower bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) + integer(IntKi) :: Indx_Hi(4) ! index associated with upper bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) + real(ReKi) :: xi(4) ! isoparametric coordinates + real(ReKi) :: N(16, 1) ! Shape function + real(ReKi) :: P(3, 16) ! Point values + real(ReKi) :: tmp + integer(IntKi) :: i + + ErrStat = ErrID_None + ErrMsg = "" + + !---------------------------------------------------------------------------- + ! Find the bounding indices for XYZ position + !---------------------------------------------------------------------------- + + do i = 1, 3 + tmp = (Position(i) - G4D%pZero(i))/G4D%delta(i) + Indx_Lo(i) = INT(tmp) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 + xi(i) = 2.0_ReKi*(tmp - aint(tmp)) - 1.0_ReKi ! convert to value between -1 and 1 + end do + + !---------------------------------------------------------------------------- + ! Find the bounding indices for time + !---------------------------------------------------------------------------- + + i = 4 + tmp = real((Time - G4D%TimeStart)/G4D%delta(i), ReKi) + Indx_Lo(i) = INT(tmp) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 + xi(i) = 2.0_ReKi*(tmp - aint(tmp)) - 1.0_ReKi ! convert to value between -1 and 1 + if ((Indx_Lo(i) == G4D%n(i))) then + if (abs(xi(i) + 1.0_SiKi) < 0.001_SiKi) then ! Allow for the special case where Time = TgridStart + deltat*( n_high_low - 1 ) + Indx_Lo(i) = Indx_Lo(i) - 1 + xi(i) = 1.0_SiKi + end if + end if + + !---------------------------------------------------------------------------- + ! Return error if outside bounds + !---------------------------------------------------------------------------- + + do i = 1, 4 + if (Indx_Lo(i) <= 0) then + Indx_Lo(i) = 1 + call SetErrStat(ErrID_Fatal, 'Outside the grid bounds.', ErrStat, ErrMsg, RoutineName) + return + elseif (Indx_Lo(i) >= G4D%n(i)) then + Indx_Lo(i) = max(G4D%n(i) - 1, 1) ! make sure it's a valid index + call SetErrStat(ErrID_Fatal, 'Outside the grid bounds.', ErrStat, ErrMsg, RoutineName) + return + end if + Indx_Hi(i) = min(Indx_Lo(i) + 1, G4D%n(i)) ! make sure it's a valid index + end do + + !---------------------------------------------------------------------------- + ! Clamp isopc to [-1, 1] so we don't extrapolate (effectively nearest neighbor) + !---------------------------------------------------------------------------- + + xi = min(+1.0_ReKi, max(-1.0_ReKi, xi)) + + !---------------------------------------------------------------------------- + ! compute weighting factors + !---------------------------------------------------------------------------- + + N(1, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(2, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(3, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(4, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(5, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(6, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(7, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(8, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(9, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(10, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(11, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(12, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(13, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N(14, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N(15, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N(16, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N = N/16.0_ReKi + + !---------------------------------------------------------------------------- + ! Get point values + !---------------------------------------------------------------------------- + + P(:, 1) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 2) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 3) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 4) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 5) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 6) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 7) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 8) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 9) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 10) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 11) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 12) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 13) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4)) + P(:, 14) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4)) + P(:, 15) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4)) + P(:, 16) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4)) + + !---------------------------------------------------------------------------- + ! Interpolate + !---------------------------------------------------------------------------- + + Velocity = pack(matmul(P, N), .true.) + +end subroutine + +subroutine UserField_GetVel(UF, Time, Position, Velocity, ErrStat, ErrMsg) + + type(UserFieldType), intent(in) :: UF !< user-field data + real(DbKi), intent(in) :: Time !< time to get value + real(ReKi), intent(in) :: Position(3) !< position X,Y,Z to get value + real(ReKi), intent(out) :: Velocity(3) !< The U, V, W velocities + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "UserField_GetVel" + + ErrStat = ErrID_None + ErrMsg = "" + + Velocity = 0.0_ReKi + call SetErrStat(ErrID_Fatal, "UserField_GetVel not implemented", ErrStat, ErrMsg, RoutineName) + +end subroutine + +function CalculateMeanVelocity(G3D, z, y) result(u) + + type(Grid3DFieldType), intent(IN) :: G3D !< Parameters + real(ReKi), intent(IN) :: Z ! height + real(ReKi), intent(IN) :: y ! lateral location + real(ReKi) :: u ! mean wind speed at position (y,z) + + select case (G3D%WindProfileType) + + case (WindProfileType_PL) + + U = G3D%MeanWS*(Z/G3D%RefHeight)**G3D%PLExp ! [IEC 61400-1 6.3.1.2 (10)] + + case (WindProfileType_Log) + + if (.not. EqualRealNos(G3D%RefHeight, G3D%Z0) .and. Z > 0.0_ReKi) then + U = G3D%MeanWS*(LOG(Z/G3D%Z0))/(LOG(G3D%RefHeight/G3D%Z0)) + else + U = 0.0_ReKi + end if + + case (WindProfileType_Constant) + + U = G3D%MeanWS + + case DEFAULT + + U = 0.0_ReKi + + end select + + if (G3D%VLinShr .ne. 0.0_ReKi) then ! Add vertical linear shear, if has + U = U + G3D%MeanWS*G3D%VLinShr*(Z - G3D%RefHeight)/G3D%RefLength + end if + + if (G3D%HLinShr .ne. 0.0_ReKi) then ! Add horizontal linear shear, if has + U = U + G3D%MeanWS*G3D%HLinShr*y/G3D%RefLength + end if + +end function CalculateMeanVelocity + +subroutine Uniform_to_Grid3D(UF, InterpCubic, G3D, ErrStat, ErrMsg) + + type(UniformFieldType), intent(IN) :: UF !< UniformWind Parameters + logical, intent(in) :: InterpCubic !< Flag to use cubic interpolation + type(Grid3DFieldType), intent(OUT) :: G3D !< FF Parameters + integer(IntKi), intent(OUT) :: ErrStat !< error status + character(*), intent(OUT) :: ErrMsg !< error message + + character(*), parameter :: RoutineName = 'Uniform_to_FFWind' + integer(ReKi), parameter :: dz = 5.0 + integer(ReKi), parameter :: dy = 5.0 + real(DbKi) :: Time + real(ReKi) :: PositionXYZ(3) + type(UniformField_Interp) :: op + integer(IntKi) :: n, i, it, iy, iz + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + G3D%WindFileFormat = -1 ! Binary file format description number + G3D%NComp = 3 ! Number of wind components + G3D%Periodic = .false. + G3D%InterpTower = .true. + G3D%RefHeight = UF%RefHeight + G3D%NTGrids = 0 + G3D%InvDY = 1.0_ReKi/dy ! reciprocal of delta y (1/meters) + G3D%InvDZ = 1.0_ReKi/dz ! reciprocal of delta z (1/meters) + + ! Number of points in the lateral (y) direction of the grids + n = nint(UF%RefLength*1.1_ReKi*0.5_ReKi/dy) + G3D%NYGrids = n*2 + 1 + + ! Number of points in the vertical (z) direction of the grids + n = nint(UF%RefLength*1.1_ReKi*0.5_ReKi/dz) + G3D%NZGrids = nint(G3D%RefHeight/dy) + n + 1 + + ! Half the grid width (meters) + G3D%YHWid = 0.5_ReKi*dy*(G3D%NYGrids - 1) + + ! Half the grid height (meters) + G3D%ZHWid = 0.5_ReKi*dz*(G3D%NZGrids - 1) + + ! Height of the bottom of the grid (meters) + G3D%GridBase = G3D%RefHeight + n*dz - G3D%ZHWid*2.0_ReKi + + ! Initial x position of grid (distance in FF is offset) meters) + G3D%InitXPosition = 0.0_ReKi + + ! time will be the smallest delta t in this Uniform wind file + if (UF%DataSize < 2) then + G3D%DTime = 600.0_ReKi ! doesn't matter what the time step is + G3D%NSteps = 2 ! "Number of time steps in the FF array + else + G3D%DTime = minval(UF%Time(2:) - UF%Time(:size(UF%Time) - 1)) ! Delta time (seconds) + if (G3D%DTime < 0.0001) then + call SetErrStat(ErrID_Fatal, "Smallest time step in uniform wind file is less that 0.0001 seconds. "// & + "Increase the time step to convert to a FF file.", ErrStat, ErrMsg, RoutineName) + return + end if + G3D%NSteps = NINT(UF%Time(UF%DataSize)/G3D%DTime) + 1 + end if + + G3D%Rate = 1.0_ReKi/G3D%DTime ! Data rate (1/DTime) + G3D%AddMeanAfterInterp = .false. ! Add the mean wind speed after interpolating at a given height? + G3D%WindProfileType = WindProfileType_PL ! Wind profile type (0=constant;1=logarithmic;2=power law) + G3D%PLExp = GetAverageVal(UF%ShrV) ! Power law exponent (used for PL wind profile type only) + G3D%Z0 = 0.0_ReKi ! Surface roughness length (used for LOG wind profile type only) + G3D%TotalTime = (G3D%NSteps - 1)*G3D%DTime ! The total time of the simulation (seconds) + + ! Allocate velocity array + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, 'G3D%Vel', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Initialize position + PositionXYZ = 0.0_ReKi + + ! Loop through time steps + do it = 1, G3D%NSteps + + ! Calculate time + Time = (it - 1)*G3D%DTime + + ! Get operating point + if (InterpCubic) then + op = UniformField_InterpCubic(UF, Time) + else + op = UniformField_InterpLinear(UF, Time) + end if + + ! Loop through y grid + do iy = 1, G3D%NYGrids + + ! Calculate Y position + PositionXYZ(2) = (iy - 1)*dy - G3D%YHWid + + ! Loop through z grid + do iz = 1, G3D%NZGrids + + ! Calculate Z position + PositionXYZ(3) = (iz - 1)*dz + G3D%GridBase + + ! If Z is zero or less + if (PositionXYZ(3) <= 0.0_Reki) then + ! Set wind velocity to zero + G3D%Vel(:, iy, iz, it) = 0.0_SiKi + else + ! Calculate velocity at operating point and position, store in grid + G3D%Vel(:, iy, iz, it) = real(UniformField_GetVel(UF, op, PositionXYZ), SiKi) + end if + end do ! iz + end do ! iy + end do ! it + + ! compute some averages for this simulation + G3D%MeanWS = GetAverageVal(UF%VelH) ! Mean wind speed (advection speed) + G3D%InvMWS = 1.0_ReKi/G3D%MeanWS + +contains + + function GetAverageVal(Ary) result(Avg) + real(ReKi), intent(in) :: Ary(:) + real(ReKi) :: Avg + + ! If array has one element, average is first value + if (UF%DataSize < 2) then + Avg = Ary(1) + return + end if + + Avg = UF%Time(1)*Ary(1) ! in case tData(1) /= 0 + do i = 2, UF%DataSize + Avg = Avg + (UF%Time(i) - UF%Time(i - 1))*(Ary(i) + Ary(i - 1)) + end do + Avg = Avg/(UF%Time(UF%DataSize) - UF%Time(1))/2.0_ReKi + + end function GetAverageVal + +end subroutine Uniform_to_Grid3D + +subroutine Grid3D_to_Uniform(G3D, UF, ErrStat, ErrMsg, SmoothingRadius) + + type(Grid3DFieldType), intent(IN) :: G3D !< FF Parameters + type(UniformFieldType), intent(OUT) :: UF !< UniformWind Parameters + integer(IntKi), intent(OUT) :: ErrStat !< error status + character(*), intent(OUT) :: ErrMsg !< error message + real(ReKi), optional, intent(IN) :: SmoothingRadius !< length of time used for smoothing data, seconds (if omitted, no smoothing will occur) + + character(*), parameter :: RoutineName = 'FFWind_to_Uniform' + integer(IntKi) :: i + integer(IntKi) :: iy_ref, iz_ref, iz_p1 + integer(IntKi) :: iy, iz, ic + real(ReKi) :: meanVel(3) + real(ReKi) :: meanWindDir + real(ReKi) :: u_p1, z_p1 + real(ReKi), parameter :: HubPositionX = 0.0_ReKi + real(ReKi) :: radius ! length of time to use for smoothing uniform wind data, seconds + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + real(SiKi), allocatable :: Vel(:, :, :, :) + real(ReKi), allocatable :: tmp(:) + real(R8Ki) :: transformMat(3, 3) + + ErrStat = ErrID_None + ErrMsg = "" + + if (G3D%RefLength > epsilon(0.0_ReKi)) then + UF%RefLength = G3D%VLinShr + else + UF%RefLength = (G3D%nYGrids - 1)/G3D%InvDY ! width of the FF wind field + end if + + UF%DataSize = G3D%NSteps + + call AllocAry(UF%Time, UF%DataSize, 'time', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%VelH, UF%DataSize, 'horizontal wind speed', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%AngleH, UF%DataSize, 'direction', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%AngleV, UF%DataSize, 'upflow', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%VelV, UF%DataSize, 'vertical wind speed', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%ShrH, UF%DataSize, 'horizontal linear shear', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%ShrV, UF%DataSize, 'vertical power-law shear exponent', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%LinShrV, UF%DataSize, 'vertical linear shear', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%VelGust, UF%DataSize, 'gust velocity', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call AllocAry(Vel, G3D%NZGrids, G3D%NYGrids, G3D%NComp, G3D%NSteps, 'FFData', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(tmp, G3D%NSteps, 'tmp', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev .or. UF%DataSize < 1) then + if (allocated(Vel)) deallocate (Vel) + if (allocated(tmp)) deallocate (tmp) + return + end if + + ! we'll assume these are 0, for simplicity + UF%ShrH = G3D%HLinShr + UF%LinShrV = G3D%VLinShr + UF%VelGust = 0.0_ReKi + + ! fill time array with time at hub position + do i = 1, UF%DataSize + UF%Time(i) = (G3D%InitXPosition - HubPositionX)*G3D%InvMWS + (i - 1)*G3D%DTime + end do + + ! calculate mean velocity at grid point nearest lateral center of grid at reference height: + iy_ref = nint(G3D%nYGrids/2.0_ReKi) + iz_ref = nint((G3D%RefHeight - G3D%GridBase)*G3D%InvDZ) + 1 + UF%RefHeight = G3D%GridBase + (iz_ref - 1)/G3D%InvDZ ! make sure RefHt is on the grid + + ! Calculate mean value for each component through + meanVel = sum(G3D%Vel(:, iy_ref, iz_ref, :), dim=2)/UF%DataSize + + ! calculate the average upflow angle + UF%AngleV = atan2(meanVel(3), TwoNorm(meanVel(1:2))) + meanWindDir = atan2(meanVel(2), meanVel(1)) + + ! rotate the FF wind to remove the mean upflow and direction + transformMat(1, 1) = cos(meanWindDir)*cos(UF%AngleV(1)) + transformMat(2, 1) = -sin(meanWindDir) + transformMat(3, 1) = -cos(meanWindDir)*sin(UF%AngleV(1)) + + transformMat(1, 2) = sin(meanWindDir)*cos(UF%AngleV(1)) + transformMat(2, 2) = cos(meanWindDir) + transformMat(3, 2) = -sin(meanWindDir)*sin(UF%AngleV(1)) + + transformMat(1, 3) = sin(UF%AngleV(1)) + transformMat(2, 3) = 0.0_R8Ki + transformMat(3, 3) = cos(UF%AngleV(1)) + + do ic = 1, size(Vel, 4) + do iy = 1, size(Vel, 2) + do iz = 1, size(Vel, 1) + Vel(iz, iy, :, ic) = real(matmul(transformMat, G3D%Vel(:, iy, iz, i)), SiKi) + end do + end do + end do + + ! make sure we have the correct mean, or the direction will also be off here + if (G3D%AddMeanAfterInterp) then + Vel(iz_ref, iy_ref, 1, :) = Vel(iz_ref, iy_ref, 1, :) + & + real(CalculateMeanVelocity(G3D, UF%RefHeight, 0.0_ReKi), SiKi) + end if + + meanVel = 0.0_ReKi + do i = 1, UF%DataSize + meanVel = meanVel + Vel(iz_ref, iy_ref, :, i) + end do + meanVel = meanVel/UF%DataSize + + ! Fill velocity arrays for uniform wind + do i = 1, UF%DataSize + UF%VelH(i) = TwoNorm(Vel(iz_ref, iy_ref, 1:2, i)) + end do + UF%VelV = Vel(iz_ref, iy_ref, 3, :) + + ! Fill wind direction array + do i = 1, UF%DataSize + UF%AngleH(i) = -(meanWindDir + atan2(Vel(iz_ref, iy_ref, 2, i), Vel(iz_ref, iy_ref, 1, i))) + end do + + ! Now, time average values, if desired: + if (present(SmoothingRadius)) then + radius = SmoothingRadius + else + radius = 0.0_ReKi + end if + + tmp = UF%VelH; call kernelSmoothing(UF%Time, tmp, kernelType_TRIWEIGHT, radius, UF%VelH) + tmp = UF%VelV; call kernelSmoothing(UF%Time, tmp, kernelType_TRIWEIGHT, radius, UF%VelV) + tmp = UF%AngleH; call kernelSmoothing(UF%Time, tmp, kernelType_TRIWEIGHT, radius, UF%AngleH) + + ! Calculate averaged power law coefficient: + if (G3D%WindProfileType == WindProfileType_PL) then + UF%ShrV = G3D%PLExp + else + iz_p1 = G3D%nZGrids ! pick a point to compute the power law exponent (least squares would be better than a single point) + z_p1 = G3D%GridBase + (iz_p1 - 1)/G3D%InvDZ + + if (G3D%AddMeanAfterInterp) then + u_p1 = CalculateMeanVelocity(G3D, z_p1, 0.0_ReKi) + else + u_p1 = 0.0_ReKi + do i = 1, UF%DataSize + u_p1 = u_p1 + Vel(iz_p1, iy_ref, 1, i) + end do + u_p1 = u_p1/UF%DataSize + end if + + if (EqualRealNos(meanVel(1), u_p1) .or. EqualRealNos(u_p1, 0.0_ReKi) .or. EqualRealNos(meanVel(1), 0.0_ReKi)) then + UF%ShrV = 0.0_ReKi + else + UF%ShrV = log(u_p1/meanVel(1))/log(z_p1/UF%RefHeight) + end if + end if + +end subroutine Grid3D_to_Uniform + +end module diff --git a/modules/inflowwind/src/IfW_FlowField.txt b/modules/inflowwind/src/IfW_FlowField.txt new file mode 100644 index 0000000000..773ec7f861 --- /dev/null +++ b/modules/inflowwind/src/IfW_FlowField.txt @@ -0,0 +1,123 @@ +#---------------------------------------------------------------------------------------------------------------------------------- +# Data structures for representing flow fields. +#---------------------------------------------------------------------------------------------------------------------------------- +# +#---------------------------------------------------------------------------------------------------------------------------------- + +param IfW_FlowField - IntKi Undef_FieldType - 0 - "This is the code for an undefined FieldType" - +param ^ - IntKi Uniform_FieldType - 1 - "Uniform FieldType from SteadyWind or Uniform Wind" - +param ^ - IntKi Grid3D_FieldType - 2 - "3D Grid FieldType from TurbSim, Bladed, HAWC" - +param ^ - IntKi Grid4D_FieldType - 3 - "4D Grid FieldType from FAST.Farm" - +param ^ - IntKi Point_FieldType - 4 - "Points FieldType from ExtInflow" - +param ^ - IntKi User_FieldType - 5 - "User FieldType configured by the user" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ UniformFieldType ReKi RefHeight - - - "reference height; used to center the wind" meters +typedef ^ ^ ReKi RefLength - - - "reference length used to scale the linear shear" meters +typedef ^ ^ IntKi DataSize - - - "size of data in HH file" +typedef ^ ^ ReKi Time : - - "HH time array" seconds +typedef ^ ^ ReKi VelH : - - "HH horizontal wind speed" meters/sec +typedef ^ ^ ReKi VelHDot : - - "Derivative of HH horizontal wind speed wrt time" meters/sec +typedef ^ ^ ReKi VelV : - - "HH vertical wind speed, including tower shadow" meters/sec +typedef ^ ^ ReKi VelVDot : - - "Derivative of HH vertical wind speed wrt time" meters/sec +typedef ^ ^ ReKi VelGust : - - "HH wind gust speed" - +typedef ^ ^ ReKi VelGustDot : - - "Derivative of HH wind gust speed wrt time" - +typedef ^ ^ ReKi AngleH : - - "HH wind direction angle" degrees +typedef ^ ^ ReKi AngleHDot : - - "Derivative of HH wind direction angle wrt time" degrees +typedef ^ ^ ReKi AngleV : - - "HH upflow angle" degrees +typedef ^ ^ ReKi AngleVDot : - - "Derivative of HH upflow angle wrt time" degrees +typedef ^ ^ ReKi ShrH : - - "HH horizontal linear shear" - +typedef ^ ^ ReKi ShrHDot : - - "Derivative of HH horizontal linear shear wrt time" - +typedef ^ ^ ReKi ShrV : - - "HH vertical shear exponent" - +typedef ^ ^ ReKi ShrVDot : - - "Derivative of HH vertical shear exponent wrt time" - +typedef ^ ^ ReKi LinShrV : - - "HH vertical linear shear" seconds +typedef ^ ^ ReKi LinShrVDot : - - "Derivative of HH vertical linear shear wrt time" seconds + +typedef ^ UniformField_Interp ReKi VelH - - - "HH horizontal wind speed" meters/sec +typedef ^ ^ ReKi VelHDot - - - "derivative of HH horizontal wind speed wrt Time" meters/sec +typedef ^ ^ ReKi VelV - - - "HH vertical wind speed, including tower shadow" meters/sec +typedef ^ ^ ReKi VelVDot - - - "derivative of HH vertical wind speed wrt Time" meters/sec +typedef ^ ^ ReKi VelGust - - - "HH wind gust speed" - +typedef ^ ^ ReKi VelGustDot - - - "derivative of HH wind gust speed wrt Time" - +typedef ^ ^ ReKi AngleH - - - "HH wind direction angle" degrees +typedef ^ ^ ReKi AngleHDot - - - "derivative of HH wind direction angle wrt Time" degrees +typedef ^ ^ ReKi AngleV - - - "HH upflow angle" degrees +typedef ^ ^ ReKi AngleVDot - - - "derivative of HH upflow angle wrt Time" degrees +typedef ^ ^ ReKi ShrH - - - "HH horizontal linear shear" - +typedef ^ ^ ReKi ShrHDot - - - "derivative of HH horizontal linear shear wrt Time" - +typedef ^ ^ ReKi ShrV - - - "HH vertical shear exponent" - +typedef ^ ^ ReKi ShrVDot - - - "derivative of HH vertical shear exponent wrt Time" - +typedef ^ ^ ReKi LinShrV - - - "HH vertical linear shear" seconds +typedef ^ ^ ReKi LinShrVDot - - - "derivative of HH vertical linear shear wrt Time" seconds +typedef ^ ^ ReKi CosAngleH - - - "Horizontal angle components" - +typedef ^ ^ ReKi SinAngleH - - - "Horizontal angle components" - +typedef ^ ^ ReKi CosAngleV - - - "Vertical angle components" - +typedef ^ ^ ReKi SinAngleV - - - "Vertical angle components" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid3DFieldType IntKi WindFileFormat - - - "Binary file format description number" - +typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - +typedef ^ ^ Logical Periodic - .false. - "Flag to indicate if the wind file is periodic" - +typedef ^ ^ Logical InterpTower - .false. - "Flag to indicate if we should interpolate wind speeds below the tower" - +typedef ^ ^ Logical AddMeanAfterInterp - .false. - "Add the mean wind speed after interpolating at a given height?" - +typedef ^ ^ ReKi RefHeight - 0 - "Reference (hub) height of the grid" meters +typedef ^ ^ ReKi RefLength - 1.0_ReKi - "Reference (rotor) length of the grid (used for horizontal wind profile type only)" - +typedef ^ ^ SiKi Vel :::: - - "Array of field velocities" - +typedef ^ ^ SiKi Acc :::: - - "Array of field accelerations" - +typedef ^ ^ SiKi VelTower ::: - - "Array of tower velocities" - +typedef ^ ^ SiKi AccTower ::: - - "Array of tower accelerations" - +typedef ^ ^ SiKi VelAvg ::: - - "Average velocity profile by Z and time" - +typedef ^ ^ SiKi AccAvg ::: - - "Average acceleration profile by Z and time" - +typedef ^ ^ ReKi DTime - 0 - "Delta time" seconds +typedef ^ ^ ReKi Rate - 0 - "Data rate (1/FFDTime)" Hertz +typedef ^ ^ ReKi YHWid - 0 - "Half the grid width" meters +typedef ^ ^ ReKi ZHWid - 0 - "Half the grid height" meters +typedef ^ ^ ReKi GridBase - 0 - "the height of the bottom of the grid" meters +typedef ^ ^ ReKi InitXPosition - 0 - "the initial x position of grid (distance in FF is offset)" meters +typedef ^ ^ ReKi InvDY - 0 - "reciprocal of delta y" 1/meters +typedef ^ ^ ReKi InvDZ - 0 - "reciprocal of delta z" 1/meters +typedef ^ ^ ReKi MeanWS - 0 - "Mean wind speed (as defined in FF file), not necessarily of the portion used" meters/second +typedef ^ ^ ReKi InvMWS - 0 - "reciprocal of mean wind speed (MeanFFWS)" seconds/meter +typedef ^ ^ ReKi TotalTime - 0 - "The total time of the simulation" seconds +typedef ^ ^ IntKi NComp - 3 - "Number of wind components" - +typedef ^ ^ IntKi NYGrids - 0 - "Number of points in the lateral (y) direction of the grids" - +typedef ^ ^ IntKi NZGrids - 0 - "Number of points in the vertical (z) direction of the grids" - +typedef ^ ^ IntKi NTGrids - 0 - "Number of points in the vertical (z) direction on the tower (below the grids)" - +typedef ^ ^ IntKi NSteps - 0 - "Number of time steps in the FF array" - +typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - +typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - +typedef ^ ^ ReKi VLinShr - 0 - "Vertical linear wind shear coefficient (used for vertical linear wind profile type only)" - +typedef ^ ^ ReKi HLinShr - 0 - "Horizontal linear wind shear coefficient (used for horizontal wind profile type only)" - +typedef ^ ^ LOGICAL BoxExceedAllowF - .FALSE. - "Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim)" - +typedef ^ ^ IntKi BoxExceedAllowIdx - -1 - "Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim)" - +typedef ^ ^ LOGICAL BoxExceedWarned - .FALSE. - "Has a warning been issued for points extrapolated beyond FFWind grid" - + + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid4DFieldType IntKi n 4 - - "number of evenly-spaced grid points in the x, y, z, and t directions" - +typedef ^ ^ ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" +typedef ^ ^ ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" +typedef ^ ^ SiKi Vel ::::: - - "this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt]" - +typedef ^ ^ ReKi TimeStart - - - "this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1))" s + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ PointsFieldType ReKi Vel :: - - "Point velocities populated by external driver [uvw,point]" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ UserFieldType SiKi Dummy - - - "" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ FlowFieldType IntKi FieldType - 0 - "Switch for flow field type {1=Uniform, 2=Grid, 3=User, 4=External}" - +typedef ^ ^ ReKi RefPosition 3 - - "Reference position (point where box is rotated)" meters +typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation" radians +typedef ^ ^ ReKi VFlowAngle - - - "Vertical (upflow) angle" radians +typedef ^ ^ logical VelInterpCubic - .false. - "Velocity interpolation order in time (1=linear; 3=cubic) [Used with WindType=2,3,4,5,7]" - +typedef ^ ^ logical RotateWindBox - .false. - "flag indicating if the wind will be rotated" - +typedef ^ ^ logical AccFieldValid - .false. - "flag indicating that acceleration field has been calculated" - +typedef ^ ^ ReKi RotToWind {3}{3} - - "Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X')" - +typedef ^ ^ ReKi RotFromWind {3}{3} - - "Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind)" - +typedef ^ ^ UniformFieldType Uniform - - - "Uniform Flow Data" +typedef ^ ^ Grid3DFieldType Grid3D - - - "Grid Field Wind Data" +typedef ^ ^ Grid4DFieldType Grid4D - - - "External Grid Flow Data" +typedef ^ ^ PointsFieldType Points - - - "External Point Flow Data" +typedef ^ ^ UserFieldType User - - - "User Field Wind Data" diff --git a/modules/inflowwind/src/IfW_FlowField_Types.f90 b/modules/inflowwind/src/IfW_FlowField_Types.f90 new file mode 100644 index 0000000000..55212a9400 --- /dev/null +++ b/modules/inflowwind/src/IfW_FlowField_Types.f90 @@ -0,0 +1,3576 @@ +!STARTOFREGISTRYGENERATEDFILE 'IfW_FlowField_Types.f90' +! +! WARNING This file is generated automatically by the FAST registry. +! Do not edit. Your changes to this file will be lost. +! +! FAST Registry +!********************************************************************************************************************************* +! IfW_FlowField_Types +!................................................................................................................................. +! This file is part of IfW_FlowField. +! +! Copyright (C) 2012-2016 National Renewable Energy Laboratory +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +! +! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. +! +!********************************************************************************************************************************* +!> This module contains the user-defined types needed in IfW_FlowField. It also contains copy, destroy, pack, and +!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. +MODULE IfW_FlowField_Types +!--------------------------------------------------------------------------------------------------------------------------------- +USE NWTC_Library +IMPLICIT NONE + INTEGER(IntKi), PUBLIC, PARAMETER :: Undef_FieldType = 0 ! This is the code for an undefined FieldType [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Uniform_FieldType = 1 ! Uniform FieldType from SteadyWind or Uniform Wind [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Grid3D_FieldType = 2 ! 3D Grid FieldType from TurbSim, Bladed, HAWC [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Grid4D_FieldType = 3 ! 4D Grid FieldType from FAST.Farm [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Point_FieldType = 4 ! Points FieldType from ExtInflow [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: User_FieldType = 5 ! User FieldType configured by the user [-] +! ========= UniformFieldType ======= + TYPE, PUBLIC :: UniformFieldType + REAL(ReKi) :: RefHeight !< reference height; used to center the wind [meters] + REAL(ReKi) :: RefLength !< reference length used to scale the linear shear [meters] + INTEGER(IntKi) :: DataSize !< size of data in HH file [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Time !< HH time array [seconds] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelH !< HH horizontal wind speed [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelHDot !< Derivative of HH horizontal wind speed wrt time [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelV !< HH vertical wind speed, including tower shadow [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelVDot !< Derivative of HH vertical wind speed wrt time [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelGust !< HH wind gust speed [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelGustDot !< Derivative of HH wind gust speed wrt time [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleH !< HH wind direction angle [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleHDot !< Derivative of HH wind direction angle wrt time [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleV !< HH upflow angle [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleVDot !< Derivative of HH upflow angle wrt time [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrH !< HH horizontal linear shear [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrHDot !< Derivative of HH horizontal linear shear wrt time [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrV !< HH vertical shear exponent [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrVDot !< Derivative of HH vertical shear exponent wrt time [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LinShrV !< HH vertical linear shear [seconds] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LinShrVDot !< Derivative of HH vertical linear shear wrt time [seconds] + END TYPE UniformFieldType +! ======================= +! ========= UniformField_Interp ======= + TYPE, PUBLIC :: UniformField_Interp + REAL(ReKi) :: VelH !< HH horizontal wind speed [meters/sec] + REAL(ReKi) :: VelHDot !< derivative of HH horizontal wind speed wrt Time [meters/sec] + REAL(ReKi) :: VelV !< HH vertical wind speed, including tower shadow [meters/sec] + REAL(ReKi) :: VelVDot !< derivative of HH vertical wind speed wrt Time [meters/sec] + REAL(ReKi) :: VelGust !< HH wind gust speed [-] + REAL(ReKi) :: VelGustDot !< derivative of HH wind gust speed wrt Time [-] + REAL(ReKi) :: AngleH !< HH wind direction angle [degrees] + REAL(ReKi) :: AngleHDot !< derivative of HH wind direction angle wrt Time [degrees] + REAL(ReKi) :: AngleV !< HH upflow angle [degrees] + REAL(ReKi) :: AngleVDot !< derivative of HH upflow angle wrt Time [degrees] + REAL(ReKi) :: ShrH !< HH horizontal linear shear [-] + REAL(ReKi) :: ShrHDot !< derivative of HH horizontal linear shear wrt Time [-] + REAL(ReKi) :: ShrV !< HH vertical shear exponent [-] + REAL(ReKi) :: ShrVDot !< derivative of HH vertical shear exponent wrt Time [-] + REAL(ReKi) :: LinShrV !< HH vertical linear shear [seconds] + REAL(ReKi) :: LinShrVDot !< derivative of HH vertical linear shear wrt Time [seconds] + REAL(ReKi) :: CosAngleH !< Horizontal angle components [-] + REAL(ReKi) :: SinAngleH !< Horizontal angle components [-] + REAL(ReKi) :: CosAngleV !< Vertical angle components [-] + REAL(ReKi) :: SinAngleV !< Vertical angle components [-] + END TYPE UniformField_Interp +! ======================= +! ========= Grid3DFieldType ======= + TYPE, PUBLIC :: Grid3DFieldType + INTEGER(IntKi) :: WindFileFormat !< Binary file format description number [-] + INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] + LOGICAL :: Periodic = .false. !< Flag to indicate if the wind file is periodic [-] + LOGICAL :: InterpTower = .false. !< Flag to indicate if we should interpolate wind speeds below the tower [-] + LOGICAL :: AddMeanAfterInterp = .false. !< Add the mean wind speed after interpolating at a given height? [-] + REAL(ReKi) :: RefHeight = 0 !< Reference (hub) height of the grid [meters] + REAL(ReKi) :: RefLength = 1.0_ReKi !< Reference (rotor) length of the grid (used for horizontal wind profile type only) [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vel !< Array of field velocities [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Acc !< Array of field accelerations [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: VelTower !< Array of tower velocities [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: AccTower !< Array of tower accelerations [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: VelAvg !< Average velocity profile by Z and time [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: AccAvg !< Average acceleration profile by Z and time [-] + REAL(ReKi) :: DTime = 0 !< Delta time [seconds] + REAL(ReKi) :: Rate = 0 !< Data rate (1/FFDTime) [Hertz] + REAL(ReKi) :: YHWid = 0 !< Half the grid width [meters] + REAL(ReKi) :: ZHWid = 0 !< Half the grid height [meters] + REAL(ReKi) :: GridBase = 0 !< the height of the bottom of the grid [meters] + REAL(ReKi) :: InitXPosition = 0 !< the initial x position of grid (distance in FF is offset) [meters] + REAL(ReKi) :: InvDY = 0 !< reciprocal of delta y [1/meters] + REAL(ReKi) :: InvDZ = 0 !< reciprocal of delta z [1/meters] + REAL(ReKi) :: MeanWS = 0 !< Mean wind speed (as defined in FF file), not necessarily of the portion used [meters/second] + REAL(ReKi) :: InvMWS = 0 !< reciprocal of mean wind speed (MeanFFWS) [seconds/meter] + REAL(ReKi) :: TotalTime = 0 !< The total time of the simulation [seconds] + INTEGER(IntKi) :: NComp = 3 !< Number of wind components [-] + INTEGER(IntKi) :: NYGrids = 0 !< Number of points in the lateral (y) direction of the grids [-] + INTEGER(IntKi) :: NZGrids = 0 !< Number of points in the vertical (z) direction of the grids [-] + INTEGER(IntKi) :: NTGrids = 0 !< Number of points in the vertical (z) direction on the tower (below the grids) [-] + INTEGER(IntKi) :: NSteps = 0 !< Number of time steps in the FF array [-] + REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] + REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] + REAL(ReKi) :: VLinShr = 0 !< Vertical linear wind shear coefficient (used for vertical linear wind profile type only) [-] + REAL(ReKi) :: HLinShr = 0 !< Horizontal linear wind shear coefficient (used for horizontal wind profile type only) [-] + LOGICAL :: BoxExceedAllowF = .FALSE. !< Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim) [-] + INTEGER(IntKi) :: BoxExceedAllowIdx = -1 !< Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim) [-] + LOGICAL :: BoxExceedWarned = .FALSE. !< Has a warning been issued for points extrapolated beyond FFWind grid [-] + END TYPE Grid3DFieldType +! ======================= +! ========= Grid4DFieldType ======= + TYPE, PUBLIC :: Grid4DFieldType + INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of evenly-spaced grid points in the x, y, z, and t directions [-] + REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] + REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] + REAL(SiKi) , DIMENSION(:,:,:,:,:), ALLOCATABLE :: Vel !< this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt] [-] + REAL(ReKi) :: TimeStart !< this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1)) [s] + END TYPE Grid4DFieldType +! ======================= +! ========= PointsFieldType ======= + TYPE, PUBLIC :: PointsFieldType + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vel !< Point velocities populated by external driver [uvw,point] [-] + END TYPE PointsFieldType +! ======================= +! ========= UserFieldType ======= + TYPE, PUBLIC :: UserFieldType + REAL(SiKi) :: Dummy !< [-] + END TYPE UserFieldType +! ======================= +! ========= FlowFieldType ======= + TYPE, PUBLIC :: FlowFieldType + INTEGER(IntKi) :: FieldType = 0 !< Switch for flow field type {1=Uniform, 2=Grid, 3=User, 4=External} [-] + REAL(ReKi) , DIMENSION(1:3) :: RefPosition !< Reference position (point where box is rotated) [meters] + REAL(ReKi) :: PropagationDir !< Direction of wind propagation [radians] + REAL(ReKi) :: VFlowAngle !< Vertical (upflow) angle [radians] + LOGICAL :: VelInterpCubic = .false. !< Velocity interpolation order in time (1=linear; 3=cubic) [Used with WindType=2,3,4,5,7] [-] + LOGICAL :: RotateWindBox = .false. !< flag indicating if the wind will be rotated [-] + LOGICAL :: AccFieldValid = .false. !< flag indicating that acceleration field has been calculated [-] + REAL(ReKi) , DIMENSION(1:3,1:3) :: RotToWind !< Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X') [-] + REAL(ReKi) , DIMENSION(1:3,1:3) :: RotFromWind !< Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind) [-] + TYPE(UniformFieldType) :: Uniform !< Uniform Flow Data [-] + TYPE(Grid3DFieldType) :: Grid3D !< Grid Field Wind Data [-] + TYPE(Grid4DFieldType) :: Grid4D !< External Grid Flow Data [-] + TYPE(PointsFieldType) :: Points !< External Point Flow Data [-] + TYPE(UserFieldType) :: User !< User Field Wind Data [-] + END TYPE FlowFieldType +! ======================= +CONTAINS + SUBROUTINE IfW_FlowField_CopyUniformFieldType( SrcUniformFieldTypeData, DstUniformFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(UniformFieldType), INTENT(IN) :: SrcUniformFieldTypeData + TYPE(UniformFieldType), INTENT(INOUT) :: DstUniformFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyUniformFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUniformFieldTypeData%RefHeight = SrcUniformFieldTypeData%RefHeight + DstUniformFieldTypeData%RefLength = SrcUniformFieldTypeData%RefLength + DstUniformFieldTypeData%DataSize = SrcUniformFieldTypeData%DataSize +IF (ALLOCATED(SrcUniformFieldTypeData%Time)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%Time,1) + i1_u = UBOUND(SrcUniformFieldTypeData%Time,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%Time)) THEN + ALLOCATE(DstUniformFieldTypeData%Time(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%Time.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%Time = SrcUniformFieldTypeData%Time +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelH)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelH,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelH,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelH)) THEN + ALLOCATE(DstUniformFieldTypeData%VelH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelH = SrcUniformFieldTypeData%VelH +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelHDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelHDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelHDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelHDot)) THEN + ALLOCATE(DstUniformFieldTypeData%VelHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelHDot = SrcUniformFieldTypeData%VelHDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelV)) THEN + ALLOCATE(DstUniformFieldTypeData%VelV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelV = SrcUniformFieldTypeData%VelV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%VelVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelVDot = SrcUniformFieldTypeData%VelVDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelGust)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelGust,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelGust,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelGust)) THEN + ALLOCATE(DstUniformFieldTypeData%VelGust(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelGust.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelGust = SrcUniformFieldTypeData%VelGust +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelGustDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelGustDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelGustDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelGustDot)) THEN + ALLOCATE(DstUniformFieldTypeData%VelGustDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelGustDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelGustDot = SrcUniformFieldTypeData%VelGustDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleH)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleH,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleH,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleH)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleH = SrcUniformFieldTypeData%AngleH +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleHDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleHDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleHDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleHDot)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleHDot = SrcUniformFieldTypeData%AngleHDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleV)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleV = SrcUniformFieldTypeData%AngleV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleVDot = SrcUniformFieldTypeData%AngleVDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrH)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrH,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrH,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrH)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrH = SrcUniformFieldTypeData%ShrH +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrHDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrHDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrHDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrHDot)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrHDot = SrcUniformFieldTypeData%ShrHDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrV)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrV = SrcUniformFieldTypeData%ShrV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrVDot = SrcUniformFieldTypeData%ShrVDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%LinShrV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%LinShrV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%LinShrV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%LinShrV)) THEN + ALLOCATE(DstUniformFieldTypeData%LinShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%LinShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%LinShrV = SrcUniformFieldTypeData%LinShrV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%LinShrVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%LinShrVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%LinShrVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%LinShrVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%LinShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%LinShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%LinShrVDot = SrcUniformFieldTypeData%LinShrVDot +ENDIF + END SUBROUTINE IfW_FlowField_CopyUniformFieldType + + SUBROUTINE IfW_FlowField_DestroyUniformFieldType( UniformFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(UniformFieldType), INTENT(INOUT) :: UniformFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyUniformFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(UniformFieldTypeData%Time)) THEN + DEALLOCATE(UniformFieldTypeData%Time) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelH)) THEN + DEALLOCATE(UniformFieldTypeData%VelH) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelHDot)) THEN + DEALLOCATE(UniformFieldTypeData%VelHDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelV)) THEN + DEALLOCATE(UniformFieldTypeData%VelV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelVDot)) THEN + DEALLOCATE(UniformFieldTypeData%VelVDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelGust)) THEN + DEALLOCATE(UniformFieldTypeData%VelGust) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelGustDot)) THEN + DEALLOCATE(UniformFieldTypeData%VelGustDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleH)) THEN + DEALLOCATE(UniformFieldTypeData%AngleH) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleHDot)) THEN + DEALLOCATE(UniformFieldTypeData%AngleHDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleV)) THEN + DEALLOCATE(UniformFieldTypeData%AngleV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleVDot)) THEN + DEALLOCATE(UniformFieldTypeData%AngleVDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrH)) THEN + DEALLOCATE(UniformFieldTypeData%ShrH) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrHDot)) THEN + DEALLOCATE(UniformFieldTypeData%ShrHDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrV)) THEN + DEALLOCATE(UniformFieldTypeData%ShrV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrVDot)) THEN + DEALLOCATE(UniformFieldTypeData%ShrVDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%LinShrV)) THEN + DEALLOCATE(UniformFieldTypeData%LinShrV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%LinShrVDot)) THEN + DEALLOCATE(UniformFieldTypeData%LinShrVDot) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyUniformFieldType + + SUBROUTINE IfW_FlowField_PackUniformFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(UniformFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackUniformFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! RefHeight + Re_BufSz = Re_BufSz + 1 ! RefLength + Int_BufSz = Int_BufSz + 1 ! DataSize + Int_BufSz = Int_BufSz + 1 ! Time allocated yes/no + IF ( ALLOCATED(InData%Time) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Time upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Time) ! Time + END IF + Int_BufSz = Int_BufSz + 1 ! VelH allocated yes/no + IF ( ALLOCATED(InData%VelH) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelH upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelH) ! VelH + END IF + Int_BufSz = Int_BufSz + 1 ! VelHDot allocated yes/no + IF ( ALLOCATED(InData%VelHDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelHDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelHDot) ! VelHDot + END IF + Int_BufSz = Int_BufSz + 1 ! VelV allocated yes/no + IF ( ALLOCATED(InData%VelV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelV) ! VelV + END IF + Int_BufSz = Int_BufSz + 1 ! VelVDot allocated yes/no + IF ( ALLOCATED(InData%VelVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelVDot) ! VelVDot + END IF + Int_BufSz = Int_BufSz + 1 ! VelGust allocated yes/no + IF ( ALLOCATED(InData%VelGust) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelGust upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelGust) ! VelGust + END IF + Int_BufSz = Int_BufSz + 1 ! VelGustDot allocated yes/no + IF ( ALLOCATED(InData%VelGustDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelGustDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelGustDot) ! VelGustDot + END IF + Int_BufSz = Int_BufSz + 1 ! AngleH allocated yes/no + IF ( ALLOCATED(InData%AngleH) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleH upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleH) ! AngleH + END IF + Int_BufSz = Int_BufSz + 1 ! AngleHDot allocated yes/no + IF ( ALLOCATED(InData%AngleHDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleHDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleHDot) ! AngleHDot + END IF + Int_BufSz = Int_BufSz + 1 ! AngleV allocated yes/no + IF ( ALLOCATED(InData%AngleV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleV) ! AngleV + END IF + Int_BufSz = Int_BufSz + 1 ! AngleVDot allocated yes/no + IF ( ALLOCATED(InData%AngleVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleVDot) ! AngleVDot + END IF + Int_BufSz = Int_BufSz + 1 ! ShrH allocated yes/no + IF ( ALLOCATED(InData%ShrH) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrH upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrH) ! ShrH + END IF + Int_BufSz = Int_BufSz + 1 ! ShrHDot allocated yes/no + IF ( ALLOCATED(InData%ShrHDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrHDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrHDot) ! ShrHDot + END IF + Int_BufSz = Int_BufSz + 1 ! ShrV allocated yes/no + IF ( ALLOCATED(InData%ShrV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrV) ! ShrV + END IF + Int_BufSz = Int_BufSz + 1 ! ShrVDot allocated yes/no + IF ( ALLOCATED(InData%ShrVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrVDot) ! ShrVDot + END IF + Int_BufSz = Int_BufSz + 1 ! LinShrV allocated yes/no + IF ( ALLOCATED(InData%LinShrV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LinShrV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%LinShrV) ! LinShrV + END IF + Int_BufSz = Int_BufSz + 1 ! LinShrVDot allocated yes/no + IF ( ALLOCATED(InData%LinShrVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LinShrVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%LinShrVDot) ! LinShrVDot + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%RefHeight + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%DataSize + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Time) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Time,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Time,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Time,1), UBOUND(InData%Time,1) + ReKiBuf(Re_Xferred) = InData%Time(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelH) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelH,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelH,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelH,1), UBOUND(InData%VelH,1) + ReKiBuf(Re_Xferred) = InData%VelH(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelHDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelHDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelHDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelHDot,1), UBOUND(InData%VelHDot,1) + ReKiBuf(Re_Xferred) = InData%VelHDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelV,1), UBOUND(InData%VelV,1) + ReKiBuf(Re_Xferred) = InData%VelV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelVDot,1), UBOUND(InData%VelVDot,1) + ReKiBuf(Re_Xferred) = InData%VelVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelGust) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelGust,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelGust,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelGust,1), UBOUND(InData%VelGust,1) + ReKiBuf(Re_Xferred) = InData%VelGust(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelGustDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelGustDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelGustDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelGustDot,1), UBOUND(InData%VelGustDot,1) + ReKiBuf(Re_Xferred) = InData%VelGustDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleH) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleH,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleH,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleH,1), UBOUND(InData%AngleH,1) + ReKiBuf(Re_Xferred) = InData%AngleH(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleHDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleHDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleHDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleHDot,1), UBOUND(InData%AngleHDot,1) + ReKiBuf(Re_Xferred) = InData%AngleHDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleV,1), UBOUND(InData%AngleV,1) + ReKiBuf(Re_Xferred) = InData%AngleV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleVDot,1), UBOUND(InData%AngleVDot,1) + ReKiBuf(Re_Xferred) = InData%AngleVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrH) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrH,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrH,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrH,1), UBOUND(InData%ShrH,1) + ReKiBuf(Re_Xferred) = InData%ShrH(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrHDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrHDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrHDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrHDot,1), UBOUND(InData%ShrHDot,1) + ReKiBuf(Re_Xferred) = InData%ShrHDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrV,1), UBOUND(InData%ShrV,1) + ReKiBuf(Re_Xferred) = InData%ShrV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrVDot,1), UBOUND(InData%ShrVDot,1) + ReKiBuf(Re_Xferred) = InData%ShrVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LinShrV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LinShrV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LinShrV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LinShrV,1), UBOUND(InData%LinShrV,1) + ReKiBuf(Re_Xferred) = InData%LinShrV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LinShrVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LinShrVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LinShrVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LinShrVDot,1), UBOUND(InData%LinShrVDot,1) + ReKiBuf(Re_Xferred) = InData%LinShrVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE IfW_FlowField_PackUniformFieldType + + SUBROUTINE IfW_FlowField_UnPackUniformFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(UniformFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackUniformFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%RefHeight = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%DataSize = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Time not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Time)) DEALLOCATE(OutData%Time) + ALLOCATE(OutData%Time(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Time.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Time,1), UBOUND(OutData%Time,1) + OutData%Time(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelH not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelH)) DEALLOCATE(OutData%VelH) + ALLOCATE(OutData%VelH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelH,1), UBOUND(OutData%VelH,1) + OutData%VelH(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelHDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelHDot)) DEALLOCATE(OutData%VelHDot) + ALLOCATE(OutData%VelHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelHDot,1), UBOUND(OutData%VelHDot,1) + OutData%VelHDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelV)) DEALLOCATE(OutData%VelV) + ALLOCATE(OutData%VelV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelV,1), UBOUND(OutData%VelV,1) + OutData%VelV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelVDot)) DEALLOCATE(OutData%VelVDot) + ALLOCATE(OutData%VelVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelVDot,1), UBOUND(OutData%VelVDot,1) + OutData%VelVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelGust not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelGust)) DEALLOCATE(OutData%VelGust) + ALLOCATE(OutData%VelGust(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelGust.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelGust,1), UBOUND(OutData%VelGust,1) + OutData%VelGust(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelGustDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelGustDot)) DEALLOCATE(OutData%VelGustDot) + ALLOCATE(OutData%VelGustDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelGustDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelGustDot,1), UBOUND(OutData%VelGustDot,1) + OutData%VelGustDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleH not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleH)) DEALLOCATE(OutData%AngleH) + ALLOCATE(OutData%AngleH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleH,1), UBOUND(OutData%AngleH,1) + OutData%AngleH(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleHDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleHDot)) DEALLOCATE(OutData%AngleHDot) + ALLOCATE(OutData%AngleHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleHDot,1), UBOUND(OutData%AngleHDot,1) + OutData%AngleHDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleV)) DEALLOCATE(OutData%AngleV) + ALLOCATE(OutData%AngleV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleV,1), UBOUND(OutData%AngleV,1) + OutData%AngleV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleVDot)) DEALLOCATE(OutData%AngleVDot) + ALLOCATE(OutData%AngleVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleVDot,1), UBOUND(OutData%AngleVDot,1) + OutData%AngleVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrH not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrH)) DEALLOCATE(OutData%ShrH) + ALLOCATE(OutData%ShrH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrH,1), UBOUND(OutData%ShrH,1) + OutData%ShrH(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrHDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrHDot)) DEALLOCATE(OutData%ShrHDot) + ALLOCATE(OutData%ShrHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrHDot,1), UBOUND(OutData%ShrHDot,1) + OutData%ShrHDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrV)) DEALLOCATE(OutData%ShrV) + ALLOCATE(OutData%ShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrV,1), UBOUND(OutData%ShrV,1) + OutData%ShrV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrVDot)) DEALLOCATE(OutData%ShrVDot) + ALLOCATE(OutData%ShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrVDot,1), UBOUND(OutData%ShrVDot,1) + OutData%ShrVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinShrV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LinShrV)) DEALLOCATE(OutData%LinShrV) + ALLOCATE(OutData%LinShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LinShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LinShrV,1), UBOUND(OutData%LinShrV,1) + OutData%LinShrV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinShrVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LinShrVDot)) DEALLOCATE(OutData%LinShrVDot) + ALLOCATE(OutData%LinShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LinShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LinShrVDot,1), UBOUND(OutData%LinShrVDot,1) + OutData%LinShrVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE IfW_FlowField_UnPackUniformFieldType + + SUBROUTINE IfW_FlowField_CopyUniformField_Interp( SrcUniformField_InterpData, DstUniformField_InterpData, CtrlCode, ErrStat, ErrMsg ) + TYPE(UniformField_Interp), INTENT(IN) :: SrcUniformField_InterpData + TYPE(UniformField_Interp), INTENT(INOUT) :: DstUniformField_InterpData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyUniformField_Interp' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUniformField_InterpData%VelH = SrcUniformField_InterpData%VelH + DstUniformField_InterpData%VelHDot = SrcUniformField_InterpData%VelHDot + DstUniformField_InterpData%VelV = SrcUniformField_InterpData%VelV + DstUniformField_InterpData%VelVDot = SrcUniformField_InterpData%VelVDot + DstUniformField_InterpData%VelGust = SrcUniformField_InterpData%VelGust + DstUniformField_InterpData%VelGustDot = SrcUniformField_InterpData%VelGustDot + DstUniformField_InterpData%AngleH = SrcUniformField_InterpData%AngleH + DstUniformField_InterpData%AngleHDot = SrcUniformField_InterpData%AngleHDot + DstUniformField_InterpData%AngleV = SrcUniformField_InterpData%AngleV + DstUniformField_InterpData%AngleVDot = SrcUniformField_InterpData%AngleVDot + DstUniformField_InterpData%ShrH = SrcUniformField_InterpData%ShrH + DstUniformField_InterpData%ShrHDot = SrcUniformField_InterpData%ShrHDot + DstUniformField_InterpData%ShrV = SrcUniformField_InterpData%ShrV + DstUniformField_InterpData%ShrVDot = SrcUniformField_InterpData%ShrVDot + DstUniformField_InterpData%LinShrV = SrcUniformField_InterpData%LinShrV + DstUniformField_InterpData%LinShrVDot = SrcUniformField_InterpData%LinShrVDot + DstUniformField_InterpData%CosAngleH = SrcUniformField_InterpData%CosAngleH + DstUniformField_InterpData%SinAngleH = SrcUniformField_InterpData%SinAngleH + DstUniformField_InterpData%CosAngleV = SrcUniformField_InterpData%CosAngleV + DstUniformField_InterpData%SinAngleV = SrcUniformField_InterpData%SinAngleV + END SUBROUTINE IfW_FlowField_CopyUniformField_Interp + + SUBROUTINE IfW_FlowField_DestroyUniformField_Interp( UniformField_InterpData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(UniformField_Interp), INTENT(INOUT) :: UniformField_InterpData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyUniformField_Interp' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE IfW_FlowField_DestroyUniformField_Interp + + SUBROUTINE IfW_FlowField_PackUniformField_Interp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(UniformField_Interp), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackUniformField_Interp' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! VelH + Re_BufSz = Re_BufSz + 1 ! VelHDot + Re_BufSz = Re_BufSz + 1 ! VelV + Re_BufSz = Re_BufSz + 1 ! VelVDot + Re_BufSz = Re_BufSz + 1 ! VelGust + Re_BufSz = Re_BufSz + 1 ! VelGustDot + Re_BufSz = Re_BufSz + 1 ! AngleH + Re_BufSz = Re_BufSz + 1 ! AngleHDot + Re_BufSz = Re_BufSz + 1 ! AngleV + Re_BufSz = Re_BufSz + 1 ! AngleVDot + Re_BufSz = Re_BufSz + 1 ! ShrH + Re_BufSz = Re_BufSz + 1 ! ShrHDot + Re_BufSz = Re_BufSz + 1 ! ShrV + Re_BufSz = Re_BufSz + 1 ! ShrVDot + Re_BufSz = Re_BufSz + 1 ! LinShrV + Re_BufSz = Re_BufSz + 1 ! LinShrVDot + Re_BufSz = Re_BufSz + 1 ! CosAngleH + Re_BufSz = Re_BufSz + 1 ! SinAngleH + Re_BufSz = Re_BufSz + 1 ! CosAngleV + Re_BufSz = Re_BufSz + 1 ! SinAngleV + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%VelH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelHDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelGust + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelGustDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleHDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrHDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%LinShrV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%LinShrVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%CosAngleH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SinAngleH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%CosAngleV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SinAngleV + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackUniformField_Interp + + SUBROUTINE IfW_FlowField_UnPackUniformField_Interp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(UniformField_Interp), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackUniformField_Interp' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%VelH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelHDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelGust = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelGustDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleHDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrHDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%LinShrV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%LinShrVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%CosAngleH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%SinAngleH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%CosAngleV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%SinAngleV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackUniformField_Interp + + SUBROUTINE IfW_FlowField_CopyGrid3DFieldType( SrcGrid3DFieldTypeData, DstGrid3DFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid3DFieldType), INTENT(IN) :: SrcGrid3DFieldTypeData + TYPE(Grid3DFieldType), INTENT(INOUT) :: DstGrid3DFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyGrid3DFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid3DFieldTypeData%WindFileFormat = SrcGrid3DFieldTypeData%WindFileFormat + DstGrid3DFieldTypeData%WindProfileType = SrcGrid3DFieldTypeData%WindProfileType + DstGrid3DFieldTypeData%Periodic = SrcGrid3DFieldTypeData%Periodic + DstGrid3DFieldTypeData%InterpTower = SrcGrid3DFieldTypeData%InterpTower + DstGrid3DFieldTypeData%AddMeanAfterInterp = SrcGrid3DFieldTypeData%AddMeanAfterInterp + DstGrid3DFieldTypeData%RefHeight = SrcGrid3DFieldTypeData%RefHeight + DstGrid3DFieldTypeData%RefLength = SrcGrid3DFieldTypeData%RefLength +IF (ALLOCATED(SrcGrid3DFieldTypeData%Vel)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%Vel,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%Vel,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%Vel,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%Vel,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%Vel,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%Vel,3) + i4_l = LBOUND(SrcGrid3DFieldTypeData%Vel,4) + i4_u = UBOUND(SrcGrid3DFieldTypeData%Vel,4) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%Vel)) THEN + ALLOCATE(DstGrid3DFieldTypeData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%Vel = SrcGrid3DFieldTypeData%Vel +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%Acc)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%Acc,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%Acc,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%Acc,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%Acc,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%Acc,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%Acc,3) + i4_l = LBOUND(SrcGrid3DFieldTypeData%Acc,4) + i4_u = UBOUND(SrcGrid3DFieldTypeData%Acc,4) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%Acc)) THEN + ALLOCATE(DstGrid3DFieldTypeData%Acc(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%Acc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%Acc = SrcGrid3DFieldTypeData%Acc +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%VelTower)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%VelTower,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%VelTower,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%VelTower,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%VelTower,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%VelTower,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%VelTower,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%VelTower)) THEN + ALLOCATE(DstGrid3DFieldTypeData%VelTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%VelTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%VelTower = SrcGrid3DFieldTypeData%VelTower +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%AccTower)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%AccTower,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%AccTower,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%AccTower,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%AccTower,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%AccTower,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%AccTower,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%AccTower)) THEN + ALLOCATE(DstGrid3DFieldTypeData%AccTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%AccTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%AccTower = SrcGrid3DFieldTypeData%AccTower +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%VelAvg)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%VelAvg,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%VelAvg,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%VelAvg,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%VelAvg,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%VelAvg,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%VelAvg,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%VelAvg)) THEN + ALLOCATE(DstGrid3DFieldTypeData%VelAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%VelAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%VelAvg = SrcGrid3DFieldTypeData%VelAvg +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%AccAvg)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%AccAvg,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%AccAvg,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%AccAvg,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%AccAvg,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%AccAvg,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%AccAvg,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%AccAvg)) THEN + ALLOCATE(DstGrid3DFieldTypeData%AccAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%AccAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%AccAvg = SrcGrid3DFieldTypeData%AccAvg +ENDIF + DstGrid3DFieldTypeData%DTime = SrcGrid3DFieldTypeData%DTime + DstGrid3DFieldTypeData%Rate = SrcGrid3DFieldTypeData%Rate + DstGrid3DFieldTypeData%YHWid = SrcGrid3DFieldTypeData%YHWid + DstGrid3DFieldTypeData%ZHWid = SrcGrid3DFieldTypeData%ZHWid + DstGrid3DFieldTypeData%GridBase = SrcGrid3DFieldTypeData%GridBase + DstGrid3DFieldTypeData%InitXPosition = SrcGrid3DFieldTypeData%InitXPosition + DstGrid3DFieldTypeData%InvDY = SrcGrid3DFieldTypeData%InvDY + DstGrid3DFieldTypeData%InvDZ = SrcGrid3DFieldTypeData%InvDZ + DstGrid3DFieldTypeData%MeanWS = SrcGrid3DFieldTypeData%MeanWS + DstGrid3DFieldTypeData%InvMWS = SrcGrid3DFieldTypeData%InvMWS + DstGrid3DFieldTypeData%TotalTime = SrcGrid3DFieldTypeData%TotalTime + DstGrid3DFieldTypeData%NComp = SrcGrid3DFieldTypeData%NComp + DstGrid3DFieldTypeData%NYGrids = SrcGrid3DFieldTypeData%NYGrids + DstGrid3DFieldTypeData%NZGrids = SrcGrid3DFieldTypeData%NZGrids + DstGrid3DFieldTypeData%NTGrids = SrcGrid3DFieldTypeData%NTGrids + DstGrid3DFieldTypeData%NSteps = SrcGrid3DFieldTypeData%NSteps + DstGrid3DFieldTypeData%PLExp = SrcGrid3DFieldTypeData%PLExp + DstGrid3DFieldTypeData%Z0 = SrcGrid3DFieldTypeData%Z0 + DstGrid3DFieldTypeData%VLinShr = SrcGrid3DFieldTypeData%VLinShr + DstGrid3DFieldTypeData%HLinShr = SrcGrid3DFieldTypeData%HLinShr + DstGrid3DFieldTypeData%BoxExceedAllowF = SrcGrid3DFieldTypeData%BoxExceedAllowF + DstGrid3DFieldTypeData%BoxExceedAllowIdx = SrcGrid3DFieldTypeData%BoxExceedAllowIdx + DstGrid3DFieldTypeData%BoxExceedWarned = SrcGrid3DFieldTypeData%BoxExceedWarned + END SUBROUTINE IfW_FlowField_CopyGrid3DFieldType + + SUBROUTINE IfW_FlowField_DestroyGrid3DFieldType( Grid3DFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid3DFieldType), INTENT(INOUT) :: Grid3DFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyGrid3DFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(Grid3DFieldTypeData%Vel)) THEN + DEALLOCATE(Grid3DFieldTypeData%Vel) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%Acc)) THEN + DEALLOCATE(Grid3DFieldTypeData%Acc) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%VelTower)) THEN + DEALLOCATE(Grid3DFieldTypeData%VelTower) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%AccTower)) THEN + DEALLOCATE(Grid3DFieldTypeData%AccTower) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%VelAvg)) THEN + DEALLOCATE(Grid3DFieldTypeData%VelAvg) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%AccAvg)) THEN + DEALLOCATE(Grid3DFieldTypeData%AccAvg) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyGrid3DFieldType + + SUBROUTINE IfW_FlowField_PackGrid3DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid3DFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackGrid3DFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WindFileFormat + Int_BufSz = Int_BufSz + 1 ! WindProfileType + Int_BufSz = Int_BufSz + 1 ! Periodic + Int_BufSz = Int_BufSz + 1 ! InterpTower + Int_BufSz = Int_BufSz + 1 ! AddMeanAfterInterp + Re_BufSz = Re_BufSz + 1 ! RefHeight + Re_BufSz = Re_BufSz + 1 ! RefLength + Int_BufSz = Int_BufSz + 1 ! Vel allocated yes/no + IF ( ALLOCATED(InData%Vel) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vel) ! Vel + END IF + Int_BufSz = Int_BufSz + 1 ! Acc allocated yes/no + IF ( ALLOCATED(InData%Acc) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Acc upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Acc) ! Acc + END IF + Int_BufSz = Int_BufSz + 1 ! VelTower allocated yes/no + IF ( ALLOCATED(InData%VelTower) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! VelTower upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelTower) ! VelTower + END IF + Int_BufSz = Int_BufSz + 1 ! AccTower allocated yes/no + IF ( ALLOCATED(InData%AccTower) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AccTower upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AccTower) ! AccTower + END IF + Int_BufSz = Int_BufSz + 1 ! VelAvg allocated yes/no + IF ( ALLOCATED(InData%VelAvg) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! VelAvg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelAvg) ! VelAvg + END IF + Int_BufSz = Int_BufSz + 1 ! AccAvg allocated yes/no + IF ( ALLOCATED(InData%AccAvg) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AccAvg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AccAvg) ! AccAvg + END IF + Re_BufSz = Re_BufSz + 1 ! DTime + Re_BufSz = Re_BufSz + 1 ! Rate + Re_BufSz = Re_BufSz + 1 ! YHWid + Re_BufSz = Re_BufSz + 1 ! ZHWid + Re_BufSz = Re_BufSz + 1 ! GridBase + Re_BufSz = Re_BufSz + 1 ! InitXPosition + Re_BufSz = Re_BufSz + 1 ! InvDY + Re_BufSz = Re_BufSz + 1 ! InvDZ + Re_BufSz = Re_BufSz + 1 ! MeanWS + Re_BufSz = Re_BufSz + 1 ! InvMWS + Re_BufSz = Re_BufSz + 1 ! TotalTime + Int_BufSz = Int_BufSz + 1 ! NComp + Int_BufSz = Int_BufSz + 1 ! NYGrids + Int_BufSz = Int_BufSz + 1 ! NZGrids + Int_BufSz = Int_BufSz + 1 ! NTGrids + Int_BufSz = Int_BufSz + 1 ! NSteps + Re_BufSz = Re_BufSz + 1 ! PLExp + Re_BufSz = Re_BufSz + 1 ! Z0 + Re_BufSz = Re_BufSz + 1 ! VLinShr + Re_BufSz = Re_BufSz + 1 ! HLinShr + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowF + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowIdx + Int_BufSz = Int_BufSz + 1 ! BoxExceedWarned + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%WindFileFormat + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WindProfileType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Periodic, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%InterpTower, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%AddMeanAfterInterp, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHeight + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Vel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Vel,4), UBOUND(InData%Vel,4) + DO i3 = LBOUND(InData%Vel,3), UBOUND(InData%Vel,3) + DO i2 = LBOUND(InData%Vel,2), UBOUND(InData%Vel,2) + DO i1 = LBOUND(InData%Vel,1), UBOUND(InData%Vel,1) + ReKiBuf(Re_Xferred) = InData%Vel(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Acc) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Acc,4), UBOUND(InData%Acc,4) + DO i3 = LBOUND(InData%Acc,3), UBOUND(InData%Acc,3) + DO i2 = LBOUND(InData%Acc,2), UBOUND(InData%Acc,2) + DO i1 = LBOUND(InData%Acc,1), UBOUND(InData%Acc,1) + ReKiBuf(Re_Xferred) = InData%Acc(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelTower) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelTower,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelTower,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelTower,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelTower,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelTower,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelTower,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%VelTower,3), UBOUND(InData%VelTower,3) + DO i2 = LBOUND(InData%VelTower,2), UBOUND(InData%VelTower,2) + DO i1 = LBOUND(InData%VelTower,1), UBOUND(InData%VelTower,1) + ReKiBuf(Re_Xferred) = InData%VelTower(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AccTower) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccTower,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccTower,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccTower,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccTower,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccTower,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccTower,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AccTower,3), UBOUND(InData%AccTower,3) + DO i2 = LBOUND(InData%AccTower,2), UBOUND(InData%AccTower,2) + DO i1 = LBOUND(InData%AccTower,1), UBOUND(InData%AccTower,1) + ReKiBuf(Re_Xferred) = InData%AccTower(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelAvg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelAvg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelAvg,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelAvg,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelAvg,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelAvg,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelAvg,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%VelAvg,3), UBOUND(InData%VelAvg,3) + DO i2 = LBOUND(InData%VelAvg,2), UBOUND(InData%VelAvg,2) + DO i1 = LBOUND(InData%VelAvg,1), UBOUND(InData%VelAvg,1) + ReKiBuf(Re_Xferred) = InData%VelAvg(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AccAvg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccAvg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccAvg,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccAvg,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccAvg,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccAvg,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccAvg,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AccAvg,3), UBOUND(InData%AccAvg,3) + DO i2 = LBOUND(InData%AccAvg,2), UBOUND(InData%AccAvg,2) + DO i1 = LBOUND(InData%AccAvg,1), UBOUND(InData%AccAvg,1) + ReKiBuf(Re_Xferred) = InData%AccAvg(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%DTime + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Rate + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%YHWid + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ZHWid + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%GridBase + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InitXPosition + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InvDY + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InvDZ + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MeanWS + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InvMWS + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%TotalTime + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NComp + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NYGrids + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NZGrids + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NTGrids + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NSteps + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Z0 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VLinShr + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HLinShr + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedAllowF, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BoxExceedAllowIdx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedWarned, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackGrid3DFieldType + + SUBROUTINE IfW_FlowField_UnPackGrid3DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid3DFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackGrid3DFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%WindFileFormat = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WindProfileType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%Periodic = TRANSFER(IntKiBuf(Int_Xferred), OutData%Periodic) + Int_Xferred = Int_Xferred + 1 + OutData%InterpTower = TRANSFER(IntKiBuf(Int_Xferred), OutData%InterpTower) + Int_Xferred = Int_Xferred + 1 + OutData%AddMeanAfterInterp = TRANSFER(IntKiBuf(Int_Xferred), OutData%AddMeanAfterInterp) + Int_Xferred = Int_Xferred + 1 + OutData%RefHeight = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vel not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vel)) DEALLOCATE(OutData%Vel) + ALLOCATE(OutData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Vel,4), UBOUND(OutData%Vel,4) + DO i3 = LBOUND(OutData%Vel,3), UBOUND(OutData%Vel,3) + DO i2 = LBOUND(OutData%Vel,2), UBOUND(OutData%Vel,2) + DO i1 = LBOUND(OutData%Vel,1), UBOUND(OutData%Vel,1) + OutData%Vel(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Acc not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Acc)) DEALLOCATE(OutData%Acc) + ALLOCATE(OutData%Acc(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Acc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Acc,4), UBOUND(OutData%Acc,4) + DO i3 = LBOUND(OutData%Acc,3), UBOUND(OutData%Acc,3) + DO i2 = LBOUND(OutData%Acc,2), UBOUND(OutData%Acc,2) + DO i1 = LBOUND(OutData%Acc,1), UBOUND(OutData%Acc,1) + OutData%Acc(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelTower not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelTower)) DEALLOCATE(OutData%VelTower) + ALLOCATE(OutData%VelTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%VelTower,3), UBOUND(OutData%VelTower,3) + DO i2 = LBOUND(OutData%VelTower,2), UBOUND(OutData%VelTower,2) + DO i1 = LBOUND(OutData%VelTower,1), UBOUND(OutData%VelTower,1) + OutData%VelTower(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AccTower not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AccTower)) DEALLOCATE(OutData%AccTower) + ALLOCATE(OutData%AccTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AccTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AccTower,3), UBOUND(OutData%AccTower,3) + DO i2 = LBOUND(OutData%AccTower,2), UBOUND(OutData%AccTower,2) + DO i1 = LBOUND(OutData%AccTower,1), UBOUND(OutData%AccTower,1) + OutData%AccTower(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelAvg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelAvg)) DEALLOCATE(OutData%VelAvg) + ALLOCATE(OutData%VelAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%VelAvg,3), UBOUND(OutData%VelAvg,3) + DO i2 = LBOUND(OutData%VelAvg,2), UBOUND(OutData%VelAvg,2) + DO i1 = LBOUND(OutData%VelAvg,1), UBOUND(OutData%VelAvg,1) + OutData%VelAvg(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AccAvg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AccAvg)) DEALLOCATE(OutData%AccAvg) + ALLOCATE(OutData%AccAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AccAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AccAvg,3), UBOUND(OutData%AccAvg,3) + DO i2 = LBOUND(OutData%AccAvg,2), UBOUND(OutData%AccAvg,2) + DO i1 = LBOUND(OutData%AccAvg,1), UBOUND(OutData%AccAvg,1) + OutData%AccAvg(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + OutData%DTime = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Rate = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%YHWid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ZHWid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%GridBase = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InitXPosition = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InvDY = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InvDZ = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MeanWS = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InvMWS = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TotalTime = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%NComp = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NYGrids = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NZGrids = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NTGrids = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NSteps = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Z0 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%BoxExceedAllowF = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedAllowF) + Int_Xferred = Int_Xferred + 1 + OutData%BoxExceedAllowIdx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%BoxExceedWarned = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedWarned) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackGrid3DFieldType + + SUBROUTINE IfW_FlowField_CopyGrid4DFieldType( SrcGrid4DFieldTypeData, DstGrid4DFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid4DFieldType), INTENT(IN) :: SrcGrid4DFieldTypeData + TYPE(Grid4DFieldType), INTENT(INOUT) :: DstGrid4DFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyGrid4DFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid4DFieldTypeData%n = SrcGrid4DFieldTypeData%n + DstGrid4DFieldTypeData%delta = SrcGrid4DFieldTypeData%delta + DstGrid4DFieldTypeData%pZero = SrcGrid4DFieldTypeData%pZero +IF (ALLOCATED(SrcGrid4DFieldTypeData%Vel)) THEN + i1_l = LBOUND(SrcGrid4DFieldTypeData%Vel,1) + i1_u = UBOUND(SrcGrid4DFieldTypeData%Vel,1) + i2_l = LBOUND(SrcGrid4DFieldTypeData%Vel,2) + i2_u = UBOUND(SrcGrid4DFieldTypeData%Vel,2) + i3_l = LBOUND(SrcGrid4DFieldTypeData%Vel,3) + i3_u = UBOUND(SrcGrid4DFieldTypeData%Vel,3) + i4_l = LBOUND(SrcGrid4DFieldTypeData%Vel,4) + i4_u = UBOUND(SrcGrid4DFieldTypeData%Vel,4) + i5_l = LBOUND(SrcGrid4DFieldTypeData%Vel,5) + i5_u = UBOUND(SrcGrid4DFieldTypeData%Vel,5) + IF (.NOT. ALLOCATED(DstGrid4DFieldTypeData%Vel)) THEN + ALLOCATE(DstGrid4DFieldTypeData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid4DFieldTypeData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid4DFieldTypeData%Vel = SrcGrid4DFieldTypeData%Vel +ENDIF + DstGrid4DFieldTypeData%TimeStart = SrcGrid4DFieldTypeData%TimeStart + END SUBROUTINE IfW_FlowField_CopyGrid4DFieldType + + SUBROUTINE IfW_FlowField_DestroyGrid4DFieldType( Grid4DFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid4DFieldType), INTENT(INOUT) :: Grid4DFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyGrid4DFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(Grid4DFieldTypeData%Vel)) THEN + DEALLOCATE(Grid4DFieldTypeData%Vel) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyGrid4DFieldType + + SUBROUTINE IfW_FlowField_PackGrid4DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid4DFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackGrid4DFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + SIZE(InData%n) ! n + Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta + Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero + Int_BufSz = Int_BufSz + 1 ! Vel allocated yes/no + IF ( ALLOCATED(InData%Vel) ) THEN + Int_BufSz = Int_BufSz + 2*5 ! Vel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vel) ! Vel + END IF + Re_BufSz = Re_BufSz + 1 ! TimeStart + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) + IntKiBuf(Int_Xferred) = InData%n(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) + ReKiBuf(Re_Xferred) = InData%delta(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) + ReKiBuf(Re_Xferred) = InData%pZero(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IF ( .NOT. ALLOCATED(InData%Vel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,4) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,5) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,5) + Int_Xferred = Int_Xferred + 2 + + DO i5 = LBOUND(InData%Vel,5), UBOUND(InData%Vel,5) + DO i4 = LBOUND(InData%Vel,4), UBOUND(InData%Vel,4) + DO i3 = LBOUND(InData%Vel,3), UBOUND(InData%Vel,3) + DO i2 = LBOUND(InData%Vel,2), UBOUND(InData%Vel,2) + DO i1 = LBOUND(InData%Vel,1), UBOUND(InData%Vel,1) + ReKiBuf(Re_Xferred) = InData%Vel(i1,i2,i3,i4,i5) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%TimeStart + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackGrid4DFieldType + + SUBROUTINE IfW_FlowField_UnPackGrid4DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid4DFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackGrid4DFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%n,1) + i1_u = UBOUND(OutData%n,1) + DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) + OutData%n(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%delta,1) + i1_u = UBOUND(OutData%delta,1) + DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) + OutData%delta(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%pZero,1) + i1_u = UBOUND(OutData%pZero,1) + DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) + OutData%pZero(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vel not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i5_l = IntKiBuf( Int_Xferred ) + i5_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vel)) DEALLOCATE(OutData%Vel) + ALLOCATE(OutData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i5 = LBOUND(OutData%Vel,5), UBOUND(OutData%Vel,5) + DO i4 = LBOUND(OutData%Vel,4), UBOUND(OutData%Vel,4) + DO i3 = LBOUND(OutData%Vel,3), UBOUND(OutData%Vel,3) + DO i2 = LBOUND(OutData%Vel,2), UBOUND(OutData%Vel,2) + DO i1 = LBOUND(OutData%Vel,1), UBOUND(OutData%Vel,1) + OutData%Vel(i1,i2,i3,i4,i5) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END DO + END IF + OutData%TimeStart = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackGrid4DFieldType + + SUBROUTINE IfW_FlowField_CopyPointsFieldType( SrcPointsFieldTypeData, DstPointsFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(PointsFieldType), INTENT(IN) :: SrcPointsFieldTypeData + TYPE(PointsFieldType), INTENT(INOUT) :: DstPointsFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyPointsFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcPointsFieldTypeData%Vel)) THEN + i1_l = LBOUND(SrcPointsFieldTypeData%Vel,1) + i1_u = UBOUND(SrcPointsFieldTypeData%Vel,1) + i2_l = LBOUND(SrcPointsFieldTypeData%Vel,2) + i2_u = UBOUND(SrcPointsFieldTypeData%Vel,2) + IF (.NOT. ALLOCATED(DstPointsFieldTypeData%Vel)) THEN + ALLOCATE(DstPointsFieldTypeData%Vel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstPointsFieldTypeData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstPointsFieldTypeData%Vel = SrcPointsFieldTypeData%Vel +ENDIF + END SUBROUTINE IfW_FlowField_CopyPointsFieldType + + SUBROUTINE IfW_FlowField_DestroyPointsFieldType( PointsFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(PointsFieldType), INTENT(INOUT) :: PointsFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyPointsFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(PointsFieldTypeData%Vel)) THEN + DEALLOCATE(PointsFieldTypeData%Vel) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyPointsFieldType + + SUBROUTINE IfW_FlowField_PackPointsFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(PointsFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackPointsFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! Vel allocated yes/no + IF ( ALLOCATED(InData%Vel) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Vel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vel) ! Vel + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ALLOCATED(InData%Vel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Vel,2), UBOUND(InData%Vel,2) + DO i1 = LBOUND(InData%Vel,1), UBOUND(InData%Vel,1) + ReKiBuf(Re_Xferred) = InData%Vel(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE IfW_FlowField_PackPointsFieldType + + SUBROUTINE IfW_FlowField_UnPackPointsFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(PointsFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackPointsFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vel not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vel)) DEALLOCATE(OutData%Vel) + ALLOCATE(OutData%Vel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Vel,2), UBOUND(OutData%Vel,2) + DO i1 = LBOUND(OutData%Vel,1), UBOUND(OutData%Vel,1) + OutData%Vel(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE IfW_FlowField_UnPackPointsFieldType + + SUBROUTINE IfW_FlowField_CopyUserFieldType( SrcUserFieldTypeData, DstUserFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(UserFieldType), INTENT(IN) :: SrcUserFieldTypeData + TYPE(UserFieldType), INTENT(INOUT) :: DstUserFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyUserFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUserFieldTypeData%Dummy = SrcUserFieldTypeData%Dummy + END SUBROUTINE IfW_FlowField_CopyUserFieldType + + SUBROUTINE IfW_FlowField_DestroyUserFieldType( UserFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(UserFieldType), INTENT(INOUT) :: UserFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyUserFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE IfW_FlowField_DestroyUserFieldType + + SUBROUTINE IfW_FlowField_PackUserFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(UserFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackUserFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! Dummy + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%Dummy + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackUserFieldType + + SUBROUTINE IfW_FlowField_UnPackUserFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(UserFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackUserFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%Dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackUserFieldType + + SUBROUTINE IfW_FlowField_CopyFlowFieldType( SrcFlowFieldTypeData, DstFlowFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(FlowFieldType), INTENT(IN) :: SrcFlowFieldTypeData + TYPE(FlowFieldType), INTENT(INOUT) :: DstFlowFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyFlowFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstFlowFieldTypeData%FieldType = SrcFlowFieldTypeData%FieldType + DstFlowFieldTypeData%RefPosition = SrcFlowFieldTypeData%RefPosition + DstFlowFieldTypeData%PropagationDir = SrcFlowFieldTypeData%PropagationDir + DstFlowFieldTypeData%VFlowAngle = SrcFlowFieldTypeData%VFlowAngle + DstFlowFieldTypeData%VelInterpCubic = SrcFlowFieldTypeData%VelInterpCubic + DstFlowFieldTypeData%RotateWindBox = SrcFlowFieldTypeData%RotateWindBox + DstFlowFieldTypeData%AccFieldValid = SrcFlowFieldTypeData%AccFieldValid + DstFlowFieldTypeData%RotToWind = SrcFlowFieldTypeData%RotToWind + DstFlowFieldTypeData%RotFromWind = SrcFlowFieldTypeData%RotFromWind + CALL IfW_FlowField_Copyuniformfieldtype( SrcFlowFieldTypeData%Uniform, DstFlowFieldTypeData%Uniform, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copygrid3dfieldtype( SrcFlowFieldTypeData%Grid3D, DstFlowFieldTypeData%Grid3D, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copygrid4dfieldtype( SrcFlowFieldTypeData%Grid4D, DstFlowFieldTypeData%Grid4D, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copypointsfieldtype( SrcFlowFieldTypeData%Points, DstFlowFieldTypeData%Points, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copyuserfieldtype( SrcFlowFieldTypeData%User, DstFlowFieldTypeData%User, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE IfW_FlowField_CopyFlowFieldType + + SUBROUTINE IfW_FlowField_DestroyFlowFieldType( FlowFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(FlowFieldType), INTENT(INOUT) :: FlowFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyFlowFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL IfW_FlowField_Destroyuniformfieldtype( FlowFieldTypeData%Uniform, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroygrid3dfieldtype( FlowFieldTypeData%Grid3D, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroygrid4dfieldtype( FlowFieldTypeData%Grid4D, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroypointsfieldtype( FlowFieldTypeData%Points, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroyuserfieldtype( FlowFieldTypeData%User, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE IfW_FlowField_DestroyFlowFieldType + + SUBROUTINE IfW_FlowField_PackFlowFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(FlowFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackFlowFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! FieldType + Re_BufSz = Re_BufSz + SIZE(InData%RefPosition) ! RefPosition + Re_BufSz = Re_BufSz + 1 ! PropagationDir + Re_BufSz = Re_BufSz + 1 ! VFlowAngle + Int_BufSz = Int_BufSz + 1 ! VelInterpCubic + Int_BufSz = Int_BufSz + 1 ! RotateWindBox + Int_BufSz = Int_BufSz + 1 ! AccFieldValid + Re_BufSz = Re_BufSz + SIZE(InData%RotToWind) ! RotToWind + Re_BufSz = Re_BufSz + SIZE(InData%RotFromWind) ! RotFromWind + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! Uniform: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packuniformfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Uniform, ErrStat2, ErrMsg2, .TRUE. ) ! Uniform + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Uniform + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Uniform + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Uniform + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! Grid3D: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packgrid3dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid3D, ErrStat2, ErrMsg2, .TRUE. ) ! Grid3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Grid3D + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Grid3D + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Grid3D + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! Grid4D: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packgrid4dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid4D, ErrStat2, ErrMsg2, .TRUE. ) ! Grid4D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Grid4D + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Grid4D + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Grid4D + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! Points: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packpointsfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Points, ErrStat2, ErrMsg2, .TRUE. ) ! Points + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Points + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Points + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Points + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! User: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packuserfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%User, ErrStat2, ErrMsg2, .TRUE. ) ! User + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! User + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! User + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! User + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%FieldType + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%RefPosition,1), UBOUND(InData%RefPosition,1) + ReKiBuf(Re_Xferred) = InData%RefPosition(i1) + Re_Xferred = Re_Xferred + 1 + END DO + ReKiBuf(Re_Xferred) = InData%PropagationDir + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VFlowAngle + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%VelInterpCubic, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%RotateWindBox, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%AccFieldValid, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(InData%RotToWind,2), UBOUND(InData%RotToWind,2) + DO i1 = LBOUND(InData%RotToWind,1), UBOUND(InData%RotToWind,1) + ReKiBuf(Re_Xferred) = InData%RotToWind(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + DO i2 = LBOUND(InData%RotFromWind,2), UBOUND(InData%RotFromWind,2) + DO i1 = LBOUND(InData%RotFromWind,1), UBOUND(InData%RotFromWind,1) + ReKiBuf(Re_Xferred) = InData%RotFromWind(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + CALL IfW_FlowField_Packuniformfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Uniform, ErrStat2, ErrMsg2, OnlySize ) ! Uniform + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packgrid3dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid3D, ErrStat2, ErrMsg2, OnlySize ) ! Grid3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packgrid4dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid4D, ErrStat2, ErrMsg2, OnlySize ) ! Grid4D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packpointsfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Points, ErrStat2, ErrMsg2, OnlySize ) ! Points + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packuserfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%User, ErrStat2, ErrMsg2, OnlySize ) ! User + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE IfW_FlowField_PackFlowFieldType + + SUBROUTINE IfW_FlowField_UnPackFlowFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(FlowFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackFlowFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%FieldType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%RefPosition,1) + i1_u = UBOUND(OutData%RefPosition,1) + DO i1 = LBOUND(OutData%RefPosition,1), UBOUND(OutData%RefPosition,1) + OutData%RefPosition(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%PropagationDir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VFlowAngle = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelInterpCubic = TRANSFER(IntKiBuf(Int_Xferred), OutData%VelInterpCubic) + Int_Xferred = Int_Xferred + 1 + OutData%RotateWindBox = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotateWindBox) + Int_Xferred = Int_Xferred + 1 + OutData%AccFieldValid = TRANSFER(IntKiBuf(Int_Xferred), OutData%AccFieldValid) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%RotToWind,1) + i1_u = UBOUND(OutData%RotToWind,1) + i2_l = LBOUND(OutData%RotToWind,2) + i2_u = UBOUND(OutData%RotToWind,2) + DO i2 = LBOUND(OutData%RotToWind,2), UBOUND(OutData%RotToWind,2) + DO i1 = LBOUND(OutData%RotToWind,1), UBOUND(OutData%RotToWind,1) + OutData%RotToWind(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + i1_l = LBOUND(OutData%RotFromWind,1) + i1_u = UBOUND(OutData%RotFromWind,1) + i2_l = LBOUND(OutData%RotFromWind,2) + i2_u = UBOUND(OutData%RotFromWind,2) + DO i2 = LBOUND(OutData%RotFromWind,2), UBOUND(OutData%RotFromWind,2) + DO i1 = LBOUND(OutData%RotFromWind,1), UBOUND(OutData%RotFromWind,1) + OutData%RotFromWind(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackuniformfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Uniform, ErrStat2, ErrMsg2 ) ! Uniform + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackgrid3dfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Grid3D, ErrStat2, ErrMsg2 ) ! Grid3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackgrid4dfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Grid4D, ErrStat2, ErrMsg2 ) ! Grid4D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackpointsfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Points, ErrStat2, ErrMsg2 ) ! Points + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackuserfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%User, ErrStat2, ErrMsg2 ) ! User + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE IfW_FlowField_UnPackFlowFieldType + +END MODULE IfW_FlowField_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_HAWCWind.f90 b/modules/inflowwind/src/IfW_HAWCWind.f90 deleted file mode 100644 index c903ee66a6..0000000000 --- a/modules/inflowwind/src/IfW_HAWCWind.f90 +++ /dev/null @@ -1,390 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is assumed periodic in the X direction (and thus not shifted like FFWind files are). -MODULE IfW_HAWCWind -!! -!! Created 25-June-2010 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Updated 8-Aug-2015 for InflowWind v3.0 in the FAST v8 Framework -! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - USE NWTC_Library - USE IfW_HAWCWind_Types - USE IfW_FFWind_Base - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_HAWCWind_Ver = ProgDesc( 'IfW_HAWCWind', '', '' ) - - PUBLIC :: IfW_HAWCWind_Init - PUBLIC :: IfW_HAWCWind_End - PUBLIC :: IfW_HAWCWind_CalcOutput - - INTEGER(IntKi), PARAMETER :: nc = 3 !< number of wind components - -CONTAINS -!==================================================================================================== -!> This routine is used to initialize the parameters for using HAWC wind format files. -SUBROUTINE IfW_HAWCWind_Init(InitInp, p, MiscVars, Interval, InitOut, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization data passed to the module - TYPE(IfW_HAWCWind_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(IfW_HAWCWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_HAWCWind_InitOutputType), INTENT( OUT) :: InitOut !< Initialization output - - REAL(DbKi), INTENT(IN ) :: Interval !< Time Interval to use (passed through here) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_Init' - - ! Local Variables: - - - - ErrStat = ErrID_None - ErrMsg = "" - - ! validate init input data: - call ValidateInput(InitInp, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Set some internal module parameters based on input file values - !------------------------------------------------------------------------------------------------- - p%FF%WindFileFormat = 0 - p%FF%Periodic = .true. - p%FF%InterpTower = .true. - - p%FF%NFFComp = 3 - p%FF%NFFSteps = InitInp%nx - p%FF%NYGrids = InitInp%ny - p%FF%NZGrids = InitInp%nz - p%FF%NTGrids = 0 - - p%FF%MeanFFWS = InitInp%FF%URef - p%FF%FFDTime = InitInp%dx / InitInp%FF%URef - p%FF%FFRate = 1.0 / p%FF%FFDTime - p%FF%InvFFYD = 1.0 / InitInp%dy - p%FF%InvFFZD = 1.0 / InitInp%dz - p%FF%InvMFFWS = 1.0 / p%FF%MeanFFWS - - p%FF%TotalTime = InitInp%nx * InitInp%dx / InitInp%FF%URef - p%FF%FFYHWid = 0.5 * InitInp%dy * (InitInp%ny-1) - p%FF%FFZHWid = 0.5 * InitInp%dz * (InitInp%nz-1) - p%FF%GridBase = InitInp%FF%RefHt - p%FF%FFZHWid - p%FF%RefHt = InitInp%FF%RefHt - - p%FF%WindProfileType = InitInp%FF%WindProfileType - p%FF%Z0 = InitInp%FF%Z0 - p%FF%PLExp = InitInp%FF%PLExp - p%FF%VLinShr = 0.0_ReKi - p%FF%HLinShr = 0.0_ReKi - p%FF%RefLength = p%FF%FFYHWid*2.0_ReKi - p%FF%AddMeanAfterInterp = .true. - - - p%FF%InitXPosition = InitInp%FF%XOffset - - IF ( p%FF%GridBase < 0.0_ReKi ) THEN - call SetErrStat( ErrID_Severe, 'WARNING: The bottom of the grid is located at a height of '//& - TRIM( Num2LStr(p%FF%GridBase) )//' meters, which is below the ground.'//& - ' Winds below the ground will be set to 0.', ErrStat,ErrMsg, RoutineName) - END IF - - !------------------------------------------------------------------------------------------------- - ! Read data files: - !------------------------------------------------------------------------------------------------- - call ReadTurbulenceData( p, InitInp, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - !------------------------------------------------------------------------------------------------- - ! scale to requested TI (or use requested scale factors) - !------------------------------------------------------------------------------------------------- - call ScaleTurbulence(InitInp%FF, p%FF%FFData, InitOut%sf, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Add the mean wind speed to the u component. - !------------------------------------------------------------------------------------------------- - if (InitInp%FF%ScaleMethod /= ScaleMethod_None) call SubtractMeanVelocity(p%FF%FFData) - if (.not. p%FF%AddMeanAfterInterp) call AddMeanVelocity(InitInp%FF, p%FF%GridBase, 1.0_ReKi/p%FF%InvFFZD, 1.0_ReKi/p%FF%InvFFYD, p%FF%FFData) - - !------------------------------------------------------------------------------------------------- - ! write info to summary file, if necessary - !------------------------------------------------------------------------------------------------- - - IF ( InitInp%SumFileUnit > 0 ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'HAWC wind type. Read by InflowWind sub-module '//TRIM(GetNVD(IfW_HAWCWind_Ver)) - - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',InitInp%FF%RefHt - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Timestep (s): ',p%FF%FFDTime - WRITE(InitInp%SumFileUnit,'(A34,I12)', IOSTAT=TmpErrStat) ' Number of timesteps: ',p%FF%NFFSteps - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Mean windspeed (m/s): ',p%FF%MeanFFWS - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr( p%FF%TotalTime ))//' ]' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' X range (m): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr( p%FF%TotalTime * p%FF%MeanFFWS ))//' ]' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Y range (m): [ '// & - TRIM(Num2LStr(-p%FF%FFYHWid))//' : '//TRIM(Num2LStr(p%FF%FFYHWid))//' ]' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(p%FF%GridBase))//' : '//TRIM(Num2LStr(p%FF%GridBase + p%FF%FFZHWid*2.0))//' ]' - - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'Scaling factors used:' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' u v w ' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) '---------- ---------- ----------' - WRITE(InitInp%SumFileUnit,'(F10.3,2x,F10.3,2x,F10.3)',IOSTAT=TmpErrStat) InitOut%sf - ENDIF - - MiscVars%DummyMiscVar = 0 - - RETURN - -END SUBROUTINE IfW_HAWCWind_Init -!==================================================================================================== -!> This routine is used to make sure the initInp data is valid. -SUBROUTINE ValidateInput(InitInp, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - character(*), parameter :: RoutineName = 'ValidateInput' - - - ErrStat = ErrID_None - ErrMsg = "" - - ! validate the inputs for scaling turbulence: - CALL FFWind_ValidateInput(InitInp%FF, nc, ErrStat, ErrMsg) - - IF ( InitInp%nx < 1 ) CALL SetErrStat( ErrID_Fatal, 'Number of grid points in the X direction must be at least 1.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%ny < 1 ) CALL SetErrStat( ErrID_Fatal, 'Number of grid points in the Y direction must be at least 1.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%nz < 1 ) CALL SetErrStat( ErrID_Fatal, 'Number of grid points in the Z direction must be at least 1.', ErrStat, ErrMsg, RoutineName ) - - IF ( InitInp%dx < 0.0_ReKi .or. EqualRealNos( InitInp%dx, 0.0_ReKi ) ) CALL SetErrStat( ErrID_Fatal, 'The grid spacing in the X direction must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%dy < 0.0_ReKi .or. EqualRealNos( InitInp%dy, 0.0_ReKi ) ) CALL SetErrStat( ErrID_Fatal, 'The grid spacing in the Y direction must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%dz < 0.0_ReKi .or. EqualRealNos( InitInp%dz, 0.0_ReKi ) ) CALL SetErrStat( ErrID_Fatal, 'The grid spacing in the Z direction must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - - -END SUBROUTINE ValidateInput -!==================================================================================================== -!> This routine is used read the full-field turbulence data stored in HAWC format. -SUBROUTINE ReadTurbulenceData(p, InitInp, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - ! Local Variables: - INTEGER :: IC ! Loop counter for the number of wind components - INTEGER :: IX ! Loop counter for the number of grid points in the X direction - INTEGER :: IY ! Loop counter for the number of grid points in the Y direction - INTEGER :: unWind ! unit number for reading binary files - - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'ReadTurbulenceData' - - - ErrStat = ErrID_None - ErrMsg = "" - - - !------------------------------------------------------------------------------------------------- - ! Allocate space for the wind array. - !------------------------------------------------------------------------------------------------- - - CALL AllocAry( p%FF%FFData, p%FF%NZGrids,p%FF%NYGrids,p%FF%NFFComp, p%FF%NFFSteps, 'p%FF%FFData', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the 3 files containg the turbulent wind speeds. - !------------------------------------------------------------------------------------------------- -!bjj: check these indices... they do not seem to be very consistant between the WAsP IEC Turbulence -! simulator and documentation of OC3 file formats... the current implementation is from the -! OC3/Kenneth Thompson documentation. - - - ! this could take a while, so we'll write a message indicating what's going on: - - CALL WrScr( NewLine//' Reading HAWC wind files with grids of '//& - TRIM( Num2LStr(p%FF%NFFSteps) )//' x '//TRIM( Num2LStr(p%FF%NYGrids) )//' x '//TRIM( Num2LStr(p%FF%NZGrids) )//' points'// & - ' ('//TRIM( Num2LStr(p%FF%FFYHWid*2) )//' m wide, '// TRIM( Num2LStr(p%FF%GridBase) )//' m to '// & - TRIM( Num2LStr(p%FF%GridBase+p%FF%FFZHWid*2) )//& - ' m above ground) with a characteristic wind speed of '//TRIM( Num2LStr(p%FF%MeanFFWS) )//' m/s. ' ) - - - CALL GetNewUnit( UnWind, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - ! The array must be filled so that x(i) < x(i+1), y(i) < y(i+1), and z(i) < z(i+1) - ! Also, note that the time axis is the negative x axis. - - DO IC = 1,NC - - CALL OpenBInpFile ( UnWind, InitInp%WindFileName(IC), TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - ! DO IX = p%FF%NFFSteps,1,-1 ! This order fixes #256 - DO IX = 1,p%FF%NFFSteps ! This order is wrong (has been in dev and hawc2 for a while now) - DO IY = p%FF%NYGrids,1,-1 - !DO IZ = 1,p%FF%NZGrids - - READ( UnWind, IOSTAT=TmpErrStat ) p%FF%FFData(:,iy,ic,ix) ! note that FFData is SiKi (4-byte reals, not default kinds) - - IF (TmpErrStat /= 0) THEN - TmpErrMsg = ' Error reading binary data from "'//TRIM(InitInp%WindFileName(IC))//'". I/O error ' & - //TRIM(Num2LStr(TmpErrStat))//' occurred at IY='//TRIM(Num2LStr(IY))//', IX='//TRIM(Num2LStr(IX))//'.' - CLOSE ( UnWind ) - CALL SetErrStat(ErrID_Fatal, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - RETURN - END IF - - !END DO - END DO - END DO - - CLOSE ( UnWind ) - - END DO - - -END SUBROUTINE ReadTurbulenceData -!==================================================================================================== -!> This routine acts as a wrapper for the GetWindSpeed routine. It steps through the array of input -!! positions and calls the GetWindSpeed routine to calculate the velocities at each point. -!! -!! There are inefficiencies in how this set of routines is coded, but that is a problem for another -!! day. For now, it merely needs to be functional. It can be fixed up and made all pretty later. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_HAWCWind_CalcOutput(Time, PositionXYZ, p, Velocity, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_HAWCWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! temporary variables - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CalcOutput' - - - !------------------------------------------------------------------------------------------------- - ! Check that the module has been initialized. - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - CALL IfW_FFWind_CalcOutput(Time, PositionXYZ, p%FF, Velocity, ErrStat, ErrMsg) - RETURN - -END SUBROUTINE IfW_HAWCWind_CalcOutput -!==================================================================================================== -!> This subroutine cleans up any data that is still allocated. The (possibly) open files are -!! closed in InflowWindMod. -SUBROUTINE IfW_HAWCWind_End( p, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_HAWCWind_End" - - - - ! Passed Variables - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(IfW_HAWCWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - - ! Destroy parameter data - - CALL IfW_HAWCWind_DestroyParam( p, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - ! Destroy the state data - - CALL IfW_HAWCWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - -END SUBROUTINE IfW_HAWCWind_End - -!==================================================================================================== -END MODULE IfW_HAWCWind diff --git a/modules/inflowwind/src/IfW_HAWCWind.txt b/modules/inflowwind/src/IfW_HAWCWind.txt deleted file mode 100644 index 1d45291817..0000000000 --- a/modules/inflowwind/src/IfW_HAWCWind.txt +++ /dev/null @@ -1,52 +0,0 @@ -################################################################################################################################### -# Registry for IfW_HAWCWind, creates MODULE IfW_HAWCWind_Types -# Module IfW_HAWCWind_Types contains all of the user-defined types needed in IfW_HAWCWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt -usefrom IfW_FFWind_Base.txt - - -######################### - -# Init Input -typedef IfW_HAWCWind/IfW_HAWCWind InitInputType CHARACTER(1024) WindFileName {3} - - "Name of the wind file to use" - -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - -typedef ^ ^ IntKi nx - 0 - "Number of grids in the x direction (in the 3 files above)" - -typedef ^ ^ IntKi ny - 0 - "Number of grids in the y direction (in the 3 files above)" - -typedef ^ ^ IntKi nz - 0 - "Number of grids in the z direction (in the 3 files above)" - -typedef ^ ^ ReKi dx - 0 - "size of grids in the x direction (in the 3 files above)" - -typedef ^ ^ ReKi dy - 0 - "size of grids in the y direction (in the 3 files above)" - -typedef ^ ^ ReKi dz - 0 - "size of grids in the z direction (in the 3 files above)" - -typedef ^ ^ IfW_FFWind_InitInputType FF - - - "scaling data" - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information of HAWCWind submodule" - -typedef ^ ^ ReKi SF 3 0 - "Turbulence scaling factor for each direction direction" - - - -# ..... States not used by this module ................................................................................................................... -typedef ^ ContinuousStateType ReKi DummyContState - - - "Remove this variable if you have continuous states" - -typedef ^ DiscreteStateType ReKi DummyDiscState - - - "Remove this variable if you have discrete states" - -typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" - -typedef ^ OtherStateType ReKi DummyOtherState - - - "Remove this variable if you have other states" - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType ReKi DummyMiscVar - - - "Remove this variable if you have misc variables" - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IfW_FFWind_ParameterType FF - - - "Parameters used in all full-field wind types" - - -# ..... Inputs .................................................................................................................... -# Define inputs that are not on this mesh here: -typedef ^ InputType ReKi Position :: - - "Array holding the input positions at a given timestep" meters - diff --git a/modules/inflowwind/src/IfW_HAWCWind_Types.f90 b/modules/inflowwind/src/IfW_HAWCWind_Types.f90 deleted file mode 100644 index 126947f674..0000000000 --- a/modules/inflowwind/src/IfW_HAWCWind_Types.f90 +++ /dev/null @@ -1,1720 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_HAWCWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_HAWCWind_Types -!................................................................................................................................. -! This file is part of IfW_HAWCWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_HAWCWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_HAWCWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_FFWind_Base_Types -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_HAWCWind_InitInputType ======= - TYPE, PUBLIC :: IfW_HAWCWind_InitInputType - CHARACTER(1024) , DIMENSION(1:3) :: WindFileName !< Name of the wind file to use [-] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - INTEGER(IntKi) :: nx = 0 !< Number of grids in the x direction (in the 3 files above) [-] - INTEGER(IntKi) :: ny = 0 !< Number of grids in the y direction (in the 3 files above) [-] - INTEGER(IntKi) :: nz = 0 !< Number of grids in the z direction (in the 3 files above) [-] - REAL(ReKi) :: dx = 0 !< size of grids in the x direction (in the 3 files above) [-] - REAL(ReKi) :: dy = 0 !< size of grids in the y direction (in the 3 files above) [-] - REAL(ReKi) :: dz = 0 !< size of grids in the z direction (in the 3 files above) [-] - TYPE(IfW_FFWind_InitInputType) :: FF !< scaling data [-] - END TYPE IfW_HAWCWind_InitInputType -! ======================= -! ========= IfW_HAWCWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_HAWCWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information of HAWCWind submodule [-] - REAL(ReKi) , DIMENSION(1:3) :: SF !< Turbulence scaling factor for each direction direction [-] - END TYPE IfW_HAWCWind_InitOutputType -! ======================= -! ========= IfW_HAWCWind_ContinuousStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_ContinuousStateType - REAL(ReKi) :: DummyContState !< Remove this variable if you have continuous states [-] - END TYPE IfW_HAWCWind_ContinuousStateType -! ======================= -! ========= IfW_HAWCWind_DiscreteStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_DiscreteStateType - REAL(ReKi) :: DummyDiscState !< Remove this variable if you have discrete states [-] - END TYPE IfW_HAWCWind_DiscreteStateType -! ======================= -! ========= IfW_HAWCWind_ConstraintStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_ConstraintStateType - REAL(ReKi) :: DummyConstrState !< Remove this variable if you have constraint states [-] - END TYPE IfW_HAWCWind_ConstraintStateType -! ======================= -! ========= IfW_HAWCWind_OtherStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_OtherStateType - REAL(ReKi) :: DummyOtherState !< Remove this variable if you have other states [-] - END TYPE IfW_HAWCWind_OtherStateType -! ======================= -! ========= IfW_HAWCWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_HAWCWind_MiscVarType - REAL(ReKi) :: DummyMiscVar !< Remove this variable if you have misc variables [-] - END TYPE IfW_HAWCWind_MiscVarType -! ======================= -! ========= IfW_HAWCWind_ParameterType ======= - TYPE, PUBLIC :: IfW_HAWCWind_ParameterType - TYPE(IfW_FFWind_ParameterType) :: FF !< Parameters used in all full-field wind types [-] - END TYPE IfW_HAWCWind_ParameterType -! ======================= -! ========= IfW_HAWCWind_InputType ======= - TYPE, PUBLIC :: IfW_HAWCWind_InputType - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Position !< Array holding the input positions at a given timestep [meters] - END TYPE IfW_HAWCWind_InputType -! ======================= -CONTAINS - SUBROUTINE IfW_HAWCWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_HAWCWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - DstInitInputData%nx = SrcInitInputData%nx - DstInitInputData%ny = SrcInitInputData%ny - DstInitInputData%nz = SrcInitInputData%nz - DstInitInputData%dx = SrcInitInputData%dx - DstInitInputData%dy = SrcInitInputData%dy - DstInitInputData%dz = SrcInitInputData%dz - CALL IfW_FFWind_CopyInitInput( SrcInitInputData%FF, DstInitInputData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_HAWCWind_CopyInitInput - - SUBROUTINE IfW_HAWCWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyInitInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL IfW_FFWind_DestroyInitInput( InitInputData%FF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_HAWCWind_DestroyInitInput - - SUBROUTINE IfW_HAWCWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + SIZE(InData%WindFileName)*LEN(InData%WindFileName) ! WindFileName - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - Int_BufSz = Int_BufSz + 1 ! nx - Int_BufSz = Int_BufSz + 1 ! ny - Int_BufSz = Int_BufSz + 1 ! nz - Re_BufSz = Re_BufSz + 1 ! dx - Re_BufSz = Re_BufSz + 1 ! dy - Re_BufSz = Re_BufSz + 1 ! dz - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%WindFileName,1), UBOUND(InData%WindFileName,1) - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%nx - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%ny - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%nz - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dx - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dy - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dz - Re_Xferred = Re_Xferred + 1 - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_HAWCWind_PackInitInput - - SUBROUTINE IfW_HAWCWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - i1_l = LBOUND(OutData%WindFileName,1) - i1_u = UBOUND(OutData%WindFileName,1) - DO i1 = LBOUND(OutData%WindFileName,1), UBOUND(OutData%WindFileName,1) - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%nx = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%ny = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%nz = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%dx = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%dy = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%dz = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_HAWCWind_UnPackInitInput - - SUBROUTINE IfW_HAWCWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_HAWCWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInitOutputData%SF = SrcInitOutputData%SF - END SUBROUTINE IfW_HAWCWind_CopyInitOutput - - SUBROUTINE IfW_HAWCWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyInitOutput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_HAWCWind_DestroyInitOutput - - SUBROUTINE IfW_HAWCWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Re_BufSz = Re_BufSz + SIZE(InData%SF) ! SF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%SF,1), UBOUND(InData%SF,1) - ReKiBuf(Re_Xferred) = InData%SF(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_HAWCWind_PackInitOutput - - SUBROUTINE IfW_HAWCWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%SF,1) - i1_u = UBOUND(OutData%SF,1) - DO i1 = LBOUND(OutData%SF,1), UBOUND(OutData%SF,1) - OutData%SF(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_HAWCWind_UnPackInitOutput - - SUBROUTINE IfW_HAWCWind_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(IN) :: SrcContStateData - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(INOUT) :: DstContStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyContState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstContStateData%DummyContState = SrcContStateData%DummyContState - END SUBROUTINE IfW_HAWCWind_CopyContState - - SUBROUTINE IfW_HAWCWind_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(INOUT) :: ContStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyContState' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_HAWCWind_DestroyContState - - SUBROUTINE IfW_HAWCWind_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackContState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyContState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyContState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackContState - - SUBROUTINE IfW_HAWCWind_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackContState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyContState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackContState - - SUBROUTINE IfW_HAWCWind_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(IN) :: SrcDiscStateData - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyDiscState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState - END SUBROUTINE IfW_HAWCWind_CopyDiscState - - SUBROUTINE IfW_HAWCWind_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(INOUT) :: DiscStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyDiscState' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_HAWCWind_DestroyDiscState - - SUBROUTINE IfW_HAWCWind_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackDiscState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyDiscState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyDiscState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackDiscState - - SUBROUTINE IfW_HAWCWind_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackDiscState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyDiscState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackDiscState - - SUBROUTINE IfW_HAWCWind_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(IN) :: SrcConstrStateData - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyConstrState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState - END SUBROUTINE IfW_HAWCWind_CopyConstrState - - SUBROUTINE IfW_HAWCWind_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(INOUT) :: ConstrStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyConstrState' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_HAWCWind_DestroyConstrState - - SUBROUTINE IfW_HAWCWind_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackConstrState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyConstrState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyConstrState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackConstrState - - SUBROUTINE IfW_HAWCWind_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackConstrState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyConstrState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackConstrState - - SUBROUTINE IfW_HAWCWind_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(IN) :: SrcOtherStateData - TYPE(IfW_HAWCWind_OtherStateType), INTENT(INOUT) :: DstOtherStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyOtherState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState - END SUBROUTINE IfW_HAWCWind_CopyOtherState - - SUBROUTINE IfW_HAWCWind_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(INOUT) :: OtherStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyOtherState' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_HAWCWind_DestroyOtherState - - SUBROUTINE IfW_HAWCWind_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackOtherState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyOtherState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyOtherState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackOtherState - - SUBROUTINE IfW_HAWCWind_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackOtherState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyOtherState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackOtherState - - SUBROUTINE IfW_HAWCWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar - END SUBROUTINE IfW_HAWCWind_CopyMisc - - SUBROUTINE IfW_HAWCWind_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyMisc' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_HAWCWind_DestroyMisc - - SUBROUTINE IfW_HAWCWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyMiscVar - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyMiscVar - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackMisc - - SUBROUTINE IfW_HAWCWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyMiscVar = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackMisc - - SUBROUTINE IfW_HAWCWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_CopyParam( SrcParamData%FF, DstParamData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_HAWCWind_CopyParam - - SUBROUTINE IfW_HAWCWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyParam' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL IfW_FFWind_DestroyParam( ParamData%FF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_HAWCWind_DestroyParam - - SUBROUTINE IfW_HAWCWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_HAWCWind_PackParam - - SUBROUTINE IfW_HAWCWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_HAWCWind_UnPackParam - - SUBROUTINE IfW_HAWCWind_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InputType), INTENT(IN) :: SrcInputData - TYPE(IfW_HAWCWind_InputType), INTENT(INOUT) :: DstInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyInput' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcInputData%Position)) THEN - i1_l = LBOUND(SrcInputData%Position,1) - i1_u = UBOUND(SrcInputData%Position,1) - i2_l = LBOUND(SrcInputData%Position,2) - i2_u = UBOUND(SrcInputData%Position,2) - IF (.NOT. ALLOCATED(DstInputData%Position)) THEN - ALLOCATE(DstInputData%Position(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Position.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputData%Position = SrcInputData%Position -ENDIF - END SUBROUTINE IfW_HAWCWind_CopyInput - - SUBROUTINE IfW_HAWCWind_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_HAWCWind_InputType), INTENT(INOUT) :: InputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - -IF (ALLOCATED(InputData%Position)) THEN - DEALLOCATE(InputData%Position) -ENDIF - END SUBROUTINE IfW_HAWCWind_DestroyInput - - SUBROUTINE IfW_HAWCWind_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Position allocated yes/no - IF ( ALLOCATED(InData%Position) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Position upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Position) ! Position - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%Position) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Position,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Position,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Position,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Position,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%Position,2), UBOUND(InData%Position,2) - DO i1 = LBOUND(InData%Position,1), UBOUND(InData%Position,1) - ReKiBuf(Re_Xferred) = InData%Position(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE IfW_HAWCWind_PackInput - - SUBROUTINE IfW_HAWCWind_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Position not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Position)) DEALLOCATE(OutData%Position) - ALLOCATE(OutData%Position(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Position.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%Position,2), UBOUND(OutData%Position,2) - DO i1 = LBOUND(OutData%Position,1), UBOUND(OutData%Position,1) - OutData%Position(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE IfW_HAWCWind_UnPackInput - -END MODULE IfW_HAWCWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_TSFFWind.f90 b/modules/inflowwind/src/IfW_TSFFWind.f90 deleted file mode 100644 index 77bcf5c4c8..0000000000 --- a/modules/inflowwind/src/IfW_TSFFWind.f90 +++ /dev/null @@ -1,661 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is shifted by half the grid width to account for turbine yaw (so that data in the X -!! direction actually starts at -1*ParamData%FF%FFYHWid meters). -MODULE IfW_TSFFWind -!! -!! Created 25-Sep-2009 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Modified to use NWTC_Library v. 2.0 -!! -- Note: Jacobians are not included in this version. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_TSFFWind_Types - USE IfW_FFWind_Base - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_TSFFWind_Ver = ProgDesc( 'IfW_TSFFWind', '', '' ) - - PUBLIC :: IfW_TSFFWind_Init - PUBLIC :: IfW_TSFFWind_End - PUBLIC :: IfW_TSFFWind_CalcOutput - - - - -CONTAINS -!==================================================================================================== -!> This routine is used read the full-field turbulence data. -!! 09/25/1997 - Created by M. Buhl from GETFILES in ViewWind. -!! 09/23/2009 - modified by B. Jonkman: this subroutine was split into several subroutines (was ReadFF) -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_TSFFWind_Init(InitData, ParamData, MiscVars, InitOutData, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_TSFFWind_Init" - - - ! Passed Variables - TYPE(IfW_TSFFWind_InitInputType), INTENT(IN ) :: InitData !< Initialization data passed to the module - TYPE(IfW_TSFFWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - TYPE(IfW_TSFFWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_TSFFWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ! Local Variables: - - INTEGER(IntKi) :: UnitWind ! Unit number for the InflowWind input file - INTEGER(B2Ki) :: Dum_Int2 - - !------------------------------------------------------------------------------------------------- - ! Initialize temporary variables - !------------------------------------------------------------------------------------------------- - - ErrMsg = '' - ErrStat = ErrID_None - - ParamData%FF%InterpTower = .false. - ParamData%FF%AddMeanAfterInterp = .false. - ParamData%FF%WindProfileType = WindProfileType_None - ParamData%FF%VLinShr = 0.0_ReKi - ParamData%FF%HLinShr = 0.0_ReKi - ParamData%FF%RefLength = 1.0_ReKi - - ! Get a unit number to use - - CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData - !------------------------------------------------------------------------------------------------- - - !---------------------------------------------------------------------------------------------- - ! Open the binary file, read its "header" (first 2-byte integer) to determine what format - ! binary file it is, and close it. - !---------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! Read the first binary integer from the file to get info on the type. - ! Cannot use library read routines since this is a 2-byte integer. - READ ( UnitWind, IOSTAT=TmpErrStat ) Dum_Int2 - CLOSE( UnitWind ) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat(ErrID_Fatal,' Error reading first binary integer from file "'//TRIM(InitData%WindFileName)//'."', & - ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - - - !---------------------------------------------------------------------------------------------- - ! Read the files to get the required FF data. - !---------------------------------------------------------------------------------------------- - - ! Store the binary format information so the InflowWind code can use it. - ! Also changes to IntKi from INT(2) to compare in the SELECT below - ParamData%FF%WindFileFormat = Dum_Int2 - - SELECT CASE (ParamData%FF%WindFileFormat) - - CASE ( 7, 8 ) ! TurbSim binary format - - CALL Read_TurbSim_FF(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - - CASE DEFAULT - CALL SetErrStat( ErrID_Fatal, ' Error: This is not a TurbSim binary wind file type (binary format identifier: '// & - TRIM(Num2LStr(ParamData%FF%WindFileFormat))//'. This might be a Bladed style binary wind file.', & - ErrStat, ErrMsg, RoutineName ) - RETURN - - END SELECT - - - IF (ParamData%FF%Periodic) THEN - ParamData%FF%InitXPosition = 0 ! start at the hub - ParamData%FF%TotalTime = ParamData%FF%NFFSteps*ParamData%FF%FFDTime - ELSE - ParamData%FF%InitXPosition = ParamData%FF%FFYHWid ! start half the grid width ahead of the turbine - ParamData%FF%TotalTime = (ParamData%FF%NFFSteps-1)*ParamData%FF%FFDTime - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_TSFFWind_Ver - - - - RETURN - - - CONTAINS - - !==================================================================================================== - !> This subroutine reads the binary TurbSim-format FF file (.bts). It fills the FFData array with - !! velocity data for the grids and fills the FFTower array with velocities at points on the tower - !! (if data exists). - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_TurbSim_FF(UnitWind, ErrStat, ErrMsg) - !---------------------------------------------------------------------------------------------------- - - CHARACTER(*), PARAMETER :: RoutineName="READ_TurbSim_FF" - - - ! Passed Variables: - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number for the wind file - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status return value (0=no error; non-zero is error) - CHARACTER(*), INTENT( OUT) :: ErrMsg !< message about the error encountered - - ! Local Variables: - - REAL(SiKi) :: Dum_Real4 ! dummy 4-byte real number - INTEGER(B1Ki) :: Dum_Int1 ! dummy 1-byte integer - INTEGER(B2Ki) :: Dum_Int2 ! dummy 2-byte integer - INTEGER(B4Ki) :: Dum_Int4 ! dummy 4-byte integer - - INTEGER(IntKi) :: IC ! loop counter for wind components - INTEGER(IntKi) :: IT ! loop counter for time - INTEGER(IntKi) :: IY ! loop counter for y - INTEGER(IntKi) :: IZ ! loop counter for z - INTEGER(IntKi) :: NChar ! number of characters in the description string - - REAL(SiKi) :: Vslope(3) ! slope for "un-normalizing" data - REAL(SiKi) :: Voffset(3) ! offset for "un-normalizing" data - - LOGICAL :: FirstWarn ! we don't need to print warning for each character that exceeds the - CHARACTER(1024) :: DescStr ! description string contained in the file - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ParamData%FF%NFFComp = 3 ! this file contains 3 wind components - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Open the file - !------------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the header information - !------------------------------------------------------------------------------------------------- - ! Read in the 2-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! the file identifier, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the file identifier in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%Periodic = Dum_Int2 == INT( 8, B2Ki) ! the number 7 is used for non-periodic wind files; 8 is periodic wind - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of grid points vertically, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of z grid points in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NZGrids = Dum_Int4 - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of grid points laterally, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of y grid points in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NYGrids = Dum_Int4 - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of tower points, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of tower points in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NTGrids = Dum_Int4 - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of time steps, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of time steps in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NFFSteps = Dum_Int4 - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! grid spacing in vertical direction (dz), REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%InvFFZD = 1.0/Dum_Real4 ! 1/dz - ParamData%FF%FFZHWid = 0.5*(ParamData%FF%NZGrids-1)*Dum_Real4 ! half the grid height - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! grid spacing in lateral direction (dy), REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dy in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%InvFFYD = 1.0 / Dum_Real4 ! 1/dy - ParamData%FF%FFYHWid = 0.5*(ParamData%FF%NYGrids-1)*Dum_Real4 ! half grid grid width - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! grid spacing in time (dt), REAL(4), in m/s - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dt in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%FFDTime = Dum_Real4 - ParamData%FF%FFRate = 1.0/ParamData%FF%FFDTime - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! the mean wind speed at hub height, REAL(4), in m/s - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading mean wind speed in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%MeanFFWS = Dum_Real4 - ParamData%FF%InvMFFWS = 1.0 / ParamData%FF%MeanFFWS - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! height of the hub, REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading zHub in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%RefHt = Dum_Real4 - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! height of the bottom of the grid, REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading GridBase in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%GridBase = Dum_Real4 - - ! ZGOffset = ParamData%FF%RefHt - ParamData%FF%GridBase - ParamData%FF%FFZHWid - - - !---------------------------------------------------------------------------------------------- - ! Read the binary scaling factors - !---------------------------------------------------------------------------------------------- - - DO IC = 1,ParamData%FF%NFFComp - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Vslope(IC) ! the IC-component slope for scaling, REAL(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading Vslope('//Num2LStr(IC)//') in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Voffset(IC) ! the IC-component offset for scaling, REAL(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading Voffset('//Num2LStr(IC)//') in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDDO !IC - - - !---------------------------------------------------------------------------------------------- - ! Read the description string: "Generated by TurbSim (vx.xx, dd-mmm-yyyy) on dd-mmm-yyyy at hh:mm:ss." - !---------------------------------------------------------------------------------------------- - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of characters in the description string, max 200, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading NCHAR in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - nchar = Dum_Int4 - - DescStr = '' ! Initialize the description string - FirstWarn = .true. - - DO IC=1,nchar - - ! Read in the 1-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int1 ! the ASCII integer representation of the character, INT(1) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading description line in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( LEN(DescStr) >= IC ) THEN - DescStr(IC:IC) = ACHAR( Dum_Int1 ) ! converted ASCII characters - ELSEIF ( FirstWarn ) THEN - FirstWarn = .FALSE. - CALL SetErrStat( ErrID_Info, ' Description string was too long for variable.'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - ENDIF - - ENDDO !IC - - - !------------------------------------------------------------------------------------------------- - ! Get the grid and tower velocities - !------------------------------------------------------------------------------------------------- - - ! this could take a while, so we'll write a message indicating what's going on: - - CALL WrScr( NewLine//' Reading a '//TRIM( Num2LStr(ParamData%FF%NYGrids) )//'x'//TRIM( Num2LStr(ParamData%FF%NZGrids) )// & - ' grid ('//TRIM( Num2LStr(ParamData%FF%FFYHWid*2) )//' m wide, '// & - TRIM( Num2LStr(ParamData%FF%GridBase) )//' m to '// & - TRIM( Num2LStr(ParamData%FF%GridBase+ParamData%FF%FFZHWid*2) )//& - ' m above ground) with a characteristic wind speed of '// & - TRIM( Num2LStr(ParamData%FF%MeanFFWS) )//' m/s. '//TRIM(DescStr) ) - - - !---------------------------------------------------------------------------------------------- - ! Allocate arrays for the FF grid as well as the tower points, if they exist - !---------------------------------------------------------------------------------------------- - - IF ( .NOT. ALLOCATED( ParamData%FF%FFData ) ) THEN - CALL AllocAry( ParamData%FF%FFData, ParamData%FF%NZGrids, ParamData%FF%NYGrids, ParamData%FF%NFFComp, ParamData%FF%NFFSteps, & - 'Full-field wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - ENDIF - - - IF ( ParamData%FF%NTGrids > 0 ) THEN - - IF ( .NOT. ALLOCATED( ParamData%FF%FFTower ) ) THEN - CALL AllocAry( ParamData%FF%FFTower, ParamData%FF%NFFComp, ParamData%FF%NTGrids, ParamData%FF%NFFSteps, & - 'Tower wind file data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - ENDIF - - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Read the 16-bit data and scale it to 32-bit reals - !------------------------------------------------------------------------------------------------- - - ! Loop through time. - - DO IT=1,ParamData%FF%NFFSteps - - !........................................................................................... - ! Read grid data at this time step. - !........................................................................................... - - DO IZ=1,ParamData%FF%NZGrids - ! Zgrid(IZ) = Z1 + (IZ-1)*dz ! Vertical location of grid data point, in m relative to ground - - DO IY=1,ParamData%FF%NYGrids - ! Ygrid(IY) = -0.5*(ny-1)*dy + (IY-1)*dy ! Horizontal location of grid data point, in m relative to tower centerline - - DO IC=1,ParamData%FF%NFFComp ! number of wind components (U, V, W) - - ! Read in the 2-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! normalized wind-component, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading grid wind components in the FF binary file "'// & - TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ParamData%FF%FFData(IZ,IY,IC,IT) = ( Dum_Int2 - Voffset(IC) ) / VSlope(IC) - - ENDDO !IC - - ENDDO !IY - - ENDDO ! IZ - - - !........................................................................................... - ! Read the tower data at this time step. - !........................................................................................... - - DO IZ=1,ParamData%FF%NTGrids ! If NTGrids<1, there are no tower points & FFTower is not allocated - - ! Ytower = 0 ! Lateral location of the tower data point, in m relative to tower centerline - ! Ztower(IZ) = Z1 - (IZ-1)*dz ! Vertical location of tower data point, in m relative to ground - - DO IC=1,ParamData%FF%NFFComp ! number of wind components - - ! Read in a 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! normalized wind-component, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading tower wind components in the FF binary file "'//TRIM(InitData%WindFileName)//'."'& - , ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ParamData%FF%FFTower(IC,IZ,IT) = ( Dum_Int2 - Voffset(IC) ) / VSlope(IC) ! wind-component scaled to m/s - - ENDDO !IC - - ENDDO ! IZ - - - ENDDO ! IT - - !------------------------------------------------------------------------------------------------- - ! close the file and return - !------------------------------------------------------------------------------------------------- - - CLOSE ( UnitWind ) - - IF ( ParamData%FF%Periodic ) THEN - TmpErrMsg = ' Processed '//TRIM( Num2LStr( ParamData%FF%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( ParamData%FF%FFRate ) )//'-Hz full-field data (period of '// & - TRIM( Num2LStr( ParamData%FF%FFDTime*( ParamData%FF%NFFSteps ) ) )//' seconds).' - ELSE - TmpErrMsg = ' Processed '//TRIM( Num2LStr( ParamData%FF%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( ParamData%FF%FFRate ) )//'-Hz full-field data ('// & - TRIM( Num2LStr( ParamData%FF%FFDTime*( ParamData%FF%NFFSteps - 1 ) ) )//' seconds).' - ENDIF - - CALL WrScr( NewLine//TRIM(TmpErrMsg) ) ! Note: the TmpErrMsg gets used below for the summary file - - - - !------------------------------------------------------------------------------------------------- - ! Write to the summary file - !------------------------------------------------------------------------------------------------- - - IF ( InitData%SumFileUnit > 0 ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'TurbSim wind type. Read by InflowWind sub-module '//TRIM(IfW_TSFFWind_Ver%Name)// & - ' '//TRIM(IfW_TSFFWind_Ver%Ver) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) TRIM(TmpErrMsg) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' FileName: '//TRIM(InitData%WindFileName) - WRITE(InitData%SumFileUnit,'(A34,I3)', IOSTAT=TmpErrStat) ' Binary file format id: ',ParamData%FF%WindFileFormat - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',ParamData%FF%RefHt - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Timestep (s): ',ParamData%FF%FFDTime - WRITE(InitData%SumFileUnit,'(A34,I12)', IOSTAT=TmpErrStat) ' Number of timesteps: ',ParamData%FF%NFFSteps - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Mean windspeed (m/s): ',ParamData%FF%MeanFFWS - WRITE(InitData%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile is periodic: ',ParamData%FF%Periodic - WRITE(InitData%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile includes tower: ',ParamData%FF%NTGrids > 0 - - IF ( ParamData%FF%Periodic ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%TotalTime))//' ]' - ELSE ! Shift the time range to compensate for the shifting of the wind grid - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' : '// & - TRIM(Num2LStr(ParamData%FF%TotalTime-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' ]' - ENDIF - - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Y range (m): [ '// & - TRIM(Num2LStr(-ParamData%FF%FFYHWid))//' : '//TRIM(Num2LStr(ParamData%FF%FFYHWid))//' ]' - - IF ( ParamData%FF%NTGrids > 0 ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ELSE - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(ParamData%FF%RefHt - ParamData%FF%FFZHWid))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ENDIF - - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - ENDIF - - - RETURN - - END SUBROUTINE READ_TurbSim_FF - - END SUBROUTINE IfW_TSFFWind_Init -!==================================================================================================== - - -!==================================================================================================== -!> This routine computes the wind speed at each of the PositionXYZ points. -SUBROUTINE IfW_TSFFWind_CalcOutput(Time, PositionXYZ, p, Velocity, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - - CHARACTER(*), PARAMETER :: RoutineName="IfW_TSFFWind_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_TSFFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - - CALL IfW_FFWind_CalcOutput(Time, PositionXYZ, p%FF, Velocity, ErrStat, ErrMsg) - - - RETURN - -END SUBROUTINE IfW_TSFFWind_CalcOutput -!==================================================================================================== -!> This subroutine cleans up any data that is still allocated. The (possibly) open files are -!! closed in InflowWindMod. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_TSFFWind_End( p, m, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_TSFFWind_End" - - - - ! Passed Variables - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_TSFFWind_DestroyParam( p, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - ! Destroy the misc data - - CALL IfW_TSFFWind_DestroyMisc( m, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - -END SUBROUTINE IfW_TSFFWind_End - -!==================================================================================================== -END MODULE IfW_TSFFWind diff --git a/modules/inflowwind/src/IfW_TSFFWind.txt b/modules/inflowwind/src/IfW_TSFFWind.txt deleted file mode 100644 index 71b9e9c753..0000000000 --- a/modules/inflowwind/src/IfW_TSFFWind.txt +++ /dev/null @@ -1,33 +0,0 @@ -################################################################################################################################### -# Registry for IfW_TSFFWind, creates MODULE IfW_TSFFWind_Types -# Module IfW_TSFFWind_Types contains all of the user-defined types needed in IfW_TSFFWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt -usefrom IfW_FFWind_Base.txt - - -######################### - -typedef IfW_TSFFWind/IfW_TSFFWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off FFWind submodule" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi dummy - 0 - "An Index into the TData array" - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IfW_FFWind_ParameterType FF - - - "Parameters used in all full-field wind types" - - diff --git a/modules/inflowwind/src/IfW_TSFFWind_Types.f90 b/modules/inflowwind/src/IfW_TSFFWind_Types.f90 deleted file mode 100644 index 5f52f9c1c9..0000000000 --- a/modules/inflowwind/src/IfW_TSFFWind_Types.f90 +++ /dev/null @@ -1,788 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_TSFFWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_TSFFWind_Types -!................................................................................................................................. -! This file is part of IfW_TSFFWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_TSFFWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_TSFFWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_FFWind_Base_Types -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_TSFFWind_InitInputType ======= - TYPE, PUBLIC :: IfW_TSFFWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - END TYPE IfW_TSFFWind_InitInputType -! ======================= -! ========= IfW_TSFFWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_TSFFWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off FFWind submodule [-] - END TYPE IfW_TSFFWind_InitOutputType -! ======================= -! ========= IfW_TSFFWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_TSFFWind_MiscVarType - INTEGER(IntKi) :: dummy = 0 !< An Index into the TData array [-] - END TYPE IfW_TSFFWind_MiscVarType -! ======================= -! ========= IfW_TSFFWind_ParameterType ======= - TYPE, PUBLIC :: IfW_TSFFWind_ParameterType - TYPE(IfW_FFWind_ParameterType) :: FF !< Parameters used in all full-field wind types [-] - END TYPE IfW_TSFFWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_TSFFWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_TSFFWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - END SUBROUTINE IfW_TSFFWind_CopyInitInput - - SUBROUTINE IfW_TSFFWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_TSFFWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyInitInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_TSFFWind_DestroyInitInput - - SUBROUTINE IfW_TSFFWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_PackInitInput - - SUBROUTINE IfW_TSFFWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_UnPackInitInput - - SUBROUTINE IfW_TSFFWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_TSFFWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_TSFFWind_CopyInitOutput - - SUBROUTINE IfW_TSFFWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyInitOutput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_TSFFWind_DestroyInitOutput - - SUBROUTINE IfW_TSFFWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_TSFFWind_PackInitOutput - - SUBROUTINE IfW_TSFFWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_TSFFWind_UnPackInitOutput - - SUBROUTINE IfW_TSFFWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%dummy = SrcMiscData%dummy - END SUBROUTINE IfW_TSFFWind_CopyMisc - - SUBROUTINE IfW_TSFFWind_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyMisc' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_TSFFWind_DestroyMisc - - SUBROUTINE IfW_TSFFWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%dummy - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_PackMisc - - SUBROUTINE IfW_TSFFWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_UnPackMisc - - SUBROUTINE IfW_TSFFWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_CopyParam( SrcParamData%FF, DstParamData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_TSFFWind_CopyParam - - SUBROUTINE IfW_TSFFWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyParam' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL IfW_FFWind_DestroyParam( ParamData%FF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_TSFFWind_DestroyParam - - SUBROUTINE IfW_TSFFWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_TSFFWind_PackParam - - SUBROUTINE IfW_TSFFWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_TSFFWind_UnPackParam - -END MODULE IfW_TSFFWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_UniformWind.f90 b/modules/inflowwind/src/IfW_UniformWind.f90 deleted file mode 100644 index 516dc25408..0000000000 --- a/modules/inflowwind/src/IfW_UniformWind.f90 +++ /dev/null @@ -1,1333 +0,0 @@ -!> This module contains all the data and procedures that define uniform wind files (formerly known as -!! hub-height files). This could more accurately be called a point wind file since the wind speed at -!! any point is calculated by shear applied to the point where wind is defined. It is basically uniform -!! wind over the rotor disk. The entire file is read on initialization, then the columns that make up -!! the wind file are interpolated to the time requested, and wind is calculated based on the location -!! in space. -!! -!! the file contains header information (rows that contain "!"), followed by numeric data stored in -!! 9 columns (if only 8 are listed, Upflow is assumed to be 0): -!! |Column | Description | Variable Name | Units| -!! |-------|-----------------------------|---------------|------| -!! | 1 | Time | Time | [s] | -!! | 2 | Horizontal wind speed | V | [m/s]| -!! | 3 | Wind direction | Delta | [deg]| -!! | 4 | Vertical wind speed | VZ | [m/s]| -!! | 5 | Horizontal linear shear | HLinShr | [-] | -!! | 6 | Vertical power-law shear | VShr | [-] | -!! | 7 | Vertical linear shear | VLinShr | [-] | -!! | 8 | Gust (horizontal) velocity | VGust | [m/s]| -!! | 9 | Upflow angle | Upflow | [deg]| -!! -!! The horizontal wind speed at (X, Y, Z) is then calculated using the interpolated columns by \n -!! \f{eqnarray}{ V_h & = & V \, \left( \frac{Z}{Z_{Ref}} \right) ^ {VShr} & \mbox{power-law wind shear} \\ -!! & + & V \, \frac{H_{LinShr}}{RefWid} \, \left( Y \cos(Delta) + X \sin(Delta) \right) & \mbox{horizontal linear shear} \\ -!! & + & V \, \frac{V_{LinShr}}{RefWid} \, \left( Z-Z_{Ref} \right) & \mbox{vertical linear shear} \\ -!! & + & V_{Gust} & \mbox{gust speed} -!! \f} -MODULE IfW_UniformWind -!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Note: Jacobians are not included in this version. -!! -!! Feb 2015 v2.01.00 A. Platt -!! -- Further updates to the new framework -!! -- name change from 'hub-height wind files' to 'Uniform wind files'. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_UniformWind_Types - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_UniformWind_Ver = ProgDesc( 'IfW_UniformWind', '', '' ) - - PUBLIC :: IfW_UniformWind_Init - PUBLIC :: IfW_UniformWind_End - PUBLIC :: IfW_UniformWind_CalcOutput - PUBLIC :: IfW_UniformWind_JacobianPInput - PUBLIC :: IfW_UniformWind_GetOP - - PUBLIC :: Uniform_to_FFWind - PUBLIC :: FFWind_to_Uniform - PUBLIC :: WrUniformWind - -CONTAINS - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> A subroutine to initialize the UniformWind module. It reads the uniform wind file and stores the data in an -!! array to use later. It requires an initial reference height (hub height) and width (rotor diameter), -!! both in meters, which are used to define the volume where wind velocities will be calculated. This -!! information is necessary because of the way the shears are defined. -!! -!! @note This routine does not conform to the framework. The InputType has been replaced with just -!! the PositionXYZ array. -!! @date 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, InitOutData, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UniformWind_Init" - - - ! Passed Variables - TYPE(IfW_UniformWind_InitInputType), INTENT(IN ) :: InitData !< Input data for initialization - TYPE(IfW_UniformWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_UniformWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output - - - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error - - ! local variables - - INTEGER(IntKi), PARAMETER :: MaxNumCols = 9 ! maximum number of columns in the Uniform file - INTEGER(IntKi) :: NumCols ! Number of columns in the Uniform file - REAL(ReKi) :: TmpData(MaxNumCols) ! Temp variable for reading all columns from a line - INTEGER(IntKi) :: LineNo - REAL(ReKi) :: DelDiff ! Temp variable for storing the direction difference - - INTEGER(IntKi) :: I - INTEGER(IntKi) :: ILine ! Counts the line number in the file - INTEGER(IntKi), PARAMETER :: MaxTries = 100 - TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !------------------------------------------------------------------------------------------------- - ! Set the Error handling variables - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Check that it's not already initialized - !------------------------------------------------------------------------------------------------- - - IF ( MiscVars%TimeIndex /= 0 ) THEN - CALL SetErrStat(ErrID_Warn,' UniformWind has already been initialized.',ErrStat,ErrMsg,RoutineName) - RETURN - END IF - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData - !------------------------------------------------------------------------------------------------- - - ParamData%RefHt = InitData%ReferenceHeight - ParamData%RefLength = InitData%RefLength - - ! Read in the data from a file, or copy from the passed InFileInfo. After this, the InFileInfo - ! should contain only a table -- all comments and empty lines have been stripped out - IF ( InitData%UseInputFile ) THEN - CALL ProcessComFile( InitData%WindFileName, InFileInfo, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - ELSE - CALL NWTC_Library_CopyFileInfoType( InitData%PassedFileData, InFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - ENDIF - - ! For diagnostic purposes, the following can be used to display the contents - ! of the InFileInfo data structure. - ! call Print_FileInfo_Struct( CU, InFileInfo ) ! CU is the screen -- different number on different systems. - - - !------------------------------------------------------------------------------------------------- - ! Allocate the data arrays - !------------------------------------------------------------------------------------------------- - - ParamData%NumDataLines = InFileInfo%NumLines - CALL Alloc_ParamDataArrays( ParamData, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Store the data arrays - !------------------------------------------------------------------------------------------------- - - ! Check if 9 columns - NumCols = MaxNumCols - LineNo = 1 ! Start at begining - CALL ParseAry( InFileInfo, LineNo, "Wind type 2 line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg ) - if (TmpErrStat /= 0) then - ! assume the upflow is 0 and try reading the rest of the files - CALL SetErrStat(ErrID_Info,' Could not read upflow column in uniform wind files. Assuming upflow is 0.', ErrStat, ErrMsg, RoutineName) - NumCols = NumCols - 1 - end if - - - ! Parse the data and store it - LineNo = 1 - DO I=1,ParamData%NumDataLines - CALL ParseAry( InFileInfo, LineNo, "Wind type 2 file line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ParamData%Tdata( I) = TmpData(1) - ParamData%V( I) = TmpData(2) - ParamData%Delta( I) = TmpData(3)*D2R - ParamData%VZ( I) = TmpData(4) - ParamData%HShr( I) = TmpData(5) - ParamData%VShr( I) = TmpData(6) - ParamData%VLinShr(I) = TmpData(7) - ParamData%VGust( I) = TmpData(8) - - if (NumCols > 8) ParamData%Upflow( I) = TmpData(9)*D2R ! otherwise, use default value from initialization in Alloc_ParamDataArrays() - END DO !I - - - - !------------------------------------------------------------------------------------------------- - ! Make sure the wind direction isn't jumping more than 180 degrees between any 2 consecutive - ! input times. (Avoids interpolation errors with modular arithemetic.) - !------------------------------------------------------------------------------------------------- - - DO I=2,ParamData%NumDataLines - - ILine = 1 - - DO WHILE ( ILine < MaxTries ) - - DelDiff = ( ParamData%Delta(I) - ParamData%Delta(I-1) ) - - IF ( ABS( DelDiff ) < Pi ) EXIT ! exit inner loop - - ParamData%Delta(I) = ParamData%Delta(I) - SIGN( TwoPi, DelDiff ) - - ILine = ILine + 1 - - END DO - - IF ( ILine >= MaxTries ) THEN - TmpErrMsg= ' Error calculating wind direction from uniform wind file. ParamData%Delta(' & - // TRIM(Num2LStr(I )) // ') = ' // TRIM(Num2LStr(ParamData%Delta(I))) // '; ParamData%Delta(' & - // TRIM(Num2LStr(I+1)) // ') = ' // TRIM(Num2LStr(ParamData%Delta(I+1))) - CALL SetErrStat(ErrID_Fatal,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - END IF - - - END DO !I - - !------------------------------------------------------------------------------------------------- - ! Find out information on the timesteps and range - !------------------------------------------------------------------------------------------------- - - ! Uniform timesteps - IF ( ParamData%NumDataLines > 3 ) THEN - - InitOutData%WindFileConstantDT = .TRUE. - InitOutData%WindFileDT = ParamData%Tdata(2) - ParamData%Tdata(1) - - DO I=3,ParamData%NumDataLines - - IF ( .NOT. EqualRealNos( (ParamData%Tdata(I ) - ParamData%Tdata(I-1) ), REAL(InitOutData%WindFileDT,ReKi )) ) THEN - InitOutData%WindFileConstantDT = .FALSE. - EXIT - END IF - - END DO !I - - ELSE - - ! There aren't enough points to check, so report that the timesteps are not uniform - InitOutData%WindFileConstantDT = .FALSE. - InitOutData%WindFileDT = 0.0_ReKi - - END IF - - - ! Time range - InitOutData%WindFileTRange(1) = ParamData%Tdata(1) - InitOutData%WindFileTRange(2) = ParamData%Tdata(ParamData%NumDataLines) - - ! Number of timesteps - InitOutData%WindFileNumTSteps = ParamData%NumDataLines - - !------------------------------------------------------------------------------------------------- - ! Print warnings and messages - !------------------------------------------------------------------------------------------------- - ! CALL WrScr( ' Processed '//TRIM( Num2LStr( ParamData%NumDataLines ) )//' records of uniform wind data from '''// & - ! TRIM(ADJUSTL(InitData%WindFileName))//'''') - - - IF ( ParamData%Tdata(1) > 0.0 ) THEN - TmpErrMsg= 'The uniform wind file : "'//TRIM(ADJUSTL(InitData%WindFileName))// & - '" starts at a time '//'greater than zero. Interpolation errors may result.' - CALL SetErrStat(ErrID_Warn,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - ENDIF - - IF ( ParamData%NumDataLines == 1 ) THEN - TmpErrMsg= ' Only 1 line in uniform wind file. Steady, horizontal wind speed at the hub height is '// & - TRIM(Num2LStr(ParamData%V(1)))//' m/s.' - CALL SetErrStat(ErrID_Info,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - END IF - - - - !------------------------------------------------------------------------------------------------- - ! Write to the summary file - !------------------------------------------------------------------------------------------------- - - IF ( InitData%SumFileUnit > 0 ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'Uniform wind. Module '//TRIM(IfW_UniformWind_Ver%Name)// & - ' '//TRIM(IfW_UniformWind_Ver%Ver) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' FileName: '//TRIM(InitData%WindFileName) - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',ParamData%RefHt - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference length (m): ',ParamData%RefLength - WRITE(InitData%SumFileUnit,'(A32,I8)', IOSTAT=TmpErrStat) ' Number of data lines: ',ParamData%NumDataLines - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(InitOutData%WindFileTRange(1)))//' : '//TRIM(Num2LStr(InitOutData%WindFileTRange(2)))//' ]' - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - ENDIF - - - - !------------------------------------------------------------------------------------------------- - ! Set the initial index into the time array (it indicates that we've initialized the module, too) - ! and initialize the spatial scaling for the wind calculations - !------------------------------------------------------------------------------------------------- - - MiscVars%TimeIndex = 1 - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_UniformWind_Ver - - - RETURN - -END SUBROUTINE IfW_UniformWind_Init - -SUBROUTINE Alloc_ParamDataArrays( ParamData, ErrStat, ErrMsg ) - - IMPLICIT NONE - CHARACTER(*), PARAMETER :: RoutineName="Alloc_ParamDataArrays" - - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! Temporary error message - - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Allocate arrays for the uniform wind data - !------------------------------------------------------------------------------------------------- - ! BJJ note: If the subroutine AllocAry() is called, the CVF compiler with A2AD does not work - ! properly. The arrays are not properly read even though they've been allocated. - ! ADP note: the above note may or may not apply after conversion to the modular framework in 2013 - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(ParamData%Tdata) ) THEN - CALL AllocAry( ParamData%Tdata, ParamData%NumDataLines, 'Uniform wind time', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%V) ) THEN - CALL AllocAry( ParamData%V, ParamData%NumDataLines, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%Delta) ) THEN - CALL AllocAry( ParamData%Delta, ParamData%NumDataLines, 'Uniform wind direction', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VZ) ) THEN - CALL AllocAry( ParamData%VZ, ParamData%NumDataLines, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%HShr) ) THEN - CALL AllocAry( ParamData%HShr, ParamData%NumDataLines, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VShr) ) THEN - CALL AllocAry( ParamData%VShr, ParamData%NumDataLines, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VLinShr) ) THEN - CALL AllocAry( ParamData%VLinShr, ParamData%NumDataLines, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VGust) ) THEN - CALL AllocAry( ParamData%VGust, ParamData%NumDataLines, 'Uniform gust velocity', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%Upflow) ) THEN - CALL AllocAry( ParamData%Upflow, ParamData%NumDataLines, 'Uniform wind upflow', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - ParamData%Upflow = 0.0_ReKi - -END SUBROUTINE Alloc_ParamDataArrays - -!==================================================================================================== - -!------------------------------------------------------------------------------------------------- -!> This routine and its subroutines calculate the wind velocity at a set of points given in -!! PositionXYZ. The UVW velocities are returned in Velocity -!! -!! @note This routine does not satisfy the Modular framework. -!! @date 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UniformWind_CalcOutput(Time, PositionXYZ, p, Velocity, m, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UniformWind_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points specified by the PositionXYZ array - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! temporary variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,DIM=2) - - - !------------------------------------------------------------------------------------------------- - !> 1. Linearly interpolate parameters in time (or use nearest-neighbor to extrapolate) - !! (compare with nwtc_num::interpstpreal) - !------------------------------------------------------------------------------------------------- - CALL InterpParams(Time, p, m, op) - - ! Step through all the positions and get the velocities - !OMP PARALLEL default(shared) if(NumPoints>1000) - !OMP do private(PointNum, TmpErrStat, TmpErrMsg ) schedule(runtime) - DO PointNum = 1, NumPoints - - ! Calculate the velocity for the position - call GetWindSpeed(PositionXYZ(:,PointNum), p, op, Velocity(:,PointNum), TmpErrStat, TmpErrMsg) - - ! Error handling - !CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (TmpErrStat >= AbortErrLev) THEN - TmpErrMsg= trim(TmpErrMsg)//" Error calculating the wind speed at position ("// & - TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in the wind-file coordinates" - !OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg - ErrStat = ErrID_None - ErrMsg = "" - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - !OMP END CRITICAL - ENDIF - - ENDDO - !OMP END DO - !OMP END PARALLEL - - IF (ErrStat >= AbortErrLev) RETURN ! Return cannot be in parallel loop - - RETURN - -END SUBROUTINE IfW_UniformWind_CalcOutput -!+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -!> This subroutine linearly interpolates the parameters that are used to compute uniform -!! wind. -SUBROUTINE InterpParams(Time, p, m, op) - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables (index) - - TYPE(IfW_UniformWind_Intrp) , INTENT( OUT) :: op !< interpolated V values at input TIME - - - ! Local Variables - REAL(ReKi) :: slope ! temporary storage for slope (in time) used in linear interpolation - - - !------------------------------------------------------------------------------------------------- - ! Linearly interpolate in time (or used nearest-neighbor to extrapolate) - ! (compare with NWTC_Num.f90\InterpStpReal) - !------------------------------------------------------------------------------------------------- - - ! Let's check the limits. - IF ( Time <= p%Tdata(1) .OR. p%NumDataLines == 1 ) THEN - - m%TimeIndex = 1 - op%V = p%V (1) - op%Delta = p%Delta (1) - op%Upflow = p%Upflow (1) - op%VZ = p%VZ (1) - op%HShr = p%HShr (1) - op%VShr = p%VShr (1) - op%VLinShr = p%VLinShr(1) - op%VGust = p%VGust (1) - - ELSE IF ( Time >= p%Tdata(p%NumDataLines) ) THEN - - m%TimeIndex = p%NumDataLines - 1 - op%V = p%V (p%NumDataLines) - op%Delta = p%Delta (p%NumDataLines) - op%Upflow = p%Upflow (p%NumDataLines) - op%VZ = p%VZ (p%NumDataLines) - op%HShr = p%HShr (p%NumDataLines) - op%VShr = p%VShr (p%NumDataLines) - op%VLinShr = p%VLinShr(p%NumDataLines) - op%VGust = p%VGust (p%NumDataLines) - - ELSE - - ! Let's interpolate! Linear interpolation. - m%TimeIndex = MAX( MIN( m%TimeIndex, p%NumDataLines-1 ), 1 ) - - DO - - IF ( Time < p%Tdata(m%TimeIndex) ) THEN - - m%TimeIndex = m%TimeIndex - 1 - - ELSE IF ( Time >= p%Tdata(m%TimeIndex+1) ) THEN - - m%TimeIndex = m%TimeIndex + 1 - - ELSE - slope = ( Time - p%Tdata(m%TimeIndex) )/( p%Tdata(m%TimeIndex+1) - p%Tdata(m%TimeIndex) ) - - op%V = ( p%V( m%TimeIndex+1) - p%V( m%TimeIndex) )*slope + p%V( m%TimeIndex) - op%Delta = ( p%Delta( m%TimeIndex+1) - p%Delta( m%TimeIndex) )*slope + p%Delta( m%TimeIndex) - op%Upflow = ( p%Upflow( m%TimeIndex+1) - p%Upflow( m%TimeIndex) )*slope + p%Upflow( m%TimeIndex) - op%VZ = ( p%VZ( m%TimeIndex+1) - p%VZ( m%TimeIndex) )*slope + p%VZ( m%TimeIndex) - op%HShr = ( p%HShr( m%TimeIndex+1) - p%HShr( m%TimeIndex) )*slope + p%HShr( m%TimeIndex) - op%VShr = ( p%VShr( m%TimeIndex+1) - p%VShr( m%TimeIndex) )*slope + p%VShr( m%TimeIndex) - op%VLinShr = ( p%VLinShr(m%TimeIndex+1) - p%VLinShr(m%TimeIndex) )*slope + p%VLinShr(m%TimeIndex) - op%VGust = ( p%VGust( m%TimeIndex+1) - p%VGust( m%TimeIndex) )*slope + p%VGust( m%TimeIndex) - EXIT - - END IF - - END DO - - END IF -END SUBROUTINE InterpParams - -!+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -!> This subroutine linearly interpolates the columns in the uniform input file to get the values for -!! the requested time, then uses the interpolated values to calclate the wind speed at a point -!! in space represented by InputPosition. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE GetWindSpeed(InputPosition, p, op, WindSpeed, ErrStat, ErrMsg) - - ! Passed Variables - REAL(ReKi), INTENT(IN ) :: InputPosition(3) !< input information: positions X,Y,Z - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_Intrp), INTENT(IN ) :: op !< operating point values; interpolated UniformWind parameters for this time (for glue-code linearization operating point) - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - ! Returned variables - REAL(ReKi), INTENT( OUT) :: WindSpeed(3) !< return velocities (U,V,W) - - ! Local Variables - REAL(ReKi) :: CosDelta ! cosine of y%Delta - REAL(ReKi) :: SinDelta ! sine of y%Delta - REAL(ReKi) :: V1 ! temporary storage for horizontal velocity - REAL(ReKi) :: V1_rotate ! temporary storage for rotated horizontal velocity - REAL(ReKi) :: VZ_rotate ! temporary storage for rotated vertical velocity - - REAL(ReKi) :: CosUpflow ! cosine of y%Upflow - REAL(ReKi) :: SinUpflow ! sine of y%Upflow - - ErrStat = ErrID_None - ErrMsg = "" - - - - !------------------------------------------------------------------------------------------------- - !> 2. Calculate the wind speed at this time (if z<0, return an error): - !------------------------------------------------------------------------------------------------- - - if ( InputPosition(3) <= 0.0_ReKi ) then - if (.not. EqualRealNos(InputPosition(3), 0.0_ReKi) ) call SetErrStat(ErrID_Severe,'Height must not be negative.',ErrStat,ErrMsg,'GetWindSpeed') - WindSpeed = 0.0 - return - end if - - !> Let \f{eqnarray}{ V_h & = & V \, \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}} & \mbox{power-law wind shear} \\ - !! & + & V \, \frac{H_{LinShr}}{RefWid} \, \left( Y \cos(Delta) + X \sin(Delta) \right) & \mbox{horizontal linear shear} \\ - !! & + & V \, \frac{V_{LinShr}}{RefWid} \, \left( Z - Z_{ref} \right) & \mbox{vertical linear shear} \\ - !! & + & V_{Gust} & \mbox{gust speed} - !! \f} Then the returned wind speed, \f$Vt\f$, is \n - !! \f$Vt_u = V_h \, \cos(Delta) \f$ \n - !! \f$Vt_v = -V_h \, \sin(Delta) \f$ \n - !! \f$Vt_w = V_z \f$ \n using input positions \f$X,Y,Z\f$ and interpolated values for time-dependent input-file parameters - !! \f$V, Delta, V_z, H_{LinShr}, V_{Shr}, V_{LinShr}, V_{Gust}\f$. - - CosDelta = COS( op%Delta ) - SinDelta = SIN( op%Delta ) - V1 = op%V * ( ( InputPosition(3)/p%RefHt ) ** op%VShr & ! power-law wind shear - + ( op%HShr * ( InputPosition(2) * CosDelta + InputPosition(1) * SinDelta ) & ! horizontal linear shear - + op%VLinShr * ( InputPosition(3) - p%RefHt ) )/p%RefLength ) & ! vertical linear shear - + op%VGust ! gust speed - - ! convert global to local: Global wind = R(op%Delta) * R(op%Upflow) * [local wind] = R(op%Delta) * R(op%Upflow) * [V1, 0, op%VZ] - - ! apply upflow angle: - CosUpflow = COS( op%Upflow ) - SinUpflow = SIN( op%Upflow ) - V1_rotate = CosUpflow*V1 - SinUpflow*op%VZ - VZ_rotate = SinUpflow*V1 + CosUpflow*op%VZ - - ! apply wind direction: - WindSpeed(1) = V1_rotate * CosDelta - WindSpeed(2) = -V1_rotate * SinDelta - WindSpeed(3) = VZ_rotate - - - RETURN - -END SUBROUTINE GetWindSpeed - -FUNCTION RotateWindSpeed(Vh, Vz, Delta, Upflow) - REAL(ReKi) :: Vh ! horizontal wind speed - REAL(ReKi) :: Vz ! vertical wind speed - REAL(ReKi) :: Delta ! wind direction - REAL(ReKi) :: Upflow ! upflow angle - - REAL(R8Ki) :: CosDelta ! cosine of y%Delta - REAL(R8Ki) :: SinDelta ! sine of y%Delta - REAL(R8Ki) :: V1_rotate ! temporary storage for rotated horizontal velocity - REAL(R8Ki) :: VZ_rotate ! temporary storage for rotated vertical velocity - - REAL(R8Ki) :: CosUpflow ! cosine of y%Upflow - REAL(R8Ki) :: SinUpflow ! sine of y%Upflow - - - REAL(R8Ki) :: RotateWindSpeed(3) - - - ! apply upflow angle: - CosUpflow = COS( REAL(Upflow,R8Ki) ) - SinUpflow = SIN( REAL(Upflow,R8Ki) ) - - V1_rotate = CosUpflow*Vh - SinUpflow*Vz - Vz_rotate = SinUpflow*Vh + CosUpflow*Vz - - - ! apply wind direction: - CosDelta = COS( REAL(Delta,R8Ki) ) - SinDelta = SIN( REAL(Delta,R8Ki) ) - - RotateWindSpeed(1) = V1_rotate * CosDelta - RotateWindSpeed(2) = -V1_rotate * SinDelta - RotateWindSpeed(3) = Vz_rotate - -END FUNCTION RotateWindSpeed - - -!> This function should be deleted ASAP. Its purpose is to reproduce results of AeroDyn 12.57; -!! when a consensus on the definition of "average velocity" is determined, this function will be -!! removed. -FUNCTION WindInf_ADhack_diskVel( t, p, m,ErrStat, ErrMsg ) - - ! Passed variables - - REAL(DbKi), INTENT(IN ) :: t !< Time - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization data (storage for efficiency index) - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status from this function - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message from this function - - ! Function definition - REAL(ReKi) :: WindInf_ADhack_diskVel(3) - - ! Local variables - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - - - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Linearly interpolate in time (or use nearest-neighbor to extrapolate) - ! (compare with NWTC_Num.f90\InterpStpReal) - !------------------------------------------------------------------------------------------------- - - call InterpParams(t, p, m, op) - - !------------------------------------------------------------------------------------------------- - ! calculate the wind speed at this time (note that it is not the full uniform wind equation!) - !------------------------------------------------------------------------------------------------- - WindInf_ADhack_diskVel = RotateWindSpeed(op%V, op%VZ, op%Delta, op%Upflow) - - RETURN - -END FUNCTION WindInf_ADhack_diskVel - - -!==================================================================================================== -!> This routine closes any open files and clears all data stored in UniformWind derived Types -!! -!! @note This routine does not satisfy the Modular framework. The InputType is not used, rather -!! an array of points is passed in. -!! @date: 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UniformWind_End( ParamData, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UniformWind_End" - - - ! Passed Variables - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_UniformWind_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the state data - - CALL IfW_UniformWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! reset time index so we know the module is no longer initialized - - MiscVars%TimeIndex = 0 - -END SUBROUTINE IfW_UniformWind_End -!.................................................................................................................................. -!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial -!! derivative dY/du is returned. This submodule does not follow the modularization framework. -SUBROUTINE IfW_UniformWind_JacobianPInput( t, Position, CosPropDir, SinPropDir, p, m, dYdu ) - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - REAL(ReKi), INTENT(IN ) :: Position(3) !< XYZ Position at which to find velocity (operating point) - REAL(ReKi), INTENT(IN ) :: CosPropDir !< cosine of InflowWind propagation direction - REAL(ReKi), INTENT(IN ) :: SinPropDir !< sine of InflowWind propagation direction - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - REAL(R8Ki), INTENT(INOUT) :: dYdu(3,6) !< Partial derivatives of output functions - !! (Y) with respect to the inputs (u) - - ! local variables: - !INTEGER(IntKi) :: ErrStat2 - !CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - !CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_JacobianPInput' - - ! Local Variables - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - REAL(R8Ki) :: CosDelta ! cosine of Delta_tmp - REAL(R8Ki) :: SinDelta ! sine of Delta_tmp - REAL(R8Ki) :: RotatePosition(3) !< rotated position - - REAL(R8Ki) :: dVhdx ! temporary value to hold partial v_h partial X - REAL(R8Ki) :: dVhdy ! temporary value to hold partial v_h partial Y - REAL(R8Ki) :: dVhdz ! temporary value to hold partial v_h partial Z - REAL(R8Ki) :: tmp_du ! temporary value to hold calculations that are part of multiple components - REAL(R8Ki) :: tmp_dv ! temporary value to hold calculations that are part of multiple components - REAL(R8Ki) :: dVhdPD ! temporary value to hold partial v_h partial propagation direction - REAL(R8Ki) :: dVhdV ! temporary value to hold partial v_h partial V - REAL(R8Ki) :: Vh ! temporary value to hold v_h - REAL(R8Ki) :: dVhdVShr ! temporary value to hold partial v_h partial VShr - REAL(R8Ki) :: zr - - - - - if ( Position(3) < 0.0_ReKi .or. EqualRealNos(Position(3), 0.0_ReKi)) then - dYdu = 0.0_R8Ki - RETURN - end if - - !------------------------------------------------------------------------------------------------- - !> 1. Linearly interpolate parameters in time at operating point (or use nearest-neighbor to extrapolate) - !! (compare with nwtc_num::interpstpreal) - !------------------------------------------------------------------------------------------------- - CALL InterpParams(t, p, m, op) - - CosDelta = COS( real(op%Delta,R8Ki) ) - SinDelta = SIN( real(op%Delta,R8Ki) ) - - RotatePosition(1) = Position(1)*cosPropDir - Position(2)*sinPropDir - RotatePosition(2) = Position(1)*sinPropDir + Position(2)*cosPropDir - RotatePosition(3) = Position(3) - - - !------------------------------------------------------------------------------------------------- - !> 2. Calculate \f$ \frac{\partial Y_{Output \, Equations}}{\partial u_{inputs}} = \begin{bmatrix} - !! \frac{\partial Vt_u}{\partial X} & \frac{\partial Vt_u}{\partial Y} & \frac{\partial Vt_u}{\partial Z} \\ - !! \frac{\partial Vt_v}{\partial X} & \frac{\partial Vt_v}{\partial Y} & \frac{\partial Vt_v}{\partial Z} \\ - !! \frac{\partial Vt_w}{\partial X} & \frac{\partial Vt_w}{\partial Y} & \frac{\partial Vt_w}{\partial Z} \\ - !! \end{bmatrix} \f$ - !------------------------------------------------------------------------------------------------- - zr = RotatePosition(3)/p%RefHt - tmp_du = op%V * op%HShr /p%RefLength * CosPropDir - dVhdx = tmp_du * SinDelta - dVhdy = tmp_du * CosDelta - dVhdz = op%V * ( op%VShr / p%RefHt * zr**(op%VShr-1.0_R8Ki) + op%VLinShr/p%RefLength) - - dVhdV = ( ( RotatePosition(3)/p%RefHt ) ** op%VShr & ! power-law wind shear - + ( op%HShr * ( RotatePosition(2) * CosDelta + RotatePosition(1) * SinDelta ) & ! horizontal linear shear - + op%VLinShr * ( RotatePosition(3) - p%RefHt ) )/p%RefLength ) ! vertical linear shear - Vh = op%V * dVhdV + op%Vgust - - dVhdVShr = op%V * zr**op%VShr * log(zr) - dVhdPD = op%V * op%HShr / p%RefLength * ( RotatePosition(1) * CosDelta - RotatePosition(2) * SinDelta ) - - tmp_du = CosPropDir*CosDelta - SinPropDir*SinDelta - tmp_dv = -SinPropDir*CosDelta - CosPropDir*SinDelta - - - !> \f$ \frac{\partial Vt_u}{\partial X} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ - dYdu(1,1) = tmp_du*dVhdx - - !> \f$ \frac{\partial Vt_v}{\partial X} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ - dYdu(2,1) = tmp_dv*dVhdx - - !> \f$ \frac{\partial Vt_w}{\partial X} = 0 \f$ - dYdu(3,1) = 0.0_R8Ki - - - !> \f$ \frac{\partial Vt_u}{\partial Y} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ - dYdu(1,2) = tmp_du*dVhdy - - !> \f$ \frac{\partial Vt_v}{\partial Y} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ - dYdu(2,2) = tmp_dv*dVhdy - - !> \f$ \frac{\partial Vt_w}{\partial Y} = 0 \f$ - dYdu(3,2) = 0.0_R8Ki - - - !> \f$ \frac{\partial Vt_u}{\partial Z} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] - !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ - dYdu(1,3) = tmp_du*dVhdz - - !> \f$ \frac{\partial Vt_v}{\partial Z} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] - !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ - dYdu(2,3) = tmp_dv*dVhdz - - !> \f$ \frac{\partial Vt_w}{\partial Z} = 0 \f$ - dYdu(3,3) = 0.0_R8Ki - - - - ! \f$ \frac{\partial Vt_u}{\partial V} = \f$ - dYdu(1,4) = tmp_du*dVhdV - ! \f$ \frac{\partial Vt_v}{\partial V} = \f$ - dYdu(2,4) = tmp_dv*dVhdV - !> \f$ \frac{\partial Vt_w}{\partial V} = 0 \f$ - dYdu(3,4) = 0.0_R8Ki - - - ! \f$ \frac{\partial Vt_u}{\partial VShr} = \f$ - dYdu(1,5) = tmp_du*dVhdVShr - ! \f$ \frac{\partial Vt_v}{\partial VShr} = \f$ - dYdu(2,5) = tmp_dv*dVhdVShr - !> \f$ \frac{\partial Vt_w}{\partial VShr} = 0 \f$ - dYdu(3,5) = 0.0_R8Ki - - ! \f$ \frac{\partial Vt_u}{\partial PropDir} = \f$ - dYdu(1,6) = tmp_dv*Vh + tmp_du*dVhdPD - ! \f$ \frac{\partial Vt_v}{\partial PropDir} = \f$ - dYdu(2,6) = -tmp_du*Vh + tmp_dv*dVhdPD - !> \f$ \frac{\partial Vt_w}{\partial PropDir} = 0 \f$ - dYdu(3,6) = 0.0_R8Ki - - RETURN - -END SUBROUTINE IfW_UniformWind_JacobianPInput -!.................................................................................................................................. -!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial -!! derivative dY/du is returned. This submodule does not follow the modularization framework. -SUBROUTINE IfW_UniformWind_GetOP( t, p, m, OP_out ) - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - REAL(ReKi), INTENT( OUT) :: OP_out(2) !< operating point (HWindSpeed and PLexp - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - - ! Local Variables - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - - - !------------------------------------------------------------------------------------------------- - !> 1. Linearly interpolate parameters in time at operating point (or use nearest-neighbor to extrapolate) - !! (compare with nwtc_num::interpstpreal) - !------------------------------------------------------------------------------------------------- - CALL InterpParams(t, p, m, op) - - OP_out(1) = op%V - OP_out(2) = op%VSHR - - RETURN - -END SUBROUTINE IfW_UniformWind_GetOP - - -!==================================================================================================== -SUBROUTINE Uniform_to_FFWind(p, m, p_ff, ErrStat, ErrMsg) - - USE IfW_FFWind_Base - - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< UniformWind Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_FFWind_ParameterType), INTENT( OUT) :: p_ff !< FF Parameters - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - ! local variables - REAL(DbKi) :: Time !< time from the start of the simulation - REAL(ReKi) :: PositionXYZ(3,1) !< Array of XYZ coordinates, 3xN - REAL(ReKi) :: Velocity(3,1) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi) :: n - - INTEGER(ReKi) , parameter :: dz = 5.0 - INTEGER(ReKi) , parameter :: dy = 5.0 - INTEGER(ReKi) :: i - INTEGER(ReKi) :: it - INTEGER(ReKi) :: iy - INTEGER(ReKi) :: iz - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), parameter :: RoutineName = 'Uniform_to_FFWind' - - ErrStat = ErrID_None - ErrMsg = "" - - p_ff%WindFileFormat = -1 ! "Binary file format description number" - - p_ff%NFFComp = 3 ! "Number of wind components" - - p_ff%Periodic = .false. - p_ff%InterpTower = .true. - p_ff%RefHt = p%RefHt - p_ff%NTGrids = 0 - p_ff%InvFFYD = 1.0_ReKi / dy ! "reciprocal of delta y" 1/meters - p_ff%InvFFZD = 1.0_ReKi / dz ! "reciprocal of delta z" 1/meters - - ! add roughly 10% to the width - n = NINT( p%RefLength*1.1_ReKi*0.5_ReKi / dy ) - p_ff%NYGrids = n*2+1 ! "Number of points in the lateral (y) direction of the grids" - - p_ff%FFYHWid = 0.5_ReKi * dy * (p_ff%NYGrids-1) ! "Half the grid width" meters - - n = NINT( p%RefLength*1.1_ReKi*0.5_ReKi / dz ) - p_ff%NZGrids = INT( p_ff%RefHt / dy ) + n + 1 ! "Number of points in the vertical (z) direction of the grids" - - - p_ff%FFZHWid = 0.5_ReKi * dz * (p_ff%NZGrids -1) ! "Half the grid height" meters - p_ff%GridBase = p_ff%RefHt + n*dz - p_ff%FFZHWid*2.0_ReKi ! "the height of the bottom of the grid" meters - - p_ff%InitXPosition = 0.0_ReKi ! "the initial x position of grid (distance in FF is offset)" meters - - - ! time will be the smallest delta t in this Uniform wind file - if (p%NumDataLines < 2) then - p_ff%FFDTime = 600.0_ReKi ! doesn't matter what the time step is - else - p_ff%FFDTime = HUGE(p_ff%FFDTime) ! "Delta time" seconds - do i=2,p%NumDataLines - p_ff%FFDTime = min(p_ff%FFDTime, p%TData(i) - p%TData(i-1)) - end do - - if (p_ff%FFDTime < 0.0001) then - call SetErrStat( ErrID_Fatal, "Smallest time step in uniform wind file is less that 0.0001 seconds. Increase the time step "//& - " to convert to a FF file.", ErrStat, ErrMsg, RoutineName ) - return - end if - - end if - - p_ff%FFRate = 1.0_ReKi / p_ff%FFDTime ! "Data rate (1/FFDTime)" Hertz - - - p_ff%AddMeanAfterInterp = .FALSE. ! "Add the mean wind speed after interpolating at a given height?" - - p_ff%WindProfileType = WindProfileType_PL ! "Wind profile type (0=constant;1=logarithmic;2=power law)" - - p_ff%PLExp = GetAverageVal(p%VSHR) ! "Power law exponent (used for PL wind profile type only)" - - p_ff%Z0 = 0.0_ReKi ! "Surface roughness length (used for LOG wind profile type only)" - - - if (p%NumDataLines < 2) then - p_ff%NFFSteps = 2 ! "Number of time steps in the FF array" - - else - p_ff%NFFSteps = NINT(p%TData(p%NumDataLines) / p_ff%FFDTime) + 1 - end if - - p_ff%TotalTime = (p_ff%NFFSteps-1) * p_ff%FFDTime ! "The total time of the simulation" seconds - - - call AllocAry( p_ff%FFData, p_ff%NZGrids,p_ff%NYGrids,p_ff%NFFComp, p_ff%NFFSteps, 'p%FF%FFData', ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >= AbortErrLev) return - - PositionXYZ = 0.0_ReKi - do it = 1,p_ff%NFFSteps - Time = (it-1)*p_ff%FFDTime - - do iy = 1,p_ff%NYGrids - PositionXYZ(2,1) = (iy-1)*dy - p_ff%FFYHWid - - do iz=1,p_ff%NZGrids - PositionXYZ(3,1) = (iz-1)*dz + p_ff%GridBase - - call IfW_UniformWind_CalcOutput(Time, PositionXYZ, p, Velocity, m, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - p_ff%FFData(iz,iy,:,it) = Velocity(:,1) - - end do ! iz - end do ! iy - end do ! it - - ! compute some averages for this simulation - p_ff%MeanFFWS = GetAverageVal(p%V) ! "Mean wind speed (advection speed)" - p_ff%InvMFFWS = 1.0_ReKi / p_ff%MeanFFWS - - RETURN - -CONTAINS -!==================================================================================================== - FUNCTION GetAverageVal(Ary) RESULT(Avg) - REAL(ReKi), intent(in) :: Ary(:) - REAL(ReKi) :: Avg - - if (p%NumDataLines < 2) then - Avg = Ary(1) - else - Avg = p%TData(1) * Ary(1) ! in case tData(1)/=0 - do i=2,p%NumDataLines - Avg = Avg + (p%TData(i)-p%TData(i-1)) * (Ary(i)+Ary(i-1))/2.0_ReKi - end do - Avg = Avg / (p%TData(p%NumDataLines)-p%TData(1)) - end if - - END FUNCTION GetAverageVal - -END SUBROUTINE Uniform_to_FFWind -!==================================================================================================== -SUBROUTINE FFWind_to_Uniform(p, m, p_ff, ErrStat, ErrMsg, SmoothingRadius) - - USE IfW_FFWind_Base - - TYPE(IfW_UniformWind_ParameterType), INTENT( OUT) :: p !< UniformWind Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p_ff !< FF Parameters - REAL(ReKi), OPTIONAL, INTENT(IN ) :: SmoothingRadius !< length of time used for smoothing data, seconds (if omitted, no smoothing will occur) - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - INTEGER(IntKi) :: i - INTEGER(IntKi) :: iy_ref, iz_ref, iz_p1 - INTEGER(IntKi) :: iy, iz, ic - REAL(ReKi) :: meanVel(3) - REAL(ReKi) :: meanWindDir - REAL(ReKi) :: u_p1, z_p1 - REAL(ReKi) :: u_ref, z_ref - REAL(ReKi), parameter :: HubPositionX = 0.0_ReKi -! REAL(ReKi), parameter :: radius = 0.0 !5.0_ReKi !seconds - REAL(ReKi) :: radius ! length of time to use for smoothing uniform wind data, seconds - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), parameter :: RoutineName = 'FFWind_to_Uniform' - - REAL(SiKi), allocatable :: FFData(:,:,:,:) - REAL(ReKi), allocatable :: tmp(:) - REAL(R8Ki) :: transformMat(3,3) - - ErrStat = ErrID_None - ErrMsg = "" - - if (p_ff%RefLength > epsilon(0.0_ReKi)) then - p%RefLength = p_ff%VLinShr - else - p%RefLength = (p_ff%nYGrids - 1) / p_ff%InvFFYD ! width of the FF wind field - end if - p%NumDataLines = p_ff%nffSteps - - - CALL AllocAry( p%Tdata, p%NumDataLines, 'time', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%V, p%NumDataLines, 'horizontal wind speed', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%Delta, p%NumDataLines, 'direction', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%Upflow, p%NumDataLines, 'upflow', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%VZ, p%NumDataLines, 'vertical wind speed', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%HShr, p%NumDataLines, 'horizontal linear shear', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%VShr, p%NumDataLines, 'vertical power-law shear exponent',ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%VLinShr,p%NumDataLines, 'vertical linear shear', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%VGust, p%NumDataLines, 'gust velocity', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( FFData, p_FF%NZGrids,p_FF%NYGrids,p_FF%NFFComp, p_FF%NFFSteps, 'FFData', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( tmp, p_FF%NFFSteps, 'tmp', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - IF ( ErrStat >= AbortErrLev .or. p%NumDataLines < 1) then - if (allocated(FFData)) deallocate(FFData) - if (allocated(tmp)) deallocate(tmp) - RETURN - END IF - - ! we'll assume these are 0, for simplicity - p%HShr = p_ff%HLinShr - p%VLinShr = p_ff%VLinShr - p%VGust = 0.0_ReKi - - ! fill time array with time at hub position - do i=1,p%NumDataLines - p%Tdata(i) = (p_ff%InitXPosition - HubPositionX) * p_ff%InvMFFWS + (i-1)*p_ff%FFDTime - end do - - - ! calculate mean velocity at grid point nearest lateral center of grid at reference height: - iy_ref = nint(p_ff%nYGrids / 2.0_ReKi) - iz_ref = nint( ( p_ff%RefHt - p_ff%GridBase )*p_ff%InvFFZD ) + 1 - p%RefHt = p_ff%GridBase + (iz_ref - 1)/p_ff%InvFFZD ! make sure RefHt is on the grid - - - meanVel = 0.0_ReKi - do i=1,p%NumDataLines - meanVel = meanVel + p_ff%FFData( iz_ref, iy_ref, :, i ) - end do - meanVel = meanVel/p%NumDataLines - - ! calculate the average upflow angle - p%Upflow = atan2( meanVel(3), TwoNorm(meanVel(1:2)) ) - meanWindDir = atan2( meanVel(2), meanVel(1) ) - - ! rotate the FF wind to remove the mean upflow and direction - transformMat(1,1) = cos(meanWindDir) * cos(p%Upflow(1)) - transformMat(2,1) = -sin(meanWindDir) - transformMat(3,1) = -cos(meanWindDir) * sin(p%Upflow(1)) - - transformMat(1,2) = sin(meanWindDir) * cos(p%Upflow(1)) - transformMat(2,2) = cos(meanWindDir) - transformMat(3,2) = -sin(meanWindDir) * sin(p%Upflow(1)) - - transformMat(1,3) = sin(p%Upflow(1)) - transformMat(2,3) = 0.0_R8Ki - transformMat(3,3) = cos(p%Upflow(1)) - - do i=1,size(FFData,4) - do iy=1,size(FFData,2) - do iz=1,size(FFData,1) - FFData(iz,iy,:,i) = matmul(transformMat, p_ff%FFData(iz,iy,:,i)) - end do - end do - end do - - ! make sure we have the correct mean, or the direction will also be off here - if (p_ff%AddMeanAfterInterp) then - FFData(iz_ref,iy_ref,1,:) = FFData(iz_ref,iy_ref,1,:) + CalculateMeanVelocity(p_ff,p%RefHt,0.0_ReKi) - end if - - meanVel = 0.0_ReKi - do i=1,p%NumDataLines - meanVel = meanVel + FFData( iz_ref, iy_ref, :, i ) - end do - meanVel = meanVel/p%NumDataLines - - - ! Fill velocity arrays for uniform wind - do i=1,p%NumDataLines - p%V(i) = TwoNorm( FFData(iz_ref,iy_ref,1:2,i) ) - end do - p%VZ = FFData(iz_ref,iy_ref,3,:) - - ! Fill wind direction array - do i=1,p%NumDataLines - p%Delta(i) = -(meanWindDir + atan2( FFData(iz_ref,iy_ref,2,i), FFData(iz_ref,iy_ref,1,i) )) - end do - - ! Now, time average values, if desired: - if (present(SmoothingRadius)) then - radius = SmoothingRadius - else - radius = 0.0_ReKi - end if - tmp = p%V; call kernelSmoothing(p%Tdata, tmp, kernelType_TRIWEIGHT, radius, p%V) - tmp = p%VZ; call kernelSmoothing(p%Tdata, tmp, kernelType_TRIWEIGHT, radius, p%VZ) - tmp = p%Delta; call kernelSmoothing(p%Tdata, tmp, kernelType_TRIWEIGHT, radius, p%Delta) - - ! Calculate averaged power law coefficient: - if (p_ff%WindProfileType == WindProfileType_PL) then - p%VShr = p_ff%PLExp - else - iz_p1 = p_ff%nZGrids ! pick a point to compute the power law exponent (least squares would be better than a single point) - z_p1 = p_ff%GridBase + (iz_p1 - 1)/p_ff%InvFFZD - - if (p_ff%AddMeanAfterInterp) then - u_p1 = CalculateMeanVelocity(p_ff,z_p1,0.0_ReKi) - else - u_p1 = 0.0_ReKi - do i=1,p%NumDataLines - u_p1 = u_p1 + FFData( iz_p1, iy_ref, 1, i ) - end do - u_p1 = u_p1/p%NumDataLines - end if - - if (EqualRealNos(meanVel(1), u_p1) .or. EqualRealNos(u_p1,0.0_ReKi) .or. EqualRealNos(meanVel(1),0.0_ReKi)) then - p%VShr = 0.0_ReKi - else - p%VShr = log( u_p1 / meanVel(1) ) / log( z_p1 / p%RefHt ) - end if - end if - - ! clean up - - if (allocated(FFData)) deallocate(FFData) - if (allocated(tmp)) deallocate(tmp) - - -END SUBROUTINE FFWind_to_Uniform - - -!==================================================================================================== -SUBROUTINE WrUniformWind(FileRootName, p, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - INTEGER(IntKi) :: i - INTEGER(IntKi) :: UnWind - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'WrUniformWind' - - ErrStat = ErrID_None - ErrMsg = "" - - ! Local variables - - CALL GetNewUnit( UnWind, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - CALL OpenFOutFile ( UnWind, trim(FileRootName)//'.UniformWind.dat', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - WRITE( UnWind, "(A)" ) "#" - WRITE( UnWind, "(A)" ) '# Uniform Wind (deterministic) file for ENFAST generated by InflowWind' - WRITE( UnWind, "(A)" ) "#" - WRITE( UnWind, "(A)" ) "! Time Wind Wind Vertical Horiz. Pwr.Law Lin.Vert. Gust Upflow" - WRITE( UnWind, "(A)" ) "! Speed Dir Speed Shear Vert.Shr Shear Speed Angle" - WRITE( UnWind, "(A)" ) "! (sec) (m/s) (Deg) (m/s) (m/s) (deg)" - - DO i=1,p%NumDataLines - WRITE( UnWind, "(F15.5,8(1x,F11.4))" ) p%Tdata(i), p%V(i), p%Delta(i)*R2D, p%VZ(i), p%HShr(i), p%VShr(i), p%VLinShr(i), p%VGust(i), p%Upflow(i)*R2D - END DO - - CLOSE(UnWind) - -END SUBROUTINE WrUniformWind -!==================================================================================================== -END MODULE IfW_UniformWind diff --git a/modules/inflowwind/src/IfW_UniformWind.txt b/modules/inflowwind/src/IfW_UniformWind.txt deleted file mode 100644 index df99ddd79e..0000000000 --- a/modules/inflowwind/src/IfW_UniformWind.txt +++ /dev/null @@ -1,67 +0,0 @@ -################################################################################################################################### -# Registry for IfW_UniformWind, creates MODULE IfW_UniformWind_Types -# Module IfW_UniformWind_Types contains all of the user-defined types needed in IfW_UniformWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt - - -######################### - -typedef IfW_UniformWind/IfW_UniformWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - -typedef ^ ^ ReKi ReferenceHeight - - - "Hub height of the turbine" meters -typedef ^ ^ ReKi RefLength - - - "RefLength of the wind field to use" meters -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - -typedef ^ ^ LOGICAL UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - -typedef ^ ^ FileInfoType PassedFileData - - - "Optional slot for wind type 2 data if file IO is not used." - - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off HHWind submodule" - -typedef ^ ^ DbKi WindFileDT - - - "TimeStep of the wind file -- zero value for none" seconds -typedef ^ ^ ReKi WindFileTRange {2} - - "Time range of the wind file" seconds -typedef ^ ^ IntKi WindFileNumTSteps - - - "Number of timesteps in the time range of wind file" - -typedef ^ ^ LOGICAL WindFileConstantDT - - - "Timesteps are the same throughout file" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi TimeIndex - 0 - "An Index into the TData array" - - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType ReKi TData : - - "Time array from the HH file" seconds -typedef ^ ^ ReKi DELTA : - - "HH Wind direction (angle)" degrees -typedef ^ ^ ReKi Upflow : - - "HH upflow angle" degrees -typedef ^ ^ ReKi V : - - "HH horizontal wind speed" meters/sec -typedef ^ ^ ReKi VZ : - - "wind, including tower shadow, along the Z axis" meters/sec -typedef ^ ^ ReKi HSHR : - - "HH Horizontal linear shear" - -typedef ^ ^ ReKi VSHR : - - "HH vertical shear exponent" - -typedef ^ ^ ReKi VLINSHR : - - "HH vertical linear shear" - -typedef ^ ^ ReKi VGUST : - - "HH wind gust" - -typedef ^ ^ ReKi RefHt - - - "reference height; was HH (hub height); used to center the wind" meters -typedef ^ ^ ReKi RefLength - - - "reference length used to scale the linear shear" meters -typedef ^ ^ IntKi NumDataLines - - - "" - - -# ..... Input (dummy type for extrap/interp routine) ................................................................................................................ -#typedef ^ InputType SiKi dummy - - - "dummy type because we need extrap/interp routine if we put the below outputs in the InflowWind type" - -# ..... Output (for extended AD inputs in linearization) ................................................................................................................ -typedef ^ IfW_UniformWind_Intrp ReKi DELTA - - - "HH Wind direction (angle)" degrees -typedef ^ ^ ReKi Upflow - - - "HH upflow angle" degrees -typedef ^ ^ ReKi V - - - "HH horizontal wind speed" meters/sec -typedef ^ ^ ReKi VZ - - - "wind, including tower shadow, along the Z axis" meters/sec -typedef ^ ^ ReKi HSHR - - - "HH Horizontal linear shear" - -typedef ^ ^ ReKi VSHR - - - "HH vertical shear exponent" - -typedef ^ ^ ReKi VLINSHR - - - "HH vertical linear shear" - -typedef ^ ^ ReKi VGUST - - - "HH wind gust" - - - diff --git a/modules/inflowwind/src/IfW_UniformWind_Types.f90 b/modules/inflowwind/src/IfW_UniformWind_Types.f90 deleted file mode 100644 index 6007f774e4..0000000000 --- a/modules/inflowwind/src/IfW_UniformWind_Types.f90 +++ /dev/null @@ -1,1546 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_UniformWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_UniformWind_Types -!................................................................................................................................. -! This file is part of IfW_UniformWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_UniformWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_UniformWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_UniformWind_InitInputType ======= - TYPE, PUBLIC :: IfW_UniformWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - REAL(ReKi) :: ReferenceHeight !< Hub height of the turbine [meters] - REAL(ReKi) :: RefLength !< RefLength of the wind field to use [meters] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - LOGICAL :: UseInputFile = .TRUE. !< Flag for toggling file based IO in wind type 2. [-] - TYPE(FileInfoType) :: PassedFileData !< Optional slot for wind type 2 data if file IO is not used. [-] - END TYPE IfW_UniformWind_InitInputType -! ======================= -! ========= IfW_UniformWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_UniformWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off HHWind submodule [-] - REAL(DbKi) :: WindFileDT !< TimeStep of the wind file -- zero value for none [seconds] - REAL(ReKi) , DIMENSION(1:2) :: WindFileTRange !< Time range of the wind file [seconds] - INTEGER(IntKi) :: WindFileNumTSteps !< Number of timesteps in the time range of wind file [-] - LOGICAL :: WindFileConstantDT !< Timesteps are the same throughout file [-] - END TYPE IfW_UniformWind_InitOutputType -! ======================= -! ========= IfW_UniformWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_UniformWind_MiscVarType - INTEGER(IntKi) :: TimeIndex = 0 !< An Index into the TData array [-] - END TYPE IfW_UniformWind_MiscVarType -! ======================= -! ========= IfW_UniformWind_ParameterType ======= - TYPE, PUBLIC :: IfW_UniformWind_ParameterType - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TData !< Time array from the HH file [seconds] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: DELTA !< HH Wind direction (angle) [degrees] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Upflow !< HH upflow angle [degrees] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: V !< HH horizontal wind speed [meters/sec] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VZ !< wind, including tower shadow, along the Z axis [meters/sec] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: HSHR !< HH Horizontal linear shear [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VSHR !< HH vertical shear exponent [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VLINSHR !< HH vertical linear shear [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VGUST !< HH wind gust [-] - REAL(ReKi) :: RefHt !< reference height; was HH (hub height); used to center the wind [meters] - REAL(ReKi) :: RefLength !< reference length used to scale the linear shear [meters] - INTEGER(IntKi) :: NumDataLines !< [-] - END TYPE IfW_UniformWind_ParameterType -! ======================= -! ========= IfW_UniformWind_Intrp ======= - TYPE, PUBLIC :: IfW_UniformWind_Intrp - REAL(ReKi) :: DELTA !< HH Wind direction (angle) [degrees] - REAL(ReKi) :: Upflow !< HH upflow angle [degrees] - REAL(ReKi) :: V !< HH horizontal wind speed [meters/sec] - REAL(ReKi) :: VZ !< wind, including tower shadow, along the Z axis [meters/sec] - REAL(ReKi) :: HSHR !< HH Horizontal linear shear [-] - REAL(ReKi) :: VSHR !< HH vertical shear exponent [-] - REAL(ReKi) :: VLINSHR !< HH vertical linear shear [-] - REAL(ReKi) :: VGUST !< HH wind gust [-] - END TYPE IfW_UniformWind_Intrp -! ======================= -CONTAINS - SUBROUTINE IfW_UniformWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_UniformWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%ReferenceHeight = SrcInitInputData%ReferenceHeight - DstInitInputData%RefLength = SrcInitInputData%RefLength - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - DstInitInputData%UseInputFile = SrcInitInputData%UseInputFile - CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%PassedFileData, DstInitInputData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_UniformWind_CopyInitInput - - SUBROUTINE IfW_UniformWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UniformWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyInitInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_UniformWind_DestroyInitInput - - SUBROUTINE IfW_UniformWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - Re_BufSz = Re_BufSz + 1 ! ReferenceHeight - Re_BufSz = Re_BufSz + 1 ! RefLength - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - Int_BufSz = Int_BufSz + 1 ! UseInputFile - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! PassedFileData: size of buffers for each call to pack subtype - CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! PassedFileData - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! PassedFileData - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! PassedFileData - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - ReKiBuf(Re_Xferred) = InData%ReferenceHeight - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefLength - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%UseInputFile, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_UniformWind_PackInitInput - - SUBROUTINE IfW_UniformWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%ReferenceHeight = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefLength = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%UseInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseInputFile) - Int_Xferred = Int_Xferred + 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_UniformWind_UnPackInitInput - - SUBROUTINE IfW_UniformWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_UniformWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInitOutputData%WindFileDT = SrcInitOutputData%WindFileDT - DstInitOutputData%WindFileTRange = SrcInitOutputData%WindFileTRange - DstInitOutputData%WindFileNumTSteps = SrcInitOutputData%WindFileNumTSteps - DstInitOutputData%WindFileConstantDT = SrcInitOutputData%WindFileConstantDT - END SUBROUTINE IfW_UniformWind_CopyInitOutput - - SUBROUTINE IfW_UniformWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UniformWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyInitOutput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_UniformWind_DestroyInitOutput - - SUBROUTINE IfW_UniformWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Db_BufSz = Db_BufSz + 1 ! WindFileDT - Re_BufSz = Re_BufSz + SIZE(InData%WindFileTRange) ! WindFileTRange - Int_BufSz = Int_BufSz + 1 ! WindFileNumTSteps - Int_BufSz = Int_BufSz + 1 ! WindFileConstantDT - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DbKiBuf(Db_Xferred) = InData%WindFileDT - Db_Xferred = Db_Xferred + 1 - DO i1 = LBOUND(InData%WindFileTRange,1), UBOUND(InData%WindFileTRange,1) - ReKiBuf(Re_Xferred) = InData%WindFileTRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%WindFileNumTSteps - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%WindFileConstantDT, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackInitOutput - - SUBROUTINE IfW_UniformWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - OutData%WindFileDT = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - i1_l = LBOUND(OutData%WindFileTRange,1) - i1_u = UBOUND(OutData%WindFileTRange,1) - DO i1 = LBOUND(OutData%WindFileTRange,1), UBOUND(OutData%WindFileTRange,1) - OutData%WindFileTRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%WindFileNumTSteps = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%WindFileConstantDT = TRANSFER(IntKiBuf(Int_Xferred), OutData%WindFileConstantDT) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackInitOutput - - SUBROUTINE IfW_UniformWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%TimeIndex = SrcMiscData%TimeIndex - END SUBROUTINE IfW_UniformWind_CopyMisc - - SUBROUTINE IfW_UniformWind_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyMisc' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_UniformWind_DestroyMisc - - SUBROUTINE IfW_UniformWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! TimeIndex - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%TimeIndex - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackMisc - - SUBROUTINE IfW_UniformWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%TimeIndex = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackMisc - - SUBROUTINE IfW_UniformWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcParamData%TData)) THEN - i1_l = LBOUND(SrcParamData%TData,1) - i1_u = UBOUND(SrcParamData%TData,1) - IF (.NOT. ALLOCATED(DstParamData%TData)) THEN - ALLOCATE(DstParamData%TData(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%TData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%TData = SrcParamData%TData -ENDIF -IF (ALLOCATED(SrcParamData%DELTA)) THEN - i1_l = LBOUND(SrcParamData%DELTA,1) - i1_u = UBOUND(SrcParamData%DELTA,1) - IF (.NOT. ALLOCATED(DstParamData%DELTA)) THEN - ALLOCATE(DstParamData%DELTA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%DELTA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%DELTA = SrcParamData%DELTA -ENDIF -IF (ALLOCATED(SrcParamData%Upflow)) THEN - i1_l = LBOUND(SrcParamData%Upflow,1) - i1_u = UBOUND(SrcParamData%Upflow,1) - IF (.NOT. ALLOCATED(DstParamData%Upflow)) THEN - ALLOCATE(DstParamData%Upflow(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Upflow.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%Upflow = SrcParamData%Upflow -ENDIF -IF (ALLOCATED(SrcParamData%V)) THEN - i1_l = LBOUND(SrcParamData%V,1) - i1_u = UBOUND(SrcParamData%V,1) - IF (.NOT. ALLOCATED(DstParamData%V)) THEN - ALLOCATE(DstParamData%V(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%V = SrcParamData%V -ENDIF -IF (ALLOCATED(SrcParamData%VZ)) THEN - i1_l = LBOUND(SrcParamData%VZ,1) - i1_u = UBOUND(SrcParamData%VZ,1) - IF (.NOT. ALLOCATED(DstParamData%VZ)) THEN - ALLOCATE(DstParamData%VZ(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VZ = SrcParamData%VZ -ENDIF -IF (ALLOCATED(SrcParamData%HSHR)) THEN - i1_l = LBOUND(SrcParamData%HSHR,1) - i1_u = UBOUND(SrcParamData%HSHR,1) - IF (.NOT. ALLOCATED(DstParamData%HSHR)) THEN - ALLOCATE(DstParamData%HSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%HSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%HSHR = SrcParamData%HSHR -ENDIF -IF (ALLOCATED(SrcParamData%VSHR)) THEN - i1_l = LBOUND(SrcParamData%VSHR,1) - i1_u = UBOUND(SrcParamData%VSHR,1) - IF (.NOT. ALLOCATED(DstParamData%VSHR)) THEN - ALLOCATE(DstParamData%VSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VSHR = SrcParamData%VSHR -ENDIF -IF (ALLOCATED(SrcParamData%VLINSHR)) THEN - i1_l = LBOUND(SrcParamData%VLINSHR,1) - i1_u = UBOUND(SrcParamData%VLINSHR,1) - IF (.NOT. ALLOCATED(DstParamData%VLINSHR)) THEN - ALLOCATE(DstParamData%VLINSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VLINSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VLINSHR = SrcParamData%VLINSHR -ENDIF -IF (ALLOCATED(SrcParamData%VGUST)) THEN - i1_l = LBOUND(SrcParamData%VGUST,1) - i1_u = UBOUND(SrcParamData%VGUST,1) - IF (.NOT. ALLOCATED(DstParamData%VGUST)) THEN - ALLOCATE(DstParamData%VGUST(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VGUST.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VGUST = SrcParamData%VGUST -ENDIF - DstParamData%RefHt = SrcParamData%RefHt - DstParamData%RefLength = SrcParamData%RefLength - DstParamData%NumDataLines = SrcParamData%NumDataLines - END SUBROUTINE IfW_UniformWind_CopyParam - - SUBROUTINE IfW_UniformWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyParam' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - -IF (ALLOCATED(ParamData%TData)) THEN - DEALLOCATE(ParamData%TData) -ENDIF -IF (ALLOCATED(ParamData%DELTA)) THEN - DEALLOCATE(ParamData%DELTA) -ENDIF -IF (ALLOCATED(ParamData%Upflow)) THEN - DEALLOCATE(ParamData%Upflow) -ENDIF -IF (ALLOCATED(ParamData%V)) THEN - DEALLOCATE(ParamData%V) -ENDIF -IF (ALLOCATED(ParamData%VZ)) THEN - DEALLOCATE(ParamData%VZ) -ENDIF -IF (ALLOCATED(ParamData%HSHR)) THEN - DEALLOCATE(ParamData%HSHR) -ENDIF -IF (ALLOCATED(ParamData%VSHR)) THEN - DEALLOCATE(ParamData%VSHR) -ENDIF -IF (ALLOCATED(ParamData%VLINSHR)) THEN - DEALLOCATE(ParamData%VLINSHR) -ENDIF -IF (ALLOCATED(ParamData%VGUST)) THEN - DEALLOCATE(ParamData%VGUST) -ENDIF - END SUBROUTINE IfW_UniformWind_DestroyParam - - SUBROUTINE IfW_UniformWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! TData allocated yes/no - IF ( ALLOCATED(InData%TData) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TData upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TData) ! TData - END IF - Int_BufSz = Int_BufSz + 1 ! DELTA allocated yes/no - IF ( ALLOCATED(InData%DELTA) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! DELTA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%DELTA) ! DELTA - END IF - Int_BufSz = Int_BufSz + 1 ! Upflow allocated yes/no - IF ( ALLOCATED(InData%Upflow) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Upflow upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Upflow) ! Upflow - END IF - Int_BufSz = Int_BufSz + 1 ! V allocated yes/no - IF ( ALLOCATED(InData%V) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! V upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%V) ! V - END IF - Int_BufSz = Int_BufSz + 1 ! VZ allocated yes/no - IF ( ALLOCATED(InData%VZ) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VZ upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VZ) ! VZ - END IF - Int_BufSz = Int_BufSz + 1 ! HSHR allocated yes/no - IF ( ALLOCATED(InData%HSHR) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! HSHR upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%HSHR) ! HSHR - END IF - Int_BufSz = Int_BufSz + 1 ! VSHR allocated yes/no - IF ( ALLOCATED(InData%VSHR) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VSHR upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VSHR) ! VSHR - END IF - Int_BufSz = Int_BufSz + 1 ! VLINSHR allocated yes/no - IF ( ALLOCATED(InData%VLINSHR) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VLINSHR upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VLINSHR) ! VLINSHR - END IF - Int_BufSz = Int_BufSz + 1 ! VGUST allocated yes/no - IF ( ALLOCATED(InData%VGUST) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VGUST upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VGUST) ! VGUST - END IF - Re_BufSz = Re_BufSz + 1 ! RefHt - Re_BufSz = Re_BufSz + 1 ! RefLength - Int_BufSz = Int_BufSz + 1 ! NumDataLines - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%TData) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TData,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TData,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TData,1), UBOUND(InData%TData,1) - ReKiBuf(Re_Xferred) = InData%TData(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%DELTA) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%DELTA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DELTA,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%DELTA,1), UBOUND(InData%DELTA,1) - ReKiBuf(Re_Xferred) = InData%DELTA(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%Upflow) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Upflow,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Upflow,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Upflow,1), UBOUND(InData%Upflow,1) - ReKiBuf(Re_Xferred) = InData%Upflow(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%V) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) - ReKiBuf(Re_Xferred) = InData%V(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VZ) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VZ,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VZ,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VZ,1), UBOUND(InData%VZ,1) - ReKiBuf(Re_Xferred) = InData%VZ(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%HSHR) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%HSHR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HSHR,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%HSHR,1), UBOUND(InData%HSHR,1) - ReKiBuf(Re_Xferred) = InData%HSHR(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VSHR) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VSHR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VSHR,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VSHR,1), UBOUND(InData%VSHR,1) - ReKiBuf(Re_Xferred) = InData%VSHR(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VLINSHR) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VLINSHR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VLINSHR,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VLINSHR,1), UBOUND(InData%VLINSHR,1) - ReKiBuf(Re_Xferred) = InData%VLINSHR(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VGUST) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VGUST,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VGUST,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VGUST,1), UBOUND(InData%VGUST,1) - ReKiBuf(Re_Xferred) = InData%VGUST(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefLength - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumDataLines - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackParam - - SUBROUTINE IfW_UniformWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TData not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TData)) DEALLOCATE(OutData%TData) - ALLOCATE(OutData%TData(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TData,1), UBOUND(OutData%TData,1) - OutData%TData(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DELTA not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%DELTA)) DEALLOCATE(OutData%DELTA) - ALLOCATE(OutData%DELTA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DELTA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%DELTA,1), UBOUND(OutData%DELTA,1) - OutData%DELTA(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Upflow not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Upflow)) DEALLOCATE(OutData%Upflow) - ALLOCATE(OutData%Upflow(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Upflow.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Upflow,1), UBOUND(OutData%Upflow,1) - OutData%Upflow(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%V)) DEALLOCATE(OutData%V) - ALLOCATE(OutData%V(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) - OutData%V(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VZ not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VZ)) DEALLOCATE(OutData%VZ) - ALLOCATE(OutData%VZ(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VZ,1), UBOUND(OutData%VZ,1) - OutData%VZ(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! HSHR not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%HSHR)) DEALLOCATE(OutData%HSHR) - ALLOCATE(OutData%HSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%HSHR,1), UBOUND(OutData%HSHR,1) - OutData%HSHR(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VSHR not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VSHR)) DEALLOCATE(OutData%VSHR) - ALLOCATE(OutData%VSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VSHR,1), UBOUND(OutData%VSHR,1) - OutData%VSHR(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VLINSHR not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VLINSHR)) DEALLOCATE(OutData%VLINSHR) - ALLOCATE(OutData%VLINSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VLINSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VLINSHR,1), UBOUND(OutData%VLINSHR,1) - OutData%VLINSHR(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VGUST not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VGUST)) DEALLOCATE(OutData%VGUST) - ALLOCATE(OutData%VGUST(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VGUST.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VGUST,1), UBOUND(OutData%VGUST,1) - OutData%VGUST(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefLength = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%NumDataLines = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackParam - - SUBROUTINE IfW_UniformWind_CopyIntrp( SrcIntrpData, DstIntrpData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_Intrp), INTENT(IN) :: SrcIntrpData - TYPE(IfW_UniformWind_Intrp), INTENT(INOUT) :: DstIntrpData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyIntrp' -! - ErrStat = ErrID_None - ErrMsg = "" - DstIntrpData%DELTA = SrcIntrpData%DELTA - DstIntrpData%Upflow = SrcIntrpData%Upflow - DstIntrpData%V = SrcIntrpData%V - DstIntrpData%VZ = SrcIntrpData%VZ - DstIntrpData%HSHR = SrcIntrpData%HSHR - DstIntrpData%VSHR = SrcIntrpData%VSHR - DstIntrpData%VLINSHR = SrcIntrpData%VLINSHR - DstIntrpData%VGUST = SrcIntrpData%VGUST - END SUBROUTINE IfW_UniformWind_CopyIntrp - - SUBROUTINE IfW_UniformWind_DestroyIntrp( IntrpData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UniformWind_Intrp), INTENT(INOUT) :: IntrpData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyIntrp' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_UniformWind_DestroyIntrp - - SUBROUTINE IfW_UniformWind_PackIntrp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_Intrp), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackIntrp' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DELTA - Re_BufSz = Re_BufSz + 1 ! Upflow - Re_BufSz = Re_BufSz + 1 ! V - Re_BufSz = Re_BufSz + 1 ! VZ - Re_BufSz = Re_BufSz + 1 ! HSHR - Re_BufSz = Re_BufSz + 1 ! VSHR - Re_BufSz = Re_BufSz + 1 ! VLINSHR - Re_BufSz = Re_BufSz + 1 ! VGUST - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DELTA - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Upflow - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%V - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VZ - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%HSHR - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VSHR - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VLINSHR - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VGUST - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackIntrp - - SUBROUTINE IfW_UniformWind_UnPackIntrp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_Intrp), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackIntrp' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DELTA = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Upflow = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%V = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VZ = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%HSHR = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VSHR = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VLINSHR = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VGUST = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackIntrp - -END MODULE IfW_UniformWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_UserWind.f90 b/modules/inflowwind/src/IfW_UserWind.f90 deleted file mode 100644 index b8a8a1596e..0000000000 --- a/modules/inflowwind/src/IfW_UserWind.f90 +++ /dev/null @@ -1,282 +0,0 @@ -!> This module is a placeholder for any user defined wind types. The end user can use this as a template for their code. -!! @note This module does not need to exactly conform to the FAST Modularization Framework standards. Three routines are required -!! though: -!! -- IfW_UserWind_Init -- Load or create any wind data. Only called at the start of FAST. -!! -- IfW_UserWind_CalcOutput -- This will be called at each timestep with a series of data points to give wind velocities at. -!! -- IfW_UserWind_End -- clear out any stored stuff. Only called at the end of FAST. -MODULE IfW_UserWind -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_UserWind_Types - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_UserWind_Ver = ProgDesc( 'IfW_UserWind', '', '' ) - - PUBLIC :: IfW_UserWind_Init - PUBLIC :: IfW_UserWind_End - PUBLIC :: IfW_UserWind_CalcOutput - -CONTAINS - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> A subroutine to initialize the UserWind module. This routine will initialize the module. -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UserWind_Init(InitData, ParamData, MiscVars, Interval, InitOutData, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UserWind_Init" - - - ! Passed Variables - - ! Anything this code needs to be able to generate or read its data in should be passed into here through InitData. - TYPE(IfW_UserWind_InitInputType), INTENT(IN ) :: InitData !< Input data for initialization. - - ! Store all data that does not change during the simulation in here (including the wind data field). This cannot be changed later. - TYPE(IfW_UserWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters. - - ! Store things that change during the simulation (indices to arrays for quicker searching etc). - TYPE(IfW_UserWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Anything that should be passed back to the InflowWind or higher modules regarding initialization. - TYPE(IfW_UserWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output. - - REAL(DbKi), INTENT(IN ) :: Interval !< Do not change this!! - - - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error. See NWTC_Library info for ErrID_* levels. - - ! local variables - ! Put local variables used during initializing your wind here. DO NOT USE GLOBAL VARIABLES EVER! - INTEGER(IntKi) :: UnitWind ! Use this unit number if you need to read in a file. - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !------------------------------------------------------------------------------------------------- - ! Set the Error handling variables - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - ! Get a unit number to use - - CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData. If you need to store it for later calculations, - ! copy it over now. - !------------------------------------------------------------------------------------------------- - ParamData%dummy = 0 -! ParamData%RefHt = InitData%ReferenceHeight -! ParamData%RefLength = InitData%RefLength - - !------------------------------------------------------------------------------------------------- - ! Open the file for reading. Proceed with file parsing etc. Populate your wind field here. - !------------------------------------------------------------------------------------------------- - -! CALL OpenFInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) -! CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) -! IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Set the MiscVars: - !------------------------------------------------------------------------------------------------- - - MiscVars%DummyMiscVar = 0 - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information. Set Any outputs here. - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_UserWind_Ver - - - - ! REMOVE THIS MESSAGE IF YOU WRITE CODE IN THIS MODULE - CALL SetErrStat(ErrID_Fatal,' This module has not been written yet.',ErrStat,ErrMsg,RoutineName) - - RETURN - -END SUBROUTINE IfW_UserWind_Init - -!==================================================================================================== - -!------------------------------------------------------------------------------------------------- -!> This routine and its subroutines calculate the wind velocity at a set of points given in -!! PositionXYZ. The UVW velocities are returned in OutData%Velocity -!! -!! @note This routine may be called multiple times in a single timestep!!! -!! -!! @note The PositionXYZ coordinates have been rotated into the wind coordinate system where the -!! primary wind flow is along the X-axis. The rotations to PropagationDir are taken care of -!! in the InflowWind_CalcOutput subroutine which calls this routine. -!------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UserWind_CalcOutput(Time, PositionXYZ, ParamData, Velocity, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UserWind_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_UserWind_ParameterType), INTENT(IN ) :: ParamData !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! local counters - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points passed in - - ! temporary variables - !INTEGER(IntKi) :: TmpErrStat ! temporary error status - !CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,DIM=2) - - - ! Step through all the positions and get the velocities - DO PointNum = 1, NumPoints - -! Place code to retrieve the windspeed at a given point here. - - - ! Some generic error handling if you want it when a calculation fails for some reason: - ! - ! ! Error handling - !CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - !IF (ErrStat >= AbortErrLev) THEN - ! TmpErrMsg= " Error calculating the wind speed at position ("// & - ! TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - ! TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - ! TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in the wind-file coordinates" - ! CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - ! RETURN - !ENDIF - - ENDDO - - ! REMOVE THIS MESSAGE IF YOU WRITE CODE IN THIS MODULE - CALL SetErrStat(ErrID_Fatal,' This module has not been written yet.',ErrStat,ErrMsg,RoutineName) - - - RETURN - -END SUBROUTINE IfW_UserWind_CalcOutput - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> This routine closes any open files and clears all data stored in UserWind derived Types -!! -!! @note This routine does not satisfy the Modular framework. The InputType is not used, rather -!! an array of points is passed in. -!! @date: 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UserWind_End( ParamData, MiscVars, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UserWind_End" - - - ! Passed Variables - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_UserWind_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the misc data - - CALL IfW_UserWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - -END SUBROUTINE IfW_UserWind_End - - -!==================================================================================================== -!==================================================================================================== -!==================================================================================================== -END MODULE IfW_UserWind diff --git a/modules/inflowwind/src/IfW_UserWind.txt b/modules/inflowwind/src/IfW_UserWind.txt deleted file mode 100644 index 62fa3e3b28..0000000000 --- a/modules/inflowwind/src/IfW_UserWind.txt +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################################################################### -# Registry for IfW_UserWind, creates MODULE IfW_UserWind_Types -# Module IfW_UserWind_Types contains all of the user-defined types needed in IfW_UserWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt - - -######################### - -typedef IfW_UserWind/IfW_UserWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off HHWind submodule" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType ReKi DummyMiscVar - - - "Remove this variable if you have misc variables" - - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType SiKi dummy - - - "remove if you have parameters" - - - - - diff --git a/modules/inflowwind/src/IfW_UserWind_Types.f90 b/modules/inflowwind/src/IfW_UserWind_Types.f90 deleted file mode 100644 index 6f7c2fe094..0000000000 --- a/modules/inflowwind/src/IfW_UserWind_Types.f90 +++ /dev/null @@ -1,695 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_UserWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_UserWind_Types -!................................................................................................................................. -! This file is part of IfW_UserWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_UserWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_UserWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_UserWind_InitInputType ======= - TYPE, PUBLIC :: IfW_UserWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - END TYPE IfW_UserWind_InitInputType -! ======================= -! ========= IfW_UserWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_UserWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off HHWind submodule [-] - END TYPE IfW_UserWind_InitOutputType -! ======================= -! ========= IfW_UserWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_UserWind_MiscVarType - REAL(ReKi) :: DummyMiscVar !< Remove this variable if you have misc variables [-] - END TYPE IfW_UserWind_MiscVarType -! ======================= -! ========= IfW_UserWind_ParameterType ======= - TYPE, PUBLIC :: IfW_UserWind_ParameterType - REAL(SiKi) :: dummy !< remove if you have parameters [-] - END TYPE IfW_UserWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_UserWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_UserWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - END SUBROUTINE IfW_UserWind_CopyInitInput - - SUBROUTINE IfW_UserWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UserWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyInitInput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_UserWind_DestroyInitInput - - SUBROUTINE IfW_UserWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END SUBROUTINE IfW_UserWind_PackInitInput - - SUBROUTINE IfW_UserWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END SUBROUTINE IfW_UserWind_UnPackInitInput - - SUBROUTINE IfW_UserWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_UserWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_UserWind_CopyInitOutput - - SUBROUTINE IfW_UserWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UserWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyInitOutput' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - END SUBROUTINE IfW_UserWind_DestroyInitOutput - - SUBROUTINE IfW_UserWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_UserWind_PackInitOutput - - SUBROUTINE IfW_UserWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_UserWind_UnPackInitOutput - - SUBROUTINE IfW_UserWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar - END SUBROUTINE IfW_UserWind_CopyMisc - - SUBROUTINE IfW_UserWind_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyMisc' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_UserWind_DestroyMisc - - SUBROUTINE IfW_UserWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyMiscVar - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyMiscVar - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_PackMisc - - SUBROUTINE IfW_UserWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyMiscVar = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_UnPackMisc - - SUBROUTINE IfW_UserWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%dummy = SrcParamData%dummy - END SUBROUTINE IfW_UserWind_CopyParam - - SUBROUTINE IfW_UserWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyParam' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE IfW_UserWind_DestroyParam - - SUBROUTINE IfW_UserWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%dummy - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_PackParam - - SUBROUTINE IfW_UserWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_UnPackParam - -END MODULE IfW_UserWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index 0cb8c145ab..4534424e51 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -41,9 +41,12 @@ MODULE InflowWind - USE InflowWind_Types USE NWTC_Library + USE InflowWind_Types USE InflowWind_Subs + USE InflowWind_IO_Types + USE InflowWind_IO + USE IfW_FlowField USE Lidar ! module for obtaining sensor data @@ -62,12 +65,6 @@ MODULE InflowWind PUBLIC :: InflowWind_CalcOutput !< Calculate the wind velocities PUBLIC :: InflowWind_End !< Ending routine (includes clean up) - PUBLIC :: InflowWind_Convert2HAWC !< An extension of the FAST framework, this routine converts an InflowWind data structure to HAWC format wind files - PUBLIC :: InflowWind_Convert2Bladed !< An extension of the FAST framework, this routine converts an InflowWind data structure to Bladed format wind files (with shear already included) - PUBLIC :: InflowWind_Convert2VTK !< An extension of the FAST framework, this routine converts an InflowWind data structure to VTK format wind files - PUBLIC :: InflowWind_Convert2Uniform !< An extension of the FAST framework, this routine converts an InflowWind data structure to Uniform Wind formatted text files - - ! These routines satisfy the framework, but do nothing at present. PUBLIC :: InflowWind_UpdateStates !< Loose coupling routine for solving for constraint states, integrating continuous states, and updating discrete states PUBLIC :: InflowWind_CalcConstrStateResidual !< Tight coupling routine for returning the constraint state residual @@ -99,145 +96,122 @@ MODULE InflowWind !! Since this module acts as an interface to other modules, on some things are set before initiating !! calls to the lower modules. !---------------------------------------------------------------------------------------------------- -SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & - y, m, TimeInterval, InitOutData, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Init" - - ! Initialization data and guesses - - TYPE(InflowWind_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization - TYPE(InflowWind_InputType), INTENT( OUT) :: InputGuess !< An initial guess for the input; the input mesh must be defined - TYPE(InflowWind_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(InflowWind_ContinuousStateType), INTENT( OUT) :: ContStates !< Initial continuous states - TYPE(InflowWind_DiscreteStateType), INTENT( OUT) :: DiscStates !< Initial discrete states - TYPE(InflowWind_ConstraintStateType), INTENT( OUT) :: ConstrStateGuess !< Initial guess of the constraint states - TYPE(InflowWind_OtherStateType), INTENT( OUT) :: OtherStates !< Initial other/optimization states - TYPE(InflowWind_OutputType), INTENT( OUT) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) - TYPE(InflowWind_MiscVarType), INTENT( OUT) :: m !< Misc variables for optimization (not copied in glue code) - REAL(DbKi), INTENT(IN ) :: TimeInterval !< Coupling time interval in seconds: InflowWind does not change this. - TYPE(InflowWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output data -- Names, units, and version info. - - - ! Error Handling - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - - TYPE(InflowWind_InputFile) :: InputFileData !< Data from input file - - TYPE(IfW_UniformWind_InitInputType) :: Uniform_InitData !< initialization info - TYPE(IfW_UniformWind_InitOutputType) :: Uniform_InitOutData !< initialization output info - - TYPE(IfW_TSFFWind_InitInputType) :: TSFF_InitData !< initialization info - TYPE(IfW_TSFFWind_InitOutputType) :: TSFF_InitOutData !< initialization output info - - TYPE(IfW_HAWCWind_InitInputType) :: HAWC_InitData !< initialization info - TYPE(IfW_HAWCWind_InitOutputType) :: HAWC_InitOutData !< initialization output info - - TYPE(IfW_BladedFFWind_InitInputType) :: BladedFF_InitData !< initialization info - TYPE(IfW_BladedFFWind_InitOutputType) :: BladedFF_InitOutData !< initialization output info - - TYPE(IfW_UserWind_InitInputType) :: User_InitData !< initialization info - TYPE(IfW_UserWind_InitOutputType) :: User_InitOutData !< initialization info - - TYPE(IfW_4Dext_InitOutputType) :: FDext_InitOutData !< initialization info - - TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future -!!! TYPE(CTBladed_Backgr) :: BackGrndValues - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat - CHARACTER(ErrMsgLen) :: TmpErrMsg !< temporary error message - CHARACTER(1024) :: PriPath - - ! Local Variables - INTEGER(IntKi) :: I, j !< Generic counter - INTEGER(IntKi) :: Lin_indx !< Generic counter - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file - CHARACTER(256) :: SumFileName !< Name of the summary file - CHARACTER(256) :: EchoFileName !< Name of the summary file - CHARACTER(1), PARAMETER :: UVW(3) = (/'U','V','W'/) - CHARACTER(1), PARAMETER :: XYZ(3) = (/'X','Y','Z'/) - - !---------------------------------------------------------------------------------------------- - ! Initialize variables and check to see if this module has been initialized before. - !---------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - SumFileUnit = -1_IntKi ! set at beginning in case of error - - ! Set a few variables. +SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & + y, m, TimeInterval, InitOutData, ErrStat, ErrMsg ) + + ! Initialization data and guesses + TYPE(InflowWind_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization + TYPE(InflowWind_InputType), INTENT( OUT) :: InputGuess !< An initial guess for the input; the input mesh must be defined + TYPE(InflowWind_ParameterType), INTENT( OUT) :: p !< Parameters + TYPE(InflowWind_ContinuousStateType), INTENT( OUT) :: ContStates !< Initial continuous states + TYPE(InflowWind_DiscreteStateType), INTENT( OUT) :: DiscStates !< Initial discrete states + TYPE(InflowWind_ConstraintStateType), INTENT( OUT) :: ConstrStateGuess !< Initial guess of the constraint states + TYPE(InflowWind_OtherStateType), INTENT( OUT) :: OtherStates !< Initial other/optimization states + TYPE(InflowWind_OutputType), INTENT( OUT) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) + TYPE(InflowWind_MiscVarType), INTENT( OUT) :: m !< Misc variables for optimization (not copied in glue code) + REAL(DbKi), INTENT(IN ) :: TimeInterval !< Coupling time interval in seconds: InflowWind does not change this. + TYPE(InflowWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output data -- Names, units, and version info. + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! Local variables + CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Init" + + TYPE(InflowWind_InputFile) :: InputFileData !< Data from input file + + Type(Steady_InitInputType) :: Steady_InitInput + Type(Uniform_InitInputType) :: Uniform_InitInput + Type(TurbSim_InitInputType) :: TurbSim_InitInput + Type(Bladed_InitInputType) :: Bladed_InitInput + Type(Bladed_InitOutputType) :: Bladed_InitOutput + Type(HAWC_InitInputType) :: HAWC_InitInput + Type(User_InitInputType) :: User_InitInput + Type(Grid4D_InitInputType) :: Grid4D_InitInput + Type(Points_InitInputType) :: Points_InitInput + + Type(WindFileDat) :: FileDat + - p%DT = TimeInterval ! InflowWind does not require a specific time interval, so this is never changed. - CALL NWTC_Init() - CALL DispNVD( IfW_Ver ) + ! TYPE(InflowWind_IO_InitInputType) :: FlowField_InitData !< initialization info + ! TYPE(InflowWind_IO_InitOutputType) :: FlowField_InitOutData !< initialization output info + TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: I, j !< Generic counter + INTEGER(IntKi) :: Lin_indx !< Generic counter + INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file + CHARACTER(256) :: SumFileName !< Name of the summary file + CHARACTER(256) :: EchoFileName !< Name of the summary file + CHARACTER(1), PARAMETER :: UVW(3) = (/'U','V','W'/) + CHARACTER(1), PARAMETER :: XYZ(3) = (/'X','Y','Z'/) + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg !< temporary error message - !---------------------------------------------------------------------------------------------- - ! Read the input file - !---------------------------------------------------------------------------------------------- + !---------------------------------------------------------------------------------------------- + ! Initialize variables and check to see if this module has been initialized before. + !---------------------------------------------------------------------------------------------- + ErrStat = ErrID_None + ErrMsg = "" + SumFileUnit = -1_IntKi ! set at beginning in case of error - ! Set the names of the files based on the inputfilename - p%RootFileName = InitInp%RootName - IF (LEN_TRIM(p%RootFileName) == 0) CALL GetRoot( InitInp%InputFileName, p%RootFileName ) - EchoFileName = TRIM(p%RootFileName)//".ech" - SumFileName = TRIM(p%RootFileName)//".sum" + ! Set a few variables. + p%DT = TimeInterval ! InflowWind does not require a specific time interval, so this is never changed. + CALL NWTC_Init() + CALL DispNVD( IfW_Ver ) + !---------------------------------------------------------------------------------------------- + ! Read the input file + !---------------------------------------------------------------------------------------------- + ! Set the names of the files based on the inputfilename + p%RootFileName = InitInp%RootName + IF (LEN_TRIM(p%RootFileName) == 0) CALL GetRoot( InitInp%InputFileName, p%RootFileName ) + EchoFileName = TRIM(p%RootFileName)//".ech" + SumFileName = TRIM(p%RootFileName)//".sum" - ! Parse all the InflowWind related input files and populate the *_InitDataType derived types - CALL GetPath( InitInp%InputFileName, PriPath ) - IF ( InitInp%UseInputFile ) THEN - CALL ProcessComFile( InitInp%InputFileName, InFileInfo, TmpErrStat, TmpErrMsg ) - ! For diagnostic purposes, the following can be used to display the contents - ! of the InFileInfo data structure. - ! call Print_FileInfo_Struct( CU, InFileInfo ) ! CU is the screen -- different number on different systems. - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - - ELSE - CALL NWTC_Library_CopyFileInfoType( InitInp%PassedFileData, InFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - - ENDIF - CALL InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, InitInp%InputFileName, EchoFileName, InitInp%FixedWindFileRootName, InitInp%TurbineID, TmpErrStat, TmpErrMsg ) + ! Parse all the InflowWind related input files and populate the *_InitDataType derived types + CALL GetPath( InitInp%InputFileName, PriPath ) + IF ( InitInp%UseInputFile ) THEN + CALL ProcessComFile( InitInp%InputFileName, InFileInfo, TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() - CALL InflowWind_DestroyInputFile( InputFileData, TmpErrStat, TmpErrMsg ) RETURN - ENDIF - ! let's tell InflowWind if an external module (e.g., FAST.Farm) is going to set the velocity grids. - - IF ( InitInp%Use4Dext) then - InputFileData%WindType = FDext_WindNumber - InputFileData%PropagationDir = 0.0_ReKi ! wind is in XYZ coordinates (already rotated if necessary), so don't rotate it again - END IF + ENDIF + ELSE + CALL NWTC_Library_CopyFileInfoType( InitInp%PassedFileData, InFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + ENDIF + + CALL InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, InitInp%InputFileName, EchoFileName, & + InitInp%FixedWindFileRootName, InitInp%TurbineID, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + + ! If wind is Grid4D from FAST.Farm, set input file values + IF (InitInp%Use4Dext) then + InputFileData%WindType = FDext_WindNumber + InputFileData%PropagationDir = 0.0_ReKi ! wind is in XYZ coordinates (already rotated if necessary), so don't rotate it again + InputFileData%VFlowAngle = 0.0_ReKi + InputFileData%VelInterpCubic = .false. + END IF ! initialize sensor data: p%lidar%NumBeam = InputFileData%NumBeam @@ -285,500 +259,370 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, SumFileUnit = -1_IntKi ! So that we don't try to write to something. Used as indicator in submodules. ENDIF + ! Allocate the array for passing points + CALL AllocAry( InputGuess%PositionXYZ, 3, InitInp%NumWindPoints, "Array of positions at which to find wind velocities", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + InputGuess%PositionXYZ = 0.0_ReKi + InputGuess%HubPosition = 0.0_ReKi + CALL Eye(InputGuess%HubOrientation,TmpErrStat,TmpErrMsg) + + ! Allocate the array for passing velocities out + CALL AllocAry( y%VelocityUVW, 3, InitInp%NumWindPoints, "Array of wind velocities returned by InflowWind", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF (ErrStat>= AbortErrLev) THEN + CALL Cleanup() + RETURN + ENDIF + y%VelocityUVW = 0.0_ReKi - ! Allocate the arrays for passing points in and velocities out - CALL AllocAry( InputGuess%PositionXYZ, 3, InitInp%NumWindPoints, "Array of positions at which to find wind velocities", TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( y%VelocityUVW, 3, InitInp%NumWindPoints, "Array of wind velocities returned by InflowWind", TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - InputGuess%PositionXYZ = 0.0_ReKi - InputGuess%HubPosition = 0.0_ReKi - CALL Eye(InputGuess%HubOrientation,TmpErrStat,TmpErrMsg) - - y%VelocityUVW = 0.0_ReKi - - - !----------------------------------------------------------------- - ! Initialize the submodules based on the WindType - !----------------------------------------------------------------- + ! If requested, allocate the array for passing accelerations out + IF ( InitInp%OutputAccel ) THEN + CALL AllocAry( y%AccelUVW, 3, InitInp%NumWindPoints, "Array of wind accelerations returned by InflowWind", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF (ErrStat>= AbortErrLev) THEN + CALL Cleanup() + RETURN + ENDIF + y%AccelUVW = 0.0_ReKi + ENDIF + !---------------------------------------------------------------------------- + ! Set flow field input data based on wind type + !---------------------------------------------------------------------------- + + InitOutData%WindFileInfo%MWS = HUGE(InitOutData%WindFileInfo%MWS) + + select case(InputFileData%WindType) + + case (Steady_WindNumber) + + Steady_InitInput%HWindSpeed = InputFileData%Steady_HWindSpeed + Steady_InitInput%RefHt = InputFileData%Steady_RefHt + Steady_InitInput%PLExp = InputFileData%Steady_PLexp + + p%FlowField%FieldType = Uniform_FieldType + call IfW_SteadyWind_Init(Steady_InitInput, SumFileUnit, p%FlowField%Uniform, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + case (Uniform_WindNumber) + + Uniform_InitInput%WindFileName = InputFileData%Uniform_FileName + Uniform_InitInput%RefHt = InputFileData%Uniform_RefHt + Uniform_InitInput%RefLength = InputFileData%Uniform_RefLength + Uniform_InitInput%PropagationDir = InputFileData%PropagationDir + Uniform_InitInput%UseInputFile = InitInp%WindType2UseInputFile + Uniform_InitInput%PassedFileData = InitInp%WindType2Data + + p%FlowField%FieldType = Uniform_FieldType + call IfW_UniformWind_Init(Uniform_InitInput, SumFileUnit, p%FlowField%Uniform, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + case (TSFF_WindNumber) + + TurbSim_InitInput%WindFileName = InputFileData%TSFF_FileName + + p%FlowField%FieldType = Grid3D_FieldType + call IfW_TurbSim_Init(TurbSim_InitInput, SumFileUnit, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + case (BladedFF_WindNumber) + + Bladed_InitInput%TurbineID = InitInp%TurbineID + IF ( InitInp%FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data + IF ( InitInp%TurbineID == 0 ) THEN ! .TRUE. for the FAST.Farm low-resolution domain + InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'Low' + ELSE ! FAST.Farm high-resolution domain(s) + InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) + ENDIF + ENDIF + Bladed_InitInput%WindType = BladedFF_WindNumber + Bladed_InitInput%WindFileName = TRIM(InputFileData%BladedFF_FileName)//'.wnd' + Bladed_InitInput%TowerFileExist = InputFileData%BladedFF_TowerFile + Bladed_InitInput%NativeBladedFmt = .false. + + p%FlowField%FieldType = Grid3D_FieldType + call IfW_Bladed_Init(Bladed_InitInput, SumFileUnit, Bladed_InitOutput, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif - InitOutData%WindFileInfo%MWS = HUGE(InitOutData%WindFileInfo%MWS) - - SELECT CASE ( InputFileData%WindType ) - - - CASE ( Steady_WindNumber ) - - ! This is a simplified case of the Uniform wind. For this, we set the OtherStates data manually and don't - ! call UniformWind_Init. We do however call it for the calculations. - - - ! Set InitInp information -- It isn't necessary to do this since that information is only used in the Uniform_Init routine, which is not called. - - ! Set the Otherstates information - p%UniformWind%NumDataLines = 1_IntKi - - CALL AllocAry( p%UniformWind%Tdata, p%UniformWind%NumDataLines, 'Uniform wind time', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%V, p%UniformWind%NumDataLines, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%Delta, p%UniformWind%NumDataLines, 'Uniform wind direction', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%Upflow, p%UniformWind%NumDataLines, 'Uniform wind upflow angle', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VZ, p%UniformWind%NumDataLines, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%HShr, p%UniformWind%NumDataLines, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VShr, p%UniformWind%NumDataLines, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VLinShr, p%UniformWind%NumDataLines, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VGust, p%UniformWind%NumDataLines, 'Uniform gust velocity', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - ! Set the array information - - p%UniformWind%Tdata( :) = 0.0_ReKi - p%UniformWind%V( :) = InputFileData%Steady_HWindSpeed - p%UniformWind%Delta( :) = 0.0_ReKi - p%UniformWind%Upflow( :) = 0.0_ReKi - p%UniformWind%VZ( :) = 0.0_ReKi - p%UniformWind%HShr( :) = 0.0_ReKi - p%UniformWind%VShr( :) = InputFileData%Steady_PLexp - p%UniformWind%VLinShr(:) = 0.0_ReKi - p%UniformWind%VGust( :) = 0.0_ReKi - - - ! Now we have in effect initialized the IfW_UniformWind module, so set the parameters - p%UniformWind%RefLength = max(1.0_ReKi, InputFileData%Uniform_RefLength) ! This is not used since no shear gusts are used. Set to 1.0 so calculations don't bomb. - p%UniformWind%RefHt = InputFileData%Steady_RefHt - m%UniformWind%TimeIndex = 1_IntKi - - p%ReferenceHeight = p%UniformWind%RefHt - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = "" - InitOutData%WindFileInfo%WindType = Steady_WindNumber - InitOutData%WindFileInfo%RefHt = InputFileData%Steady_RefHt - InitOutData%WindFileInfo%RefHt_Set = .FALSE. ! The wind file does not set this - InitOutData%WindFileInfo%DT = 0.0_ReKi - InitOutData%WindFileInfo%NumTSteps = 1_IntKi - InitOutData%WindFileInfo%ConstantDT = .FALSE. - InitOutData%WindFileInfo%TRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%TRange_Limited = .FALSE. ! This is constant - InitOutData%WindFileInfo%YRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%YRange_Limited = .FALSE. ! Hard boundaries not enforced in y-direction - InitOutData%WindFileInfo%ZRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%ZRange_Limited = .FALSE. ! Hard boundaries not enforced in z-direction - InitOutData%WindFileInfo%BinaryFormat = 0_IntKi - InitOutData%WindFileInfo%IsBinary = .FALSE. - InitOutData%WindFileInfo%TI = 0.0_ReKi - InitOutData%WindFileInfo%TI_listed = .FALSE. - InitOutData%WindFileInfo%MWS = InputFileData%Steady_HWindSpeed - - ! Write summary file information - IF ( SumFileUnit > 0 ) THEN - WRITE(SumFileUnit,'(A)',IOSTAT=TmpErrStat) - WRITE(SumFileUnit,'(A80)',IOSTAT=TmpErrStat) 'Steady wind -- Constant wind profile for entire simulation. No windfile read in.' - WRITE(SumFileUnit,'(A40,G12.4)',IOSTAT=TmpErrStat) ' Reference height: ',p%UniformWind%RefHt - WRITE(SumFileUnit,'(A40,G12.4)',IOSTAT=TmpErrStat) ' Horizontal velocity: ',p%UniformWind%V - WRITE(SumFileUnit,'(A40,G12.4)',IOSTAT=TmpErrStat) ' Vertical sheer power law exponent: ',p%UniformWind%VShr - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - CALL Cleanup - RETURN - ENDIF - ENDIF - - - CASE ( Uniform_WindNumber ) - - ! Set InitInp information - Uniform_InitData%ReferenceHeight = InputFileData%Uniform_RefHt - Uniform_InitData%RefLength = InputFileData%Uniform_RefLength - Uniform_InitData%WindFileName = InputFileData%Uniform_FileName - Uniform_InitData%SumFileUnit = SumFileUnit - - Uniform_InitData%UseInputFile = InitInp%WindType2UseInputFile - Uniform_InitData%PassedFileData = InitInp%WindType2Data - - ! Initialize the UniformWind module - CALL IfW_UniformWind_Init(Uniform_InitData, p%UniformWind, & - m%UniformWind, Uniform_InitOutData, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, ' IfW_Init' ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - if (InitInp%Linearize) then - ! we'd have to redo the math to get this correct, so for now we are disabling upflow for linearization: - if (any(p%UniformWind%upflow /= 0.0_ReKi) ) then - call SetErrStat(ErrID_Fatal, 'Upflow in uniform wind files must be 0 for linearization analysis in InflowWind.', ErrStat, ErrMsg, RoutineName) - CALL Cleanup() - return - end if - end if - - - p%ReferenceHeight = p%UniformWind%RefHt - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = InputFileData%Uniform_FileName - InitOutData%WindFileInfo%WindType = Uniform_WindNumber - InitOutData%WindFileInfo%RefHt = p%UniformWind%RefHt - InitOutData%WindFileInfo%RefHt_Set = .FALSE. ! The wind file does not set this - InitOutData%WindFileInfo%DT = Uniform_InitOutData%WindFileDT - InitOutData%WindFileInfo%NumTSteps = Uniform_InitOutData%WindFileNumTSteps - InitOutData%WindFileInfo%ConstantDT = Uniform_InitOutData%WindFileConstantDT - InitOutData%WindFileInfo%TRange = Uniform_InitOutData%WindFileTRange - InitOutData%WindFileInfo%TRange_Limited = .FALSE. ! UniformWind sets to limit of file if outside time bounds - InitOutData%WindFileInfo%YRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%YRange_Limited = .FALSE. ! Hard boundaries not enforced in y-direction - InitOutData%WindFileInfo%ZRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%ZRange_Limited = .FALSE. ! Hard boundaries not enforced in z-direction - InitOutData%WindFileInfo%BinaryFormat = 0_IntKi - InitOutData%WindFileInfo%IsBinary = .FALSE. - InitOutData%WindFileInfo%TI = 0.0_ReKi - InitOutData%WindFileInfo%TI_listed = .FALSE. - - if (p%UniformWind%NumDataLines == 1) then - InitOutData%WindFileInfo%MWS = p%UniformWind%V(1) - else - InitOutData%WindFileInfo%MWS = 0.0_ReKi - do i=2,p%UniformWind%NumDataLines - InitOutData%WindFileInfo%MWS = InitOutData%WindFileInfo%MWS + & - 0.5_ReKi*(p%UniformWind%V(i)+p%UniformWind%V(i-1))*& - (p%UniformWind%Tdata(i)-p%UniformWind%Tdata(i-1)) - end do - InitOutData%WindFileInfo%MWS = InitOutData%WindFileInfo%MWS / & - ( p%UniformWind%Tdata(p%UniformWind%NumDataLines) - p%UniformWind%Tdata(1) ) - end if - - - ! Check if the fist data point from the file is not along the X-axis while applying the windfield rotation - IF ( ( .NOT. EqualRealNos (p%UniformWind%Delta(1), 0.0_ReKi) ) .AND. & - ( .NOT. EqualRealNos (p%PropagationDir, 0.0_ReKi) ) ) THEN - CALL SetErrStat( ErrID_Warn,' Possible double rotation of wind field! Uniform wind file starts with a wind direction of '// & - TRIM(Num2LStr(p%UniformWind%Delta(1)*R2D))// & - ' degrees and the InflowWind input file specifies a PropagationDir of '// & - TRIM(Num2LStr(p%PropagationDir*R2D))//' degrees.', & - ErrStat,ErrMsg,RoutineName ) - ENDIF - - - - CASE ( TSFF_WindNumber ) - - ! Set InitInp information - TSFF_InitData%WindFileName = InputFileData%TSFF_FileName - TSFF_InitData%SumFileUnit = SumFileUnit - - ! Initialize the TSFFWind module - CALL IfW_TSFFWind_Init(TSFF_InitData, p%TSFFWind, & - m%TSFFWind, TSFF_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrSTat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = InputFileData%TSFF_FileName - - CALL SetFFInitOutData(p%TSFFWind%FF) - p%ReferenceHeight = InitOutData%WindFileInfo%RefHt - - - CASE ( BladedFF_WindNumber, BladedFF_Shr_WindNumber ) - - ! Set InitInp information - BladedFF_InitData%SumFileUnit = SumFileUnit - BladedFF_InitData%FixedWindFileRootName = InitInp%FixedWindFileRootName - BladedFF_InitData%TurbineID = InitInp%TurbineID - - if (InputFileData%WindType /= BladedFF_Shr_WindNumber) then - IF ( InitInp%FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data - IF ( InitInp%TurbineID == 0 ) THEN ! .TRUE. for the FAST.Farm low-resolution domain - InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'Low' - ELSE ! FAST.Farm high-resolution domain(s) - InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) - ENDIF - ENDIF - - BladedFF_InitData%WindFileName = TRIM(InputFileData%BladedFF_FileName)//'.wnd' - BladedFF_InitData%TowerFileExist = InputFileData%BladedFF_TowerFile - BladedFF_InitData%NativeBladedFmt = .false. - else - BladedFF_InitData%WindFileName = InputFileData%BladedFF_FileName - BladedFF_InitData%TowerFileExist = .false. - BladedFF_InitData%NativeBladedFmt = .true. - !call IfW_FFWind_CopyInitInput( InputFileData%FF, BladedFF_InitData%FF, MESH_NEWCOPY, TmpErrStat, TmpErrMsg) - end if - - ! Initialize the BladedFFWind module - CALL IfW_BladedFFWind_Init(BladedFF_InitData, p%BladedFFWind, m%BladedFFWind, & - BladedFF_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrSTat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = InputFileData%BladedFF_FileName - - CALL SetFFInitOutData(p%BladedFFWind%FF) - - InitOutData%WindFileInfo%TI = BladedFF_InitOutData%TI - InitOutData%WindFileInfo%TI_listed = .TRUE. ! This must be listed in the file someplace - - if (InputFileData%WindType == BladedFF_Shr_WindNumber) then - InputFileData%WindType = BladedFF_WindNumber - ! this overwrites the values of PropagationDir and VFlowAngle with values from the native Bladed file - InputFileData%PropagationDir = BladedFF_InitOutData%PropagationDir - InputFileData%VFlowAngle = BladedFF_InitOutData%VFlowAngle - end if - p%ReferenceHeight = InitOutData%WindFileInfo%RefHt - - - CASE ( HAWC_WindNumber ) - - ! Set InitInp information - HAWC_InitData%WindFileName(1) = InputFileData%HAWC_FileName_u - HAWC_InitData%WindFileName(2) = InputFileData%HAWC_FileName_v - HAWC_InitData%WindFileName(3) = InputFileData%HAWC_FileName_w - HAWC_InitData%SumFileUnit = SumFileUnit - HAWC_InitData%nx = InputFileData%HAWC_nx - HAWC_InitData%ny = InputFileData%HAWC_ny - HAWC_InitData%nz = InputFileData%HAWC_nz - - HAWC_InitData%dx = InputFileData%HAWC_dx - HAWC_InitData%dy = InputFileData%HAWC_dy - HAWC_InitData%dz = InputFileData%HAWC_dz - - call IfW_FFWind_CopyInitInput( InputFileData%FF, HAWC_InitData%FF, MESH_NEWCOPY, TmpErrStat, TmpErrMsg) - - - ! Initialize the HAWCWind module - CALL IfW_HAWCWind_Init(HAWC_InitData, p%HAWCWind, m%HAWCWind, & - TimeInterval, HAWC_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - - ! Store wind file metadata - CALL SetFFInitOutData(p%HAWCWind%FF) - InitOutData%WindFileInfo%FileName = InputFileData%HAWC_FileName_u - p%ReferenceHeight = InitOutData%WindFileInfo%RefHt - - - CASE (User_WindNumber) - - ! Initialize the UserWind module - CALL IfW_UserWind_Init(User_InitData, p%UserWind, m%UserWind, & - TimeInterval, User_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - p%ReferenceHeight = InputFileData%Steady_RefHt ! FIXME!!!! - - CASE ( FDext_WindNumber ) - - ! Initialize the UserWind module - CALL IfW_4Dext_Init(InitInp%FDext, p%FDext, m%FDext, TimeInterval, FDext_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - p%ReferenceHeight = p%FDext%pZero(3) + (p%FDext%n(3)/2) * p%FDext%delta(3) ! should be middle of grid, right???? FIXME - - CASE DEFAULT ! keep this check to make sure that all new wind types have been accounted for - CALL SetErrStat(ErrID_Fatal,' Undefined wind type.',ErrStat,ErrMsg,'InflowWind_Init()') - - - - - END SELECT - - - !IF ( InputFileData%CTTS_Flag ) THEN - ! ! Initialize the CTTS_Wind module - !ENDIF - + case (BladedFF_Shr_WindNumber) + + Bladed_InitInput%WindType = BladedFF_Shr_WindNumber + Bladed_InitInput%TurbineID = InitInp%TurbineID + Bladed_InitInput%WindFileName = InputFileData%BladedFF_FileName + Bladed_InitInput%TowerFileExist = .false. + Bladed_InitInput%NativeBladedFmt = .true. + + p%FlowField%FieldType = Grid3D_FieldType + call IfW_Bladed_Init(Bladed_InitInput, SumFileUnit, Bladed_InitOutput, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + ! Overwrite the values of PropagationDir and VFlowAngle with values from the native Bladed file + InputFileData%PropagationDir = Bladed_InitOutput%PropagationDir + InputFileData%VFlowAngle = Bladed_InitOutput%VFlowAngle + + case (HAWC_WindNumber) + + HAWC_InitInput%WindFileName(1) = InputFileData%HAWC_FileName_u + HAWC_InitInput%WindFileName(2) = InputFileData%HAWC_FileName_v + HAWC_InitInput%WindFileName(3) = InputFileData%HAWC_FileName_w + HAWC_InitInput%nx = InputFileData%HAWC_nx + HAWC_InitInput%ny = InputFileData%HAWC_ny + HAWC_InitInput%nz = InputFileData%HAWC_nz + HAWC_InitInput%dx = InputFileData%HAWC_dx + HAWC_InitInput%dy = InputFileData%HAWC_dy + HAWC_InitInput%dz = InputFileData%HAWC_dz + HAWC_InitInput%G3D%RefHt = InputFileData%FF%RefHt + HAWC_InitInput%G3D%ScaleMethod = InputFileData%FF%ScaleMethod + HAWC_InitInput%G3D%SF = InputFileData%FF%SF + HAWC_InitInput%G3D%SigmaF = InputFileData%FF%SigmaF + HAWC_InitInput%G3D%URef = InputFileData%FF%URef + HAWC_InitInput%G3D%WindProfileType = InputFileData%FF%WindProfileType + HAWC_InitInput%G3D%PLExp = InputFileData%FF%PLExp + HAWC_InitInput%G3D%Z0 = InputFileData%FF%Z0 + HAWC_InitInput%G3D%XOffset = InputFileData%FF%XOffset + + p%FlowField%FieldType = Grid3D_FieldType + call IfW_HAWC_Init(HAWC_InitInput, SumFileUnit, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + case (User_WindNumber) + + p%FlowField%FieldType = User_FieldType + call IfW_User_Init(User_InitInput, SumFileUnit, p%FlowField%User, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + case (FDext_WindNumber) + + p%FlowField%FieldType = Grid4D_FieldType + call IfW_Grid4D_Init(InitInp%FDext, p%FlowField%Grid4D, TmpErrStat, TmpErrMsg) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + case (Point_WindNumber) + + p%FlowField%FieldType = Point_FieldType + Points_InitInput%NumWindPoints = InitInp%NumWindPoints + call IfW_Points_Init(Points_InitInput, p%FlowField%Points, TmpErrStat, TmpErrMsg) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + case default + call SetErrStat(ErrID_Fatal, ' Undefined wind type.', ErrStat, ErrMsg, RoutineName) + return + end select + + !---------------------------------------------------------------------------- + ! Initialization by Field Type + !---------------------------------------------------------------------------- + + ! Reset flag indicating that acceleration field is valid + p%FlowField%AccFieldValid = .false. + + ! Copy flag for enabling cubic velocity interpolation + p%FlowField%VelInterpCubic = InputFileData%VelInterpCubic + + ! If cubic velocity interpolation requested and linearization is performed, + ! display message that cubic interpolation is incompatible with linearization + ! and will be disabled + if (p%FlowField%VelInterpCubic .and. InitInp%Linearize) then + call WrScr("InflowWind: Cubic interpolation of wind velocity is disabled for linearization") + p%FlowField%VelInterpCubic = .false. + end if + + ! Set box exceed flag and index + p%FlowField%Grid3D%BoxExceedAllowF = InitInp%BoxExceedAllowF + p%FlowField%Grid3D%BoxExceedAllowIdx = huge(1_IntKi) + if (InitInp%BoxExceedAllowF .and. (InitInp%BoxExceedAllowIdx <= InitInp%NumWindPoints)) then + p%FlowField%Grid3D%BoxExceedAllowIdx = InitInp%BoxExceedAllowIdx + end if + + ! Select based on field type + select case (p%FlowField%FieldType) + case (Uniform_FieldType) + + if (InitInp%OutputAccel .or. p%FlowField%VelInterpCubic) then + call IfW_UniformField_CalcAccel(p%FlowField%Uniform, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + p%FlowField%AccFieldValid = .true. + end if - !............................................ - ! Set the p and OtherStates for InflowWind using the input file information. - ! (set this after initializing modules so that we can use propagationDir and VFlowAng from native-Bladed files - !............................................ + case (Grid3D_FieldType) - CALL InflowWind_SetParameters( InitInp, InputFileData, p, m, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF + ! Calculate acceleration + if (InitInp%OutputAccel .or. p%FlowField%VelInterpCubic) then + call IfW_Grid3DField_CalcAccel(p%FlowField%Grid3D, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + p%FlowField%AccFieldValid = .true. + end if - + ! Calculate field average if box is allowed to be exceeded + if (p%FlowField%Grid3D%BoxExceedAllowF .and. p%FlowField%Grid3D%BoxExceedAllowIdx > 0) then + call IfW_Grid3DField_CalcVelAvgProfile(p%FlowField%Grid3D, p%FlowField%AccFieldValid, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + end if -!!! !---------------------------------------------------------------------------------------------- -!!! ! Check for coherent turbulence file (KH superimposed on a background wind file) -!!! ! Initialize the CTWind module and initialize the module of the other wind type. -!!! !---------------------------------------------------------------------------------------------- -!!! -!!! IF ( p%WindType == CTP_WindNumber ) THEN -!!! -!!!!FIXME: remove this error message when we add CTP_Wind in -!!! CALL SetErrStat( ErrID_Fatal, ' InflowWind cannot currently handle the CTP_Wind type.', ErrStat, ErrMsg, ' IfW_Init' ) -!!! RETURN -!!! -!!! CALL CTTS_Init(UnWind, p%WindFileName, BackGrndValues, ErrStat, ErrMsg) -!!! IF (ErrStat /= 0) THEN -!!! p%WindType = Undef_Wind -!!! ErrStat = ErrID_Fatal -!!! RETURN -!!! END IF -!!! -!!! !FIXME: check this -!!! p%WindFileName = BackGrndValues%WindFile -!!! p%WindType = BackGrndValues%WindType -!!! ! CTTS_Flag = BackGrndValues%CoherentStr -!!! p%CTTS_Flag = BackGrndValues%CoherentStr ! This might be wrong -!!! -!!! ELSE -!!! -!!! p%CTTS_Flag = .FALSE. -!!! -!!! END IF -!!! + case default + if (InitInp%OutputAccel) then + call SetErrStat(ErrID_Fatal, "Acceleration not implemented for field type "// & + num2LStr(p%FlowField%FieldType), ErrStat, ErrMsg, RoutineName) + return + end if + if (p%FlowField%VelInterpCubic) then + call WrScr(' Cubic velocity interpolation not implemented for WindType '// & + num2LStr(InputFileData%WindType)) + p%FlowField%VelInterpCubic = .false. + end if + end select + + !---------------------------------------------------------------------------- + ! Set the p and OtherStates for InflowWind using the input file information. + ! (set this after initializing modules so that we can use PropagationDir + ! and VFlowAng from native-Bladed files + !---------------------------------------------------------------------------- + + CALL InflowWind_SetParameters( InitInp, InputFileData, p, m, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + + ! Allocate arrays for the WriteOutput + CALL AllocAry( y%WriteOutput, p%NumOuts, 'WriteOutput', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + y%WriteOutput = 0.0_ReKi + + CALL AllocAry( InitOutData%WriteOutputHdr, p%NumOuts, 'WriteOutputHdr', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + CALL AllocAry( InitOutData%WriteOutputUnt, p%NumOuts, 'WriteOutputUnt', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + InitOutData%WriteOutputHdr = p%OutParam(1:p%NumOuts)%Name + InitOutData%WriteOutputUnt = p%OutParam(1:p%NumOuts)%Units + !---------------------------------------------------------------------------- + ! Linearization + !---------------------------------------------------------------------------- - ! Allocate arrays for the WriteOutput + ! allocate and fill variables for linearization + if (InitInp%Linearize) then + + ! If field is uniform and there is any nonzero upflow, return error + ! Math needs work before this can be implemented + if (p%FlowField%FieldType == Uniform_FieldType) then + if (any(p%FlowField%Uniform%AngleV /= 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'Upflow in uniform wind files must be 0 for linearization analysis in InflowWind.', ErrStat, ErrMsg, RoutineName) + call Cleanup() + return + end if + end if - CALL AllocAry( y%WriteOutput, p%NumOuts, 'WriteOutput', TmpErrStat, TmpErrMsg ) + ! also need to add InputGuess%HubOrientation to the u%Linear items + CALL AllocAry(InitOutData%LinNames_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'LinNames_u', TmpErrStat, TmpErrMsg) ! add hub position, orientation(3) + extended inputs CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - y%WriteOutput = 0.0_ReKi - - CALL AllocAry( InitOutData%WriteOutputHdr, p%NumOuts, 'WriteOutputHdr', TmpErrStat, TmpErrMsg ) + CALL AllocAry(InitOutData%RotFrame_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'RotFrame_u', TmpErrStat, TmpErrMsg) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( InitOutData%WriteOutputUnt, p%NumOuts, 'WriteOutputUnt', TmpErrStat, TmpErrMsg ) + CALL AllocAry(InitOutData%IsLoad_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'IsLoad_u', TmpErrStat, TmpErrMsg) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - - InitOutData%WriteOutputHdr = p%OutParam(1:p%NumOuts)%Name - InitOutData%WriteOutputUnt = p%OutParam(1:p%NumOuts)%Units - - - ! allocate and fill variables for linearization: - if (InitInp%Linearize) then - ! also need to add InputGuess%HubOrientation to the u%Linear items - CALL AllocAry(InitOutData%LinNames_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'LinNames_u', TmpErrStat, TmpErrMsg) ! add hub position, orientation(3) + extended inputs - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%RotFrame_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'RotFrame_u', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%IsLoad_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'IsLoad_u', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%LinNames_y, InitInp%NumWindPoints*3 + size(y%DiskVel) + p%NumOuts, 'LinNames_y', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%RotFrame_y, InitInp%NumWindPoints*3 + size(y%DiskVel) + p%NumOuts, 'RotFrame_y', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - do i=1,InitInp%NumWindPoints - do j=1,3 - InitOutData%LinNames_y((i-1)*3+j) = UVW(j)//'-component inflow velocity at node '//trim(num2lstr(i))//', m/s' - InitOutData%LinNames_u((i-1)*3+j) = XYZ(j)//'-component position of node '//trim(num2lstr(i))//', m' - end do - end do - - ! hub position - Lin_Indx = InitInp%NumWindPoints*3 - do j=1,3 - InitOutData%LinNames_y(Lin_Indx+j) = 'average '//UVW(j)//'-component rotor-disk velocity, m/s' - InitOutData%LinNames_u(Lin_Indx+j) = XYZ(j)//'-component position of moving hub, m' - end do - Lin_Indx = Lin_Indx + 3 - - ! hub orientation angles + CALL AllocAry(InitOutData%LinNames_y, InitInp%NumWindPoints*3 + size(y%DiskVel) + p%NumOuts, 'LinNames_y', TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + CALL AllocAry(InitOutData%RotFrame_y, InitInp%NumWindPoints*3 + size(y%DiskVel) + p%NumOuts, 'RotFrame_y', TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev) THEN + CALL Cleanup() + RETURN + ENDIF + + do i=1,InitInp%NumWindPoints do j=1,3 - InitOutData%LinNames_u(Lin_Indx+j) = XYZ(j)//' orientation of moving hub, rad' + InitOutData%LinNames_y((i-1)*3+j) = UVW(j)//'-component inflow velocity at node '//trim(num2lstr(i))//', m/s' + InitOutData%LinNames_u((i-1)*3+j) = XYZ(j)//'-component position of node '//trim(num2lstr(i))//', m' end do - Lin_Indx = Lin_Indx + 3 - - - InitOutData%LinNames_u(Lin_Indx + 1) = 'Extended input: horizontal wind speed (steady/uniform wind), m/s' - InitOutData%LinNames_u(Lin_Indx + 2) = 'Extended input: vertical power-law shear exponent, -' - InitOutData%LinNames_u(Lin_Indx + 3) = 'Extended input: propagation direction, rad' - - do i=1,p%NumOuts - InitOutData%LinNames_y(i+3*InitInp%NumWindPoints+size(y%DiskVel)) = trim(p%OutParam(i)%Name)//', '//p%OutParam(i)%Units - end do - - ! IfW inputs and outputs are in the global, not rotating frame - InitOutData%RotFrame_u = .false. - InitOutData%RotFrame_y = .false. - - InitOutData%IsLoad_u = .false. ! IfW inputs for linearization are not loads - - !InitOutData%PropagationDir = -p%PropagationDir - !InitOutData%RefHt = p%UniformWind%RefHt - !InitOutData%RefLength = p%UniformWind%RefLength - - end if - - - ! Set the version information in InitOutData - InitOutData%Ver = IfW_Ver - + end do - CALL CleanUp() + ! hub position + Lin_Indx = InitInp%NumWindPoints*3 + do j=1,3 + InitOutData%LinNames_y(Lin_Indx+j) = 'average '//UVW(j)//'-component rotor-disk velocity, m/s' + InitOutData%LinNames_u(Lin_Indx+j) = XYZ(j)//'-component position of moving hub, m' + end do + Lin_Indx = Lin_Indx + 3 + + ! hub orientation angles + do j=1,3 + InitOutData%LinNames_u(Lin_Indx+j) = XYZ(j)//' orientation of moving hub, rad' + end do + Lin_Indx = Lin_Indx + 3 + + InitOutData%LinNames_u(Lin_Indx + 1) = 'Extended input: horizontal wind speed (steady/uniform wind), m/s' + InitOutData%LinNames_u(Lin_Indx + 2) = 'Extended input: vertical power-law shear exponent, -' + InitOutData%LinNames_u(Lin_Indx + 3) = 'Extended input: propagation direction, rad' + + do i=1,p%NumOuts + InitOutData%LinNames_y(i+3*InitInp%NumWindPoints+size(y%DiskVel)) = trim(p%OutParam(i)%Name)//', '//p%OutParam(i)%Units + end do + ! IfW inputs and outputs are in the global, not rotating frame + InitOutData%RotFrame_u = .false. + InitOutData%RotFrame_y = .false. - RETURN + InitOutData%IsLoad_u = .false. ! IfW inputs for linearization are not loads + + end if + + ! Set the version information in InitOutData + InitOutData%Ver = IfW_Ver + CALL CleanUp() - !---------------------------------------------------------------------------------------------------- CONTAINS SUBROUTINE CleanUp() @@ -789,6 +633,7 @@ SUBROUTINE CleanUp() ! Ignore error messages from InFileInfo destruction call NWTC_Library_DestroyFileInfoType( InFileInfo, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) ! Close the summary file if we were writing one IF ( SumFileUnit > 0 ) THEN @@ -796,45 +641,7 @@ SUBROUTINE CleanUp() CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) ENDIF - END SUBROUTINE CleanUp - - - SUBROUTINE SetFFInitOutData(FFp) - - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: FFp !< Parameters - - - InitOutData%WindFileInfo%WindType = p%WindType - InitOutData%WindFileInfo%RefHt = FFp%RefHt - InitOutData%WindFileInfo%RefHt_Set = .TRUE. - InitOutData%WindFileInfo%DT = FFp%FFDTime - InitOutData%WindFileInfo%NumTSteps = FFp%NFFSteps - InitOutData%WindFileInfo%ConstantDT = .TRUE. - IF ( FFp%Periodic ) THEN - InitOutData%WindFileInfo%TRange = (/ 0.0_ReKi, FFp%TotalTime /) - InitOutData%WindFileInfo%TRange_Limited = .FALSE. - ELSE ! Shift the time range to compensate for the shifting of the wind grid - InitOutData%WindFileInfo%TRange = (/ 0.0_ReKi, FFp%TotalTime /) - FFp%InitXPosition*FFp%InvMFFWS - InitOutData%WindFileInfo%TRange_Limited = .TRUE. - ENDIF - InitOutData%WindFileInfo%YRange = (/ -FFp%FFYHWid, FFp%FFYHWid /) - InitOutData%WindFileInfo%YRange_Limited = .TRUE. ! Hard boundaries enforced in y-direction - IF ( p%TSFFWind%FF%NTGrids > 0 ) THEN ! have tower data - InitOutData%WindFileInfo%ZRange = (/ 0.0_Reki, FFp%RefHt + FFp%FFZHWid /) - ELSE - InitOutData%WindFileInfo%ZRange = (/ FFp%GridBase, & - FFp%GridBase + FFp%FFZHWid*2.0 /) - ENDIF - InitOutData%WindFileInfo%ZRange_Limited = .TRUE. - InitOutData%WindFileInfo%BinaryFormat = FFp%WindFileFormat - InitOutData%WindFileInfo%IsBinary = .TRUE. - InitOutData%WindFileInfo%MWS = FFp%MeanFFWS - - InitOutData%WindFileInfo%TI = 0.0_ReKi - InitOutData%WindFileInfo%TI_listed = .FALSE. - - END SUBROUTINE SetFFInitOutData END SUBROUTINE InflowWind_Init @@ -858,14 +665,8 @@ SUBROUTINE InflowWind_CalcOutput( Time, InputData, p, & ContStates, DiscStates, ConstrStates, & ! Framework required states -- empty in this case. OtherStates, OutputData, m, ErrStat, ErrMsg ) - - IMPLICIT NONE - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_CalcOutput" - - ! Inputs / Outputs - REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters @@ -875,24 +676,18 @@ SUBROUTINE InflowWind_CalcOutput( Time, InputData, p, & TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other/optimization states at Time TYPE(InflowWind_OutputType), INTENT(INOUT) :: OutputData !< Outputs computed at Time (IN for mesh reasons and data allocation) TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - ! Local variables INTEGER(IntKi) :: i ! Temporary variables for error handling INTEGER(IntKi) :: TmpErrStat CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" - ! Allocate the velocity array to get out IF ( .NOT. ALLOCATED(OutputData%VelocityUVW) ) THEN CALL AllocAry( OutputData%VelocityUVW, 3, SIZE(InputData%PositionXYZ,DIM=2), & @@ -961,81 +756,36 @@ END SUBROUTINE InflowWind_CalcOutput !> Clean up the allocated variables and close all open files. Reset the initialization flag so !! that we have to reinitialize before calling the routines again. SUBROUTINE InflowWind_End( InputData, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & - y, m, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_End" - - ! Initialization data and guesses + y, m, ErrStat, ErrMsg ) TYPE(InflowWind_InputType), INTENT(INOUT) :: InputData !< Input data for initialization - TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< Parameters + TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< Parameters TYPE(InflowWind_ContinuousStateType), INTENT(INOUT) :: ContStates !< Continuous states TYPE(InflowWind_DiscreteStateType), INTENT(INOUT) :: DiscStates !< Discrete states TYPE(InflowWind_ConstraintStateType), INTENT(INOUT) :: ConstrStateGuess !< Guess of the constraint states TYPE(InflowWind_OtherStateType), INTENT(INOUT) :: OtherStates !< Other/optimization states - TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Output data - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - + TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Output data + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) INTEGER( IntKi ), INTENT( OUT) :: ErrStat !< error status CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message + CHARACTER(*), PARAMETER :: RoutineName="InflowWind_End" ErrStat = ErrID_None ErrMsg = "" - ! End the sub-modules (deallocates their arrays and closes their files): - - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) ! The Steady wind is a simple wrapper for the UniformWind module. - CALL IfW_UniformWind_End( p%UniformWind, m%UniformWind, ErrStat, ErrMsg ) - - CASE (TSFF_WindNumber) - CALL IfW_TSFFWind_End( p%TSFFWind, m%TSFFWind, ErrStat, ErrMsg ) - - CASE (BladedFF_WindNumber) - CALL IfW_BladedFFWind_End( p%BladedFFWind, m%BladedFFWind, ErrStat, ErrMsg ) - - CASE (HAWC_WindNumber) - CALL IfW_HAWCWind_End( p%HAWCWind, m%HAWCWind, ErrStat, ErrMsg ) - - CASE (User_WindNumber) - CALL IfW_UserWind_End( p%UserWind, m%UserWind, ErrStat, ErrMsg ) - - CASE (FDext_WindNumber) - CALL IfW_4Dext_End( p%FDext, m%FDext, ErrStat, ErrMsg ) - - CASE ( Undef_WindNumber ) - ! Do nothing - - CASE DEFAULT ! keep this check to make sure that all new wind types have been accounted for - CALL SetErrStat(ErrID_Fatal,' Undefined wind type.',ErrStat,ErrMsg,RoutineName) - - END SELECT - -!!! ! IF (CTTS_Flag) CALL CTTS_Terminate( ErrStat ) !FIXME: should it be this line or the next? -!!! CALL CTTS_Terminate( ErrStat, ErrMsg ) - + ! Reset the wind type so that the initialization routine must be called + p%WindType = Undef_WindNumber + ! Destroy all inflow wind derived types CALL InflowWind_DestroyInput( InputData, ErrStat, ErrMsg ) - CALL InflowWind_DestroyParam( p, ErrStat, ErrMsg ) + CALL InflowWind_DestroyParam( p, ErrStat, ErrMsg, DeallocatePointers=.true. ) CALL InflowWind_DestroyContState( ContStates, ErrStat, ErrMsg ) CALL InflowWind_DestroyDiscState( DiscStates, ErrStat, ErrMsg ) CALL InflowWind_DestroyConstrState( ConstrStateGuess, ErrStat, ErrMsg ) CALL InflowWind_DestroyOtherState( OtherStates, ErrStat, ErrMsg ) CALL InflowWind_DestroyOutput( y, ErrStat, ErrMsg ) CALL InflowWind_DestroyMisc( m, ErrStat, ErrMsg ) - - - ! Reset the wind type so that the initialization routine must be called - p%WindType = Undef_WindNumber - p%CTTS_Flag = .FALSE. - END SUBROUTINE InflowWind_End @@ -1251,10 +1001,10 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt n = SIZE(u%PositionXYZ,2) ! these are the positions used in the module coupling do i=1,n - ! note that p%RotToWind(1,1) = cos(p%PropagationDir) and p%RotToWind(2,1) = sin(p%PropagationDir), which are the + ! note that p%FlowField%RotToWind(1,1) = cos(p%PropagationDir) and p%FlowField%RotToWind(2,1) = sin(p%PropagationDir), which are the ! values we need to compute the jacobian. !!!FIX ME with the propagation values!!!! - call IfW_UniformWind_JacobianPInput( t, u%PositionXYZ(:,i), p%RotToWind(1,1), p%RotToWind(2,1), p%UniformWind, m%UniformWind, local_dYdu ) + call IfW_UniformWind_JacobianPInput( p%FlowField%Uniform, t, u%PositionXYZ(:,i), p%FlowField%RotToWind(1,1), p%FlowField%RotToWind(2,1), local_dYdu ) i_end = 3*i i_start= i_end - 2 @@ -1277,7 +1027,7 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt do i=1,IfW_NumPtsAvg m%u_Avg%PositionXYZ(:,i) = matmul(u%HubOrientation,p%PositionAvg(:,i)) + u%HubPosition !!!FIX ME with the propagation values!!!! - call IfW_UniformWind_JacobianPInput( t, m%u_Avg%PositionXYZ(:,i), p%RotToWind(1,1), p%RotToWind(2,1), p%UniformWind, m%UniformWind, local_dYdu ) + call IfW_UniformWind_JacobianPInput( p%FlowField%Uniform, t, m%u_Avg%PositionXYZ(:,i), p%FlowField%RotToWind(1,1), p%FlowField%RotToWind(2,1), local_dYdu ) ! y%DiskAvg has the same index as u%HubPosition ! Also note that partial_(m%u_Avg%PositionXYZ) / partial_(u%HubPosition) is identity, so we can skip that part of the chain rule for these derivatives: @@ -1299,7 +1049,7 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt if (node > 0) then !!!FIX ME with the propagation values!!!! - call IfW_UniformWind_JacobianPInput( t, p%WindViXYZ(:,node), p%RotToWind(1,1), p%RotToWind(2,1), p%UniformWind, m%UniformWind, local_dYdu ) + call IfW_UniformWind_JacobianPInput( p%FlowField%Uniform, t, p%WindViXYZ(:,node), p%FlowField%RotToWind(1,1), p%FlowField%RotToWind(2,1), local_dYdu ) else local_dYdu = 0.0_R8Ki comp = 1 @@ -1328,6 +1078,121 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt END SUBROUTINE InflowWind_JacobianPInput +!.................................................................................................................................. +!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial +!! derivative dY/du is returned. This submodule does not follow the modularization framework. +SUBROUTINE IfW_UniformWind_JacobianPInput(UF, t, Position, CosPropDir, SinPropDir, dYdu) + USE IfW_FlowField, only : UniformField_InterpLinear, UniformField_InterpCubic + + TYPE(UniformFieldType), INTENT(IN ) :: UF !< Uniform field derived type + REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds + REAL(ReKi), INTENT(IN ) :: Position(3) !< XYZ Position at which to find velocity (operating point) + REAL(ReKi), INTENT(IN ) :: CosPropDir !< cosine of InflowWind propagation direction + REAL(ReKi), INTENT(IN ) :: SinPropDir !< sine of InflowWind propagation direction + REAL(R8Ki), INTENT(INOUT) :: dYdu(3,6) !< Partial derivatives of output functions (Y) with respect to the inputs (u) + + TYPE(UniformField_Interp) :: op ! interpolated values of InterpParams + REAL(R8Ki) :: RotatePosition(3) !< rotated position + REAL(R8Ki) :: dVhdx ! temporary value to hold partial v_h partial X + REAL(R8Ki) :: dVhdy ! temporary value to hold partial v_h partial Y + REAL(R8Ki) :: dVhdz ! temporary value to hold partial v_h partial Z + REAL(R8Ki) :: tmp_du ! temporary value to hold calculations that are part of multiple components + REAL(R8Ki) :: tmp_dv ! temporary value to hold calculations that are part of multiple components + REAL(R8Ki) :: dVhdPD ! temporary value to hold partial v_h partial propagation direction + REAL(R8Ki) :: dVhdV ! temporary value to hold partial v_h partial V + REAL(R8Ki) :: Vh ! temporary value to hold v_h + REAL(R8Ki) :: dVhdVShr ! temporary value to hold partial v_h partial VShr + REAL(R8Ki) :: zr + + if ( Position(3) < 0.0_ReKi .or. EqualRealNos(Position(3), 0.0_ReKi)) then + dYdu = 0.0_R8Ki + return + end if + + !------------------------------------------------------------------------------------------------- + !> 1. Interpolate uniform field to get values at operating point + !------------------------------------------------------------------------------------------------- + + op = UniformField_InterpLinear(UF, t) + + RotatePosition(1) = Position(1)*cosPropDir - Position(2)*sinPropDir + RotatePosition(2) = Position(1)*sinPropDir + Position(2)*cosPropDir + RotatePosition(3) = Position(3) + + !------------------------------------------------------------------------------------------------- + !> 2. Calculate \f$ \frac{\partial Y_{Output \, Equations}}{\partial u_{inputs}} = \begin{bmatrix} + !! \frac{\partial Vt_u}{\partial X} & \frac{\partial Vt_u}{\partial Y} & \frac{\partial Vt_u}{\partial Z} \\ + !! \frac{\partial Vt_v}{\partial X} & \frac{\partial Vt_v}{\partial Y} & \frac{\partial Vt_v}{\partial Z} \\ + !! \frac{\partial Vt_w}{\partial X} & \frac{\partial Vt_w}{\partial Y} & \frac{\partial Vt_w}{\partial Z} \\ + !! \end{bmatrix} \f$ + !------------------------------------------------------------------------------------------------- + + zr = RotatePosition(3)/UF%RefHeight + tmp_du = op%VelH * op%ShrH / UF%RefLength * CosPropDir + dVhdx = tmp_du * op%SinAngleH + dVhdy = tmp_du * op%CosAngleH + dVhdz = op%VelH * ( op%ShrV / UF%RefHeight * zr**(op%ShrV-1.0_R8Ki) + op%LinShrV/UF%RefLength) + + dVhdV = ( ( RotatePosition(3)/UF%RefHeight ) ** op%ShrV & ! power-law wind shear + + ( op%ShrH * ( RotatePosition(2) * op%CosAngleH + RotatePosition(1) * op%SinAngleH ) & ! horizontal linear shear + + op%LinShrV * ( RotatePosition(3) - UF%RefHeight ) )/UF%RefLength ) ! vertical linear shear + Vh = op%VelH * dVhdV + op%VelGust + + dVhdVShr = op%VelH * zr**op%ShrV * log(zr) + dVhdPD = op%VelH * op%ShrH / UF%RefLength * ( RotatePosition(1) * op%CosAngleH - RotatePosition(2) * op%SinAngleH ) + + tmp_du = CosPropDir*op%CosAngleH - SinPropDir*op%SinAngleH + tmp_dv = -SinPropDir*op%CosAngleH - CosPropDir*op%SinAngleH + + !> \f$ \frac{\partial Vt_u}{\partial X} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ + dYdu(1,1) = tmp_du*dVhdx + !> \f$ \frac{\partial Vt_v}{\partial X} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ + dYdu(2,1) = tmp_dv*dVhdx + !> \f$ \frac{\partial Vt_w}{\partial X} = 0 \f$ + dYdu(3,1) = 0.0_R8Ki + + !> \f$ \frac{\partial Vt_u}{\partial Y} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ + dYdu(1,2) = tmp_du*dVhdy + !> \f$ \frac{\partial Vt_v}{\partial Y} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ + dYdu(2,2) = tmp_dv*dVhdy + !> \f$ \frac{\partial Vt_w}{\partial Y} = 0 \f$ + dYdu(3,2) = 0.0_R8Ki + + !> \f$ \frac{\partial Vt_u}{\partial Z} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] + !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ + dYdu(1,3) = tmp_du*dVhdz + !> \f$ \frac{\partial Vt_v}{\partial Z} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] + !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ + dYdu(2,3) = tmp_dv*dVhdz + !> \f$ \frac{\partial Vt_w}{\partial Z} = 0 \f$ + dYdu(3,3) = 0.0_R8Ki + + ! \f$ \frac{\partial Vt_u}{\partial V} = \f$ + dYdu(1,4) = tmp_du*dVhdV + ! \f$ \frac{\partial Vt_v}{\partial V} = \f$ + dYdu(2,4) = tmp_dv*dVhdV + !> \f$ \frac{\partial Vt_w}{\partial V} = 0 \f$ + dYdu(3,4) = 0.0_R8Ki + + ! \f$ \frac{\partial Vt_u}{\partial VShr} = \f$ + dYdu(1,5) = tmp_du*dVhdVShr + ! \f$ \frac{\partial Vt_v}{\partial VShr} = \f$ + dYdu(2,5) = tmp_dv*dVhdVShr + !> \f$ \frac{\partial Vt_w}{\partial VShr} = 0 \f$ + dYdu(3,5) = 0.0_R8Ki + + ! \f$ \frac{\partial Vt_u}{\partial PropDir} = \f$ + dYdu(1,6) = tmp_dv*Vh + tmp_du*dVhdPD + ! \f$ \frac{\partial Vt_v}{\partial PropDir} = \f$ + dYdu(2,6) = -tmp_du*Vh + tmp_dv*dVhdPD + !> \f$ \frac{\partial Vt_w}{\partial PropDir} = 0 \f$ + dYdu(3,6) = 0.0_R8Ki + +END SUBROUTINE IfW_UniformWind_JacobianPInput !---------------------------------------------------------------------------------------------------------------------------------- !> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions !! with respect to the continuous states (x). The partial derivatives dY/dx, dX/dx, dXd/dx, and dZ/dx are returned. @@ -1609,8 +1474,8 @@ SUBROUTINE InflowWind_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs u_op((index+1):(index+3)) = EulerExtract(u%HubOrientation) index = index + 3 - call IfW_UniformWind_GetOP( t, p%UniformWind, m%UniformWind, u_op(index+1:index+2) ) - u_op(index + 3) = p%PropagationDir + call IfW_UniformWind_GetOP( p%FlowField%Uniform, t, p%FlowField%VelInterpCubic, u_op(index+1:index+2) ) + u_op(index + 3) = p%FlowField%PropagationDir END IF @@ -1657,252 +1522,5 @@ SUBROUTINE InflowWind_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs END IF END SUBROUTINE InflowWind_GetOP -!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -!==================================================================================================== -SUBROUTINE InflowWind_Convert2HAWC( FileRootName, p, m, ErrStat, ErrMsg ) - - USE IfW_FFWind_Base - IMPLICIT NONE - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Convert2HAWC" - - ! Subroutine arguments - - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - TYPE(IfW_FFWind_ParameterType) :: p_ff !< FF Parameters - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - CALL Uniform_to_FFWind(p%UniformWind, m%UniformWind, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - IF (ErrStat < AbortErrLev) THEN - CALL ConvertFFWind_to_HAWC2(FileRootName, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END IF - - CALL IfW_FFWind_DestroyParam(p_ff,ErrStat2,ErrMsg2) - - CASE (TSFF_WindNumber) - - CALL ConvertFFWind_to_HAWC2(FileRootName, p%TSFFWind%FF, ErrStat, ErrMsg) - - CASE (BladedFF_WindNumber) - - CALL ConvertFFWind_to_HAWC2(FileRootName, p%BladedFFWind%FF, ErrStat, ErrMsg) - - CASE ( HAWC_WindNumber ) - - CALL ConvertFFWind_to_HAWC2(FileRootName, p%HAWCWind%FF, ErrStat, ErrMsg) - - CASE DEFAULT ! User_WindNumber - - ErrStat = ErrID_Warn - ErrMsg = 'Wind type '//TRIM(Num2LStr(p%WindType))//' cannot be converted to HAWC format.' - - END SELECT - -END SUBROUTINE InflowWind_Convert2HAWC - -!==================================================================================================== -SUBROUTINE InflowWind_Convert2Bladed( FileRootName, p, m, ErrStat, ErrMsg ) - - USE IfW_FFWind_Base - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Convert2Bladed" - - ! Subroutine arguments - - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - ! Local variables - TYPE(IfW_FFWind_ParameterType) :: p_ff !< FF Parameters - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None - ErrMsg = "" - - ! Local variables - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - CALL Uniform_to_FFWind(p%UniformWind, m%UniformWind, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - IF (ErrStat < AbortErrLev) THEN - CALL ConvertFFWind_to_Bladed(FileRootName, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END IF - - CALL IfW_FFWind_DestroyParam(p_ff,ErrStat2,ErrMsg2) - - CASE (TSFF_WindNumber) - - CALL ConvertFFWind_to_Bladed(FileRootName, p%TSFFWind%FF, ErrStat, ErrMsg) - - CASE (BladedFF_WindNumber) - - CALL ConvertFFWind_to_Bladed(FileRootName, p%BladedFFWind%FF, ErrStat, ErrMsg) - - CASE ( HAWC_WindNumber ) - - CALL ConvertFFWind_to_Bladed(FileRootName, p%HAWCWind%FF, ErrStat, ErrMsg) - - CASE DEFAULT ! User_WindNumber - - ErrStat = ErrID_Warn - ErrMsg = 'Wind type '//TRIM(Num2LStr(p%WindType))//' cannot be converted to Bladed format.' - - END SELECT - -END SUBROUTINE InflowWind_Convert2Bladed - -!==================================================================================================== -SUBROUTINE InflowWind_Convert2Uniform( FileRootName, p, m, ErrStat, ErrMsg ) - - USE IfW_FFWind_Base - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Convert2Uniform" - - ! Subroutine arguments - - TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None - ErrMsg = "" - - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - ! no need to convert anything here - - CASE (TSFF_WindNumber) - CALL FFWind_to_Uniform(p%UniformWind, m%UniformWind, p%TSFFWind%FF, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - CASE (BladedFF_WindNumber) - CALL FFWind_to_Uniform(p%UniformWind, m%UniformWind, p%BladedFFWind%FF, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - CASE ( HAWC_WindNumber ) - - CALL FFWind_to_Uniform(p%UniformWind, m%UniformWind, p%HAWCWind%FF, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - CASE DEFAULT ! User_WindNumber - - ErrStat = ErrID_Warn - ErrMsg = RoutineName//': Wind type '//TRIM(Num2LStr(p%WindType))//' cannot be converted to UniformWind format.' - RETURN - - END SELECT - IF (ErrStat >= AbortErrLev) RETURN - - CALL WrUniformWind(FileRootName, p%UniformWind, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - -END SUBROUTINE InflowWind_Convert2Uniform - -!==================================================================================================== -SUBROUTINE InflowWind_Convert2VTK( FileRootName, p, m, ErrStat, ErrMsg ) - - USE IfW_FFWind_Base - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Convert2VTK" - - ! Subroutine arguments - - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - ! Local variables - TYPE(IfW_FFWind_ParameterType) :: p_ff !< FF Parameters - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None - ErrMsg = "" - - ! Local variables - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - CALL Uniform_to_FFWind(p%UniformWind, m%UniformWind, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - IF (ErrStat < AbortErrLev) THEN - CALL ConvertFFWind_toVTK(FileRootName, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END IF - - CALL IfW_FFWind_DestroyParam(p_ff,ErrStat2,ErrMsg2) - - CASE (TSFF_WindNumber) - - CALL ConvertFFWind_toVTK(FileRootName, p%TSFFWind%FF, ErrStat, ErrMsg) - - CASE (BladedFF_WindNumber) - - CALL ConvertFFWind_toVTK(FileRootName, p%BladedFFWind%FF, ErrStat, ErrMsg) - - CASE ( HAWC_WindNumber ) - - CALL ConvertFFWind_toVTK(FileRootName, p%HAWCWind%FF, ErrStat, ErrMsg) - - CASE DEFAULT ! User_WindNumber - - ErrStat = ErrID_Warn - ErrMsg = 'Wind type '//TRIM(Num2LStr(p%WindType))//' cannot be converted to VTK format.' - - END SELECT - -END SUBROUTINE InflowWind_Convert2VTK -!==================================================================================================== END MODULE InflowWind diff --git a/modules/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt index e9cf120675..4231273e3c 100644 --- a/modules/inflowwind/src/InflowWind.txt +++ b/modules/inflowwind/src/InflowWind.txt @@ -7,13 +7,8 @@ # keyword ################################################################################################################################### -usefrom IfW_UniformWind.txt -usefrom IfW_TSFFWind.txt -usefrom IfW_FFWind_Base.txt -usefrom IfW_BladedFFWind.txt -usefrom IfW_HAWCWind.txt -usefrom IfW_UserWind.txt -usefrom IfW_4Dext.txt +usefrom IfW_FlowField.txt +usefrom InflowWind_IO.txt usefrom Lidar.txt include Registry_NWTC_Library.txt @@ -28,34 +23,11 @@ param ^ - IntKi HAWC_WindNu param ^ - IntKi User_WindNumber - 6 - "User defined wind." - param ^ - IntKi BladedFF_Shr_WindNumber - 7 - "Native Bladed binary full-field file." - param ^ - IntKi FDext_WindNumber - 8 - "4D wind from external souce (i.e., FAST.Farm)." - -param ^ - IntKi Highest_WindNumber - 8 - "Highest wind number supported." - +param ^ - IntKi Point_WindNumber - 9 - "1D wind components from ExtInflow" - +param ^ - IntKi Highest_WindNumber - 9 - "Highest wind number supported." - param ^ - IntKi IfW_NumPtsAvg - 144 - "Number of points averaged for rotor-average wind speed" - -######################### -# ..... WindFile metadata ........................................................................................................ -# This is metadata about the windfile that is retrieved when InflowWind is initialized -# ................................................................................................................................ -typedef InflowWind/InflowWind WindFileMetaData CHARACTER(1024) FileName - - - "Name of the windfile retrieved" - -typedef ^ ^ IntKi WindType - 0 - "Type of the windfile" - -typedef ^ ^ ReKi RefHt - - - "Reference height given in file" meters -typedef ^ ^ Logical RefHt_Set - - - "Reference height was given in file" - -typedef ^ ^ DbKi DT - - - "TimeStep of the wind file -- zero value for none" seconds -typedef ^ ^ IntKi NumTSteps - - - "Number of timesteps in the time range of wind file" - -typedef ^ ^ Logical ConstantDT - - - "Timesteps are the same throughout file" - -typedef ^ ^ ReKi TRange {2} - - "Time range of the wind file" seconds -typedef ^ ^ Logical TRange_Limited - - - "TRange limits strictly enforced" - -typedef ^ ^ ReKi YRange {2} - - "Range in y direction" meters -typedef ^ ^ Logical YRange_Limited - - - "YRange limits strictly enforced" - -typedef ^ ^ ReKi ZRange {2} - - "Range in z direction" meters -typedef ^ ^ Logical ZRange_Limited - - - "ZRange limits strictly enforced" - -typedef ^ ^ IntKi BinaryFormat - - - "Binary format identifier" - -typedef ^ ^ Logical IsBinary - - - "Windfile is a binary file" - -typedef ^ ^ ReKi TI {3} - - "Turbulence intensity (U,V,W)" - -typedef ^ ^ Logical TI_listed - - - "Turbulence intesity given in file" - -typedef ^ ^ ReKi MWS - - - "Approximate mean wind speed" - - - ######################### # ..... Input file data ........................................................................................................... # This is data defined in the Input File for this module (or could otherwise be passed in) @@ -64,6 +36,7 @@ typedef InflowWind/InflowWind InflowWind_InputFile LOGICAL EchoFlag typedef ^ ^ IntKi WindType - 0 - "Type of windfile" - typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation (meteorological direction)" (degrees) typedef ^ ^ ReKi VFlowAngle - - - "Vertical (upflow) angle" degrees +typedef ^ ^ LOGICAL VelInterpCubic - .FALSE. - "Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7]" - typedef ^ ^ IntKi NWindVel - - - "Number of points to output the wind velocity (0 to 9)" typedef ^ ^ ReKi WindVxiList : - - "List of X coordinates for wind velocity measurements" meters typedef ^ ^ ReKi WindVyiList : - - "List of Y coordinates for wind velocity measurements" meters @@ -104,7 +77,7 @@ typedef ^ ^ ReKi Measurement typedef ^ ^ ReKi URefLid - - - "Reference average wind speed for the lidar" m/s typedef ^ ^ LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - typedef ^ ^ IntKi ConsiderHubMotion - - - "Flag whether or not the hub motion's impact on the Lidar measurement will be considered [0 for no, 1 for yes]" - -typedef ^ ^ IfW_FFWind_InitInputType FF - - - "scaling data" - +typedef ^ ^ Grid3D_InitInputType FF - - - "scaling data" - @@ -119,16 +92,19 @@ typedef ^ ^ CHARACTER(1024) RootName typedef ^ ^ FileInfoType PassedFileData - - - "If we don't use the input file, pass everything through this" - typedef ^ ^ LOGICAL WindType2UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - typedef ^ ^ FileInfoType WindType2Data - - - "Optional slot for wind type 2 data if file IO is not used." - -typedef ^ ^ Lidar_InitInputType lidar - - - "InitInput for lidar data" - -typedef ^ ^ IfW_4Dext_InitInputType FDext - - - "InitInput for 4D external wind data" - +typedef ^ ^ LOGICAL OutputAccel - .FALSE. - "Flag to output wind acceleration" - +typedef ^ ^ Lidar_InitInputType lidar - - - "InitInput for lidar data" - +typedef ^ ^ Grid4D_InitInputType FDext - - - "InitInput for 4D external wind data" - typedef ^ ^ ReKi RadAvg - - - "Radius (from hub) used for averaging wind speed" - +typedef ^ ^ IntKi BoxExceedAllowIdx - -1 - "Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim)" - +typedef ^ ^ LOGICAL BoxExceedAllowF - .FALSE. - "Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim)" - # Init Output typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr : - - "Names of output-to-file channels" - typedef ^ ^ CHARACTER(ChanLen) WriteOutputUnt : - - "Units of output-to-file channels" - typedef ^ ^ ProgDesc Ver - - - "Version information of InflowWind module" - -typedef ^ ^ WindFileMetaData WindFileInfo - - - "Meta data from the wind file" - +typedef ^ ^ WindFileDat WindFileInfo - - - "Meta data from the wind file" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_u {:} - - "Names of the inputs used in linearization" - typedef ^ InitOutputType LOGICAL RotFrame_y {:} - - "Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame" - @@ -141,33 +117,20 @@ typedef ^ InitOutputType LOGICAL IsLoad # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: typedef ^ ParameterType CHARACTER(1024) RootFileName - - - "Root of the InflowWind input filename" - -typedef ^ ^ LOGICAL CTTS_Flag - .FALSE. - "determines if coherent turbulence is used" - -typedef ^ ^ LOGICAL RotateWindBox - .FALSE. - "determines if wind will be rotated" - +typedef ^ ^ IntKi WindType - 0 - "Type of wind -- set to Undef_Wind initially" - typedef ^ ^ DbKi DT - - - "Time step for cont. state integration & disc. state update" seconds -typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation" radians -typedef ^ ^ ReKi VFlowAngle - - - "Vertical (upflow) angle" radians - -typedef ^ ^ ReKi RotToWind {3}{3} - - "Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X')" - -typedef ^ ^ ReKi RotFromWind {3}{3} - - "Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind)" - typedef ^ ^ ReKi WindViXYZprime :: - - "List of XYZ coordinates for velocity measurements, translated to the wind coordinate system (prime coordinates). This equals MATMUL( RotToWind, ParamData%WindViXYZ )" meters - -typedef ^ ^ IntKi WindType - 0 - "Type of wind -- set to Undef_Wind initially" - +typedef ^ ^ ReKi WindViXYZ :: - - "List of XYZ coordinates for wind velocity measurements, 3xNWindVel" meters +typedef ^ ^ FlowFieldType FlowField - - - "Parameters from Full-Field" - +typedef ^ ^ ReKi PositionAvg :: - - "(non-rotated) positions of points used for averaging wind speed" meters typedef ^ ^ ReKi ReferenceHeight - - - "Height of the wind turbine" meters typedef ^ ^ ReKi RefPosition 3 - - "Reference position (point where box is rotated)" meters typedef ^ ^ IntKi NWindVel - - - "Number of points in the wind velocity list" - -typedef ^ ^ ReKi WindViXYZ :: - - "List of XYZ coordinates for wind velocity measurements, 3xNWindVel" meters -typedef ^ ^ IfW_UniformWind_ParameterType UniformWind - - - "Parameters from UniformWind" - -typedef ^ ^ IfW_TSFFWind_ParameterType TSFFWind - - - "Parameters from TSFFWind -- TurbSim full-field format" - -typedef ^ ^ IfW_BladedFFWind_ParameterType BladedFFWind - - - "Parameters from BladedFFWind -- Bladed-style full-field format" - -typedef ^ ^ IfW_HAWCWind_ParameterType HAWCWind - - - "Parameters from HAWCWind" - -typedef ^ ^ IfW_UserWind_ParameterType UserWind - - - "Parameters from UserWind" - -typedef ^ ^ IfW_4Dext_ParameterType FDext - - - "Parameters from FDext" - -#typedef ^ ^ IfW_CTWind_ParameterType CTWind - - - "Parameters from CTWind" - typedef ^ ^ IntKi NumOuts - 0 - "Number of parameters in the output list (number of outputs requested)" - typedef ^ ^ OutParmType OutParam {:} - - "Names and units (and other characteristics) of all requested output parameters" - typedef ^ ^ IntKi OutParamLinIndx {:}{:} - - "Index into WriteOutput for WindViXYZ in linearization analysis" - -typedef ^ ^ lidar_ParameterType lidar - - - "Lidar parameter data" - -typedef ^ ^ ReKi PositionAvg :: - - "(non-rotated) positions of points used for averaging wind speed" meters +typedef ^ ^ lidar_ParameterType lidar - - - "Lidar parameter data" - +typedef ^ ^ LOGICAL OutputAccel - .FALSE. - "Flag to output wind acceleration" - # ..... Inputs .................................................................................................................... @@ -181,11 +144,11 @@ typedef ^ ^ ReKi HubOrientat # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: typedef ^ OutputType ReKi VelocityUVW :: - - "Array holding the U,V,W velocity for a given timestep" meters/sec +typedef ^ OutputType ReKi AccelUVW :: - - "Array holding the U,V,W acceleration for a given timestep" meters/sec typedef ^ OutputType ReKi WriteOutput : - - "Array with values to output to file" - typedef ^ ^ ReKi DiskVel {3} - - "Vector holding the U,V,W average velocity of the disk" meters/sec typedef ^ ^ ReKi HubVel {3} - - "Vector holding the U,V,W velocity at the hub" meters/sec typedef ^ ^ lidar_OutputType lidar - - - "Lidar data" - -#typedef ^ ^ IfW_UniformWind_OutputType UniformWind - - - "uniform/steady wind operating point" # ..... States not used by this module ................................................................................................................... typedef ^ ContinuousStateType ReKi DummyContState - - - "Remove this variable if you have continuous states" - @@ -197,16 +160,10 @@ typedef ^ OtherStateType ReKi DummyOtherS # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): # e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi TimeIndex - 0 - "An Index into the TData array" - -typedef ^ ^ IfW_UniformWind_MiscVarType UniformWind - - - "MiscVars from UniformWind" - -typedef ^ ^ IfW_TSFFWind_MiscVarType TSFFWind - - - "MiscVars from TSFFWind" - -typedef ^ ^ IfW_HAWCWind_MiscVarType HAWCWind - - - "MiscVars from HAWCWind" - -typedef ^ ^ IfW_BladedFFWind_MiscVarType BladedFFWind - - - "MiscVars from BladedFFWind" - -typedef ^ ^ IfW_UserWind_MiscVarType UserWind - - - "MiscVars from UserWind" - -typedef ^ ^ IfW_4Dext_MiscVarType FDext - - - "MiscVars from FDext" - -typedef ^ ^ ReKi AllOuts : - - "An array holding the value of all of the calculated (not only selected) output channels" "see OutListParameters.xlsx spreadsheet" +typedef ^ MiscVarType ReKi AllOuts : - - "An array holding the value of all of the calculated (not only selected) output channels" "see OutListParameters.xlsx spreadsheet" typedef ^ ^ ReKi WindViUVW :: - - "List of UVW velocities for wind velocity measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ" meters/second -typedef ^ MiscVarType InflowWind_InputType u_Avg - - - "inputs for computing rotor-averaged values" - -typedef ^ MiscVarType InflowWind_OutputType y_Avg - - - "outputs for computing rotor-averaged values" - -typedef ^ MiscVarType InflowWind_InputType u_Hub - - - "inputs for computing hub values" - -typedef ^ MiscVarType InflowWind_OutputType y_Hub - - - "outputs for computing hub values" - +typedef ^ ^ ReKi WindAiUVW :: - - "List of UVW accelerations for wind acceleration measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ" m/s^2 +typedef ^ ^ InflowWind_InputType u_Avg - - - "inputs for computing rotor-averaged values" - +typedef ^ ^ InflowWind_OutputType y_Avg - - - "outputs for computing rotor-averaged values" - +typedef ^ ^ InflowWind_InputType u_Hub - - - "inputs for computing hub values" - +typedef ^ ^ InflowWind_OutputType y_Hub - - - "outputs for computing hub values" - diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index c2d4b104da..77beb83a58 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -30,6 +30,8 @@ PROGRAM InflowWind_Driver USE InflowWind_Types USE InflowWind_Driver_Types ! Contains types and routines for handling the input arguments USE InflowWind_Driver_Subs ! Contains subroutines for the driver program + USE IfW_FlowField + USE InflowWind_Subs, only: CalculateOutput IMPLICIT NONE @@ -61,19 +63,16 @@ PROGRAM InflowWind_Driver TYPE(IfWDriver_Settings) :: Settings ! Driver settings REAL(DbKi) :: Timer(1:2) ! Keep track of how long this takes to run REAL(DbKi) :: TimeNow ! The current time - INTEGER(IntKi) :: NumTotalPoints ! Number of points for this iteration LOGICAL :: TempFileExist ! Flag for inquiring file existence - CHARACTER(11) :: TmpNumString ! Temporary string for holding a number INTEGER(IntKi) :: ITime ! Generic counter for keeping track of the timestep index - !FIXME: may want to borrow some of the type storage concepts from WAMIT2 !FIXME: look at Waves.f90 for ideas on other things needed for this ! Local variables for the FFT calculations - REAL(ReKi), ALLOCATABLE :: FFTDataSetVel(:,:) ! Velocity dataset for FFT calcs. Indices of (NumTimeSteps,3). Index 2 gives dimension U,V,W - COMPLEX(ReKi), ALLOCATABLE :: FFTDataSetFrq(:,:) ! Complex frequency information for the FFT (NumFreqs,3). Index 2 gives dimension X,Y,Z - REAL(ReKi), ALLOCATABLE :: TimeArray(:) ! Time array information. (NumTimeSteps) - REAL(ReKi), ALLOCATABLE :: FreqArray(:) ! Frequency array information (NumFreqs) + ! REAL(ReKi), ALLOCATABLE :: FFTDataSetVel(:,:) ! Velocity dataset for FFT calcs. Indices of (NumTimeSteps,3). Index 2 gives dimension U,V,W + ! COMPLEX(ReKi), ALLOCATABLE :: FFTDataSetFrq(:,:) ! Complex frequency information for the FFT (NumFreqs,3). Index 2 gives dimension X,Y,Z + ! REAL(ReKi), ALLOCATABLE :: TimeArray(:) ! Time array information. (NumTimeSteps) + ! REAL(ReKi), ALLOCATABLE :: FreqArray(:) ! Frequency array information (NumFreqs) @@ -109,10 +108,6 @@ PROGRAM InflowWind_Driver CALL NWTC_Init CALL DispNVD(ProgInfo) -! Beep = .FALSE. - - - !-------------------------------------------------------------------------------------------------------------------------------- !-=-=- Setup the program -=-=- !-------------------------------------------------------------------------------------------------------------------------------- @@ -120,62 +115,9 @@ PROGRAM InflowWind_Driver ! Start the timer CALL CPU_TIME( Timer(1) ) - ! Set some CLSettings to null/default values - CLSettings%DvrIptFileName = "" ! No input name name until set - CLSettings%IfWIptFileName = "" ! No IfW input file name until set - CLSettings%SummaryFileName = "" ! No summary file name until set - CLSettings%NumTimeSteps = 0_IntKi - CLSettings%DT = 0.0_DbKi - CLSettings%TStart = 0.0_ReKi - CLSettings%FFTcoord = 0.0_ReKi ! Set to origin - CLSettings%GridDelta = 0.0_ReKi ! No stepsize - CLSettings%GridN = 1_IntKi ! No grid points to calculate -- center of grid only - CLSettings%XRange = 0.0_ReKi ! No xrange points - CLSettings%YRange = 0.0_ReKi ! No Yrange points - CLSettings%ZRange = 0.0_ReKi ! No Zrange points - CLSettings%PointsFileName = "" ! No points file name until set - CLSettings%PointsOutputName = "" ! No points file name until set - CLSettings%FFTOutputName = "" ! No FFT output file name until set - CLSettings%WindGridOutputName = "" ! No WindGrid output file name until set - CLSettings%WindGridOutputUnit = -1_IntKi ! No WindGrid output unit set - CLSettings%FFTOutputUnit = -1_IntKi ! No FFT output unit set - CLSettings%PointsOutputUnit = -1_IntKi ! No Points file output unit set - CLSettings%ProgInfo = ProgInfo ! Driver info - - ! Set some CLSettingsFlags to null/default values - CLSettingsFlags%DvrIptFile = .FALSE. ! Driver input filename given as command line argument - CLSettingsFlags%IfWIptFile = .FALSE. ! InflowWind input filename given as command line argument - CLSettingsFlags%Summary = .FALSE. ! create a summary at command line? (data extents in the wind file) - CLSettingsFlags%SummaryFile = .FALSE. ! create a summary file of the output? - CLSettingsFlags%TStart = .FALSE. ! specified time to start at - CLSettingsFlags%NumTimeSteps = .FALSE. ! specified a number of timesteps - CLSettingsFlags%NumTimeStepsDefault = .FALSE. ! specified 'DEFAULT' for number of timesteps - CLSettingsFlags%DT = .FALSE. ! specified a resolution in time - CLSettingsFlags%DTDefault = .FALSE. ! specified 'DEFAULT' for resolution in time - CLSettingsFlags%FFTcalc = .FALSE. ! do an FFT - CLSettingsFlags%WindGrid = .FALSE. ! Requested output of wind data on a grid -- input file option only - CLSettingsFlags%XRange = .FALSE. ! specified a range of x -- command line option only -- stored as GridCtrCoord and GridDelta - CLSettingsFlags%YRange = .FALSE. ! specified a range of y -- command line option only -- stored as GridCtrCoord and GridDelta - CLSettingsFlags%ZRange = .FALSE. ! specified a range of z -- command line option only -- stored as GridCtrCoord and GridDelta - CLSettingsFlags%Dx = .FALSE. ! specified a resolution in x -- command line option only, 0.0 otherwise - CLSettingsFlags%Dy = .FALSE. ! speficied a resolution in y - CLSettingsFlags%Dz = .FALSE. ! specified a resolution in z - CLSettingsFlags%PointsFile = .FALSE. ! points filename to read in -- command line option only - CLSettingsFlags%WindGridOutputInit = .FALSE. ! Wind Grid output file not started - CLSettingsFlags%FFTOutputInit = .FALSE. ! FFT output file not started - CLSettingsFlags%PointsOutputInit = .FALSE. ! Points output file not started - CLSettingsFlags%Verbose = .FALSE. ! Turn on verbose error reporting? - CLSettingsFlags%VVerbose = .FALSE. ! Turn on very verbose error reporting? - CLSettingsFlags%WrHAWC = .FALSE. ! don't convert to HAWC format - CLSettingsFlags%WrBladed = .FALSE. ! don't convert to Bladed format - CLSettingsFlags%WrVTK = .FALSE. ! don't convert to VTK format - CLSettingsFlags%WrUniform = .FALSE. ! don't convert to UniformWind format - - ! Initialize the driver settings to their default values (same as the CL -- command line -- values) - Settings = CLSettings - SettingsFlags = CLSettingsFlags - + CLSettings%ProgInfo = ProgInfo + Settings%ProgInfo = ProgInfo !-------------------------------------------------------------------------------------------------------------------------------- !-=-=- Parse the command line inputs -=-=- @@ -307,13 +249,14 @@ PROGRAM InflowWind_Driver - ! Sanity check: if an input points file is specified, make sure it actually exists. Open it if specified - + ! If output based a points file was requested IF ( SettingsFlags%PointsFile ) THEN + + ! Check if the points file exists, abort if not found INQUIRE( file=TRIM(Settings%PointsFileName), exist=TempFileExist ) IF ( TempFileExist .eqv. .FALSE. ) CALL ProgAbort( "Cannot find the points file "//TRIM(Settings%PointsFileName)) - ! Now read the file in and save the points + ! Now read the file in and save the points CALL ReadPointsFile( Settings%PointsFileName, PointsXYZ, ErrStat,ErrMsg ) IF ( ErrStat >= AbortErrLev ) THEN CALL ProgAbort( ErrMsg ) @@ -322,16 +265,16 @@ PROGRAM InflowWind_Driver ErrStat = ErrID_None ENDIF - ! Make name for output - CALL GetRoot( Settings%PointsFileName, Settings%PointsOutputName ) - Settings%PointsOutputName = TRIM(Settings%PointsOutputName)//'.Velocity.dat' + ! Display number of points read from file + CALL WrScr(NewLine//"Read "//TRIM(Num2LStr(SIZE(PointsXYZ,DIM=2)))//" points from '"//TRIM(Settings%PointsFileName)//"'.") - CALL WrScr(NewLine//"Read "//TRIM(Num2LStr(SIZE(PointsXYZ,DIM=2)))//" points from '"//TRIM(Settings%PointsFileName)// & - "'. Results output to '"//TRIM(Settings%PointsOutputName)//"'.") - - ! If the output file already exists, warn that it will be overwritten - INQUIRE( file=TRIM(Settings%PointsOutputName), exist=TempFileExist ) - IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%PointsOutputName)) + ! Create velocity output file name from points input file name + ! Display that file will be created, output message if it will be overwritten + CALL GetRoot( Settings%PointsFileName, Settings%PointsVelOutput%Name ) + Settings%PointsVelOutput%Name = TRIM(Settings%PointsVelOutput%Name)//'.Velocity.dat' + CALL WrScr(NewLine//"Results output to '"//TRIM(Settings%PointsVelOutput%Name)//"'.") + INQUIRE( file=TRIM(Settings%PointsVelOutput%Name), exist=TempFileExist ) + IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%PointsVelOutput%Name)) ENDIF @@ -340,24 +283,24 @@ PROGRAM InflowWind_Driver IF ( SettingsFlags%FFTcalc ) THEN ! Make name for output IF ( SettingsFlags%DvrIptFile ) THEN - CALL GetRoot( Settings%DvrIptFileName, Settings%FFTOutputName ) + CALL GetRoot( Settings%DvrIptFileName, Settings%FFTOutput%Name ) ELSE - CALL GetRoot( Settings%IfWIptFileName, Settings%FFTOutputName ) + CALL GetRoot( Settings%IfWIptFileName, Settings%FFTOutput%Name ) ENDIF - Settings%FFTOutputName = TRIM(Settings%FFTOutputName)//'_'// & + Settings%FFTOutput%Name = TRIM(Settings%FFTOutput%Name)//'_'// & TRIM(Num2LStr(Settings%FFTcoord(1)))//'x_'// & TRIM(Num2LStr(Settings%FFTcoord(2)))//'y_'// & TRIM(Num2LStr(Settings%FFTcoord(3)))//'z'//'.FFT' - CALL WrScr(NewLine//"Writing FFT results to '"//TRIM(Settings%FFTOutputName)//"' for coordinate ( "// & + CALL WrScr(NewLine//"Writing FFT results to '"//TRIM(Settings%FFTOutput%Name)//"' for coordinate ( "// & TRIM(Num2LStr(Settings%FFTcoord(1)))//", "// & TRIM(Num2LStr(Settings%FFTcoord(2)))//", "// & TRIM(Num2LStr(Settings%FFTcoord(3)))//" ).") ! If the output file already exists, warn that it will be overwritten - INQUIRE( file=TRIM(Settings%FFTOutputName), exist=TempFileExist ) - IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%FFTOutputName)) + INQUIRE( file=TRIM(Settings%FFTOutput%Name), exist=TempFileExist ) + IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%FFTOutput%Name)) ENDIF @@ -368,12 +311,12 @@ PROGRAM InflowWind_Driver ! Create WindGrid output name IF ( SettingsFlags%DvrIptFile ) THEN - CALL GetRoot( Settings%DvrIptFileName, Settings%WindGridOutputName ) + CALL GetRoot( Settings%DvrIptFileName, Settings%WindGridOutput%Name ) ELSE - CALL GetRoot( Settings%IfWIptFileName, Settings%WindGridOutputName ) + CALL GetRoot( Settings%IfWIptFileName, Settings%WindGridOutput%Name ) ENDIF - Settings%WindGridOutputName = TRIM(Settings%WindGridOutputName)//'.WindGrid.out' + Settings%WindGridOutput%Name = TRIM(Settings%WindGridOutput%Name)//'.WindGrid.out' ! Output message if some verbosity. IF ( IfWDriver_Verbose >= 5_IntKi ) THEN @@ -461,9 +404,13 @@ PROGRAM InflowWind_Driver END IF InflowWind_InitInp%RootName = trim(InflowWind_InitInp%RootName)//'.IfW' InflowWind_InitInp%RadAvg = -1.0_ReKi ! let the IfW code guess what to use + InflowWind_InitInp%BoxExceedAllowF = SettingsFlags%BoxExceedAllowF ! Set flag for allowing points outside the wind box (alternate interpolation method for FF) + if (InflowWind_InitInp%BoxExceedAllowF) InflowWind_InitInp%BoxExceedAllowIdx = 1_IntKi IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr('Calling InflowWind_Init...') + ! Set flag to calculate accelerations if requested + InflowWind_InitInp%OutputAccel = SettingsFlags%OutputAccel CALL InflowWind_Init( InflowWind_InitInp, InflowWind_u1, InflowWind_p, & InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & @@ -493,28 +440,24 @@ PROGRAM InflowWind_Driver ! Convert InflowWind file to HAWC format IF (SettingsFlags%WrHAWC) THEN - - CALL InflowWind_Convert2HAWC( InflowWind_InitInp%RootName, InflowWind_p, InflowWind_MiscVars, ErrStat, ErrMsg ) - + CALL IfW_WriteHAWC( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) IF (ErrStat > ErrID_None) THEN CALL WrScr( TRIM(ErrMsg) ) IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' InflowWind_Convert2HAWC returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + CALL WrScr(NewLine//' IfW_WriteHAWC returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) END IF - ELSE - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Convert2HAWC CALL returned without errors.'//NewLine) + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'IfW_WriteHAWC CALL returned without errors.'//NewLine) END IF - - END IF ! Write HAWC2 files + END IF ! Convert InflowWind file to Native Bladed format IF (SettingsFlags%WrBladed) THEN - CALL InflowWind_Convert2Bladed( InflowWind_InitInp%RootName, InflowWind_p, InflowWind_MiscVars, ErrStat, ErrMsg ) - + CALL IfW_WriteBladed( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) IF (ErrStat > ErrID_None) THEN CALL WrScr( TRIM(ErrMsg) ) IF ( ErrStat >= AbortErrLev ) THEN @@ -523,42 +466,40 @@ PROGRAM InflowWind_Driver ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN CALL WrScr(NewLine//' InflowWind_Convert2Bladed returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) END IF - ELSE - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Convert2Bladed CALL returned without errors.'//NewLine) + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'InflowWind_Convert2Bladed CALL returned without errors.'//NewLine) END IF END IF IF (SettingsFlags%WrVTK) THEN - CALL InflowWind_Convert2VTK( InflowWind_InitInp%RootName, InflowWind_p, InflowWind_MiscVars, ErrStat, ErrMsg ) - + CALL IfW_WriteVTK( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) IF (ErrStat > ErrID_None) THEN CALL WrScr( TRIM(ErrMsg) ) IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' InflowWind_Convert2VTK returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + CALL WrScr(NewLine//' IfW_WriteVTK returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) END IF - ELSE - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Convert2VTK CALL returned without errors.'//NewLine) + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'IfW_WriteVTK CALL returned without errors.'//NewLine) END IF END IF IF (SettingsFlags%WrUniform) THEN - CALL InflowWind_Convert2Uniform( InflowWind_InitInp%RootName, InflowWind_p, InflowWind_MiscVars, ErrStat, ErrMsg ) - + CALL IfW_WriteUniform( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) IF (ErrStat > ErrID_None) THEN CALL WrScr( TRIM(ErrMsg) ) IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' InflowWind_Convert2Uniform returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + CALL WrScr(NewLine//' IfW_WriteUniform returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) END IF - ELSE - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Convert2Uniform CALL returned without errors.'//NewLine) + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'IfW_WriteUniform CALL returned without errors.'//NewLine) END IF END IF @@ -629,9 +570,8 @@ PROGRAM InflowWind_Driver IF ( SettingsFlags%WindGrid ) THEN ! Write the header for the WindGrid output file - CALL WindGridVel_OutputWrite( Settings%WindGridOutputUnit, Settings%WindGridOutputName, SettingsFlags%WindGridOutputInit, & - Settings, InflowWind_u1%PositionXYZ, InflowWind_y1%VelocityUVW, & - TimeNow, ErrStat, ErrMsg ) + CALL WindGridVel_OutputWrite( Settings%WindGridOutput, Settings, InflowWind_u1%PositionXYZ, & + InflowWind_y1%VelocityUVW, TimeNow, ErrStat, ErrMsg ) ! Setup the actual grid points -- scan order, Y,Z,X @@ -679,6 +619,16 @@ PROGRAM InflowWind_Driver CALL ProgAbort( ErrMsg ) ENDIF + ! Allocate the array for the acceleration results -- 3 x Npoints + IF ( SettingsFlags%OutputAccel ) THEN + CALL AllocAry( InflowWind_y2%AccelUVW, 3, SIZE(InflowWind_u2%PositionXYZ, DIM=2 ), & + "Array of accelerations corresponding to Points file", ErrStat, ErrMsg ) + IF ( ErrStat /= ErrID_None ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ENDIF + ENDIF + ! WriteOutput info IF ( ALLOCATED(InflowWind_y1%WriteOutput) ) THEN ALLOCATE( InflowWind_y2%WriteOutput(SIZE(InflowWind_y1%WriteOutput)), STAT=ErrStat ) @@ -689,19 +639,19 @@ PROGRAM InflowWind_Driver InflowWind_y2%WriteOutput = InflowWind_y1%WriteOutput ENDIF - ! Now create the output file. Write header information - CALL PointsVel_OutputWrite( Settings%PointsOutputUnit, Settings%PointsOutputName, SettingsFlags%PointsOutputInit, & - Settings, InflowWind_u2%PositionXYZ, InflowWind_y2%VelocityUVW, & - TimeNow, ErrStat, ErrMsg ) + ! Now create the velocity output file. Write header information + CALL PointData_OutputWrite( Settings%PointsVelOutput, Settings, & + InflowWind_u2%PositionXYZ, & + InflowWind_y2%VelocityUVW, & + InflowWind_y2%AccelUVW, & + TimeNow, .true., ErrStat, ErrMsg ) + IF ( ErrStat /= ErrID_None ) THEN + CALL DriverCleanup() + CALL ProgAbort( 'Error creating point data velocity output file: '//trim(Settings%PointsVelOutput%Name) ) + ENDIF ENDIF - - - - - - ! FFT setup IF ( SettingsFlags%FFTcalc ) THEN @@ -745,7 +695,7 @@ PROGRAM InflowWind_Driver ! Report the rotation of the coordinates. IF ( IfWDriver_Verbose >= 10_IntKi .and. InflowWind_p%NumOuts > 0 ) THEN CALL WrScr(NewLine//NewLine//' Rotation of coordinates to prime (wind file) coordinates by rotating '// & - TRIM(Num2LStr(R2D*InflowWind_p%PropagationDir))// & + TRIM(Num2LStr(R2D*InflowWind_p%FlowField%PropagationDir))// & ' degrees (meteorological wind direction change) ...'//NewLine) if (InflowWind_p%NWindVel > 0_IntKi) then CALL WrScr(' ------ WindViXYZ --------- ----- WindViXYZprime -----') @@ -788,69 +738,72 @@ PROGRAM InflowWind_Driver TimeNow = Settings%TStart + Settings%DT*(ITime) - ! Get results for WindGrid data from IfW -- WindGrid may contain only a single point at the hub if the WindGrid flag isn't set. - CALL InflowWind_CalcOutput( TimeNow, InflowWind_u1, InflowWind_p, & - InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & - InflowWind_y1, InflowWind_MiscVars, ErrStat, ErrMsg) - + IF ( SettingsFlags%WindGrid ) THEN + ! Get results for WindGrid data from IfW -- WindGrid may contain only a single point at the hub if the WindGrid flag isn't set. + CALL InflowWind_CalcOutput( TimeNow, InflowWind_u1, InflowWind_p, & + InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & + InflowWind_y1, InflowWind_MiscVars, ErrStat, ErrMsg) - ! Make sure no errors occured that give us reason to terminate now. - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose >= 10_IntKi ) ) THEN - CALL WrScr(NewLine//' Timestep '//TRIM(Num2LStr(ITime))// & - ' InflowWind_Calc returned: ErrStat: '//TRIM(Num2LStr(ErrStat))// & - NewLine//' ErrMsg: '//TRIM(ErrMsg)//NewLine) - ENDIF - + ! Make sure no errors occured that give us reason to terminate now. + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose >= 10_IntKi ) ) THEN + CALL WrScr(NewLine//' Timestep '//TRIM(Num2LStr(ITime))// & + ' InflowWind_Calc returned: ErrStat: '//TRIM(Num2LStr(ErrStat))//NewLine// & + ' ErrMsg: '//TRIM(ErrMsg)//NewLine) + ENDIF ! Write the WindGrid results to a file for this timestep - IF ( SettingsFlags%WindGrid ) THEN - - CALL WindGridVel_OutputWrite( Settings%WindGridOutputUnit, Settings%WindGridOutputName, SettingsFlags%WindGridOutputInit, & - Settings, InflowWind_u1%PositionXYZ, InflowWind_y1%VelocityUVW, & + CALL WindGridVel_OutputWrite( Settings%WindGridOutput, Settings, & + InflowWind_u1%PositionXYZ, InflowWind_y1%VelocityUVW, & TimeNow, ErrStat, ErrMsg ) - ENDIF - - - ! Calculate results for the Points and export them for this timestep + ! If point results were requested IF ( SettingsFlags%PointsFile ) THEN - - ! Get results for Points data from IfW - CALL InflowWind_CalcOutput( TimeNow, InflowWind_u2, InflowWind_p, & - InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & - InflowWind_y2, InflowWind_MiscVars, ErrStat, ErrMsg) - - ! Output the Points results for this timestep - CALL PointsVel_OutputWrite( Settings%PointsOutputUnit, Settings%PointsOutputName, SettingsFlags%PointsOutputInit, & - Settings, InflowWind_u2%PositionXYZ, InflowWind_y2%VelocityUVW, & - TimeNow, ErrStat, ErrMsg ) - - ENDIF - - + + ! Calculate velocity/acceleration at points + CALL InflowWind_CalcOutput( TimeNow, InflowWind_u2, InflowWind_p, & + InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & + InflowWind_y2, InflowWind_MiscVars, ErrStat, ErrMsg) + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose >= 10_IntKi ) ) THEN + CALL WrScr(NewLine//' Timestep '//TRIM(Num2LStr(ITime))// & + ' InflowWind_Calc returned: ErrStat: '//TRIM(Num2LStr(ErrStat))//NewLine// & + ' ErrMsg: '//TRIM(ErrMsg)//NewLine) + ENDIF + + ! Output the Points results for this timestep + CALL PointData_OutputWrite( Settings%PointsVelOutput, Settings, & + InflowWind_u2%PositionXYZ, & + InflowWind_y2%VelocityUVW, & + InflowWind_y2%AccelUVW, & + TimeNow, .true., ErrStat, ErrMsg ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + END IF + + END IF ! Calculate results for FFT if we are performing one IF ( SettingsFlags%FFTcalc ) THEN - ! Get the results from IfW + ! Get the results from IfW ! CALL InflowWind_CalcOutput() - ! Copy results over to the array for storage + ! Copy results over to the array for storage ! FFTdata(ITime,:) = - - + ENDIF - ENDDO ! ITime loop - ! output table of results for the outlist comparison and check if very verbose -- print statements are ! used because we don't want linewrapping. IF ( IfWDriver_Verbose >= 10_IntKi ) THEN @@ -980,11 +933,10 @@ PROGRAM InflowWind_Driver SUBROUTINE DriverCleanup() - - if (Settings%WindGridOutputUnit > -1_IntKi ) CLOSE( Settings%WindGridOutputUnit ) - if (Settings%PointsOutputUnit > -1_IntKi ) CLOSE( Settings%PointsOutputUnit ) - if (Settings%FFTOutputUnit > -1_IntKi ) CLOSE( Settings%FFTOutputUnit ) - + ! Close output files that may have been opened + if (Settings%WindGridOutput%Unit > -1_IntKi ) CLOSE( Settings%WindGridOutput%Unit ) + if (Settings%PointsVelOutput%Unit > -1_IntKi ) CLOSE( Settings%PointsVelOutput%Unit ) + if (Settings%FFTOutput%Unit > -1_IntKi ) CLOSE( Settings%FFTOutput%Unit ) ! Find out how long this actually took CALL CPU_TIME( Timer(2) ) diff --git a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 index ed7801e79f..d7033445b2 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 @@ -27,6 +27,8 @@ MODULE InflowWind_Driver_Subs USE NWTC_Library USE InflowWind_Driver_Types + USE InflowWind_IO + USE IfW_FlowField IMPLICIT NONE @@ -59,25 +61,27 @@ SUBROUTINE DispHelpText( ErrStat, ErrMsg ) CALL WrScr(" (no driver input file)") CALL WrScr("") CALL WrScr(" The following options will overwrite values in the driver input file:") - CALL WrScr(" "//SwChar//"DT[#] -- timestep ") - CALL WrScr(" "//SwChar//"TStart[#] -- start time ") - CALL WrScr(" "//SwChar//"TSteps[#] -- number of timesteps ") - CALL WrScr(" "//SwChar//"xrange[#:#] -- range of x (#'s are reals) ") - CALL WrScr(" "//SwChar//"yrange[#:#] -- range of y ") - CALL WrScr(" "//SwChar//"zrange[#:#] -- range in z (ground = 0.0) ") - CALL WrScr(" "//SwChar//"Dx[#] -- spacing in x ") - CALL WrScr(" "//SwChar//"Dy[#] -- spacing in y ") - CALL WrScr(" "//SwChar//"Dz[#] -- spacing in z ") -! CALL WrScr(" "//SwChar//"sum -- summarize wind file info [N/A]") -! CALL WrScr(" "//SwChar//"FFT[X,Y,Z] -- an fft over all t using specified DT at X,Y,Z [N/A]") - CALL WrScr(" "//SwChar//"points[FILE] -- calculates at x,y,z coordinates specified in a ") + CALL WrScr(" "//SwChar//"DT[#] -- timestep ") + CALL WrScr(" "//SwChar//"TStart[#] -- start time ") + CALL WrScr(" "//SwChar//"TSteps[#] -- number of timesteps ") + CALL WrScr(" "//SwChar//"xrange[#:#] -- range of x (#'s are reals) ") + CALL WrScr(" "//SwChar//"yrange[#:#] -- range of y ") + CALL WrScr(" "//SwChar//"zrange[#:#] -- range in z (ground = 0.0) ") + CALL WrScr(" "//SwChar//"Dx[#] -- spacing in x ") + CALL WrScr(" "//SwChar//"Dy[#] -- spacing in y ") + CALL WrScr(" "//SwChar//"Dz[#] -- spacing in z ") +! CALL WrScr(" "//SwChar//"sum -- summarize wind file info [N/A]") +! CALL WrScr(" "//SwChar//"FFT[X,Y,Z] -- an fft over all t using specified DT at X,Y,Z [N/A]") + CALL WrScr(" "//SwChar//"points[FILE] -- calculates at x,y,z coordinates specified in a ") CALL WrScr(" white space delimited FILE") - CALL WrScr(" "//SwChar//"v -- verbose output ") - CALL WrScr(" "//SwChar//"vv -- very verbose output ") - CALL WrScr(" "//SwChar//"HAWC -- convert contents of to HAWC format ") - CALL WrScr(" "//SwChar//"Bladed -- convert contents of to Bladed format ") - CALL WrScr(" "//SwChar//"vtk -- convert contents of to vtk format ") - CALL WrScr(" "//SwChar//"help -- print this help menu and exit") + CALL WrScr(" "//SwChar//"v -- verbose output ") + CALL WrScr(" "//SwChar//"vv -- very verbose output ") + CALL WrScr(" "//SwChar//"HAWC -- convert contents of to HAWC format ") + CALL WrScr(" "//SwChar//"Bladed -- convert contents of to Bladed format ") + CALL WrScr(" "//SwChar//"vtk -- convert contents of to vtk format ") + CALL WrScr(" "//SwChar//"accel -- calculate wind acceleration in addition to velocity") + CALL WrScr(" "//SwChar//"BoxExceedAllow -- set flag to allow FF points outside wind box") + CALL WrScr(" "//SwChar//"help -- print this help menu and exit") CALL WrScr("") CALL WrScr(" Notes:") CALL WrScr(" -- Unspecified ranges and resolutions default to what is in the file.") @@ -327,6 +331,12 @@ SUBROUTINE ParseArg( CLSettings, CLFlags, ThisArgUC, ThisArg, ifwFlagSet, ErrSta ELSEIF ( TRIM(ThisArgUC) == "UNIFORM" ) THEN CLFlags%WrUniform = .TRUE. RETURN + ELSEIF ( TRIM(ThisArgUC) == "BOXEXCEEDALLOW" ) THEN + CLFlags%BoxExceedAllowF = .TRUE. + RETURN + ELSEIF ( TRIM(ThisArgUC) == "ACCEL" ) THEN + CLFlags%OutputAccel = .TRUE. + RETURN ELSE CALL SetErrStat( ErrID_Warn," Unrecognized option '"//SwChar//TRIM(ThisArg)//"'. Ignoring. Use option "//SwChar//"help for list of options.", & ErrStat,ErrMsg,'ParseArg') @@ -984,7 +994,15 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ! DvrFlags%SummaryFile = .TRUE. ENDIF - + ! Flag to allow sampling outside grid + CALL ReadVar( UnIn, FileName,DvrFlags%BoxExceedAllowF,'BoxExceedAllow',' Allow point sampling outside grid', & + ErrStatTmp,ErrMsgTmp, UnEchoLocal ) + IF ( ErrStatTmp /= ErrID_None ) THEN + CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) + CLOSE( UnIn ) + RETURN + ENDIF #ifdef UNUSED_INPUTFILE_LINES !------------------------------------------------------------------------------------------------- @@ -1073,7 +1091,15 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat IF ( PathIsRelative( DvrSettings%PointsFileName ) ) DvrSettings%PointsFileName = TRIM(PriPath)//TRIM(DvrSettings%PointsFileName) - + ! CalcAccel - calculate wind acceleration (unused if .not. DvrFlags%PointsFile) + CALL ReadVar( UnIn, FileName,DvrFlags%OutputAccel, 'CalcAccel', ' Calc and output wind acceleration', & + ErrStatTmp,ErrMsgTmp, UnEchoLocal ) + IF ( ErrStatTmp /= ErrID_None ) THEN + CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) + CLOSE( UnIn ) + RETURN + ENDIF !------------------------------------------------------------------------------------------------- ! gridded data output @@ -1340,6 +1366,8 @@ SUBROUTINE UpdateSettingsWithCL( DvrFlags, DvrSettings, CLFlags, CLSettings, DVR DvrFlags%WrBladed = DvrFlags%WrBladed .or. CLFlags%WrBladed ! create file if specified in either place DvrFlags%WrVTK = DvrFlags%WrVTK .or. CLFlags%WrVTK ! create file if specified in either place DvrFlags%WrUniform = DvrFlags%WrUniform .or. CLFlags%WrUniform ! create file if specified in either place + DvrFlags%BoxExceedAllowF = DvrFlags%BoxExceedAllowF .or. CLFlags%BoxExceedAllowF ! flag to allow points beyond box for FF + DvrFlags%OutputAccel = DvrFlags%OutputAccel .or. CLFlags%OutputAccel ! calculate acceleration if specified in either place ! ! Due to the complexity, we are handling overwriting driver input file settings with ! ! command line settings and the instance where no driver input file is read separately. @@ -2153,7 +2181,7 @@ SUBROUTINE WindGridMessage( Settings, ToFile, Msg, MsgLen ) IF ( ToFile ) THEN Msg='# ' ELSE - Msg="Requested wind grid data will be written to "//TRIM(Settings%WindGridOutputName)//'.' + Msg="Requested wind grid data will be written to "//TRIM(Settings%WindGridOutput%Name)//'.' ENDIF Msg = TRIM(Msg)//" Requested data:"//NewLine @@ -2262,11 +2290,8 @@ SUBROUTINE WindGridMessage( Settings, ToFile, Msg, MsgLen ) !> This subroutine outputs the results of the WindGrid calculations information at each timestep. -SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, GridXYZ, GridVel, TIME, ErrStat, ErrMsg) - - INTEGER(IntKi), INTENT(INOUT) :: FileUnit !< Unit number for the output file - CHARACTER(*), INTENT(IN ) :: FileName !< Name of the current unit number - LOGICAL, INTENT(INOUT) :: Initialized !< Was this file started before? +SUBROUTINE WindGridVel_OutputWrite (OutFile, Settings, GridXYZ, GridVel, TIME, ErrStat, ErrMsg) + TYPE(OutputFile), INTENT(INOUT) :: OutFile TYPE(IfWDriver_Settings), INTENT(IN ) :: Settings !< Settings for IfW driver REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: GridXYZ(:,:) !< The position grid passed in REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: GridVel(:,:) !< The velocity grid passed in @@ -2283,7 +2308,7 @@ SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, G INTEGER(IntKi) :: I !< generic counter - WindVelFmt = "(3(F14.7,3x),3(F10.3,3x))" + WindVelFmt = "(3(F14.7,3x),3(F14.7,3x))" ErrMsg = '' ErrStat = ErrID_None @@ -2292,39 +2317,39 @@ SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, G ! If it hasn't been initially written to, do this then exit. Otherwise set a few things and continue. - IF ( .NOT. Initialized ) THEN + IF ( .NOT. OutFile%Initialized ) THEN - CALL GetNewUnit( FileUnit ) - CALL OpenFOutFile( FileUnit, TRIM(FileName), ErrStatTmp, ErrMsgTmp ) + CALL GetNewUnit( OutFile%Unit ) + CALL OpenFOutFile( OutFile%Unit, TRIM(OutFile%Name), ErrStatTmp, ErrMsgTmp ) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WindGridVel_OutputWrite' ) IF ( ErrStat >= AbortErrLev ) RETURN - Initialized = .TRUE. + OutFile%Initialized = .TRUE. ! Write header section - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & ' on '//CurDate()//' at '//CurTime()//'.' - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at a grid of points at each '// & + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at a grid of points at each '// & 'requested timestep' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## It is arranged as blocks of X,Y,Z,U,V,W at each timestep' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## Each block is separated by two blank lines for use in gnuplot' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## It is arranged as blocks of X,Y,Z,U,V,W at each timestep' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## Each block is separated by two blank lines for use in gnuplot' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' CALL WindGridMessage( Settings, .TRUE., ErrMsgTmp, LenErrMsgTmp ) - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) ErrMsgTmp(1:LenErrMsgTmp) - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# X Y Z '// & + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) ErrMsgTmp(1:LenErrMsgTmp) + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# X Y Z '// & ' U V W' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# (m) (m) (m) '// & + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# (m) (m) (m) '// & ' (m/s) (m/s) (m/s)' ELSE - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) NewLine//NewLine - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# Time: '//TRIM(Num2LStr(TIME)) + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) NewLine//NewLine + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# Time: '//TRIM(Num2LStr(TIME)) DO I = 1,SIZE(GridXYZ,DIM=2) - WRITE (FileUnit,WindVelFmt, IOSTAT=ErrStatTmp ) GridXYZ(1,I),GridXYZ(2,I),GridXYZ(3,I),GridVel(1,I),GridVel(2,I),GridVel(3,I) + WRITE (OutFile%Unit,WindVelFmt, IOSTAT=ErrStatTmp ) GridXYZ(1,I),GridXYZ(2,I),GridXYZ(3,I),GridVel(1,I),GridVel(2,I),GridVel(3,I) ENDDO @@ -2333,29 +2358,27 @@ SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, G END SUBROUTINE WindGridVel_OutputWrite -SUBROUTINE PointsVel_OutputWrite (FileUnit, FileName, Initialized, Settings, GridXYZ, GridVel, TIME, ErrStat, ErrMsg) +SUBROUTINE PointData_OutputWrite (OutFile, Settings, GridXYZ, GridVel, GridAcc, TIME, IsVel, ErrStat, ErrMsg) - INTEGER(IntKi), INTENT(INOUT) :: FileUnit !< Unit number for the output file - CHARACTER(*), INTENT(IN ) :: FileName !< Name of the current unit number - LOGICAL, INTENT(INOUT) :: Initialized !< Was this file started before? + TYPE(OutputFile), INTENT(INOUT) :: OutFile TYPE(IfWDriver_Settings), INTENT(IN ) :: Settings !< Settings for IfW driver REAL(ReKi), INTENT(IN ) :: GridXYZ(:,:) !< The position grid passed in REAL(ReKi), INTENT(IN ) :: GridVel(:,:) !< The velocity grid passed in + REAL(ReKi), allocatable, INTENT(IN ) :: GridAcc(:,:) !< The acceleration grid passed in REAL(DbKi), INTENT(IN ) :: TIME !< The current time + LOGICAL, INTENT(IN ) :: IsVel !< Is this velocity output INTEGER(IntKi), INTENT( OUT) :: ErrStat !< returns a non-zero value when an error occurs CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - ! Temporary local variables INTEGER(IntKi) :: ErrStatTmp !< Temporary variable for the status of error message CHARACTER(2048) :: ErrMsgTmp !< Temporary variable for the error message - INTEGER(IntKi) :: LenErrMsgTmp !< Length of ErrMsgTmp (for getting WindGrid info) - INTEGER(IntKi) :: I !< Generic counter + INTEGER(IntKi) :: I, J !< Generic counter CHARACTER(61) :: NameUnitFmt !< Format specifier for the output file for channel names and units CHARACTER(61) :: PointsVelFmt !< Format specifier for the output file for wind point location and velocity - NameUnitFmt = "( 7(A16, 3X) )" - PointsVelFmt = "( 7(F16.8, 3X) )" + NameUnitFmt = "( *(A16,3X) )" + PointsVelFmt = "( *(F16.8,3X) )" ErrMsg = '' ErrStat = ErrID_None @@ -2364,40 +2387,240 @@ SUBROUTINE PointsVel_OutputWrite (FileUnit, FileName, Initialized, Settings, Gri ! If it hasn't been initially written to, do this then exit. Otherwise set a few things and continue. - IF ( .NOT. Initialized ) THEN + IF ( .NOT. OutFile%Initialized ) THEN - CALL GetNewUnit( FileUnit ) - CALL OpenFOutFile( FileUnit, TRIM(FileName), ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'PointsVel_OutputWrite' ) + CALL GetNewUnit( OutFile%Unit ) + CALL OpenFOutFile( OutFile%Unit, TRIM(OutFile%Name), ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'PointData_OutputWrite' ) IF ( ErrStat >= AbortErrLev ) RETURN - Initialized = .TRUE. + OutFile%Initialized = .TRUE. ! Write header section - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & ' on '//CurDate()//' at '//CurTime()//'.' - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at the '// & - TRIM(Num2LStr(SIZE(GridXYZ,DIM=2)))//' points specified in the '// & - 'file '//TRIM(Settings%PointsFileName)//'.' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit, NameUnitFmt, IOSTAT=ErrStatTmp ) 'T', 'X', 'Y', 'Z', 'U', 'V', 'W' - WRITE (FileUnit, NameUnitFmt, IOSTAT=ErrStatTmp ) '(s)', '(m)', '(m)', '(m)', '(m/s)', '(m/s)', '(m/s)' + if (allocated(GridAcc)) then + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity and acceleration at the '// & + TRIM(Num2LStr(SIZE(GridXYZ,DIM=2)))//' points specified in the '// & + 'file '//TRIM(Settings%PointsFileName)//'.' + else + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at the '// & + TRIM(Num2LStr(SIZE(GridXYZ,DIM=2)))//' points specified in the '// & + 'file '//TRIM(Settings%PointsFileName)//'.' + end if + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + if (allocated(GridAcc)) then + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) 'T', 'X', 'Y', 'Z', 'U', 'V', 'W', 'UA', 'VA', 'WA' + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) '(s)', '(m)', '(m)', '(m)', '(m/s)', '(m/s)', '(m/s)', '(m/s/s)', '(m/s/s)', '(m/s/s)' + else + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) 'T', 'X', 'Y', 'Z', 'U', 'V', 'W' + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) '(s)', '(m)', '(m)', '(m)', '(m/s)', '(m/s)', '(m/s)' + end if ELSE - DO I = 1,SIZE(GridXYZ,DIM=2) + if (allocated(GridAcc)) then + DO I = 1,SIZE(GridXYZ,DIM=2) + WRITE (OutFile%Unit, PointsVelFmt, IOSTAT=ErrStatTmp) TIME, (GridXYZ(J,I),j=1,3), (GridVel(J,I),j=1,3), (GridAcc(J,I),j=1,3) + ENDDO + else + DO I = 1,SIZE(GridXYZ,DIM=2) + WRITE (OutFile%Unit, PointsVelFmt, IOSTAT=ErrStatTmp) TIME, (GridXYZ(J,I),j=1,3), (GridVel(J,I),j=1,3) + ENDDO + end if - WRITE (FileUnit, PointsVelFmt, IOSTAT=ErrStatTmp ) TIME, GridXYZ(1,I), GridXYZ(2,I), GridXYZ(3,I), GridVel(1,I), GridVel(2,I), GridVel(3,I) + ENDIF - ENDDO +END SUBROUTINE PointData_OutputWrite - ENDIF -END SUBROUTINE PointsVel_OutputWrite +subroutine IfW_WriteUniform(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteUniform" + type(UniformFieldType) :: UF + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_WriteHH(FF%Uniform, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + case (Grid3D_FieldType) + + call Grid3D_to_Uniform(FF%Grid3D, UF, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Uniform_WriteHH(UF, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case default + + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to UniformWind format.' + end select +end subroutine IfW_WriteUniform +subroutine IfW_WriteHAWC(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_Convert2HAWC" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Grid3D_WriteHAWC(G3D, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case (Grid3D_FieldType) + + call Grid3D_WriteHAWC(FF%Grid3D, FileRootName, unit, ErrStat, ErrMsg) + + case default + + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field Type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to HAWC format.' + + end select + +end subroutine + +subroutine IfW_WriteBladed(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteBladed" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Grid3D_WriteBladed(G3D, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case (Grid3D_FieldType) + + call Grid3D_WriteBladed(FF%Grid3D, FileRootName, unit, ErrStat, ErrMsg) + + case default + + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to Bladed format.' + + end select + +end subroutine + + +subroutine IfW_WriteVTK(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteVTK" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Grid3D_WriteVTK(G3D, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case (Grid3D_FieldType) + + call Grid3D_WriteVTK(FF%Grid3D, FileRootName, unit, ErrStat, ErrMsg) + + case default + + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to VTK format.' + + end select + +end subroutine IfW_WriteVTK !> This routine exists only to support the development of the module. It will not be needed after the module is complete. @@ -2405,13 +2628,14 @@ SUBROUTINE printSettings( DvrFlags, DvrSettings ) ! The arguments TYPE( IfWDriver_Flags ), INTENT(IN ) :: DvrFlags !< Flags indicating which settings were set TYPE( IfWDriver_Settings ), INTENT(IN ) :: DvrSettings !< Stored settings + integer(IntKi) :: i CALL WrsCr(TRIM(GetNVD(DvrSettings%ProgInfo))) CALL WrScr(' DvrIptFile: '//FLAG(DvrFlags%DvrIptFile)// ' '//TRIM(DvrSettings%DvrIptFileName)) CALL WrScr(' IfWIptFile: '//FLAG(DvrFlags%IfWIptFile)// ' '//TRIM(DvrSettings%IfWIptFileName)) CALL WrScr(' PointsFile: '//FLAG(DvrFlags%PointsFile)// ' '//TRIM(DvrSettings%PointsFileName)) - CALL WrScr(' FFTOutputName: '//FLAG(DvrFlags%FFTcalc)// ' '//TRIM(DvrSettings%FFTOutputName)) - CALL WrScr(' WindGridOutName: '//FLAG(DvrFlags%WindGrid)// ' '//TRIM(DvrSettings%WindGridOutputName)) + CALL WrScr(' FFTOutputName: '//FLAG(DvrFlags%FFTcalc)// ' '//TRIM(DvrSettings%FFTOutput%Name)) + CALL WrScr(' WindGridOutName: '//FLAG(DvrFlags%WindGrid)// ' '//TRIM(DvrSettings%WindGridOutput%Name)) CALL WrScr(' Summary: '//FLAG(DvrFlags%Summary)) CALL WrScr(' SummaryFile: '//FLAG(DvrFlags%SummaryFile)// ' '//TRIM(DvrSettings%SummaryFileName)) CALL WrScr(' TStart: '//FLAG(DvrFlags%TStart)// ' '//TRIM(Num2LStr(DvrSettings%TStart))) @@ -2442,11 +2666,11 @@ SUBROUTINE printSettings( DvrFlags, DvrSettings ) CALL WrScr(' Dx: '//FLAG(DvrFlags%Dx)// ' '//TRIM(Num2LStr(DvrSettings%GridDelta(1)))) CALL WrScr(' Dy: '//FLAG(DvrFlags%Dy)// ' '//TRIM(Num2LStr(DvrSettings%GridDelta(2)))) CALL WrScr(' Dz: '//FLAG(DvrFlags%Dz)// ' '//TRIM(Num2LStr(DvrSettings%GridDelta(3)))) - CALL WrScr(' WindGridOutputInit: '//FLAG(DvrFlags%WindGridOutputInit)//' Unit #: '//TRIM(Num2LStr(DvrSettings%WindGridOutputUnit))) + CALL WrScr(' WindGridOutputInit: '//FLAG(DvrSettings%WindGridOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%WindGridOutput%Unit))) end if - CALL WrScr(' FFTOutputInit: '//FLAG(DvrFlags%FFTOutputInit)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%FFTOutputUnit))) - CALL WrScr(' PointsOutputInit: '//FLAG(DvrFlags%PointsOutputInit)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsOutputUnit))) - RETURN + CALL WrScr(' FFTOutputInit: '//FLAG(DvrSettings%FFTOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%FFTOutput%Unit))) + CALL WrScr(' PointsVelOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) + CALL WrScr(' PointsAccOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) END SUBROUTINE printSettings diff --git a/modules/inflowwind/src/InflowWind_Driver_Types.f90 b/modules/inflowwind/src/InflowWind_Driver_Types.f90 index 49fa3446d5..669303cf60 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Types.f90 @@ -31,6 +31,12 @@ MODULE InflowWind_Driver_Types IMPLICIT NONE + TYPE OutputFile + LOGICAL :: Initialized = .FALSE. !< Flag indicating that file has been initialized + CHARACTER(1024) :: Name = "" !< Filename for output from points read in from points file + INTEGER(IntKi) :: Unit = -1 !< Unit number for the output file for the Points file output + END TYPE + !> This contains flags to note if the settings were made. This same data structure is !! used both during the driver input file and the command line options. !! @@ -38,7 +44,7 @@ MODULE InflowWind_Driver_Types !! it is handled internally by InflowWInd. !! !! NOTE: The wind direction is specified by the InflowWind input file. - TYPE :: IfWDriver_Flags + TYPE :: IfWDriver_Flags LOGICAL :: DvrIptFile = .FALSE. !< Was an input file name given on the command line? LOGICAL :: IfWIptFile = .FALSE. !< Was an InflowWind input file requested? LOGICAL :: Summary = .FALSE. !< create a summary at command line? (data extents in the wind file) @@ -59,54 +65,47 @@ MODULE InflowWind_Driver_Types LOGICAL :: Dy = .FALSE. !< speficied a resolution in y LOGICAL :: Dz = .FALSE. !< specified a resolution in z - LOGICAL :: PointsFile = .FALSE. !< points filename to read in -- command line option only + LOGICAL :: PointsFile = .FALSE. !< points filename to read in + LOGICAL :: OutputAccel = .FALSE. !< flag to calculate and output wind acceleration in addition to velocity - LOGICAL :: WindGridOutputInit = .FALSE. !< Is the WindGridOut file initialized - LOGICAL :: PointsOutputInit = .FALSE. !< Is the Points output file initialized - LOGICAL :: FFTOutputInit = .FALSE. !< Is the FFT output file initialized LOGICAL :: Verbose = .FALSE. !< Verbose error reporting LOGICAL :: VVerbose = .FALSE. !< Very Verbose error reporting + LOGICAL :: BoxExceedAllowF = .FALSE. !< set flag to allow exceeding wind box boundaries for FF files (for diagnostic purposes) LOGICAL :: WrHAWC = .FALSE. !< Requested file conversion to HAWC2 format? LOGICAL :: WrBladed = .FALSE. !< Requested file conversion to Bladed format? LOGICAL :: WrVTK = .FALSE. !< Requested file output as VTK? LOGICAL :: WrUniform = .FALSE. !< Requested file output as Uniform wind format? - END TYPE IfWDriver_Flags + END TYPE IfWDriver_Flags ! This contains all the settings (possible passed in arguments). - TYPE :: IfWDriver_Settings - CHARACTER(1024) :: DvrIptFileName !< Driver input file name - CHARACTER(1024) :: IfWIptFileName !< Filename of InflowWind input file to read (if no driver input file) - CHARACTER(1024) :: SummaryFileName !< Filename for the summary information output - - CHARACTER(1024) :: PointsFileName !< Filename of points file to read in - CHARACTER(1024) :: PointsOutputName !< Filename for output from points read in from points file - CHARACTER(1024) :: FFTOutputName !< Filename for output from points read in from points file - CHARACTER(1024) :: WindGridOutputName !< Filename for output from points read in from points file - - INTEGER(IntKi) :: WindGridOutputUnit !< Unit number for the output file for the wind grid data - INTEGER(IntKi) :: PointsOutputUnit !< Unit number for the output file for the Points file output - INTEGER(IntKi) :: FFTOutputUnit !< Unit number for the output file for the FFT results - - INTEGER(IntKi) :: NumTimeSteps !< Number of timesteps - REAL(DbKi) :: DT !< resolution of time - REAL(DbKi) :: TStart !< range of time -- end time converted from TRange (command line option only) + TYPE :: IfWDriver_Settings + CHARACTER(1024) :: DvrIptFileName = "" !< Driver input file name + CHARACTER(1024) :: IfWIptFileName = "" !< Filename of InflowWind input file to read (if no driver input file) + CHARACTER(1024) :: SummaryFileName = "" !< Filename for the summary information output + CHARACTER(1024) :: PointsFileName = "" !< Filename of points file to read in + + INTEGER(IntKi) :: NumTimeSteps = 0 !< Number of timesteps + REAL(DbKi) :: DT = 0.0_DbKi !< resolution of time + REAL(DbKi) :: TStart = 0.0_DbKi !< range of time -- end time converted from TRange (command line option only) - REAL(ReKi) :: FFTcoord(1:3) !< (x,y,z) coordinate to do an FFT at + REAL(ReKi) :: FFTcoord(1:3) = 0.0_ReKi !< (x,y,z) coordinate to do an FFT at - REAL(ReKi) :: GridDelta(1:3) !< (GridDx,GridDy,GridDz) -- grid point spacing - INTEGER(IntKi) :: GridN(1:3) !< (GridNx,GridNy,GridNz) -- number of grid points + REAL(ReKi) :: GridDelta(1:3) = 0.0_ReKi !< (GridDx,GridDy,GridDz) -- grid point spacing + INTEGER(IntKi) :: GridN(1:3) = 1_IntKi !< (GridNx,GridNy,GridNz) -- number of grid points - REAL(ReKi) :: XRange(1:2) !< Range in the x-direction for the gridded data - REAL(ReKi) :: YRange(1:2) !< Range in the y-direction for the gridded data - REAL(ReKi) :: ZRange(1:2) !< Range in the z-direction for the gridded data + REAL(ReKi) :: XRange(1:2) = 0.0_ReKi !< Range in the x-direction for the gridded data + REAL(ReKi) :: YRange(1:2) = 0.0_ReKi !< Range in the y-direction for the gridded data + REAL(ReKi) :: ZRange(1:2) = 0.0_ReKi !< Range in the z-direction for the gridded data - TYPE(ProgDesc) :: ProgInfo !< Program info - TYPE(ProgDesc) :: IfWProgInfo !< Program info for InflowWind + TYPE(ProgDesc) :: ProgInfo !< Program info + TYPE(OutputFile) :: WindGridOutput + TYPE(OutputFile) :: FFTOutput + TYPE(OutputFile) :: PointsVelOutput - END TYPE IfWDriver_Settings + END TYPE IfWDriver_Settings END MODULE InflowWind_Driver_Types diff --git a/modules/inflowwind/src/InflowWind_IO.f90 b/modules/inflowwind/src/InflowWind_IO.f90 new file mode 100644 index 0000000000..117cdb0d6d --- /dev/null +++ b/modules/inflowwind/src/InflowWind_IO.f90 @@ -0,0 +1,2922 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2022 National Renewable Energy Laboratory +! +! This file is part of InflowWind. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +!********************************************************************************************************************************** + +module InflowWind_IO + +use NWTC_Library +use InflowWind_IO_Types +use IfW_FlowField + +implicit none +private + +public :: IfW_SteadyWind_Init, & + IfW_UniformWind_Init, & + IfW_TurbSim_Init, & + IfW_Bladed_Init, & + IfW_HAWC_Init, & + IfW_User_Init, & + IfW_Grid4D_Init, & + IfW_Points_Init + +public :: Uniform_WriteHH, & + Grid3D_WriteBladed, & + Grid3D_WriteHAWC, & + Grid3D_WriteVTK + +type(ProgDesc), parameter :: InflowWind_IO_Ver = ProgDesc('InflowWind_IO', '', '') + +integer(IntKi), parameter :: ScaleMethod_None = 0, & !< no scaling + ScaleMethod_Direct = 1, & !< direct scaling factors + ScaleMethod_StdDev = 2 !< requested standard deviation + +contains + +subroutine IfW_Points_Init(InitInp, PF, ErrStat, ErrMsg) + type(Points_InitInputType), intent(in) :: InitInp + type(PointsFieldType), intent(out) :: PF + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'IfW_Points_Init' + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! UVW components at points + call AllocAry(PF%Vel, 3, InitInp%NumWindPoints, & + 'Point Velocity Array', TmpErrStat, TmpErrMsg) + call SetErrStat(ErrStat, ErrMsg, TmpErrStat, TmpErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + +end subroutine + +!> IfW_SteadyWind_Init initializes a Uniform field with with one set of values. +subroutine IfW_SteadyWind_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg) + type(Steady_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(UniformFieldType), intent(out) :: UF + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'IfW_SteadyWind_Init' + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! Set parameters from inititialization input + UF%DataSize = 1 + UF%RefHeight = InitInp%RefHt + UF%RefLength = 1.0_ReKi + + ! Allocate uniform wind data arrays + call UniformWind_AllocArrays(UF, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Set data values + UF%Time = 0.0_ReKi + UF%VelH = InitInp%HWindSpeed + UF%VelV = 0.0_ReKi + UF%VelGust = 0.0_ReKi + UF%AngleH = 0.0_ReKi + UF%AngleV = 0.0_ReKi + UF%ShrH = 0.0_ReKi + UF%ShrV = InitInp%PLExp + UF%LinShrV = 0.0_ReKi + + !---------------------------------------------------------------------------- + ! Set wind file data + !---------------------------------------------------------------------------- + + FileDat%FileName = "" + FileDat%WindType = 1 + FileDat%RefHt = UF%RefHeight + FileDat%RefHt_Set = .false. + FileDat%DT = 0.0_ReKi + FileDat%NumTSteps = UF%DataSize + FileDat%ConstantDT = .false. + FileDat%TRange = 0.0_ReKi + FileDat%TRange_Limited = .false. + FileDat%YRange = 0.0_ReKi + FileDat%YRange_Limited = .false. + FileDat%ZRange = 0.0_ReKi + FileDat%ZRange_Limited = .false. + FileDat%BinaryFormat = 0_IntKi + FileDat%IsBinary = .false. + FileDat%TI = 0.0_ReKi + FileDat%TI_listed = .false. + FileDat%MWS = InitInp%HWindSpeed + + !---------------------------------------------------------------------------- + ! Write summary file if applicable + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A80)') 'Steady wind -- Constant wind profile for entire simulation. No windfile read in.' + write (SumFileUnit, '(A40,G12.4)') ' Reference height: ', UF%RefHeight + write (SumFileUnit, '(A40,G12.4)') ' Horizontal velocity: ', UF%VelH(1) + write (SumFileUnit, '(A40,G12.4)') ' Vertical sheer power law exponent: ', UF%ShrV(1) + + ! Get IO status for unit + inquire (SumFileUnit, iostat=TmpErrStat) + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine + +!> IfW_UniformWind_Init initializes a Uniform field from file. +subroutine IfW_UniformWind_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg) + type(Uniform_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(UniformFieldType), intent(out) :: UF + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'IfW_UniformWind_Init' + integer(IntKi), parameter :: MaxNumCols = 9 + integer(IntKi), parameter :: MaxTries = 100 + integer(IntKi) :: NumCols + integer(IntKi) :: LineNo, ILine + integer(IntKi) :: i + type(FileInfoType) :: WindFileInfo + logical :: WindFileConstantDT + real(DbKi) :: WindFileDT + real(ReKi) :: DirDiff + real(ReKi) :: TmpData(MaxNumCols) ! Temp variable for storing wind file data + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! Set parameters from inititialization input + UF%RefHeight = InitInp%RefHt + UF%RefLength = InitInp%RefLength + + ! Read wind data from file or init input data + if (InitInp%UseInputFile) then + call ProcessComFile(InitInp%WindFileName, WindFileInfo, TmpErrStat, TmpErrMsg) + else + call NWTC_Library_CopyFileInfoType(InitInp%PassedFileData, WindFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg) + end if + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Get number of data lines in file + UF%DataSize = WindFileInfo%NumLines + + ! Allocate uniform wind data arrays + call UniformWind_AllocArrays(UF, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Parse wind file data + !---------------------------------------------------------------------------- + + ! Initialize reading variables + NumCols = MaxNumCols + LineNo = 1 + + ! Attempt to read 9 columns from line; if error, upflow column is not in file + ! so set upflow=0 and reduce number of columns to read remaning data + call ParseAry(WindFileInfo, LineNo, "HH file line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Info, ' Could not read upflow column in uniform wind files. Assuming upflow is 0.', & + ErrStat, ErrMsg, RoutineName) + UF%AngleV = 0 + NumCols = MaxNumCols - 1 + end if + + ! Parse the data and store it + LineNo = 1 + do i = 1, UF%DataSize + call ParseAry(WindFileInfo, LineNo, "HH file line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + UF%Time(i) = TmpData(1) + UF%VelH(i) = TmpData(2) + UF%AngleH(i) = TmpData(3)*D2R + UF%VelV(i) = TmpData(4) + UF%ShrH(i) = TmpData(5) + UF%ShrV(i) = TmpData(6) + UF%LinShrV(i) = TmpData(7) + UF%VelGust(i) = TmpData(8) + if (NumCols > 8) UF%AngleV(i) = TmpData(9)*D2R + end do + + !---------------------------------------------------------------------------- + ! Ensure the wind direction isn't jumping more than 180 degrees between + ! any 2 consecutive input times. + ! (Avoids interpolation errors with modular arithemetic.) + !---------------------------------------------------------------------------- + + do i = 2, UF%DataSize + ILine = 1 + do while (ILine < MaxTries) + DirDiff = (UF%AngleH(i) - UF%AngleH(i - 1)) + if (abs(DirDiff) < Pi) exit + UF%AngleH(i) = UF%AngleH(i) - SIGN(TwoPi, DirDiff) + ILine = ILine + 1 + end do + + if (ILine >= MaxTries) then + TmpErrMsg = ' Error calculating wind direction from uniform wind file. p%AngleH(' & + //TRIM(Num2LStr(i))//') = '//TRIM(Num2LStr(UF%AngleH(i)))//'; p%AngleH(' & + //TRIM(Num2LStr(i + 1))//') = '//TRIM(Num2LStr(UF%AngleH(i + 1))) + call SetErrStat(ErrID_Fatal, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + end if + end do + + !---------------------------------------------------------------------------- + ! Find out information on the timesteps and range + !---------------------------------------------------------------------------- + + ! Uniform timesteps + if (UF%DataSize > 3) then + WindFileConstantDT = .true. + WindFileDT = UF%Time(2) - UF%Time(1) + do I = 3, UF%DataSize + if (.not. EqualRealNos((UF%Time(i) - UF%Time(i - 1)), real(WindFileDT, ReKi))) then + WindFileConstantDT = .false. + exit + end if + end do + else + ! Insufficient points to check, report that the timesteps are not uniform + WindFileConstantDT = .false. + WindFileDT = 0.0_ReKi + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + FileDat%FileName = InitInp%WindFileName + FileDat%WindType = 2 + FileDat%RefHt = UF%RefHeight + FileDat%RefHt_Set = .false. + FileDat%DT = WindFileDT + FileDat%NumTSteps = UF%DataSize + FileDat%ConstantDT = WindFileConstantDT + FileDat%TRange = [UF%Time(1), UF%Time(UF%DataSize)] + FileDat%TRange_Limited = .false. + FileDat%YRange = (/0.0_ReKi, 0.0_ReKi/) + FileDat%YRange_Limited = .false. + FileDat%ZRange = (/0.0_ReKi, 0.0_ReKi/) + FileDat%ZRange_Limited = .false. + FileDat%BinaryFormat = 0_IntKi + FileDat%IsBinary = .false. + FileDat%TI = 0.0_ReKi + FileDat%TI_listed = .false. + + if (UF%DataSize == 1) then + FileDat%MWS = UF%VelH(1) + else + FileDat%MWS = 0.0_ReKi + do i = 2, UF%DataSize + FileDat%MWS = FileDat%MWS + 0.5_ReKi*(UF%VelH(i) + UF%VelH(i - 1))* & + (UF%Time(i) - UF%Time(i - 1)) + end do + FileDat%MWS = FileDat%MWS/(UF%Time(UF%DataSize) - UF%Time(1)) + end if + + ! Check if the fist data point from the file is not along the X-axis while + ! applying the windfield rotation + if ((.not. EqualRealNos(UF%AngleH(1), 0.0_ReKi)) .and. & + (.not. EqualRealNos(InitInp%PropagationDir, 0.0_ReKi))) then + call SetErrStat(ErrID_Warn, ' Possible double rotation of wind field! Uniform wind file starts with a wind direction of '// & + TRIM(Num2LStr(UF%AngleH(1)*R2D))// & + ' degrees and the InflowWind input file specifies a PropagationDir of '// & + TRIM(Num2LStr(InitInp%PropagationDir*R2D))//' degrees.', & + ErrStat, ErrMsg, RoutineName) + end if + + !---------------------------------------------------------------------------- + ! Print warnings and messages + !---------------------------------------------------------------------------- + + if (UF%Time(1) > 0.0) then + TmpErrMsg = 'The uniform wind file : "'//TRIM(ADJUSTL(InitInp%WindFileName))// & + '" starts at a time '//'greater than zero. Interpolation errors may result.' + call SetErrStat(ErrID_Warn, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + end if + + if (UF%DataSize == 1) then + TmpErrMsg = ' Only 1 line in uniform wind file. Steady, horizontal wind speed at the hub height is '// & + TRIM(Num2LStr(UF%VelH(1)))//' m/s.' + call SetErrStat(ErrID_Info, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + end if + + !---------------------------------------------------------------------------- + ! Write to the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'Uniform wind. Module '//TRIM(InflowWind_IO_Ver%Name)//' '//TRIM(InflowWind_IO_Ver%Ver) + write (SumFileUnit, '(A)') ' FileName: '//TRIM(InitInp%WindFileName) + write (SumFileUnit, '(A34,G12.4)') ' Reference height (m): ', UF%RefHeight + write (SumFileUnit, '(A34,G12.4)') ' Reference length (m): ', UF%RefLength + write (SumFileUnit, '(A32,I8)') ' Number of data lines: ', UF%DataSize + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(UF%Time(1)))//' : '//TRIM(Num2LStr(UF%Time(UF%DataSize)))//' ]' + + ! Get IO status for unit + inquire (SumFileUnit, iostat=TmpErrStat) + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine + +!> UniformWind_AllocArrays allocates the data arrays in the Uniform field. +subroutine UniformWind_AllocArrays(UF, ErrStat, ErrMsg) + type(UniformFieldType), intent(inout) :: UF + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'UniformWind_AllocArrays' + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + if (.not. allocated(UF%Time)) then + call AllocAry(UF%Time, UF%DataSize, 'Uniform wind time', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%VelH)) then + call AllocAry(UF%VelH, UF%DataSize, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%AngleH)) then + call AllocAry(UF%AngleH, UF%DataSize, 'Uniform wind direction', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%AngleV)) then + call AllocAry(UF%AngleV, UF%DataSize, 'Uniform wind upflow angle', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%VelV)) then + call AllocAry(UF%VelV, UF%DataSize, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%ShrH)) then + call AllocAry(UF%ShrH, UF%DataSize, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%ShrV)) then + call AllocAry(UF%ShrV, UF%DataSize, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%LinShrV)) then + call AllocAry(UF%LinShrV, UF%DataSize, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%VelGust)) then + call AllocAry(UF%VelGust, UF%DataSize, 'Uniform gust velocity', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + +end subroutine + +!> Uniform_WriteHH writes a Uniform field hub-height wind file. +subroutine Uniform_WriteHH(UF, FileRootName, unit, ErrStat, ErrMsg) + + type(UniformFieldType), intent(in) :: UF !< Parameter + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(in) :: Unit !< Indicates whether an error occurred (see NWTC_Library) + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = 'Uniform_WriteHH' + integer(IntKi) :: i + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + call OpenFOutFile(unit, trim(FileRootName)//'.UniformWind.dat', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit, "(A)") "#" + write (unit, "(A)") '# Uniform Wind (deterministic) file for ENFAST generated by InflowWind' + write (unit, "(A)") "#" + write (unit, "(A)") "! Time Wind Wind Vertical Horiz. Pwr.Law Lin.Vert. Gust Upflow" + write (unit, "(A)") "! Speed Dir Speed Shear Vert.Shr Shear Speed Angle" + write (unit, "(A)") "! (sec) (m/s) (Deg) (m/s) (m/s) (deg)" + + do i = 1, UF%DataSize + write (unit, "(F15.5,8(1x,F11.4))") UF%Time(i), UF%VelH(i), UF%AngleH(i)*R2D, UF%VelV(i), & + UF%ShrH(i), UF%ShrV(i), UF%LinShrV(i), UF%VelGust(i), UF%AngleV(i)*R2D + end do + + close (unit) + +end subroutine Uniform_WriteHH + +!> Read_TurbSim reads the binary TurbSim-format FF file (.bts). It fills the FFData array with +!! velocity data for the grids and fills the Tower array with velocities at points on the tower +!! (if data exists). +subroutine IfW_TurbSim_Init(InitInp, SumFileUnit, G3D, FileDat, ErrStat, ErrMsg) + + type(TurbSim_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(Grid3DFieldType), intent(out) :: G3D + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_TurbSim_Init" + integer(IntKi) :: WindFileUnit + integer(B2Ki), allocatable :: VelRaw(:, :, :) ! raw grid-field velocity data at one time step + integer(B2Ki), allocatable :: TwrRaw(:, :) ! raw towrer velocity data at one time step + character(:), allocatable :: DescStr ! description string contained in the file + integer(IntKi) :: IC ! loop counter for wind components + integer(IntKi) :: IT ! loop counter for time + integer(IntKi) :: NChar ! number of characters in the description string + real(SiKi) :: Vslope(3) ! slope for "un-normalizing" data + real(SiKi) :: Voffset(3) ! offset for "un-normalizing" data + integer(IntKi) :: TmpErrStat ! temporary error status + character(ErrMsgLen) :: TmpErrMsg ! temporary error message + + type :: TurbSimHeaderType + integer(B2Ki) :: FileID + integer(B4Ki) :: NZGrids, NYGrids, NTGrids, NSteps + real(SiKi) :: dz, dy, dt + real(SiKi) :: mws, ref_height, grid_base_height + real(SiKi) :: VslopeX, VoffsetX + real(SiKi) :: VslopeY, VoffsetY + real(SiKi) :: VslopeZ, VoffsetZ + integer(B4Ki) :: DescLen + end type + + type(TurbSimHeaderType) :: header + + !---------------------------------------------------------------------------- + ! Initialize error variables + !---------------------------------------------------------------------------- + + ErrStat = ErrID_None + ErrMsg = "" + + !---------------------------------------------------------------------------- + ! Open the binary wind file and read header + !---------------------------------------------------------------------------- + + ! Get a unit number to use for the wind file + call GetNewUnit(WindFileUnit, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Open binary file + call OpenBInpFile(WindFileUnit, TRIM(InitInp%WindFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Read header from file + read (WindFileUnit, IOSTAT=TmpErrStat) header + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header of the FF binary file "' & + //TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Populate parameter data from header + !---------------------------------------------------------------------------- + + G3D%WindFileFormat = header%FileID ! file format identifier + G3D%Periodic = header%FileID == 8 ! 7 is used for non-periodic wind files; 8 is periodic wind + G3D%InterpTower = .false. ! wind should not be interpolated at tower + G3D%AddMeanAfterInterp = .false. ! do not add mean wind speed after interpolation + + G3D%DTime = real(header%dt, ReKi) ! grid spacing in time (dt), m/s + G3D%Rate = 1.0_ReKi/G3D%DTime ! Data rate (1/DTime), Hertz + + G3D%NComp = 3 ! TurbSim file file contains 3 wind components + G3D%NYGrids = header%NYGrids ! the number of grid points laterally + G3D%NZGrids = header%NZGrids ! the number of grid points vertically + G3D%NTGrids = header%NTGrids ! the number of tower points + G3D%NSteps = header%NSteps ! the number of time steps + + G3D%InvDY = 1.0_ReKi/real(header%dy, ReKi) ! 1/dy + G3D%YHWid = 0.5_ReKi*(G3D%NYGrids - 1)/G3D%InvDY ! half the grid width (m) + + G3D%InvDZ = 1.0_ReKi/real(header%dz, ReKi) ! 1/dz + G3D%ZHWid = 0.5_ReKi*(G3D%NZGrids - 1)/G3D%InvDZ ! half the grid height (m) + + G3D%MeanWS = real(header%mws, ReKi) ! the mean wind speed at hub height (m/s) + G3D%InvMWS = 1.0_ReKi/G3D%MeanWS ! inverse of mean wind speed + + G3D%RefHeight = real(header%ref_height, ReKi) ! height of the hub (m) + G3D%GridBase = real(header%grid_base_height, ReKi) ! height of the bottom of the grid (m) + + if (G3D%Periodic) then + G3D%InitXPosition = 0 ! start at the hub + G3D%TotalTime = G3D%NSteps*G3D%DTime + else + G3D%InitXPosition = G3D%YHWid ! start half the grid width ahead of the turbine + G3D%TotalTime = (G3D%NSteps - 1)*G3D%DTime + end if + + G3D%WindProfileType = WindProfileType_None ! unused for turbsim + G3D%PLExp = 0 ! unused for turbsim + G3D%Z0 = 0 ! unused for turbsim + + !---------------------------------------------------------------------------- + ! Binary scaling factors from header + !---------------------------------------------------------------------------- + + ! Wind component slope for scaling, REAL(4) + Vslope = [header%VslopeX, header%VslopeY, header%VslopeZ] + + ! Wind component offset for scaling, REAL(4) + Voffset = [header%VoffsetX, header%VoffsetY, header%VoffsetZ] + + !---------------------------------------------------------------------------------------------- + ! Read the description string: "Generated by TurbSim (vx.xx, dd-mmm-yyyy) on dd-mmm-yyyy at hh:mm:ss." + !---------------------------------------------------------------------------------------------- + + ! The number of characters in the description string, max 200, INT(4) + NChar = header%DescLen + + ! Read description bytes, INT(1) + allocate (character(NChar)::DescStr) + read (WindFileUnit, IOSTAT=TmpErrStat) DescStr + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading description line in the FF binary file "' & + //TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Allocate arrays for the grid-field grid and tower if applicable + !---------------------------------------------------------------------------- + + ! Allocate storage for grid-field velocity data + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, & + 'grid-field velocity data', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for raw grid-field velocity for each time step + allocate (VelRaw(G3D%NComp, G3D%NYGrids, G3D%NZGrids), stat=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, "error allocating grid-field time step velocity data", & + ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + + ! If tower grids specified + if (G3D%NTGrids > 0) then + + ! Allocate storage for tower velocity data + call AllocAry(G3D%VelTower, G3D%NComp, G3D%NTGrids, G3D%NSteps, & + 'tower wind velocity data.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for raw tower data for each timestep + allocate (TwrRaw(G3D%NComp, G3D%NTGrids), stat=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, "error allocating tower time step velocity data", & + ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + end if + + !---------------------------------------------------------------------------- + ! Read the 16-bit raw velocity data and scale it to 32-bit real + !---------------------------------------------------------------------------- + + ! This could take a while, so we'll write a message indicating what's going on: + call WrScr(NewLine//' Reading a ' & + //TRIM(Num2LStr(G3D%NYGrids))//'x' & + //TRIM(Num2LStr(G3D%NZGrids))// & + ' grid ('//TRIM(Num2LStr(G3D%YHWid*2))//' m wide, '// & + TRIM(Num2LStr(G3D%GridBase))//' m to '// & + TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2))// & + ' m above ground) with a characteristic wind speed of '// & + TRIM(Num2LStr(G3D%MeanWS))//' m/s. '//TRIM(DescStr)) + + ! Loop through time steps + do IT = 1, G3D%NSteps + + ! Read grid-field raw wind data (normalized) comprised of 2-byte integers, INT(2) + ! Indices are Velocity components, Y coordinates, Z coordinates + read (WindFileUnit, IOSTAT=TmpErrStat) VelRaw + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading grid wind components in the FF binary file "'// & + TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + ! Loop through wind components (U, V, W), calculate de-normalized velocity (m/s) + do IC = 1, 3 + G3D%Vel(IC, :, :, IT) = (real(VelRaw(IC, :, :), SiKi) - Voffset(IC))/VSlope(IC) + end do !IC + + ! Read tower raw wind data (normalized) comprised of 2-byte integers, INT(2) + ! Indices are Velocity components, Z coordinates + if (G3D%NTGrids > 0) then + read (WindFileUnit, IOSTAT=TmpErrStat) TwrRaw + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading tower wind components in the FF binary file "'// & + TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + ! Loop through wind components (U, V, W), calculate de-normalized velocity (m/s) + do IC = 1, 3 + G3D%VelTower(IC, :, IT) = (real(TwrRaw(IC, :), SiKi) - Voffset(IC))/VSlope(IC) + end do + end if + end do + + !---------------------------------------------------------------------------- + ! Close the file + !---------------------------------------------------------------------------- + + close (WindFileUnit) + + if (G3D%Periodic) then + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz grid-field data (period of '// & + TRIM(Num2LStr(G3D%DTime*(G3D%NSteps)))//' seconds).') + else + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz grid-field data ('// & + TRIM(Num2LStr(G3D%DTime*(G3D%NSteps - 1)))//' seconds).') + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + call Grid3D_PopulateWindFileDat(G3D, InitInp%WindFileName, 3, G3D%NTGrids > 0, FileDat) + + !---------------------------------------------------------------------------- + ! Write the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'TurbSim wind type. Read by InflowWind sub-module ' & + //TRIM(InflowWind_IO_Ver%Name)//' '//TRIM(InflowWind_IO_Ver%Ver) + write (SumFileUnit, '(A)') TRIM(TmpErrMsg) + write (SumFileUnit, '(5x,A)') 'FileName: '//TRIM(InitInp%WindFileName) + write (SumFileUnit, '(5x,A29,I3)') 'Binary file format id: ', G3D%WindFileFormat + write (SumFileUnit, '(5x,A29,G12.4)') 'Reference height (m): ', G3D%RefHeight + write (SumFileUnit, '(5x,A29,G12.4)') 'Timestep (s): ', G3D%DTime + write (SumFileUnit, '(5x,A29,I12)') 'Number of timesteps: ', G3D%NSteps + write (SumFileUnit, '(5x,A29,G12.4)') 'Mean windspeed (m/s): ', G3D%MeanWS + write (SumFileUnit, '(5x,A29,L1)') 'Windfile is periodic: ', G3D%Periodic + write (SumFileUnit, '(5x,A29,L1)') 'Windfile includes tower: ', G3D%NTGrids > 0 + + if (G3D%Periodic) then + write (SumFileUnit, '(5x,A)') 'Time range (s): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime))//' ]' + else ! Shift the time range to compensate for the shifting of the wind grid + write (SumFileUnit, '(5x,A)') 'Time range (s): [ '// & + TRIM(Num2LStr(-G3D%InitXPosition*G3D%InvMWS))//' : '// & + TRIM(Num2LStr(G3D%TotalTime - G3D%InitXPosition*G3D%InvMWS))//' ]' + end if + + write (SumFileUnit, '(5x,A)') 'Y range (m): [ '// & + TRIM(Num2LStr(-G3D%YHWid))//' : '//TRIM(Num2LStr(G3D%YHWid))//' ]' + + if (G3D%NTGrids > 0) then + write (SumFileUnit, '(5x,A)') 'Z range (m): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + else + write (SumFileUnit, '(5x,A)') 'Z range (m): [ '// & + TRIM(Num2LStr(G3D%RefHeight - G3D%ZHWid))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + end if + + if (G3D%BoxExceedAllowF) then + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'True -- Only for points requested by OLAF free vortex wake, or LidarSim module' + write (SumFileUnit, '(A)') ' '// & + ' Out of bounds values are linearly interpolated to mean at Z loction for' + write (SumFileUnit, '(A)') ' '// & + ' given timestep and X,T value. Values above grid are held to top of wind' + write (SumFileUnit, '(A)') ' '// & + ' grid value' + else + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: False' + end if + + ! Get IO status for unit + inquire (SumFileUnit, iostat=TmpErrStat) + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine + +subroutine IfW_HAWC_Init(InitInp, SumFileUnit, G3D, FileDat, ErrStat, ErrMsg) + + type(HAWC_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(Grid3DFieldType), intent(out) :: G3D + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_HAWC_Init" + integer(IntKi) :: WindFileUnit + real(SiKi), allocatable :: VelRaw(:, :) ! grid-field data for one timestep + integer :: IC ! Loop counter for the number of wind components + integer :: IX, IY, IZ ! Loop counters for the number of grid points in the X,Y,Z directions + real(DbKi) :: vMean ! average wind speeds over time at target position + real(ReKi) :: ScaleFactors(3) ! scale factors + integer(IntKi) :: TmpErrStat ! temporary error status + character(ErrMsgLen) :: TmpErrMsg + + !---------------------------------------------------------------------------- + ! Initialize variables + !---------------------------------------------------------------------------- + + ErrStat = ErrID_None + ErrMsg = "" + + G3D%WindFileFormat = 0 + G3D%Periodic = .true. + G3D%InterpTower = .true. + G3D%AddMeanAfterInterp = .true. + + G3D%DTime = InitInp%dx/InitInp%G3D%URef + G3D%Rate = 1.0_ReKi/G3D%DTime + + G3D%NComp = 3 + G3D%NYGrids = InitInp%ny + G3D%NZGrids = InitInp%nz + G3D%NTGrids = 0 + G3D%NSteps = InitInp%nx + + G3D%YHWid = 0.5_ReKi*InitInp%dy*(G3D%NYGrids - 1) + G3D%InvDY = 1.0/InitInp%dy + + G3D%ZHWid = 0.5_ReKi*InitInp%dz*(G3D%NZGrids - 1) + G3D%InvDZ = 1.0_ReKi/InitInp%dz + + G3D%MeanWS = InitInp%G3D%URef + G3D%InvMWS = 1.0_ReKi/G3D%MeanWS + + G3D%RefHeight = InitInp%G3D%RefHt + G3D%GridBase = G3D%RefHeight - G3D%ZHWid + + G3D%InitXPosition = InitInp%G3D%XOffset + G3D%TotalTime = G3D%NSteps*InitInp%dx/G3D%MeanWS + + G3D%WindProfileType = InitInp%G3D%WindProfileType + G3D%Z0 = InitInp%G3D%Z0 + G3D%PLExp = InitInp%G3D%PLExp + + ScaleFactors = 0.0_ReKi + + !---------------------------------------------------------------------------- + ! Validate initialization iput + !---------------------------------------------------------------------------- + + call Grid3D_ValidateInput(InitInp%G3D, 3, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + if (InitInp%nx < 1) then + call SetErrStat(ErrID_Fatal, 'Number of grid points in the X direction must be at least 1.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%ny < 1) then + call SetErrStat(ErrID_Fatal, 'Number of grid points in the Y direction must be at least 1.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%nz < 1) then + call SetErrStat(ErrID_Fatal, 'Number of grid points in the Z direction must be at least 1.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%dx < 0.0_ReKi .or. EqualRealNos(InitInp%dx, 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'The grid spacing in the X direction must be larger than 0.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%dy < 0.0_ReKi .or. EqualRealNos(InitInp%dy, 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'The grid spacing in the Y direction must be larger than 0.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%dz < 0.0_ReKi .or. EqualRealNos(InitInp%dz, 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'The grid spacing in the Z direction must be larger than 0.', ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Allocate storage for grid-field velocity data + !---------------------------------------------------------------------------- + + ! Allocate storage for grid-field velocity data + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, & + 'grid-field velocity data', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for raw grid-field velocity for each time step + allocate (VelRaw(G3D%NZGrids, G3D%NYGrids), stat=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, "error allocating grid-field time step velocity data", & + ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Loop through files and read data + !---------------------------------------------------------------------------- + + ! Display message indicating that file is being read + call WrScr(NewLine//' Reading HAWC wind files with grids of '// & + TRIM(Num2LStr(G3D%NSteps))//' x '//TRIM(Num2LStr(G3D%NYGrids))//' x '//TRIM(Num2LStr(G3D%NZGrids))//' points'// & + ' ('//TRIM(Num2LStr(G3D%YHWid*2))//' m wide, '//TRIM(Num2LStr(G3D%GridBase))//' m to '// & + TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2))// & + ' m above ground) with a characteristic wind speed of '//TRIM(Num2LStr(G3D%MeanWS))//' m/s. ') + + ! Get a unit number to use for the wind file + call GetNewUnit(WindFileUnit, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through wind components (X, Y, Z) + do IC = 1, G3D%NComp + + ! Open wind file for this component + call OpenBInpFile(WindFileUnit, InitInp%WindFileName(IC), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through time steps + do IX = 1, G3D%NSteps + + ! Read file data for this timestep (Z(1:N),Y(N:1),C(1:3)) + read (WindFileUnit, IOSTAT=TmpErrStat) VelRaw + if (TmpErrStat /= 0) then + TmpErrMsg = ' Error reading binary data from "'//TRIM(InitInp%WindFileName(IC)) & + //'". I/O error '//TRIM(Num2LStr(TmpErrStat)) & + //' occurred at IX='//TRIM(Num2LStr(IX))//'.' + close (WindFileUnit) + call SetErrStat(ErrID_Fatal, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + + ! Reorganize raw data into grid-field array (reverse Y indices) + do IZ = 1, G3D%NZGrids + G3D%Vel(IC, :, IZ, IX) = VelRaw(IZ, G3D%NYGrids:1:-1) + end do + end do + + ! Close file + close (WindFileUnit) + + end do + + !---------------------------------------------------------------------------- + ! Scale turbulence to requested intensity + !---------------------------------------------------------------------------- + + call Grid3D_ScaleTurbulence(InitInp%G3D, G3D%Vel, ScaleFactors, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Remove the U component mean wind speed + !---------------------------------------------------------------------------- + + ! If scaling method is not none, remove mean value of X component at each grid point + if (InitInp%G3D%ScaleMethod /= ScaleMethod_None) then + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + vMean = sum(G3D%Vel(1, iy, iz, :))/G3D%NSteps + G3D%Vel(1, iy, iz, :) = real(G3D%Vel(1, iy, iz, :) - vMean, SiKi) + end do + end do + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + call Grid3D_PopulateWindFileDat(G3D, InitInp%WindFileName(1), 5, .false., FileDat) + + !---------------------------------------------------------------------------- + ! Write the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'HAWC wind type. Read by InflowWind sub-module InflowWind_IO' + + write (SumFileUnit, '(A34,G12.4)') ' Reference height (m): ', G3D%RefHeight + write (SumFileUnit, '(A34,G12.4)') ' Timestep (s): ', G3D%DTime + write (SumFileUnit, '(A34,I12)') ' Number of timesteps: ', G3D%NSteps + write (SumFileUnit, '(A34,G12.4)') ' Mean windspeed (m/s): ', G3D%MeanWS + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime))//' ]' + write (SumFileUnit, '(A)') ' X range (m): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime*G3D%MeanWS))//' ]' + write (SumFileUnit, '(A)') ' Y range (m): [ '// & + TRIM(Num2LStr(-G3D%YHWid))//' : '//TRIM(Num2LStr(G3D%YHWid))//' ]' + write (SumFileUnit, '(A)') ' Z range (m): [ '// & + TRIM(Num2LStr(G3D%GridBase))//' : '//TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2.0))//' ]' + + if (G3D%BoxExceedAllowF) then + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'True -- Only for points requested by OLAF free vortex wake, or LidarSim module' + write (SumFileUnit, '(A)') ' '// & + ' Out of bounds values are linearly interpolated to mean at Z loction for' + write (SumFileUnit, '(A)') ' '// & + ' given timestep and X,T value. Values above grid are held to top of wind' + write (SumFileUnit, '(A)') ' '// & + ' grid value' + else + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: False' + end if + + write (SumFileUnit, '(A)') 'Scaling factors used:' + write (SumFileUnit, '(A)') ' u v w ' + write (SumFileUnit, '(A)') '---------- ---------- ----------' + write (SumFileUnit, '(F10.3,2x,F10.3,2x,F10.3)') ScaleFactors + end if + +end subroutine + +!> User_Init initializes a user defined wind field. +subroutine IfW_User_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg) + + type(User_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(UserFieldType), intent(out) :: UF + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_User_Init" + + ErrStat = ErrID_None + ErrMsg = "" + + UF%Dummy = 1 + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') InitInp%Dummy + end if + +end subroutine + +!> IfW_Grid4D_Init initializes a wind field defined by a 4D grid. +subroutine IfW_Grid4D_Init(InitInp, G4D, ErrStat, ErrMsg) + + type(Grid4D_InitInputType), intent(in) :: InitInp + type(Grid4DFieldType), intent(out) :: G4D + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_Grid4D_Init" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! Initialize field from inputs + G4D%n = InitInp%n + G4D%delta = InitInp%delta + G4D%pZero = InitInp%pZero + G4D%TimeStart = 0.0_ReKi + + ! uvw velocity components at x,y,z,t coordinates + call AllocAry(G4D%Vel, 3, G4D%n(1), G4D%n(2), G4D%n(3), G4D%n(4), & + 'External Grid Velocity', TmpErrStat, TmpErrMsg) + call SetErrStat(ErrStat, ErrMsg, TmpErrStat, TmpErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Initialize velocities to zero + G4D%Vel = 0.0_SiKi + +end subroutine + +subroutine IfW_Bladed_Init(InitInp, SumFileUnit, InitOut, G3D, FileDat, ErrStat, ErrMsg) + + type(Bladed_InitInputType), intent(in) :: InitInp !< Initialization data passed to the module + integer(IntKi), intent(in) :: SumFileUnit + type(Bladed_InitOutputType), intent(out) :: InitOut !< Initial output + type(Grid3DFieldType), intent(out) :: G3D !< Parameters + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat !< determines if an error has been encountered + character(*), intent(out) :: ErrMsg !< Message about errors + + character(*), parameter :: RoutineName = "IfW_Bladed_Init" + real(ReKi) :: TI(3) ! turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + type(Grid3D_InitInputType) :: G3D_InitInp ! initialization input for grid 3d field + real(ReKi) :: BinTI(3) ! turbulence intensities of the wind components as defined in the FF binary file, not necessarially the actual TI + real(ReKi) :: NatTI(3) ! turbulence intensities of the wind components as defined in the native FF summary file + real(ReKi) :: UBar + real(ReKi) :: ZCenter + real(ReKi) :: ScaleFactors(3) ! turbulence scaling factors + real(ReKi) :: SigmaF(3) ! Turbulence standard deviation + integer(IntKi) :: UnitWind ! Unit number for the InflowWind input file + integer(B2Ki) :: Dum_Int2 + integer(IntKi) :: I + logical :: CWise + logical :: LHR ! Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) + logical :: Exists + character(1028) :: SumFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. + character(1028) :: TwrFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. + character(1024) :: BinFileName + character(1024) :: PriPath + character(ErrMsgLen) :: TmpErrMsg ! temporary error message + integer(IntKi) :: TmpErrStat ! temporary error status + + ErrMsg = '' + ErrStat = ErrID_None + + if (InitInp%NativeBladedFmt) then + + call Bladed_ReadNativeSummary(InitInp%WindFileName, G3D%PLExp, G3D%VLinShr, & + G3D%HLinShr, G3D_InitInp%RefLength, NatTI, G3D%MeanWS, & + G3D%RefHeight, InitOut%PropagationDir, InitOut%VFlowAngle, & + BinFileName, G3D_InitInp%XOffset, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + if (pathIsRelative(BinFileName)) then + call GetPath(InitInp%WindFileName, PriPath) ! Binary file will be relative to the path where the primary input file is located. + BinFileName = TRIM(PriPath)//TRIM(BinFileName) + end if + + if (InitInp%FixedWindFileRootName) then ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data + if (InitInp%TurbineID == 0) then ! .TRUE. for the FAST.Farm low-resolution domain + BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'Low' + else ! FAST.Farm high-resolution domain(s) + BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) + end if + end if + + ! default values for Bladed Format + CWise = .false. + ZCenter = G3D%RefHeight + G3D%Periodic = .true. + + G3D_InitInp%ScaleMethod = ScaleMethod_StdDev + G3D_InitInp%SigmaF = NatTI*G3D%MeanWS + G3D_InitInp%SF = SigmaF + + ! it could also have logarithmic, but I'm going to leave that off for now + G3D_InitInp%RefHt = G3D%RefHeight + G3D_InitInp%URef = G3D%MeanWS + G3D_InitInp%WindProfileType = WindProfileType_PL ! it could also have logarithmic, but I'm going to leave that off for now + + TI = 100.0_ReKi + UBar = 0.0_ReKi + LHR = .true. + + else + InitOut%PropagationDir = 0.0_ReKi + InitOut%VFlowAngle = 0.0_ReKi + G3D%VLinShr = 0.0_ReKi + G3D%HLinShr = 0.0_ReKi + G3D%RefLength = 1.0_ReKi + + BinFileName = InitInp%WindFileName + end if + + ! Get a unit number to use + call GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Open the binary file, read its "header" (first 2-byte integer) to + ! determine what format binary file it is, and close it. + !---------------------------------------------------------------------------- + + call OpenBInpFile(UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Read the first binary integer from the file to get info on the type. + ! Cannot use library read routines since this is a 2-byte integer. + read (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 + close (UnitWind) + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading first binary integer from file "' & + //TRIM(BinFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Read the files to get the required FF data. + !---------------------------------------------------------------------------- + + ! Store the binary format information so the InflowWind code can use it. + ! Also changes to IntKi from INT(2) to compare in the SELECT below + G3D%WindFileFormat = Dum_Int2 + + select case (G3D%WindFileFormat) + + case (-1, -2, -3, -99) ! Bladed-style binary format + + if (.not. InitInp%NativeBladedFmt) then + + !---------------------------------------------------------------------- + ! Create full-field summary file name from binary file root name. + ! Also get tower file name. + !---------------------------------------------------------------------- + + call GetRoot(BinFileName, SumFile) + + TwrFile = TRIM(SumFile)//'.twr' + SumFile = TRIM(SumFile)//'.sum' + + !---------------------------------------------------------------------- + ! Read the summary file to get necessary scaling information + !---------------------------------------------------------------------- + + call Bladed_ReadTurbSimSummary(UnitWind, TRIM(SumFile), CWise, ZCenter, TI, & + UBar, G3D%RefHeight, G3D%Periodic, LHR, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + end if + + !------------------------------------------------------------------------- + ! Open the binary file and read its header + !------------------------------------------------------------------------- + + call OpenBInpFile(UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + if (Dum_Int2 == -99) then ! Newer-style BLADED format + call Bladed_ReadHeader1(UnitWind, BinTI, G3D, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + ! If the TIs are also in the binary file (BinTI > 0), + ! use those numbers instead of ones from the summary file + + if (.not. InitInp%NativeBladedFmt) then + do I = 1, G3D%NComp + if (BinTI(I) > 0) TI(I) = BinTI(I) + end do + end if + + else + call Bladed_ReadHeader0(UnitWind, G3D, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) ! Older-style BLADED format + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + end if + + !------------------------------------------------------------------------- + ! Let's see if the summary and binary FF wind files go together before continuing. + !------------------------------------------------------------------------- + + if (.not. InitInp%NativeBladedFmt) then + if (ABS(UBar - G3D%MeanWS) > 0.1) then + call SetErrStat(ErrID_Fatal, ' Error: Incompatible mean hub-height wind speeds in FF wind files. '// & + '(Check that the .sum and .wnd files were generated together.)', ErrStat, ErrMsg, RoutineName) + close (UnitWind) + return + end if + + end if + + !------------------------------------------------------------------------- + ! Calculate the height of the bottom of the grid + !------------------------------------------------------------------------- + + G3D%GridBase = ZCenter - G3D%ZHWid ! the location, in meters, of the bottom of the grid + if (G3D%GridBase < 0.0_ReKi) then + call SetErrStat(ErrID_Severe, 'WARNING: The bottom of the grid is located at a height of '// & + TRIM(Num2LStr(G3D%GridBase))//' meters, which is below the ground.'// & + ' Winds below the ground will be set to 0.', ErrStat, ErrMsg, RoutineName) + end if + + !------------------------------------------------------------------------- + ! Read the binary grids (converted tƒo m/s) and close the file + !------------------------------------------------------------------------- + + call Bladed_ReadGrids(UnitWind, InitInp%NativeBladedFmt, CWise, LHR, TI, G3D, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + + close (UnitWind) + if (InitInp%NativeBladedFmt) TI = NatTI*100.0_ReKi ! report these TI for the native Bladed format in percent + + if (ErrStat >= AbortErrLev) return + + !------------------------------------------------------------------------- + ! Read the tower points file + !------------------------------------------------------------------------- + + if (InitInp%TowerFileExist .and. .not. InitInp%NativeBladedFmt) then ! If we specified a tower file + inquire (FILE=TRIM(TwrFile), EXIST=Exists) + + ! Double check that the tower file exists and read it. If it was requested but doesn't exist, + ! throw fatal error and exit. + if (Exists) then + call Bladed_ReadTower(UnitWind, G3D, TwrFile, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + else + call SetErrStat(ErrID_Fatal, ' Tower file '//TRIM(TwrFile)//' specified for Bladed full-field '// & + 'wind files does not exist.', ErrStat, ErrMsg, RoutineName) + close (UnitWind) + return + end if + else + G3D%NTGrids = 0_IntKi + end if + + case DEFAULT + call SetErrStat(ErrID_Fatal, ' This is not a bladed-style binary wind file (binary format identifier: '// & + TRIM(Num2LStr(G3D%WindFileFormat))//'. This might be a TurbSim binary wind file.', & + ErrStat, ErrMsg, RoutineName) + return + + end select + + !---------------------------------------------------------------------------- + ! Post reading + !---------------------------------------------------------------------------- + + !---------------------------------------------------------------------------- + ! If the wind file has zero-mean and unit standard deviation (native Bladed format), scale the data: + !---------------------------------------------------------------------------- + + G3D%AddMeanAfterInterp = .false. + G3D%Z0 = G3D_InitInp%Z0 + G3D%PLExp = G3D_InitInp%PLExp + G3D%VLinShr = G3D_InitInp%VLinShr + G3D%HLinShr = G3D_InitInp%HLinShr + G3D%RefLength = G3D_InitInp%RefLength + + if (InitInp%NativeBladedFmt) then + + G3D%InterpTower = .true. + G3D%AddMeanAfterInterp = .true. + + ! Validate scaling data if we've got native-Bladed format + call Grid3D_ValidateInput(G3D_InitInp, G3D%NComp, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! scale to requested TI (or use requested scale factors) + call Grid3D_ScaleTurbulence(G3D_InitInp, G3D%Vel(:, :, :, 1:G3D%NSteps), ScaleFactors, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + else + G3D%InterpTower = .false. + G3D%WindProfileType = WindProfileType_None + end if + + if (G3D%Periodic) then + G3D%InitXPosition = 0 ! start at the hub + G3D%TotalTime = G3D%NSteps*G3D%DTime + else + G3D%InitXPosition = G3D%YHWid ! start half the grid width ahead of the turbine + G3D%TotalTime = (G3D%NSteps - 1)*G3D%DTime + end if + + if (InitInp%NativeBladedFmt) then + G3D%InitXPosition = G3D_InitInp%XOffset + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + call Grid3D_PopulateWindFileDat(G3D, InitInp%WindFileName, InitInp%WindType, G3D%NTGrids > 0, FileDat) + + FileDat%TI = TI + FileDat%TI_listed = .true. + + !---------------------------------------------------------------------------- + ! Write to the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'Bladed-style wind type. Read by InflowWind sub-module '// & + TRIM(InflowWind_IO_Ver%Name)//' '//TRIM(InflowWind_IO_Ver%Ver) + write (SumFileUnit, '(A)') TRIM(TmpErrMsg) + write (SumFileUnit, '(A)') ' FileName: '//TRIM(InitInp%WindFileName) + write (SumFileUnit, '(A34,I3)') ' Binary file format id: ', G3D%WindFileFormat + write (SumFileUnit, '(A34,G12.4)') ' Reference height (m): ', G3D%RefHeight + write (SumFileUnit, '(A34,G12.4)') ' Timestep (s): ', G3D%DTime + write (SumFileUnit, '(A34,I12)') ' Number of timesteps: ', G3D%NSteps + write (SumFileUnit, '(A34,G12.4)') ' Mean windspeed (m/s): ', G3D%MeanWS + write (SumFileUnit, '(A)') ' Characteristic TI: [ '// & + TRIM(Num2LStr(TI(1)))//', '//TRIM(Num2LStr(TI(2)))//', '//TRIM(Num2LStr(TI(3)))//' ] ' + write (SumFileUnit, '(A34,L1)') ' Windfile is periodic: ', G3D%Periodic + write (SumFileUnit, '(A34,L1)') ' Windfile includes tower: ', G3D%NTGrids > 0 + + if (G3D%Periodic) then + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime))//' ]' + else ! Shift the time range to compensate for the shifting of the wind grid + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(-G3D%InitXPosition*G3D%InvMWS))//' : '// & + TRIM(Num2LStr(G3D%TotalTime - G3D%InitXPosition*G3D%InvMWS))//' ]' + end if + + write (SumFileUnit, '(A)') ' Y range (m): [ '// & + TRIM(Num2LStr(-G3D%YHWid))//' : '//TRIM(Num2LStr(G3D%YHWid))//' ]' + + if (G3D%NTGrids > 0) then + write (SumFileUnit, '(A)') ' Z range (m): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + else + write (SumFileUnit, '(A)') ' Z range (m): [ '// & + TRIM(Num2LStr(G3D%RefHeight - G3D%ZHWid))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + end if + + if (G3D%BoxExceedAllowF) then + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'True -- Only for points requested by OLAF free vortex wake, or LidarSim module' + write (SumFileUnit, '(A)') ' '// & + ' Out of bounds values are linearly interpolated to mean at Z loction for' + write (SumFileUnit, '(A)') ' '// & + ' given timestep and X,T value. Values above grid are held to top of wind' + write (SumFileUnit, '(A)') ' '// & + ' grid value' + else + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'False' + end if + + ! We are assuming that if the last line was written ok, then all of them were. + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine IfW_Bladed_Init + +subroutine Bladed_ReadTurbSimSummary(UnitWind, FileName, CWise, ZCenter, TI, UBar, RefHt, Periodic, LHR, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: UnitWind !< unit number for the file to open + character(*), intent(in) :: FileName !< name of the summary file + logical, intent(out) :: CWise !< rotation (for reading the order of the binary data) + real(ReKi), intent(out) :: ZCenter !< the height at the center of the grid + real(ReKi), intent(out) :: TI(3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + real(ReKi), intent(out) :: UBar !< mean (advection) wind speed + real(ReKi), intent(out) :: RefHt !< Reference height + logical, intent(out) :: Periodic !< rotation (for reading the order of the binary data) + logical, intent(out) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) + integer(IntKi), intent(out) :: ErrStat !< returns 0 if no error encountered in the subroutine + character(*), intent(out) :: ErrMsg !< holds the error messages + + character(*), parameter :: RoutineName = "Bladed_ReadTurbSimSummary" + integer(IntKi) :: TmpErrStat ! temporary error status + character(ErrMsgLen) :: TmpErrMsg ! temporary error message + real(ReKi) :: ZGOffset ! The vertical offset of the turbine on rectangular grid (allows turbulence not centered on turbine hub) + integer, parameter :: NumStrings = 7 ! number of strings to be looking for in the file + integer(IntKi) :: FirstIndx ! The first character of a line where data is located + integer(IntKi) :: I ! A loop counter + integer(IntKi) :: LastIndx ! The last character of a line where data is located + integer(IntKi) :: LineCount ! Number of lines that have been read in the file + logical :: StrNeeded(NumStrings) ! if the string has been found + character(1024) :: LINE ! temporary storage for reading a line from the file + + !---------------------------------------------------------------------------------------------- + ! Initialize some variables + !---------------------------------------------------------------------------------------------- + + ErrStat = ErrID_None + ErrMsg = '' + + LineCount = 0 + StrNeeded(:) = .true. + ZGOffset = 0.0 + RefHt = 0.0 + Periodic = .false. + LHR = .false. + CWise = .false. ! default value, in case it is not in this file + + !---------------------------------------------------------------------------------------------- + ! Open summary file. + !---------------------------------------------------------------------------------------------- + + call OpenFInpFile(UnitWind, TRIM(FileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------------------------- + ! Read the summary file. + !---------------------------------------------------------------------------------------------- + + ! Here are the strings we're looking for, in this order: + ! 1) 'CLOCKWISE' (optional) + ! 2) 'HUB HEIGHT' + ! 3) (unused; decided we didn't need to read data also stored in the binary file) + ! 4) 'UBAR' + ! 5) 'HEIGHT OFFSET' (optional) + ! 6) 'PERIODIC' (optional) + ! 7) 'BLADED LEFT-HAND RULE' (optional) + + do while ((ErrStat == ErrID_None) .and. StrNeeded(NumStrings)) + + LineCount = LineCount + 1 + + read (UnitWind, '(A)', IOSTAT=TmpErrStat) LINE + if (TmpErrStat /= 0) then + + ! the "HEIGHT OFFSET", "PERIODIC", and "BLADED LEFT-HAND RULE" parameters are not necessary. We'll assume they are zero/false if we didn't find it. + ! We will also assume "CLOCKWISE" is false if we didn't find it. + if (StrNeeded(2) .or. StrNeeded(4)) then + call SetErrStat(ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'// & + TRIM(FileName)//'". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName) + return + else + exit + end if + + end if + + call Conv2UC(LINE) + + if (StrNeeded(2)) then ! if "CLOCKWISE" (StrNeeded(1)) is in the file, we would have already read it. If not, it's not in this file. + + if (StrNeeded(1)) then + + !------------------------------------------------------------------------------------------- + ! #1: Get the rotation direction, using the string "CLOCKWISE" + !------------------------------------------------------------------------------------------- + + if (INDEX(LINE, 'CLOCKWISE') > 0) then + + read (LINE, *, IOSTAT=TmpErrStat) CWise ! Look for True/False values + + if (TmpErrStat /= 0) then ! Look for Yes/No values instead + + LINE = ADJUSTL(LINE) ! Remove leading spaces from input line + + select case (LINE(1:1)) + case ('Y') + CWise = .true. + case ('N') + CWise = .false. + case DEFAULT + call SetErrStat(ErrID_Fatal, ' Error reading rotation direction (CLOCKWISE) from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end select + cycle + + end if ! TmpErrStat /= 0 + StrNeeded(1) = .false. + + end if ! INDEX for "CLOCKWISE" + + end if + + !------------------------------------------------------------------------------------------- + ! #2: Get the hub height, using the strings "HUB HEIGHT" or "ZHUB" + !------------------------------------------------------------------------------------------- + + if (INDEX(LINE, 'HUB HEIGHT') > 0 .or. INDEX(LINE, 'ZHUB') > 0) then + + read (LINE, *, IOSTAT=TmpErrStat) RefHt + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading hub height from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + StrNeeded(2) = .false. + + end if !INDEX for "HUB HEIGHT" or "ZHUB" + + ! ELSEIF ( StrNeeded(3) ) THEN + ! + ! !------------------------------------------------------------------------------------------- + ! ! #3: Get the grid width (& height, if available), using the strings "GRID WIDTH" or "RDIAM" + ! ! If GRID HEIGHT is specified, use it, too. -- THIS IS UNNECESSARY AS IT'S STORED IN THE BINARY FILE + ! !------------------------------------------------------------------------------------------- + + elseif (StrNeeded(4)) then + + !------------------------------------------------------------------------------------------- + ! #4: Get the mean wind speed "UBAR" and turbulence intensities from following lines for + ! scaling Bladed-style FF binary files + !------------------------------------------------------------------------------------------- + + if (INDEX(LINE, 'UBAR') > 0) then + + FirstIndx = INDEX(LINE, '=') + 1 ! Look for the equal siqn to find the number we're looking for + + read (LINE(FirstIndx:LEN(LINE)), *, IOSTAT=TmpErrStat) UBar + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading UBar binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + + do I = 1, 3 + + LineCount = LineCount + 1 + + read (UnitWind, '(A)', IOSTAT=TmpErrStat) LINE + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'//TRIM(FileName)// & + '". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName) + return + end if + + FirstIndx = INDEX(LINE, '=') + 1 ! Read the number between the = and % signs + LastIndx = INDEX(LINE, '%') - 1 + + if (LastIndx <= FirstIndx) LastIndx = LEN(LINE) ! If there's no % sign, read to the end of the line + + read (LINE(FirstIndx:LastIndx), *, IOSTAT=TmpErrStat) TI(I) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading TI('//TRIM(Num2LStr(I))// & + ') binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + + end do !I + + StrNeeded(4) = .false. + + end if + + elseif (StrNeeded(5)) then + + !------------------------------------------------------------------------------------------- + ! #5: Get the grid "HEIGHT OFFSET", if it exists (in TurbSim). Otherwise, assume it's zero + ! ZGOffset = HH - GridBase - ParamData%FF%ZHWid + !------------------------------------------------------------------------------------------- + if (INDEX(LINE, 'HEIGHT OFFSET') > 0) then + + FirstIndx = INDEX(LINE, '=') + 1 + + read (LINE(FirstIndx:LEN(LINE)), *, IOSTAT=TmpErrStat) ZGOffset + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading height offset from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + + StrNeeded(5) = .false. + + end if !INDEX for "HEIGHT OFFSET" + + else + + if (StrNeeded(6)) then + + !------------------------------------------------------------------------------------------- + ! #6: Get the grid "PERIODIC", if it exists (in TurbSim). Otherwise, assume it's + ! not a periodic file (would only show up if the HEIGHT OFFSET is in the file) + !------------------------------------------------------------------------------------------- + if (INDEX(LINE, 'PERIODIC') > 0) then + + Periodic = .true. + StrNeeded(6) = .false. + cycle + end if !INDEX for "PERIODIC" + end if + + if (StrNeeded(7)) then + + if (INDEX(LINE, 'BLADED LEFT-HAND RULE') > 0) then + LHR = .true. + StrNeeded(7) = .false. + end if ! INDEX for "BLADED LEFT-HAND RULE" + + end if + + end if ! StrNeeded + + end do !WHILE + + !---------------------------------------------------------------------------- + ! Close the summary file + !---------------------------------------------------------------------------- + + close (UnitWind) + + !---------------------------------------------------------------------------- + ! Calculate the height of the grid center + !---------------------------------------------------------------------------- + + ZCenter = RefHt - ZGOffset + +end subroutine Bladed_ReadTurbSimSummary + +subroutine Bladed_ReadNativeSummary(FileName, PLExp, VLinShr, HLinShr, RefLength, TI, & + UBar, RefHt, PropagationDir, VFlowAngle, BinFileName, & + XOffset, ErrStat, ErrMsg) + + character(*), intent(in) :: FileName !< name of the summary file + real(ReKi), intent(out) :: PLExp !< the power-law exponent for vertical wind shear + real(ReKi), intent(out) :: VLinShr !< the linear shape for vertical wind shear + real(ReKi), intent(out) :: HLinShr !< the linear shape for horizontal wind shear + real(ReKi), intent(out) :: RefLength !< Reference (rotor) diameter + real(ReKi), intent(out) :: TI(3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + real(ReKi), intent(out) :: UBar !< mean (advection) wind speed + real(ReKi), intent(out) :: RefHt !< Reference height + real(ReKi), intent(out) :: PropagationDir !< propagation direction + real(ReKi), intent(out) :: VFlowAngle !< vertical flow angle + character(*), intent(out) :: BinFileName !< name of the binary file containing wind data + real(ReKi), intent(out) :: XOffset !< distance offset for start of wind files + integer(IntKi), intent(out) :: ErrStat !< returns 0 if no error encountered in the subroutine + character(*), intent(out) :: ErrMsg !< holds the error messages + + character(*), parameter :: RoutineName = "Bladed_ReadNativeSummary" + integer(IntKi) :: ErrStat2 ! temporary error status + character(ErrMsgLen) :: ErrMsg2 ! temporary error message + integer(IntKi), parameter :: UnEc = -1 ! echo file unit number (set to something else > 0 for debugging) + integer(IntKi) :: CurLine ! Current line to parse in FileInfo data structure + + type(FileInfoType) :: FileInfo ! The derived type for holding the file information. + + ErrStat = ErrID_None + ErrMsg = '' + + !---------------------------------------------------------------------------- + ! Open and read the summary file; store data in FileInfo structure. + !---------------------------------------------------------------------------- + + call ProcessComFile(FileName, FileInfo, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + end if + + !---------------------------------------------------------------------------- + ! Process the lines stored in FileInfo + !---------------------------------------------------------------------------- + + CurLine = 1 + + call ParseVar(FileInfo, CurLine, 'UBAR', UBar, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'REFHT', RefHt, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'TI', TI(1), ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'TI_V', TI(2), ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'TI_W', TI(3), ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'WDIR', PropagationDir, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + PropagationDir = R2D*PropagationDir + + call ParseVar(FileInfo, CurLine, 'FLINC', VFlowAngle, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + VFlowAngle = R2D*VFlowAngle ! convert to degrees + + call ParseVar(FileInfo, CurLine, 'WINDF', BinFileName, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'WSHEAR', PLExp, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + end if + + call ParseVar(FileInfo, CurLine, 'VLINSHEAR', VLinShr, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + VLinShr = 0.0_ReKi ! this will be the default if VLINSHEAR is not in the file + end if + + call ParseVar(FileInfo, CurLine, 'HLINSHEAR', HLinShr, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + HLinShr = 0.0_ReKi ! this will be the default if HLINSHEAR is not in the file + end if + + call ParseVar(FileInfo, CurLine, 'REFLENGTH', RefLength, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + RefLength = 0.0_ReKi ! this will be the default if RefLength is not in the file; it will cause an error if either of the linear shears are non-zero + end if + + call ParseVar(FileInfo, CurLine, 'XOffset', XOffset, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + XOffset = 0.0_ReKi ! this will be the default if offset is not in the file + end if + + !---------------------------------------------------------------------------- + ! Clean FileInfo data structure (including pointers and allocatable arrays) + !---------------------------------------------------------------------------- + + call Cleanup() + +contains + + subroutine Cleanup() + call NWTC_Library_DestroyFileInfoType(FileInfo, ErrStat2, ErrMsg2) + end subroutine Cleanup + +end subroutine Bladed_ReadNativeSummary + +!> Reads the binary headers from the turbulence files of the old Bladed variety. Note that +!! because of the normalization, neither ParamData%FF%NZGrids or ParamData%FF%NYGrids are larger than 32 points. +!! 21-Sep-2009 - B. Jonkman, NREL/NWTC. +!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 +subroutine Bladed_ReadHeader0(WindFileUnit, G3D, NativeBladedFmt, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: WindFileUnit !< unit number of already-opened wind file + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + logical, intent(in) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + type :: HeaderType + integer(B2Ki) :: NComp + integer(B2Ki) :: DeltaZ, DeltaY, DeltaX + integer(B2Ki) :: NStepsHalf, MWS10 + integer(B2Ki) :: zLu, yLu, xLu, dummy, rnd + integer(B2Ki) :: NZ1000, NY1000 + end type + + character(*), parameter :: RoutineName = "Bladed_ReadHeader0" + real(ReKi) :: FFXDelt + real(ReKi) :: FFYDelt + real(ReKi) :: FFZDelt + + type(HeaderType) :: header + integer(B2Ki) :: dummy(6) + integer(IntKi) :: iostat ! for checking the IOSTAT from a READ or Open statement + + ErrStat = ErrID_None + ErrMsg = '' + + !---------------------------------------------------------------------------- + ! Read the header (file has just been opened) + !---------------------------------------------------------------------------- + + ! Read header + read (WindFileUnit, IOSTAT=iostat) header + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header 0 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + G3D%NComp = -1*header%NComp + + FFZDelt = 0.001*header%DeltaZ + G3D%InvDZ = 1.0/FFZDelt + + FFYDelt = 0.001*header%DeltaY + G3D%InvDY = 1.0/FFYDelt + + FFXDelt = 0.001*header%DeltaX + G3D%NSteps = 2*header%NStepsHalf + + if (.not. NativeBladedFmt) G3D%MeanWS = 0.1*header%MWS10 + G3D%InvMWS = 1.0/G3D%MeanWS + G3D%DTime = FFXDelt/G3D%MeanWS + G3D%Rate = 1.0/G3D%DTime + + G3D%NZGrids = header%NZ1000/1000 + G3D%ZHWid = 0.5*FFZDelt*(G3D%NZGrids - 1) + + G3D%NYGrids = header%NY1000/1000 + G3D%YHWid = 0.5*FFYDelt*(G3D%NYGrids - 1) + + if (G3D%NComp == 3) then + read (WindFileUnit, IOSTAT=iostat) dummy + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header 0 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine Bladed_ReadHeader0 + +subroutine Bladed_ReadHeader1(UnitWind, TI, G3D, NativeBladedFmt, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: UnitWind !< unit number of already-opened wind file + real(ReKi), intent(out) :: TI(3) !< turbulence intensity contained in file header + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + logical, intent(in) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + type :: Turb4Type + integer(B4Ki) :: NComp + real(SiKi) :: Latitude, RoughLen, RefHeight, TurbInt(3) + end type + + type :: Turb78Type + integer(B4Ki) :: HeaderSize, NComp + end type + + type :: Turb7Type + real(SiKi) :: CoherenceDecay, CoherenceScale + end type + + type :: Turb8Type + real(SiKi) :: dummy1(6) + integer(B4Ki) :: dummy2(3) + real(SiKi) :: dummy3(2) + integer(B4Ki) :: dummy4(3) + real(SiKi) :: dummy5(2) + end type + + type :: Sub1Type + real(SiKi) :: DeltaZ, DeltaY, DeltaX + integer(B4Ki) :: NStepsHalf + real(SiKi) :: MeanWS, zLu, yLu, xLu + integer(B4Ki) :: dummy, rnd, NZ, NY + end type + + type :: Sub2Type + real(SiKi) :: zLv, yLv, xLv, zLw, yLw, xLw + end type + + character(*), parameter :: RoutineName = "Bladed_ReadHeader1" + + type(Turb4Type) :: Turb4 + type(Turb78Type) :: Turb78 + type(Sub1Type) :: Sub1 + type(Sub2Type) :: Sub2 + type(Turb7Type) :: Turb7 + type(Turb8Type) :: Turb8 + + real(ReKi) :: FFXDelt + real(ReKi) :: FFYDelt + real(ReKi) :: FFZDelt + integer(B2Ki) :: Dum_Int2 + integer(B2Ki) :: TurbType + integer(IntKi) :: iostat + + ErrStat = ErrID_None + ErrMsg = '' + + ! Initialize turbulence intensities + TI(:) = -1 !Initialize to -1 (not all models contain TI) + + !---------------------------------------------------------------------------- + ! File reading + !---------------------------------------------------------------------------- + + ! Read 2-byte integer. Can't use library routines for this. + read (UnitWind, IOSTAT=iostat) Dum_Int2 ! -99 (file ID) + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading integer from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + + ! Read 2-byte integer. Can't use library routines for this. + read (UnitWind, IOSTAT=iostat) TurbType ! turbulence type + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading turbulence type from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + + select case (TurbType) + + case (1, 2) ! 1-component Von Karman (1) or Kaimal (2) + G3D%NComp = 1 + + case (3, 5) ! 3-component Von Karman (3) or IEC-2 Kaimal (5) + G3D%NComp = 3 + + case (4) ! improved Von Karman + + read (UnitWind, IOSTAT=iostat) Turb4 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading number of components from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + G3D%NComp = Turb4%NComp + TI = Turb4%TurbInt + + case (7, 8) ! General Kaimal (7) or Mann model (8) + + read (UnitWind, IOSTAT=iostat) Turb78 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading number of header records from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + G3D%NComp = Turb78%NComp + + case DEFAULT + + call SetErrStat(ErrID_Warn, ' InflowWind does not recognize the full-field turbulence file type ='// & + TRIM(Num2LStr(int(TurbType)))//'.', ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + end select + + read (UnitWind, IOSTAT=iostat) Sub1 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header Sub1 from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + + FFZDelt = Sub1%DeltaZ + G3D%InvDZ = 1.0/FFZDelt + + FFYDelt = Sub1%DeltaY + G3D%InvDY = 1.0/FFYDelt + + FFXDelt = Sub1%DeltaX + + G3D%NSteps = 2*Sub1%NStepsHalf + + if (.not. NativeBladedFmt) G3D%MeanWS = Sub1%MeanWS + G3D%InvMWS = 1.0/G3D%MeanWS + G3D%DTime = FFXDelt/G3D%MeanWS + G3D%Rate = 1.0/G3D%DTime + + G3D%NZGrids = Sub1%NZ + G3D%ZHWid = 0.5*FFZDelt*(G3D%NZGrids - 1) ! half the vertical size of the grid + + G3D%NYGrids = Sub1%NY + G3D%YHWid = 0.5*FFYDelt*(G3D%NYGrids - 1) + + ! unused variables: zLv, yLv, xLv, zLw, yLw, xLw + if (G3D%NComp == 3) then + read (UnitWind, IOSTAT=iostat) Sub2 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading 4-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + + select case (TurbType) + case (7) ! General Kaimal model + + ! Unused variables: coherence decay constant and coherence scale parameter in m + read (UnitWind, IOSTAT=iostat) Turb7 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header for Turb7 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + case (8) ! Mann model + + ! Unused variables + read (UnitWind, IOSTAT=iostat) Turb8 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header for Turb8 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + end select !TurbType + +end subroutine Bladed_ReadHeader1 + +subroutine Bladed_ReadGrids(UnitWind, NativeBladedFmt, CWise, LHR, TI, G3D, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: UnitWind !< unit number of already-opened wind file + logical, intent(in) :: NativeBladedFmt !< whether this data is in native Bladed format (scale to zero mean and unit standard deviation) + logical, intent(in) :: CWise !< clockwise flag (determines if y is increasing or decreasing in file) + logical, intent(in) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) + real(ReKi), intent(in) :: TI(3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + character(*), parameter :: RoutineName = "Bladed_ReadGrids" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + real(ReKi) :: FF_Scale(3) !< used for "un-normalizing" the data + real(ReKi) :: FF_Offset(3) !< used for "un-normalizing" the data + integer(B2Ki), allocatable :: raw_ff(:, :, :) + integer(IntKi) :: CFirst, CLast, CStep + integer(IntKi) :: IC, IR, IT + + ErrMsg = "" + ErrStat = ErrID_None + + if (NativeBladedFmt) then + FF_Scale = 0.001_ReKi + FF_Offset = 0.0_ReKi + else + FF_Scale = 0.001_ReKi*G3D%MeanWS*TI/100.0_ReKi + FF_Offset = (/G3D%MeanWS, 0.0_ReKi, 0.0_ReKi/) ! used for "un-normalizing" the data + end if + + ! Bladed convention has positive V pointed along negative Y + if (LHR) then ! left-hand rule + FF_Scale(2) = -FF_Scale(2) + end if + + !---------------------------------------------------------------------------- + ! Generate an informative message + !---------------------------------------------------------------------------- + ! This could take a while, so we'll write a message to tell users what's going on: + + call WrScr(NewLine//' Reading a '//TRIM(Num2LStr(G3D%NYGrids))//'x'// & + TRIM(Num2LStr(G3D%NZGrids))// & + ' grid ('//TRIM(Num2LStr(G3D%YHWid*2))//' m wide, '// & + TRIM(Num2LStr(G3D%GridBase))//' m to '// & + TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2))// & + ' m above ground) with a characteristic wind speed of '// & + TRIM(Num2LStr(G3D%MeanWS))//' m/s. ') + + !---------------------------------------------------------------------------- + ! Allocate space for the data array + !---------------------------------------------------------------------------- + + ! Add another step, just in case there is an odd number of steps. + G3D%NSteps = G3D%NSteps + 1 + + ! If velocity array is allocated and the size is wrong, deallocate + if (allocated(G3D%Vel)) then + if (SIZE(G3D%Vel, 1) /= G3D%NZGrids .or. & + SIZE(G3D%Vel, 2) /= G3D%NYGrids .or. & + SIZE(G3D%Vel, 3) /= G3D%NComp .or. & + SIZE(G3D%Vel, 3) /= G3D%NSteps) then + deallocate (G3D%Vel) + end if + end if + + ! If velocity array isn't allocated, allocate it with proper size + if (.not. ALLOCATED(G3D%Vel)) then + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, & + 'Full-field wind data array.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + end if + + ! Allocate space to read all data for a given time slice + allocate (raw_ff(G3D%NComp, G3D%NYGrids, G3D%NZGrids), STAT=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating memory for '// & + TRIM(Num2LStr(G3D%NComp*G3D%NYGrids*G3D%NZGrids))// & + ' B2Ki in the raw data array.', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Initialize the data and set column indexing to account for + ! direction of turbine rotation (CWise) + !---------------------------------------------------------------------------- + + ! Initialize velocity components not in file to zero + do IC = G3D%NComp + 1, 3 + G3D%Vel(IC, :, :, :) = 0.0_SiKi + end do + + if (CWise) then + CFirst = G3D%NYGrids + CLast = 1 + CStep = -1 + else + CFirst = 1 + CLast = G3D%NYGrids + CStep = 1 + end if + + !---------------------------------------------------------------------------- + ! Loop through all the time steps, reading the data and converting to m/s + !---------------------------------------------------------------------------- + + ! Loop through time steps + do IT = 1, G3D%NSteps + + ! Read raw data (NComp,NYGrids,NZGrids) + read (UnitWind, IOStat=TmpErrStat) raw_ff + + ! If data was read successfully, transfer into velocity array, continue + if (TmpErrStat == 0) then + do IC = 1, G3D%NComp + G3D%Vel(IC, :, :, IT) = real(FF_Offset(IC) + FF_Scale(IC)*raw_ff(IC, CFirst:CLast:CStep, :), SiKi) + end do + cycle + end if + + ! If time iterator equals number of steps, then the number of steps were even + ! so fix the number of steps and exit loop + if (IT == G3D%NSteps) then + G3D%NSteps = G3D%NSteps - 1 + ErrStat = ErrID_None + exit + end if + + ! Otherwise, an error occurred reading the file, return + call SetErrStat(ErrID_Fatal, ' Error reading binary data file. '// & + 'ic = '//TRIM(Num2LStr(ic))// & + ', ir = '//TRIM(Num2LStr(ir))// & + ', it = '//TRIM(Num2LStr(it))// & + ', nsteps = '//TRIM(Num2LStr(G3D%NSteps)), ErrStat, ErrMsg, RoutineName) + return + end do + + if (G3D%Periodic) then + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz full-field data (period of '// & + TRIM(Num2LStr(G3D%DTime*G3D%NSteps))//' seconds).') + + else + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz full-field data ('// & + TRIM(Num2LStr(G3D%DTime*(G3D%NSteps - 1)))//' seconds).') + end if + +end subroutine Bladed_ReadGrids + +subroutine Bladed_ReadTower(UnitWind, G3D, TwrFileName, ErrStat, ErrMsg) + + integer(IntKi) :: UnitWind !< unit number of wind file to be opened + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + character(*), intent(in) :: TwrFileName + integer(IntKi), intent(out) :: ErrStat !< error status return value (0=no error; non-zero is error) + character(*), intent(out) :: ErrMsg !< a message for errors that occur + + type :: HeaderType + real(SiKi) :: DZ, DX, Zmax + integer(B4Ki) :: NumOutSteps, NumZ + real(SiKi) :: UHub, TI(3) + end type + + character(*), parameter :: RoutineName = "Bladed_ReadTower" + integer(IntKi) :: TmpErrStat ! IOSTAT value. + character(ErrMsgLen) :: TmpErrMsg + real(ReKi), parameter :: FF_Offset(3) = (/1.0, 0.0, 0.0/) ! used for "un-normalizing" the data + real(ReKi), parameter :: TOL = 1E-4 ! tolerence for wind file comparisons + integer(IntKi) :: IC, IT ! loop counters + real(SiKi) :: TI(3) ! scaling values for "un-normalizing the data" [approx. turbulence intensities of the wind components] + integer(B2Ki), allocatable :: raw_twr(:, :) ! holds tower velocity for one timestep + type(HeaderType) :: header + + ErrMsg = '' + ErrStat = ErrID_None + + !---------------------------------------------------------------------------- + ! Initialization + !---------------------------------------------------------------------------- + + ! If number of wind components is not three, return with error + if (G3D%NComp /= 3) then + call SetErrStat(ErrID_Fatal, ' Error: Tower binary files require 3 wind components.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + ! Initialize the number of tower grids to zero + G3D%NTGrids = 0 + + !---------------------------------------------------------------------------- + ! Open the file + !---------------------------------------------------------------------------- + + call OpenBInpFile(UnitWind, TRIM(TwrFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Read the header information and check that it's compatible with the + ! FF Bladed-style binary parameters already read. + !---------------------------------------------------------------------------- + + read (UnitWind, IOSTAT=TmpErrStat) header + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, & + ' Error reading header of the binary tower file "' & + //TRIM(TwrFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + ! If delta Z in file doesn't match tower file + if (ABS(header%DZ*G3D%InvDZ - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Z resolution in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If X resolution doesn't match the tower file + if (ABS(header%DX*G3D%InvMWS/G3D%DTime - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Time resolution in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If the height doesn't match the tower file + if (ABS(header%Zmax/G3D%GridBase - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Height in the FF binary file does not match the tower file "'//TRIM(TwrFileName)//'."', & + ErrStat, ErrMsg, RoutineName) + end if + + ! Number of time steps doesn't match the tower file + if (header%NumOutSteps /= G3D%NSteps) then + call SetErrStat(ErrID_Fatal, ' Number of time steps in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If mean wind speed doesn't match tower file + if (ABS(header%UHub*G3D%InvMWS - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Mean wind speed in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If any of the previous checks failed, or the number of tower grids is zero, + ! close the wind file and return + if (ErrStat >= AbortErrLev .or. header%NumZ == 0) then + close (UnitWind) + return + end if + + ! Set number of tower grids from header + G3D%NTGrids = header%NumZ + + ! Set turbulence intensity from header + TI = header%TI + + !---------------------------------------------------------------------------- + ! Allocate arrays for the tower points + !---------------------------------------------------------------------------- + + ! If tower array is allocated and the wrong size, deallocate + if (allocated(G3D%VelTower)) then + if (size(G3D%VelTower, 1) /= G3D%NComp .or. & + size(G3D%VelTower, 1) /= G3D%NTGrids .or. & + size(G3D%VelTower, 1) /= G3D%NSteps) then + deallocate (G3D%VelTower) + end if + end if + + ! If the tower array isn't allocated, allocate it + if (.not. ALLOCATED(G3D%VelTower)) then + call AllocAry(G3D%VelTower, G3D%NComp, G3D%NTGrids, G3D%NSteps, & + 'Tower wind data array.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + end if + + ! Allocate space to read all data for a given time slice + allocate (raw_twr(G3D%NComp, G3D%NTGrids), STAT=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating memory for '// & + TRIM(Num2LStr(G3D%NComp*G3D%NYGrids*G3D%NZGrids))// & + ' B2Ki in the raw data array.', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Read the 16-bit time-series data and scale it to 32-bit reals + !---------------------------------------------------------------------------- + + ! Loop through time. + do IT = 1, G3D%NSteps + + ! Read wind compnents for this time slice. Can't use library read routines for this. + read (UnitWind, IOSTAT=TmpErrStat) raw_twr ! normalized wind-component, INT(2) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading binary tower data file. it = '//TRIM(Num2LStr(it))// & + ', nsteps = '//TRIM(Num2LStr(G3D%NSteps)), ErrStat, ErrMsg, RoutineName) + G3D%NTGrids = 0 + return + end if + + ! Loop through wind components and populate array after scaling to m/s + do IC = 1, G3D%NComp + G3D%VelTower(IC, :, IT) = real(G3D%MeanWS*(FF_Offset(IC) + 0.00001*TI(IC)*raw_twr(IC, :)), SiKi) + end do + end do + + !---------------------------------------------------------------------------- + ! Close the file + !---------------------------------------------------------------------------- + + close (UnitWind) + + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%NTGrids))//'x1 tower data grids.') + +end subroutine Bladed_ReadTower + +subroutine Grid3D_PopulateWindFileDat(Grid3DField, FileName, WindType, HasTower, FileDat) + + type(Grid3DFieldType), intent(in) :: Grid3DField + character(*), intent(in) :: FileName + integer(IntKi), intent(in) :: WindType + logical, intent(in) :: HasTower + type(WindFileDat), intent(out) :: FileDat + + FileDat%FileName = FileName + FileDat%WindType = WindType + FileDat%RefHt = Grid3DField%RefHeight + FileDat%RefHt_Set = .true. + FileDat%DT = Grid3DField%DTime + FileDat%NumTSteps = Grid3DField%NSteps + FileDat%ConstantDT = .true. + + if (Grid3DField%Periodic) then + FileDat%TRange = [0.0_ReKi, Grid3DField%TotalTime] + FileDat%TRange_Limited = .false. + else + ! Shift the time range to compensate for the shifting of the wind grid + FileDat%TRange = [0.0_ReKi, Grid3DField%TotalTime] - Grid3DField%InitXPosition*Grid3DField%InvMWS + FileDat%TRange_Limited = .true. + end if + + FileDat%YRange = [-Grid3DField%YHWid, Grid3DField%YHWid] + FileDat%YRange_Limited = .true. ! Hard boundaries enforced in y-direction + + ! If has tower data + if (HasTower) then + FileDat%ZRange = [0.0_Reki, Grid3DField%RefHeight + Grid3DField%ZHWid] + else + FileDat%ZRange = [Grid3DField%GridBase, Grid3DField%GridBase + Grid3DField%ZHWid*2.0] + end if + + FileDat%ZRange_Limited = .true. + FileDat%BinaryFormat = Grid3DField%WindFileFormat + FileDat%IsBinary = .true. + FileDat%MWS = Grid3DField%MeanWS + + FileDat%TI = 0.0_ReKi + FileDat%TI_listed = .false. + +end subroutine + +subroutine Grid3D_AddMeanVelocity(InitInp, G3D) + + type(Grid3D_InitInputType), intent(in) :: InitInp !< Initialization input data passed to the module + type(Grid3DFieldType), intent(inout) :: G3D !< Initialization input data passed to the module + + real(ReKi) :: Z ! height + real(ReKi) :: Y ! distance from centre in horizontal direction + real(ReKi) :: U ! mean wind speed + integer(IntKi) :: iz, iy ! loop counter + integer(IntKi) :: centre_y ! index of centre in y direction + + ! Loop through grid elevations + do iz = 1, G3D%NZGrids + + ! calculate height + Z = G3D%GridBase + (iz - 1)/G3D%InvDZ + if (Z <= 0.0_ReKi) cycle + + ! Calculate wind speed to add based on profile + select case (G3D%WindProfileType) + + case (WindProfileType_PL) + U = G3D%MeanWS*(Z/G3D%RefHeight)**G3D%PLExp ! [IEC 61400-1 6.3.1.2 (10)] + + case (WindProfileType_Log) + if (.not. EqualRealNos(G3D%RefHeight, G3D%Z0) .and. Z > 0.0_ReKi) then + U = G3D%MeanWS*(LOG(Z/G3D%Z0))/(LOG(G3D%RefHeight/G3D%Z0)) + else + U = 0.0_ReKi + end if + + case (WindProfileType_Constant) + U = G3D%MeanWS + + case DEFAULT + U = 0.0_ReKi + + end select + + ! Add vertical linear shear, if nonzero + if (InitInp%VLinShr /= 0.0_ReKi) then + U = U + G3D%MeanWS*InitInp%VLinShr*(Z - G3D%RefHeight)/G3D%RefLength + end if + + ! Add velocity + G3D%Vel(1, :, iz, :) = real(G3D%Vel(1, :, iz, :) + U, SiKi) + + end do + + ! Add horizontal linear shear, if nonzero + if (InitInp%HLinShr /= 0.0_ReKi) then + + ! find the center point of the grid (if we don't have an odd number of grid points, we'll pick the point closest to the center) + centre_y = (G3D%NYGrids + 1)/2 ! integer division + + ! Loop through grid Y coordinates + do iy = 1, G3D%NYGrids + Y = (iy - centre_y)/G3D%InvDY + U = G3D%MeanWS*InitInp%HLinShr*Y/G3D%RefLength + G3D%Vel(1, iy, :, :) = real(G3D%Vel(1, iy, :, :) + U, SiKi) + end do + end if + +end subroutine Grid3D_AddMeanVelocity + +subroutine Grid3D_ScaleTurbulence(InitInp, Vel, ScaleFactors, ErrStat, ErrMsg) + + type(Grid3D_InitInputType), intent(in) :: InitInp !< Initialization input data passed to the module + real(SiKi), intent(INOUT) :: Vel(:, :, :, :) !< full-field wind inflow data + real(ReKi), intent(out) :: ScaleFactors(3) !< scaling factors that were used + integer(IntKi), intent(out) :: ErrStat !< determines if an error has been encountered + character(*), intent(out) :: ErrMsg !< Message about errors + + character(*), parameter :: RoutineName = 'Grid3D_ScaleTurbulence' + real(DbKi) :: vMean(3) ! average wind speeds over time at target position + real(DbKi) :: vSum(3) ! sum over time of wind speeds at target position + real(DbKi) :: vSum2(3) ! sum of wind speeds squared + real(ReKi) :: ActualSigma(3) ! computed standard deviation + + integer :: ic ! Loop counter for wind component + integer :: iy ! Loop counter for y + integer :: iz ! Loop counter for z + + integer :: nc ! number of FF wind components + integer :: nt ! size of x (or t) dimension of turbulence box + integer :: ny ! size of y dimension of turbulence box + integer :: nz ! size of z dimension of turbulence box + + ErrStat = ErrID_None + ErrMsg = "" + + nz = size(Vel, 1) + ny = size(Vel, 2) + nc = size(Vel, 3) + nt = size(Vel, 4) + + ! If scaling method is none, set factors to 1 and return (no scaling) + if (InitInp%ScaleMethod == ScaleMethod_None) then + ScaleFactors = 1.0_ReKi + return + end if + + !---------------------------------------------------------------------------- + ! Determine the scaling factors: + !---------------------------------------------------------------------------- + + ! Use the scaling factors specified in the input file + if (InitInp%ScaleMethod == ScaleMethod_Direct) then + ScaleFactors = InitInp%sf + + else ! compute the scaling factors to get requested sigma: + + ! find the center point of the grid (if we don't have an odd number of grid points, we'll pick the point closest to the center) + iz = (nz + 1)/2 ! integer division + iy = (ny + 1)/2 ! integer division + + ! compute the actual sigma at the point specified by (iy,iz). (This sigma should be close to 1.) + vSum = sum(Vel(:, iy, iz, :), dim=2) + vSum2 = sum(Vel(:, iy, iz, :)**2, dim=2) + vMean = vSum/nt + ActualSigma = real(SQRT(ABS((vSum2/nt) - vMean**2)), ReKi) + + ! check that the ActualSigma isn't 0 + ! InitOut%sf = InitInp%SigmaF / ActualSigma ! factor = Target / actual + do ic = 1, nc + if (EqualRealNos(ActualSigma(ic), 0.0_ReKi)) then + ScaleFactors(ic) = 0.0_ReKi + if (.not. EqualRealNos(InitInp%SigmaF(ic), 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, "Computed standard deviation is zero; cannot scale to achieve target non-zero standard deviation.", & + ErrStat, ErrMsg, RoutineName) + end if + else + ScaleFactors(ic) = InitInp%SigmaF(ic)/ActualSigma(ic) + end if + end do + + end if + + !---------------------------------------------------------------------------- + ! scale the data using our scaling factors: + !---------------------------------------------------------------------------- + + do ic = 1, nc + Vel(ic, :, :, :) = real(ScaleFactors(ic)*Vel(ic, :, :, :), SiKi) + end do + +end subroutine Grid3D_ScaleTurbulence + +subroutine Grid3D_ValidateInput(InitInp, NComp, ErrStat, ErrMsg) + + type(Grid3D_InitInputType), intent(in) :: InitInp !< Initialization input data passed to the module + integer(IntKi), intent(in) :: NComp !< number of full-field wind components (normally 3) + + character(*), parameter :: RoutineName = 'Grid3D_ValidateInput' + integer(IntKi), intent(out) :: ErrStat !< determines if an error has been encountered + character(*), intent(out) :: ErrMsg !< Message about errors + + ErrStat = ErrID_None + ErrMsg = "" + + if (InitInp%RefHt < 0.0_ReKi .or. EqualRealNos(InitInp%RefHt, 0.0_ReKi)) call SetErrStat(ErrID_Fatal, 'The grid reference height must be larger than 0.', ErrStat, ErrMsg, RoutineName) + + if (InitInp%ScaleMethod == ScaleMethod_Direct) then + if (any(InitInp%sf < 0.0_ReKi)) call SetErrStat(ErrID_Fatal, 'Turbulence scaling factors must not be negative.', ErrStat, ErrMsg, RoutineName) + elseif (InitInp%ScaleMethod == ScaleMethod_StdDev) then + if (any(InitInp%sigmaf < 0.0_ReKi)) call SetErrStat(ErrID_Fatal, 'Turbulence standard deviations must not be negative.', ErrStat, ErrMsg, RoutineName) + elseif (InitInp%ScaleMethod /= ScaleMethod_None) then + call SetErrStat(ErrID_Fatal, 'Turbulence scaling method must be 0 (none), 1 (direct scaling factors), or 2 (target standard deviation).', ErrStat, ErrMsg, RoutineName) + end if + + if (InitInp%WindProfileType == WindProfileType_Log) then + if (InitInp%z0 < 0.0_ReKi .or. EqualRealNos(InitInp%z0, 0.0_ReKi)) & + call SetErrStat(ErrID_Fatal, 'The surface roughness length, Z0, must be greater than zero', ErrStat, ErrMsg, RoutineName) + elseif (InitInp%WindProfileType < WindProfileType_Constant .or. InitInp%WindProfileType > WindProfileType_PL) then + call SetErrStat(ErrID_Fatal, 'The WindProfile type must be 0 (constant), 1 (logarithmic) or 2 (power law).', ErrStat, ErrMsg, RoutineName) + end if + + if (InitInp%URef < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'The reference wind speed must not be negative.', ErrStat, ErrMsg, RoutineName) + + if (EqualRealNos(InitInp%RefLength, 0.0_ReKi) .or. InitInp%RefLength < 0.0_ReKi) then + if (InitInp%VLinShr /= 0.0_ReKi .or. InitInp%HLinShr /= 0.0_ReKi) then + call SetErrStat(ErrID_Fatal, 'The reference length must be a positive number when vertical or horizontal linear shear is used.', ErrStat, ErrMsg, RoutineName) + end if + end if + +end subroutine + +subroutine Grid3D_WriteBladed(G3D, FileRootName, unit, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(in) :: G3D !< Parameters + character(*), intent(in) :: FileRootName !< Name of the file to write the output in + integer(IntKi), intent(in) :: Unit !< Indicates whether an error occurred (see NWTC_Library) + integer(IntKi), intent(out) :: ErrStat !< Indicates whether an error occurred (see NWTC_Library) + character(*), intent(out) :: ErrMsg !< Error message associated with the ErrStat + + character(*), parameter :: RoutineName = 'Grid3D_WriteBladed' + real(SiKi), parameter :: Tolerance = 0.0001 ! The largest difference between two numbers that are assumed to be equal + integer(IntKi) :: ic, it, iy, iz + real(SiKi), allocatable :: MeanVal(:, :) + real(SiKi), allocatable :: SigmaGrid(:, :) + real(SiKi) :: TI(3) !< array containing turbulence intensity (for scaling factors) + real(SiKi) :: Sigma(3) !< array containing standard deviations (for scaling factors) + real(SiKi) :: Scl(3) !< array containing scaling factors + real(SiKi) :: Off(3) !< array containing offsets + real(SiKi) :: Tmp + real(ReKi) :: MeanWS_nonZero !< advection speed (mean wind speed at hub) + real(ReKi) :: delta(3) + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + delta = [G3D%MeanWS*G3D%DTime, 1.0_ReKi/G3D%InvDY, 1.0_ReKi/G3D%InvDZ] + + call AllocAry(MeanVal, G3D%NYGrids, G3D%NZGrids, "MeanVal", ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + call AllocAry(SigmaGrid, G3D%NYGrids, G3D%NZGrids, "SigmaGrid", ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through components + do ic = 3, 1, -1 + + ! mean values: + MeanVal = sum(G3D%Vel(ic, :, :, :), dim=3)/G3D%NSteps + + ! standard deviations (with 1/N scaling factor): + SigmaGrid = sum(G3D%Vel(ic, :, :, :)**2, dim=3)/G3D%NSteps + SigmaGrid = sqrt(max(SigmaGrid - MeanVal**2, 0.0_SiKi)) + + ! now get the average standard deviation for each component: + Sigma(ic) = sum(SigmaGrid)/size(SigmaGrid) ! get the average sigma over the grid + Sigma(ic) = max(100.0_SiKi*Tolerance, Sigma(ic)) ! make sure this scaling isn't too small + + end do + + ! We need to take into account the shear across the grid in the sigma calculations for scaling the data, + ! and ensure that 32.767*sigma_u >= |V-UHub| so that we don't get values out of the range of our scaling values + ! in this BLADED-style binary output. Tmp is |V-UHub| + ! Get the range of wind speed values for scaling in BLADED-format .wnd files + Tmp = real(max(abs(maxval(G3D%Vel(:, :, 1, :)) - G3D%MeanWS), abs(minval(G3D%Vel(1, :, :, :)) - G3D%MeanWS)), SiKi) + Sigma(1) = max(Sigma(1), 0.05_SiKi*Tmp) + do ic = 2, 3 + ! put the abs() after the maxval() and minval() to avoid stack-overflow issues with large wind files + Sigma(ic) = max(Sigma(ic), 0.05_SiKi*abs(maxVAL(G3D%Vel(ic, :, :, :))), 0.05_SiKi*abs(minval(G3D%Vel(ic, :, :, :)))) + end do + + ! Put normalizing factors into the summary file. The user can use them to + ! tell a simulation program how to rescale the data. + if (abs(G3D%MeanWS) < 0.1_ReKi) then + MeanWS_nonZero = sign(0.1_ReKi, G3D%MeanWS) + else + MeanWS_nonZero = G3D%MeanWS + end if + + TI = real(Sigma/MeanWS_nonZero, SiKi) + + !---------------------------------------------------------------------------- + ! The summary file + !---------------------------------------------------------------------------- + + call OpenFOutFile(unit, trim(FileRootName)//'-Bladed.sum', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! The string "TurbSim" needs to be in the 2nd line of the summary file if AeroDyn will read this. + write (unit, "( / 'TurbSim - This summary file was generated by ', A, ' on ' , A , ' at ' , A , '.' / )") "NWTC_Library", CurDate(), CurTime() + write (unit, '(/)') + write (unit, '(/)') + write (unit, '( L10, 2X, "Clockwise rotation when looking downwind?")') .false. + write (unit, '( F10.3, 2X, "Hub height [m]")') G3D%RefHeight + write (unit, '( F10.3, 2X, "Grid height [m]")') delta(3)*(G3D%NZGrids - 1) + write (unit, '( F10.3, 2X, "Grid width [m]")') delta(2)*(G3D%NYGrids - 1) + write (unit, '(/"BLADED-style binary scaling parameters:"/)') + write (unit, '( 2X, "UBar = ", F9.4, " m/s")') MeanWS_nonZero + write (unit, '( 2X, "TI(u) = ", F9.4, " %")') 100.0*TI(1) + write (unit, '( 2X, "TI(v) = ", F9.4, " %")') 100.0*TI(2) + write (unit, '( 2X, "TI(w) = ", F9.4, " %")') 100.0*TI(3) + write (unit, '(/)') + write (unit, '( 2X, "Height offset = ", F9.4, " m" )') G3D%RefHeight - 0.5*delta(3)*(G3D%NZGrids - 1) - G3D%GridBase + write (unit, '( 2X, "Grid Base = ", F9.4, " m" )') G3D%GridBase + if (G3D%Periodic) then + write (unit, '()') + write (unit, '( A)') 'Creating a PERIODIC output file.' + end if + write (unit, '( A)') 'Creating a BLADED LEFT-HAND RULE output file.' + + close (unit) + + !---------------------------------------------------------------------------- + ! The BINARY file + !---------------------------------------------------------------------------- + + call OpenBOutFile(unit, TRIM(FileRootName)//'-Bladed.wnd', ErrStat, ErrMsg) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit) int(-99, B2Ki) ! -99 = New Bladed format + write (unit) int(4, B2Ki) ! 4 = improved von karman (not used, but needed for next 7 inputs) + write (unit) int(size(G3D%Vel, 3), B4Ki) ! size(FFWind,3) = 3 = number of wind components + write (unit) real(45.0_SiKi, SiKi) ! Latitude (degrees) (informational, not used in FAST) + write (unit) real(0.03_SiKi, SiKi) ! Roughness length (m) (informational, not used in FAST) + write (unit) real(G3D%RefHeight, SiKi) ! Reference Height (m) (informational, not used in FAST) + write (unit) real(100.0*TI(1), SiKi) ! Longitudinal turbulence intensity (%) + write (unit) real(100.0*TI(2), SiKi) ! Lateral turbulence intensity (%) + write (unit) real(100.0*TI(3), SiKi) ! Vertical turbulence intensity (%) + + write (unit) real(delta(3), SiKi) ! grid spacing in vertical direction, in m + write (unit) real(delta(2), SiKi) ! grid spacing in lateral direction, in m + write (unit) real(delta(1), SiKi) ! grid spacing in longitudinal direciton, in m + write (unit) int(G3D%NSteps/2, B4Ki) ! half the number of points in alongwind direction + write (unit) real(MeanWS_nonZero, SiKi) ! the mean wind speed in m/s + write (unit) real(0, SiKi) ! the vertical length scale of the longitudinal component in m + write (unit) real(0, SiKi) ! the lateral length scale of the longitudinal component in m + write (unit) real(0, SiKi) ! the longitudinal length scale of the longitudinal component in m + write (unit) int(0, B4Ki) ! an unused integer + write (unit) int(0, B4Ki) ! the random number seed + write (unit) int(G3D%NZGrids, B4Ki) ! the number of grid points vertically + write (unit) int(G3D%NYGrids, B4Ki) ! the number of grid points laterally + write (unit) int(0, B4Ki) ! the vertical length scale of the lateral component, not used + write (unit) int(0, B4Ki) ! the lateral length scale of the lateral component, not used + write (unit) int(0, B4Ki) ! the longitudinal length scale of the lateral component, not used + write (unit) int(0, B4Ki) ! the vertical length scale of the vertical component, not used + write (unit) int(0, B4Ki) ! the lateral length scale of the vertical component, not used + write (unit) int(0, B4Ki) ! the longitudinal length scale of the vertical component, not used + + ! Scaling value to convert wind speeds to 16-bit integers + do ic = 1, 3 + if (.not. EqualRealNos(Sigma(ic), 0.0_SiKi)) then + Scl(ic) = 1000.0/(Sigma(ic)) + else + Scl(ic) = 1.0_SiKi + end if + end do + + ! Bladed convention is positive V is pointed along negative Y (IEC turbine coordinate) + Scl(2) = -Scl(2) + + ! Offset value to convert wind speeds to 16-bit integers + if (G3D%AddMeanAfterInterp) then ! Note that this will not take into account any shear!!! + Off(1) = 0.0 + else + Off(1) = real(G3D%MeanWS*Scl(1), SiKi) + end if + Off(2) = 0.0 + Off(3) = 0.0 + + ! Scale velocity for 16-bit integers and write to file + do it = 1, G3D%NSteps + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + write (unit) NINT(G3D%Vel(:, iy, iz, it)*Scl - Off, B2Ki) ! scale to int16 + end do !IY + end do !IZ + end do !IT + + close (unit) + +end subroutine Grid3D_WriteBladed + +subroutine Grid3D_WriteVTK(G3D, FileRootName, unit, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(in) :: G3D !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(in) :: unit !< Error status of the operation + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = 'ConvertField_toVTK' + character(1024) :: RootPathName + character(1024) :: FileName + integer :: i + integer :: iy + integer :: iz + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + call GetPath(FileRootName, RootPathName) + RootPathName = trim(RootPathName)//PathSep//"vtk" + call MkDir(trim(RootPathName)) ! make this directory if it doesn't already exist + + ! Loop through time steps + do i = 1, G3D%NSteps + + ! Create the output vtk file with naming /vtk/DisYZ.t.vtk + FileName = trim(RootPathName)//PathSep//"DisYZ.t"//trim(num2lstr(i))//".vtp" + + ! see WrVTK_SP_header + call OpenFOutFile(unit, TRIM(FileName), ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit, '(A)') '# vtk DataFile Version 3.0' + write (unit, '(A)') "InflowWind YZ Slice at T= "//trim(num2lstr((i - 1)*G3D%DTime))//" s" + write (unit, '(A)') 'ASCII' + write (unit, '(A)') 'DATASET STRUCTURED_POINTS' + + ! Note: gridVals must be stored such that the left-most dimension is X + ! and the right-most dimension is Z (see WrVTK_SP_vectors3D) + write (unit, '(A,3(i5,1X))') 'DIMENSIONS ', 1, G3D%NYGrids, G3D%NZGrids + write (unit, '(A,3(f10.2,1X))') 'ORIGIN ', G3D%InitXPosition, -G3D%YHWid, G3D%GridBase + write (unit, '(A,3(f10.2,1X))') 'SPACING ', 0.0_ReKi, 1.0_ReKi/G3D%InvDY, 1.0_ReKi/G3D%InvDZ + write (unit, '(A,i5)') 'POINT_DATA ', G3D%NYGrids*G3D%NZGrids + write (unit, '(A)') 'VECTORS DisYZ float' + + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + write (unit, '(3(f10.2,1X))') G3D%Vel(:, iy, iz, i) + end do + end do + + close (unit) + + end do + +end subroutine Grid3D_WriteVTK + +subroutine Grid3D_WriteHAWC(G3D, FileRootName, unit, ErrStat, ErrMsg) + + character(*), intent(in) :: FileRootName !< Name of the file to write the output in + type(Grid3DFieldType), intent(in) :: G3D !< Parameters + integer(IntKi), intent(in) :: unit !< Error status of the operation + integer(IntKi), intent(out) :: ErrStat !< Indicates whether an error occurred (see NWTC_Library) + character(*), intent(out) :: ErrMsg !< Error message associated with the ErrStat + + character(*), parameter :: RoutineName = 'Grid3D_WriteHAWC' + character(*), parameter :: Comp(3) = (/'u', 'v', 'w'/) + real(ReKi) :: delta(3) + integer(IntKi) :: IC, IX, IY, IZ + real(SiKi), allocatable :: MeanVal(:) + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(1024) :: RootWithoutPathName + + ErrStat = ErrID_None + ErrMsg = "" + + ! Array containing dx, dy, dz in meters + delta = [G3D%MeanWS*G3D%DTime, 1.0_ReKi/G3D%InvDY, 1.0_ReKi/G3D%InvDZ] + + ! Allocate array to hold mean value by Z location + call AllocAry(MeanVal, G3D%NZGrids, "MeanVal", ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Calculate mean value at each Z location + MeanVal = sum(G3D%Vel(1, 1, :, :), dim=2)/G3D%NSteps + + !---------------------------------------------------------------------------- + ! Write summary file + !---------------------------------------------------------------------------- + + call OpenFOutFile(unit, trim(FileRootName)//'-HAWC.sum', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit, '(A)') '; Wind file converted to HAWC format on '//CurDate()//' at '//CurTime() + + write (unit, '()') + do IZ = G3D%NZGrids, 1, -1 + write (unit, '(A,I3,A,F15.5)') '; mean removed at z(', iz, ') = ', MeanVal(iz) + end do + + write (unit, '(A)') 'turb_format 1 ;' + + write (unit, '()') + write (unit, '(A)') 'begin mann;' + + ic = INDEX(FileRootName, '\', BACK=.true.) + ic = MAX(ic, INDEX(FileRootName, '/', BACK=.true.)) + RootWithoutPathName = FileRootName((ic + 1):) + + write (unit, '(2x,A, T30, A, " ;")') 'filename_u', trim(RootWithoutPathName)//'-HAWC-u.bin' + write (unit, '(2x,A, T30, A, " ;")') 'filename_v', trim(RootWithoutPathName)//'-HAWC-v.bin' + write (unit, '(2x,A, T30, A, " ;")') 'filename_w', trim(RootWithoutPathName)//'-HAWC-w.bin' + + write (unit, '(2x,A, T30, I8, 1x, F15.5, " ;")') 'box_dim_u', G3D%NSteps, delta(1) + write (unit, '(2x,A, T30, I8, 1x, F15.5, " ;")') 'box_dim_v', G3D%NYGrids, delta(2) + write (unit, '(2x,A, T30, I8, 1x, F15.5, " ;")') 'box_dim_w', G3D%NZGrids, delta(3) + + write (unit, '(2x,A)') 'dont_scale 1; converter did not rescale turbulence to unit standard deviation' + write (unit, '(A)') 'end mann;' + close (unit) + + !---------------------------------------------------------------------------- + ! Write the binary files for each component + !---------------------------------------------------------------------------- + + do IC = 1, G3D%NComp + + call OpenBOutFile(unit, trim(FileRootName)//'-HAWC-'//Comp(ic)//'.bin', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + do IX = 1, G3D%NSteps + do IY = G3D%NYGrids, 1, -1 + write (unit, IOSTAT=ErrStat2) real(G3D%Vel(ic, iy, :, ix) - MeanVal, SiKi) + end do + end do + + close (unit) + + MeanVal = 0.0_SiKi + + end do + +end subroutine Grid3D_WriteHAWC + +end module InflowWind_IO diff --git a/modules/inflowwind/src/InflowWind_IO.txt b/modules/inflowwind/src/InflowWind_IO.txt new file mode 100644 index 0000000000..5d6c60e59b --- /dev/null +++ b/modules/inflowwind/src/InflowWind_IO.txt @@ -0,0 +1,92 @@ +#---------------------------------------------------------------------------------------------------------------------------------- +# Registry for IfW_Interp, creates MODULE IfW_Interp_Types +# Module IfW_Interp_Types contains all of the user-defined types needed in IfW_FF. It also contains copy, destroy, pack, and +# unpack routines associated with each defined data types. +#---------------------------------------------------------------------------------------------------------------------------------- +# keyword +#---------------------------------------------------------------------------------------------------------------------------------- + +include Registry_NWTC_Library.txt +usefrom IfW_FlowField.txt + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef InflowWind_IO WindFileDat character(1024) FileName - - - "Name of the windfile retrieved" - +typedef ^ ^ IntKi WindType - 0 - "Type of the windfile" - +typedef ^ ^ ReKi RefHt - - - "Reference height given in file" meters +typedef ^ ^ Logical RefHt_Set - - - "Reference height was given in file" - +typedef ^ ^ DbKi DT - - - "TimeStep of the wind file -- zero value for none" seconds +typedef ^ ^ IntKi NumTSteps - - - "Number of timesteps in the time range of wind file" - +typedef ^ ^ Logical ConstantDT - - - "Timesteps are the same throughout file" - +typedef ^ ^ ReKi TRange {2} - - "Time range of the wind file" seconds +typedef ^ ^ Logical TRange_Limited - - - "TRange limits strictly enforced" - +typedef ^ ^ ReKi YRange {2} - - "Range in y direction" meters +typedef ^ ^ Logical YRange_Limited - - - "YRange limits strictly enforced" - +typedef ^ ^ ReKi ZRange {2} - - "Range in z direction" meters +typedef ^ ^ Logical ZRange_Limited - - - "ZRange limits strictly enforced" - +typedef ^ ^ IntKi BinaryFormat - - - "Binary format identifier" - +typedef ^ ^ Logical IsBinary - - - "Windfile is a binary file" - +typedef ^ ^ ReKi TI {3} - - "Turbulence intensity (U,V,W)" - +typedef ^ ^ Logical TI_listed - - - "Turbulence intesity given in file" - +typedef ^ ^ ReKi MWS - - - "Approximate mean wind speed" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Steady_InitInputType ReKi HWindSpeed - - - "Horizontal wind speed" m/s +typedef ^ ^ ReKi RefHt - - - "Reference height for horizontal wind speed" meters +typedef ^ ^ ReKi PLExp - - - "Power law exponent" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Uniform_InitInputType character(1024) WindFileName - - - "Name of the wind file to use" - +typedef ^ ^ ReKi RefHt - - - "Reference height for horizontal wind speed" meters +typedef ^ ^ ReKi RefLength - - - "Reference length for linear horizontal and vertical sheer" - +typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation" radians +typedef ^ ^ logical UseInputFile - .true. - "Flag for toggling file based IO in wind type 2." - +typedef ^ ^ FileInfoType PassedFileData - - - "Optional slot for wind type 2 data if file IO is not used." - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid3D_InitInputType IntKi ScaleMethod - 0 - "Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation]" - +typedef ^ ^ ReKi SF 3 0 - "Turbulence scaling factor for each direction [ScaleMethod=1]" - +typedef ^ ^ ReKi SigmaF 3 0 - "Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2]" - +typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - +typedef ^ ^ ReKi RefHt - 0 - "Reference (hub) height of the grid" meters +typedef ^ ^ ReKi URef - 0 - "Mean u-component wind speed at the reference height" meters +typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - +typedef ^ ^ ReKi VLinShr - 0 - "Vertical linear wind shear coefficient (used for vertical linear wind profile type only)" - +typedef ^ ^ ReKi HLinShr - 0 - "Horizontal linear wind shear coefficient (used for horizontal wind profile type only)" - +typedef ^ ^ ReKi RefLength - 1 - "Reference (rotor) length of the grid (used for horizontal wind profile type only)" - +typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - +typedef ^ ^ ReKi XOffset - 0 - "distance offset for FF wind files" m + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ TurbSim_InitInputType character(1024) WindFileName - - - "Name of the wind file to use" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Bladed_InitInputType character(1024) WindFileName - - - "Root filename" - +typedef ^ ^ IntKi WindType - - - "Whether this is native Bladed (needs wind profile and TI scaling) or not" - +typedef ^ ^ logical NativeBladedFmt - - - "Whether this is native Bladed (needs wind profile and TI scaling) or not" - +typedef ^ ^ logical TowerFileExist - - - "Tower file exists" - +typedef ^ ^ IntKi TurbineID - 0 - "Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm)" - +typedef ^ ^ logical FixedWindFileRootName - .false. - "Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm)" - + +typedef ^ Bladed_InitOutputType ReKi PropagationDir - - - "Propogation direction from native Bladed format" degrees +typedef ^ ^ ReKi VFlowAngle - - - "Vertical flow angle from native Bladed format" degrees + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ HAWC_InitInputType character(1024) WindFileName {3} - - "Name of the wind file to use" - +typedef ^ ^ IntKi nx - 0 - "Number of grids in the x direction (in the 3 files above)" - +typedef ^ ^ IntKi ny - 0 - "Number of grids in the y direction (in the 3 files above)" - +typedef ^ ^ IntKi nz - 0 - "Number of grids in the z direction (in the 3 files above)" - +typedef ^ ^ ReKi dx - 0 - "size of grids in the x direction (in the 3 files above)" - +typedef ^ ^ ReKi dy - 0 - "size of grids in the y direction (in the 3 files above)" - +typedef ^ ^ ReKi dz - 0 - "size of grids in the z direction (in the 3 files above)" - +typedef ^ ^ Grid3D_InitInputType G3D - - - "Grid3D initialization input" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ User_InitInputType SiKi Dummy - - - "User field initialization input dummy value" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid4D_InitInputType IntKi n 4 - - "number of grid points in the x, y, z, and t directions" - +typedef ^ ^ ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" +typedef ^ ^ ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Points_InitInputType IntKi NumWindPoints - - - "Number of points where wind components will be provided" - diff --git a/modules/inflowwind/src/InflowWind_IO_Types.f90 b/modules/inflowwind/src/InflowWind_IO_Types.f90 new file mode 100644 index 0000000000..4409b9804d --- /dev/null +++ b/modules/inflowwind/src/InflowWind_IO_Types.f90 @@ -0,0 +1,2209 @@ +!STARTOFREGISTRYGENERATEDFILE 'InflowWind_IO_Types.f90' +! +! WARNING This file is generated automatically by the FAST registry. +! Do not edit. Your changes to this file will be lost. +! +! FAST Registry +!********************************************************************************************************************************* +! InflowWind_IO_Types +!................................................................................................................................. +! This file is part of InflowWind_IO. +! +! Copyright (C) 2012-2016 National Renewable Energy Laboratory +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +! +! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. +! +!********************************************************************************************************************************* +!> This module contains the user-defined types needed in InflowWind_IO. It also contains copy, destroy, pack, and +!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. +MODULE InflowWind_IO_Types +!--------------------------------------------------------------------------------------------------------------------------------- +USE IfW_FlowField_Types +USE NWTC_Library +IMPLICIT NONE +! ========= WindFileDat ======= + TYPE, PUBLIC :: WindFileDat + character(1024) :: FileName !< Name of the windfile retrieved [-] + INTEGER(IntKi) :: WindType = 0 !< Type of the windfile [-] + REAL(ReKi) :: RefHt !< Reference height given in file [meters] + LOGICAL :: RefHt_Set !< Reference height was given in file [-] + REAL(DbKi) :: DT !< TimeStep of the wind file -- zero value for none [seconds] + INTEGER(IntKi) :: NumTSteps !< Number of timesteps in the time range of wind file [-] + LOGICAL :: ConstantDT !< Timesteps are the same throughout file [-] + REAL(ReKi) , DIMENSION(1:2) :: TRange !< Time range of the wind file [seconds] + LOGICAL :: TRange_Limited !< TRange limits strictly enforced [-] + REAL(ReKi) , DIMENSION(1:2) :: YRange !< Range in y direction [meters] + LOGICAL :: YRange_Limited !< YRange limits strictly enforced [-] + REAL(ReKi) , DIMENSION(1:2) :: ZRange !< Range in z direction [meters] + LOGICAL :: ZRange_Limited !< ZRange limits strictly enforced [-] + INTEGER(IntKi) :: BinaryFormat !< Binary format identifier [-] + LOGICAL :: IsBinary !< Windfile is a binary file [-] + REAL(ReKi) , DIMENSION(1:3) :: TI !< Turbulence intensity (U,V,W) [-] + LOGICAL :: TI_listed !< Turbulence intesity given in file [-] + REAL(ReKi) :: MWS !< Approximate mean wind speed [-] + END TYPE WindFileDat +! ======================= +! ========= Steady_InitInputType ======= + TYPE, PUBLIC :: Steady_InitInputType + REAL(ReKi) :: HWindSpeed !< Horizontal wind speed [m/s] + REAL(ReKi) :: RefHt !< Reference height for horizontal wind speed [meters] + REAL(ReKi) :: PLExp !< Power law exponent [-] + END TYPE Steady_InitInputType +! ======================= +! ========= Uniform_InitInputType ======= + TYPE, PUBLIC :: Uniform_InitInputType + character(1024) :: WindFileName !< Name of the wind file to use [-] + REAL(ReKi) :: RefHt !< Reference height for horizontal wind speed [meters] + REAL(ReKi) :: RefLength !< Reference length for linear horizontal and vertical sheer [-] + REAL(ReKi) :: PropagationDir !< Direction of wind propagation [radians] + LOGICAL :: UseInputFile = .true. !< Flag for toggling file based IO in wind type 2. [-] + TYPE(FileInfoType) :: PassedFileData !< Optional slot for wind type 2 data if file IO is not used. [-] + END TYPE Uniform_InitInputType +! ======================= +! ========= Grid3D_InitInputType ======= + TYPE, PUBLIC :: Grid3D_InitInputType + INTEGER(IntKi) :: ScaleMethod = 0 !< Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation] [-] + REAL(ReKi) , DIMENSION(1:3) :: SF !< Turbulence scaling factor for each direction [ScaleMethod=1] [-] + REAL(ReKi) , DIMENSION(1:3) :: SigmaF !< Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2] [-] + INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] + REAL(ReKi) :: RefHt = 0 !< Reference (hub) height of the grid [meters] + REAL(ReKi) :: URef = 0 !< Mean u-component wind speed at the reference height [meters] + REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] + REAL(ReKi) :: VLinShr = 0 !< Vertical linear wind shear coefficient (used for vertical linear wind profile type only) [-] + REAL(ReKi) :: HLinShr = 0 !< Horizontal linear wind shear coefficient (used for horizontal wind profile type only) [-] + REAL(ReKi) :: RefLength = 1 !< Reference (rotor) length of the grid (used for horizontal wind profile type only) [-] + REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] + REAL(ReKi) :: XOffset = 0 !< distance offset for FF wind files [m] + END TYPE Grid3D_InitInputType +! ======================= +! ========= TurbSim_InitInputType ======= + TYPE, PUBLIC :: TurbSim_InitInputType + character(1024) :: WindFileName !< Name of the wind file to use [-] + END TYPE TurbSim_InitInputType +! ======================= +! ========= Bladed_InitInputType ======= + TYPE, PUBLIC :: Bladed_InitInputType + character(1024) :: WindFileName !< Root filename [-] + INTEGER(IntKi) :: WindType !< Whether this is native Bladed (needs wind profile and TI scaling) or not [-] + LOGICAL :: NativeBladedFmt !< Whether this is native Bladed (needs wind profile and TI scaling) or not [-] + LOGICAL :: TowerFileExist !< Tower file exists [-] + INTEGER(IntKi) :: TurbineID = 0 !< Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm) [-] + LOGICAL :: FixedWindFileRootName = .false. !< Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm) [-] + END TYPE Bladed_InitInputType +! ======================= +! ========= Bladed_InitOutputType ======= + TYPE, PUBLIC :: Bladed_InitOutputType + REAL(ReKi) :: PropagationDir !< Propogation direction from native Bladed format [degrees] + REAL(ReKi) :: VFlowAngle !< Vertical flow angle from native Bladed format [degrees] + END TYPE Bladed_InitOutputType +! ======================= +! ========= HAWC_InitInputType ======= + TYPE, PUBLIC :: HAWC_InitInputType + character(1024) , DIMENSION(1:3) :: WindFileName !< Name of the wind file to use [-] + INTEGER(IntKi) :: nx = 0 !< Number of grids in the x direction (in the 3 files above) [-] + INTEGER(IntKi) :: ny = 0 !< Number of grids in the y direction (in the 3 files above) [-] + INTEGER(IntKi) :: nz = 0 !< Number of grids in the z direction (in the 3 files above) [-] + REAL(ReKi) :: dx = 0 !< size of grids in the x direction (in the 3 files above) [-] + REAL(ReKi) :: dy = 0 !< size of grids in the y direction (in the 3 files above) [-] + REAL(ReKi) :: dz = 0 !< size of grids in the z direction (in the 3 files above) [-] + TYPE(Grid3D_InitInputType) :: G3D !< Grid3D initialization input [-] + END TYPE HAWC_InitInputType +! ======================= +! ========= User_InitInputType ======= + TYPE, PUBLIC :: User_InitInputType + REAL(SiKi) :: Dummy !< User field initialization input dummy value [-] + END TYPE User_InitInputType +! ======================= +! ========= Grid4D_InitInputType ======= + TYPE, PUBLIC :: Grid4D_InitInputType + INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of grid points in the x, y, z, and t directions [-] + REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] + REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] + END TYPE Grid4D_InitInputType +! ======================= +! ========= Points_InitInputType ======= + TYPE, PUBLIC :: Points_InitInputType + INTEGER(IntKi) :: NumWindPoints !< Number of points where wind components will be provided [-] + END TYPE Points_InitInputType +! ======================= +CONTAINS + SUBROUTINE InflowWind_IO_CopyWindFileDat( SrcWindFileDatData, DstWindFileDatData, CtrlCode, ErrStat, ErrMsg ) + TYPE(WindFileDat), INTENT(IN) :: SrcWindFileDatData + TYPE(WindFileDat), INTENT(INOUT) :: DstWindFileDatData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyWindFileDat' +! + ErrStat = ErrID_None + ErrMsg = "" + DstWindFileDatData%FileName = SrcWindFileDatData%FileName + DstWindFileDatData%WindType = SrcWindFileDatData%WindType + DstWindFileDatData%RefHt = SrcWindFileDatData%RefHt + DstWindFileDatData%RefHt_Set = SrcWindFileDatData%RefHt_Set + DstWindFileDatData%DT = SrcWindFileDatData%DT + DstWindFileDatData%NumTSteps = SrcWindFileDatData%NumTSteps + DstWindFileDatData%ConstantDT = SrcWindFileDatData%ConstantDT + DstWindFileDatData%TRange = SrcWindFileDatData%TRange + DstWindFileDatData%TRange_Limited = SrcWindFileDatData%TRange_Limited + DstWindFileDatData%YRange = SrcWindFileDatData%YRange + DstWindFileDatData%YRange_Limited = SrcWindFileDatData%YRange_Limited + DstWindFileDatData%ZRange = SrcWindFileDatData%ZRange + DstWindFileDatData%ZRange_Limited = SrcWindFileDatData%ZRange_Limited + DstWindFileDatData%BinaryFormat = SrcWindFileDatData%BinaryFormat + DstWindFileDatData%IsBinary = SrcWindFileDatData%IsBinary + DstWindFileDatData%TI = SrcWindFileDatData%TI + DstWindFileDatData%TI_listed = SrcWindFileDatData%TI_listed + DstWindFileDatData%MWS = SrcWindFileDatData%MWS + END SUBROUTINE InflowWind_IO_CopyWindFileDat + + SUBROUTINE InflowWind_IO_DestroyWindFileDat( WindFileDatData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(WindFileDat), INTENT(INOUT) :: WindFileDatData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyWindFileDat' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyWindFileDat + + SUBROUTINE InflowWind_IO_PackWindFileDat( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(WindFileDat), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackWindFileDat' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%FileName) ! FileName + Int_BufSz = Int_BufSz + 1 ! WindType + Re_BufSz = Re_BufSz + 1 ! RefHt + Int_BufSz = Int_BufSz + 1 ! RefHt_Set + Db_BufSz = Db_BufSz + 1 ! DT + Int_BufSz = Int_BufSz + 1 ! NumTSteps + Int_BufSz = Int_BufSz + 1 ! ConstantDT + Re_BufSz = Re_BufSz + SIZE(InData%TRange) ! TRange + Int_BufSz = Int_BufSz + 1 ! TRange_Limited + Re_BufSz = Re_BufSz + SIZE(InData%YRange) ! YRange + Int_BufSz = Int_BufSz + 1 ! YRange_Limited + Re_BufSz = Re_BufSz + SIZE(InData%ZRange) ! ZRange + Int_BufSz = Int_BufSz + 1 ! ZRange_Limited + Int_BufSz = Int_BufSz + 1 ! BinaryFormat + Int_BufSz = Int_BufSz + 1 ! IsBinary + Re_BufSz = Re_BufSz + SIZE(InData%TI) ! TI + Int_BufSz = Int_BufSz + 1 ! TI_listed + Re_BufSz = Re_BufSz + 1 ! MWS + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%FileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%FileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%WindType + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%RefHt_Set, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%DT + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumTSteps + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%ConstantDT, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%TRange,1), UBOUND(InData%TRange,1) + ReKiBuf(Re_Xferred) = InData%TRange(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%TRange_Limited, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%YRange,1), UBOUND(InData%YRange,1) + ReKiBuf(Re_Xferred) = InData%YRange(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%YRange_Limited, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%ZRange,1), UBOUND(InData%ZRange,1) + ReKiBuf(Re_Xferred) = InData%ZRange(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%ZRange_Limited, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BinaryFormat + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%IsBinary, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) + ReKiBuf(Re_Xferred) = InData%TI(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%TI_listed, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MWS + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackWindFileDat + + SUBROUTINE InflowWind_IO_UnPackWindFileDat( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(WindFileDat), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackWindFileDat' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%FileName) + OutData%FileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%WindType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefHt_Set = TRANSFER(IntKiBuf(Int_Xferred), OutData%RefHt_Set) + Int_Xferred = Int_Xferred + 1 + OutData%DT = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%NumTSteps = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ConstantDT = TRANSFER(IntKiBuf(Int_Xferred), OutData%ConstantDT) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%TRange,1) + i1_u = UBOUND(OutData%TRange,1) + DO i1 = LBOUND(OutData%TRange,1), UBOUND(OutData%TRange,1) + OutData%TRange(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%TRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%TRange_Limited) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%YRange,1) + i1_u = UBOUND(OutData%YRange,1) + DO i1 = LBOUND(OutData%YRange,1), UBOUND(OutData%YRange,1) + OutData%YRange(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%YRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%YRange_Limited) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%ZRange,1) + i1_u = UBOUND(OutData%ZRange,1) + DO i1 = LBOUND(OutData%ZRange,1), UBOUND(OutData%ZRange,1) + OutData%ZRange(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%ZRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%ZRange_Limited) + Int_Xferred = Int_Xferred + 1 + OutData%BinaryFormat = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%IsBinary = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsBinary) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%TI,1) + i1_u = UBOUND(OutData%TI,1) + DO i1 = LBOUND(OutData%TI,1), UBOUND(OutData%TI,1) + OutData%TI(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%TI_listed = TRANSFER(IntKiBuf(Int_Xferred), OutData%TI_listed) + Int_Xferred = Int_Xferred + 1 + OutData%MWS = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackWindFileDat + + SUBROUTINE InflowWind_IO_CopySteady_InitInputType( SrcSteady_InitInputTypeData, DstSteady_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Steady_InitInputType), INTENT(IN) :: SrcSteady_InitInputTypeData + TYPE(Steady_InitInputType), INTENT(INOUT) :: DstSteady_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopySteady_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstSteady_InitInputTypeData%HWindSpeed = SrcSteady_InitInputTypeData%HWindSpeed + DstSteady_InitInputTypeData%RefHt = SrcSteady_InitInputTypeData%RefHt + DstSteady_InitInputTypeData%PLExp = SrcSteady_InitInputTypeData%PLExp + END SUBROUTINE InflowWind_IO_CopySteady_InitInputType + + SUBROUTINE InflowWind_IO_DestroySteady_InitInputType( Steady_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Steady_InitInputType), INTENT(INOUT) :: Steady_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroySteady_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroySteady_InitInputType + + SUBROUTINE InflowWind_IO_PackSteady_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Steady_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackSteady_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! HWindSpeed + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! PLExp + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%HWindSpeed + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackSteady_InitInputType + + SUBROUTINE InflowWind_IO_UnPackSteady_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Steady_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackSteady_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%HWindSpeed = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackSteady_InitInputType + + SUBROUTINE InflowWind_IO_CopyUniform_InitInputType( SrcUniform_InitInputTypeData, DstUniform_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Uniform_InitInputType), INTENT(IN) :: SrcUniform_InitInputTypeData + TYPE(Uniform_InitInputType), INTENT(INOUT) :: DstUniform_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyUniform_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUniform_InitInputTypeData%WindFileName = SrcUniform_InitInputTypeData%WindFileName + DstUniform_InitInputTypeData%RefHt = SrcUniform_InitInputTypeData%RefHt + DstUniform_InitInputTypeData%RefLength = SrcUniform_InitInputTypeData%RefLength + DstUniform_InitInputTypeData%PropagationDir = SrcUniform_InitInputTypeData%PropagationDir + DstUniform_InitInputTypeData%UseInputFile = SrcUniform_InitInputTypeData%UseInputFile + CALL NWTC_Library_Copyfileinfotype( SrcUniform_InitInputTypeData%PassedFileData, DstUniform_InitInputTypeData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE InflowWind_IO_CopyUniform_InitInputType + + SUBROUTINE InflowWind_IO_DestroyUniform_InitInputType( Uniform_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Uniform_InitInputType), INTENT(INOUT) :: Uniform_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyUniform_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyfileinfotype( Uniform_InitInputTypeData%PassedFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_IO_DestroyUniform_InitInputType + + SUBROUTINE InflowWind_IO_PackUniform_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Uniform_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackUniform_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! RefLength + Re_BufSz = Re_BufSz + 1 ! PropagationDir + Int_BufSz = Int_BufSz + 1 ! UseInputFile + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! PassedFileData: size of buffers for each call to pack subtype + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! PassedFileData + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! PassedFileData + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! PassedFileData + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PropagationDir + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%UseInputFile, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE InflowWind_IO_PackUniform_InitInputType + + SUBROUTINE InflowWind_IO_UnPackUniform_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Uniform_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackUniform_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PropagationDir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%UseInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseInputFile) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE InflowWind_IO_UnPackUniform_InitInputType + + SUBROUTINE InflowWind_IO_CopyGrid3D_InitInputType( SrcGrid3D_InitInputTypeData, DstGrid3D_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid3D_InitInputType), INTENT(IN) :: SrcGrid3D_InitInputTypeData + TYPE(Grid3D_InitInputType), INTENT(INOUT) :: DstGrid3D_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyGrid3D_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid3D_InitInputTypeData%ScaleMethod = SrcGrid3D_InitInputTypeData%ScaleMethod + DstGrid3D_InitInputTypeData%SF = SrcGrid3D_InitInputTypeData%SF + DstGrid3D_InitInputTypeData%SigmaF = SrcGrid3D_InitInputTypeData%SigmaF + DstGrid3D_InitInputTypeData%WindProfileType = SrcGrid3D_InitInputTypeData%WindProfileType + DstGrid3D_InitInputTypeData%RefHt = SrcGrid3D_InitInputTypeData%RefHt + DstGrid3D_InitInputTypeData%URef = SrcGrid3D_InitInputTypeData%URef + DstGrid3D_InitInputTypeData%PLExp = SrcGrid3D_InitInputTypeData%PLExp + DstGrid3D_InitInputTypeData%VLinShr = SrcGrid3D_InitInputTypeData%VLinShr + DstGrid3D_InitInputTypeData%HLinShr = SrcGrid3D_InitInputTypeData%HLinShr + DstGrid3D_InitInputTypeData%RefLength = SrcGrid3D_InitInputTypeData%RefLength + DstGrid3D_InitInputTypeData%Z0 = SrcGrid3D_InitInputTypeData%Z0 + DstGrid3D_InitInputTypeData%XOffset = SrcGrid3D_InitInputTypeData%XOffset + END SUBROUTINE InflowWind_IO_CopyGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_DestroyGrid3D_InitInputType( Grid3D_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid3D_InitInputType), INTENT(INOUT) :: Grid3D_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyGrid3D_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_PackGrid3D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid3D_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackGrid3D_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! ScaleMethod + Re_BufSz = Re_BufSz + SIZE(InData%SF) ! SF + Re_BufSz = Re_BufSz + SIZE(InData%SigmaF) ! SigmaF + Int_BufSz = Int_BufSz + 1 ! WindProfileType + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! URef + Re_BufSz = Re_BufSz + 1 ! PLExp + Re_BufSz = Re_BufSz + 1 ! VLinShr + Re_BufSz = Re_BufSz + 1 ! HLinShr + Re_BufSz = Re_BufSz + 1 ! RefLength + Re_BufSz = Re_BufSz + 1 ! Z0 + Re_BufSz = Re_BufSz + 1 ! XOffset + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%ScaleMethod + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%SF,1), UBOUND(InData%SF,1) + ReKiBuf(Re_Xferred) = InData%SF(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%SigmaF,1), UBOUND(InData%SigmaF,1) + ReKiBuf(Re_Xferred) = InData%SigmaF(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%WindProfileType + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%URef + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VLinShr + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HLinShr + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Z0 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%XOffset + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_UnPackGrid3D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid3D_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackGrid3D_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%ScaleMethod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%SF,1) + i1_u = UBOUND(OutData%SF,1) + DO i1 = LBOUND(OutData%SF,1), UBOUND(OutData%SF,1) + OutData%SF(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%SigmaF,1) + i1_u = UBOUND(OutData%SigmaF,1) + DO i1 = LBOUND(OutData%SigmaF,1), UBOUND(OutData%SigmaF,1) + OutData%SigmaF(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%WindProfileType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%URef = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Z0 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%XOffset = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_CopyTurbSim_InitInputType( SrcTurbSim_InitInputTypeData, DstTurbSim_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(TurbSim_InitInputType), INTENT(IN) :: SrcTurbSim_InitInputTypeData + TYPE(TurbSim_InitInputType), INTENT(INOUT) :: DstTurbSim_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyTurbSim_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstTurbSim_InitInputTypeData%WindFileName = SrcTurbSim_InitInputTypeData%WindFileName + END SUBROUTINE InflowWind_IO_CopyTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_DestroyTurbSim_InitInputType( TurbSim_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(TurbSim_InitInputType), INTENT(INOUT) :: TurbSim_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyTurbSim_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_PackTurbSim_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(TurbSim_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackTurbSim_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END SUBROUTINE InflowWind_IO_PackTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_UnPackTurbSim_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(TurbSim_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackTurbSim_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END SUBROUTINE InflowWind_IO_UnPackTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_CopyBladed_InitInputType( SrcBladed_InitInputTypeData, DstBladed_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Bladed_InitInputType), INTENT(IN) :: SrcBladed_InitInputTypeData + TYPE(Bladed_InitInputType), INTENT(INOUT) :: DstBladed_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyBladed_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstBladed_InitInputTypeData%WindFileName = SrcBladed_InitInputTypeData%WindFileName + DstBladed_InitInputTypeData%WindType = SrcBladed_InitInputTypeData%WindType + DstBladed_InitInputTypeData%NativeBladedFmt = SrcBladed_InitInputTypeData%NativeBladedFmt + DstBladed_InitInputTypeData%TowerFileExist = SrcBladed_InitInputTypeData%TowerFileExist + DstBladed_InitInputTypeData%TurbineID = SrcBladed_InitInputTypeData%TurbineID + DstBladed_InitInputTypeData%FixedWindFileRootName = SrcBladed_InitInputTypeData%FixedWindFileRootName + END SUBROUTINE InflowWind_IO_CopyBladed_InitInputType + + SUBROUTINE InflowWind_IO_DestroyBladed_InitInputType( Bladed_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Bladed_InitInputType), INTENT(INOUT) :: Bladed_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyBladed_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyBladed_InitInputType + + SUBROUTINE InflowWind_IO_PackBladed_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Bladed_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackBladed_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName + Int_BufSz = Int_BufSz + 1 ! WindType + Int_BufSz = Int_BufSz + 1 ! NativeBladedFmt + Int_BufSz = Int_BufSz + 1 ! TowerFileExist + Int_BufSz = Int_BufSz + 1 ! TurbineID + Int_BufSz = Int_BufSz + 1 ! FixedWindFileRootName + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%WindType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%NativeBladedFmt, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TowerFileExist, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%TurbineID + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%FixedWindFileRootName, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackBladed_InitInputType + + SUBROUTINE InflowWind_IO_UnPackBladed_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Bladed_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackBladed_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%WindType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NativeBladedFmt = TRANSFER(IntKiBuf(Int_Xferred), OutData%NativeBladedFmt) + Int_Xferred = Int_Xferred + 1 + OutData%TowerFileExist = TRANSFER(IntKiBuf(Int_Xferred), OutData%TowerFileExist) + Int_Xferred = Int_Xferred + 1 + OutData%TurbineID = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%FixedWindFileRootName = TRANSFER(IntKiBuf(Int_Xferred), OutData%FixedWindFileRootName) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackBladed_InitInputType + + SUBROUTINE InflowWind_IO_CopyBladed_InitOutputType( SrcBladed_InitOutputTypeData, DstBladed_InitOutputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Bladed_InitOutputType), INTENT(IN) :: SrcBladed_InitOutputTypeData + TYPE(Bladed_InitOutputType), INTENT(INOUT) :: DstBladed_InitOutputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyBladed_InitOutputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstBladed_InitOutputTypeData%PropagationDir = SrcBladed_InitOutputTypeData%PropagationDir + DstBladed_InitOutputTypeData%VFlowAngle = SrcBladed_InitOutputTypeData%VFlowAngle + END SUBROUTINE InflowWind_IO_CopyBladed_InitOutputType + + SUBROUTINE InflowWind_IO_DestroyBladed_InitOutputType( Bladed_InitOutputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Bladed_InitOutputType), INTENT(INOUT) :: Bladed_InitOutputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyBladed_InitOutputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyBladed_InitOutputType + + SUBROUTINE InflowWind_IO_PackBladed_InitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Bladed_InitOutputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackBladed_InitOutputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! PropagationDir + Re_BufSz = Re_BufSz + 1 ! VFlowAngle + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%PropagationDir + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VFlowAngle + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackBladed_InitOutputType + + SUBROUTINE InflowWind_IO_UnPackBladed_InitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Bladed_InitOutputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackBladed_InitOutputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%PropagationDir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VFlowAngle = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackBladed_InitOutputType + + SUBROUTINE InflowWind_IO_CopyHAWC_InitInputType( SrcHAWC_InitInputTypeData, DstHAWC_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(HAWC_InitInputType), INTENT(IN) :: SrcHAWC_InitInputTypeData + TYPE(HAWC_InitInputType), INTENT(INOUT) :: DstHAWC_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyHAWC_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstHAWC_InitInputTypeData%WindFileName = SrcHAWC_InitInputTypeData%WindFileName + DstHAWC_InitInputTypeData%nx = SrcHAWC_InitInputTypeData%nx + DstHAWC_InitInputTypeData%ny = SrcHAWC_InitInputTypeData%ny + DstHAWC_InitInputTypeData%nz = SrcHAWC_InitInputTypeData%nz + DstHAWC_InitInputTypeData%dx = SrcHAWC_InitInputTypeData%dx + DstHAWC_InitInputTypeData%dy = SrcHAWC_InitInputTypeData%dy + DstHAWC_InitInputTypeData%dz = SrcHAWC_InitInputTypeData%dz + CALL InflowWind_IO_Copygrid3d_initinputtype( SrcHAWC_InitInputTypeData%G3D, DstHAWC_InitInputTypeData%G3D, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE InflowWind_IO_CopyHAWC_InitInputType + + SUBROUTINE InflowWind_IO_DestroyHAWC_InitInputType( HAWC_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(HAWC_InitInputType), INTENT(INOUT) :: HAWC_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyHAWC_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_IO_Destroygrid3d_initinputtype( HAWC_InitInputTypeData%G3D, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_IO_DestroyHAWC_InitInputType + + SUBROUTINE InflowWind_IO_PackHAWC_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(HAWC_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackHAWC_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + SIZE(InData%WindFileName)*LEN(InData%WindFileName) ! WindFileName + Int_BufSz = Int_BufSz + 1 ! nx + Int_BufSz = Int_BufSz + 1 ! ny + Int_BufSz = Int_BufSz + 1 ! nz + Re_BufSz = Re_BufSz + 1 ! dx + Re_BufSz = Re_BufSz + 1 ! dy + Re_BufSz = Re_BufSz + 1 ! dz + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! G3D: size of buffers for each call to pack subtype + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%G3D, ErrStat2, ErrMsg2, .TRUE. ) ! G3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! G3D + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! G3D + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! G3D + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%WindFileName,1), UBOUND(InData%WindFileName,1) + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + IntKiBuf(Int_Xferred) = InData%nx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%ny + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nz + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dx + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dy + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dz + Re_Xferred = Re_Xferred + 1 + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%G3D, ErrStat2, ErrMsg2, OnlySize ) ! G3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE InflowWind_IO_PackHAWC_InitInputType + + SUBROUTINE InflowWind_IO_UnPackHAWC_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(HAWC_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackHAWC_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%WindFileName,1) + i1_u = UBOUND(OutData%WindFileName,1) + DO i1 = LBOUND(OutData%WindFileName,1), UBOUND(OutData%WindFileName,1) + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + OutData%nx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ny = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nz = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%dx = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%dy = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%dz = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_IO_Unpackgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%G3D, ErrStat2, ErrMsg2 ) ! G3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE InflowWind_IO_UnPackHAWC_InitInputType + + SUBROUTINE InflowWind_IO_CopyUser_InitInputType( SrcUser_InitInputTypeData, DstUser_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(User_InitInputType), INTENT(IN) :: SrcUser_InitInputTypeData + TYPE(User_InitInputType), INTENT(INOUT) :: DstUser_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyUser_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUser_InitInputTypeData%Dummy = SrcUser_InitInputTypeData%Dummy + END SUBROUTINE InflowWind_IO_CopyUser_InitInputType + + SUBROUTINE InflowWind_IO_DestroyUser_InitInputType( User_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(User_InitInputType), INTENT(INOUT) :: User_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyUser_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyUser_InitInputType + + SUBROUTINE InflowWind_IO_PackUser_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(User_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackUser_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! Dummy + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%Dummy + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackUser_InitInputType + + SUBROUTINE InflowWind_IO_UnPackUser_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(User_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackUser_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%Dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackUser_InitInputType + + SUBROUTINE InflowWind_IO_CopyGrid4D_InitInputType( SrcGrid4D_InitInputTypeData, DstGrid4D_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid4D_InitInputType), INTENT(IN) :: SrcGrid4D_InitInputTypeData + TYPE(Grid4D_InitInputType), INTENT(INOUT) :: DstGrid4D_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyGrid4D_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid4D_InitInputTypeData%n = SrcGrid4D_InitInputTypeData%n + DstGrid4D_InitInputTypeData%delta = SrcGrid4D_InitInputTypeData%delta + DstGrid4D_InitInputTypeData%pZero = SrcGrid4D_InitInputTypeData%pZero + END SUBROUTINE InflowWind_IO_CopyGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_DestroyGrid4D_InitInputType( Grid4D_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid4D_InitInputType), INTENT(INOUT) :: Grid4D_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyGrid4D_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_PackGrid4D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid4D_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackGrid4D_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + SIZE(InData%n) ! n + Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta + Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) + IntKiBuf(Int_Xferred) = InData%n(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) + ReKiBuf(Re_Xferred) = InData%delta(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) + ReKiBuf(Re_Xferred) = InData%pZero(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END SUBROUTINE InflowWind_IO_PackGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_UnPackGrid4D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid4D_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackGrid4D_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%n,1) + i1_u = UBOUND(OutData%n,1) + DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) + OutData%n(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%delta,1) + i1_u = UBOUND(OutData%delta,1) + DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) + OutData%delta(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%pZero,1) + i1_u = UBOUND(OutData%pZero,1) + DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) + OutData%pZero(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END SUBROUTINE InflowWind_IO_UnPackGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_CopyPoints_InitInputType( SrcPoints_InitInputTypeData, DstPoints_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Points_InitInputType), INTENT(IN) :: SrcPoints_InitInputTypeData + TYPE(Points_InitInputType), INTENT(INOUT) :: DstPoints_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyPoints_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstPoints_InitInputTypeData%NumWindPoints = SrcPoints_InitInputTypeData%NumWindPoints + END SUBROUTINE InflowWind_IO_CopyPoints_InitInputType + + SUBROUTINE InflowWind_IO_DestroyPoints_InitInputType( Points_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Points_InitInputType), INTENT(INOUT) :: Points_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyPoints_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyPoints_InitInputType + + SUBROUTINE InflowWind_IO_PackPoints_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Points_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackPoints_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! NumWindPoints + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%NumWindPoints + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackPoints_InitInputType + + SUBROUTINE InflowWind_IO_UnPackPoints_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Points_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackPoints_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%NumWindPoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackPoints_InitInputType + +END MODULE InflowWind_IO_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index e56b8a2f18..4b4e381420 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -19,22 +19,9 @@ !********************************************************************************************************************************** MODULE InflowWind_Subs - USE InflowWind_Types - USE NWTC_Library - - !------------------------------------------------------------------------------------------------- - ! The included wind modules (TYPES modules are inherited from InflowWind_Types, so not specified here again.) - !------------------------------------------------------------------------------------------------- - USE IfW_UniformWind ! uniform wind files (text files) - USE IfW_TSFFWind ! TurbSim style full-field binary wind files - USE IfW_BladedFFWind ! Bladed style full-field binary wind files - USE IfW_UserWind ! User-defined wind module - USE IfW_HAWCWind ! full-field binary wind files in HAWC format - USE IfW_4Dext ! 4D wind field from external source (e.g., FAST.Farm) - -!!! USE FDWind ! 4-D binary wind files -!!! USE CTWind ! coherent turbulence from KH billow - binary file superimposed on another wind type - + USE InflowWind_Types + USE NWTC_Library + USE IfW_FlowField, only: IfW_FlowField_GetVelAcc IMPLICIT NONE @@ -45,7 +32,7 @@ MODULE InflowWind_Subs ! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these ! lines should be modified in the Matlab script and/or Excel worksheet as necessary. ! =================================================================================================== -! This code was generated by "Write_ChckOutLst.m" at 29-Jul-2022 19:48:38. +! This code was generated by "Write_ChckOutLst.m" at 05-Apr-2023. ! Indices for computing output channels: @@ -55,104 +42,141 @@ MODULE InflowWind_Subs ! Time: - INTEGER(IntKi), PARAMETER :: Time = 0 + INTEGER(IntKi), PARAMETER :: Time = 0 ! Wind Motions: - INTEGER(IntKi), PARAMETER :: Wind1VelX = 1 - INTEGER(IntKi), PARAMETER :: Wind1VelY = 2 - INTEGER(IntKi), PARAMETER :: Wind1VelZ = 3 - INTEGER(IntKi), PARAMETER :: Wind2VelX = 4 - INTEGER(IntKi), PARAMETER :: Wind2VelY = 5 - INTEGER(IntKi), PARAMETER :: Wind2VelZ = 6 - INTEGER(IntKi), PARAMETER :: Wind3VelX = 7 - INTEGER(IntKi), PARAMETER :: Wind3VelY = 8 - INTEGER(IntKi), PARAMETER :: Wind3VelZ = 9 - INTEGER(IntKi), PARAMETER :: Wind4VelX = 10 - INTEGER(IntKi), PARAMETER :: Wind4VelY = 11 - INTEGER(IntKi), PARAMETER :: Wind4VelZ = 12 - INTEGER(IntKi), PARAMETER :: Wind5VelX = 13 - INTEGER(IntKi), PARAMETER :: Wind5VelY = 14 - INTEGER(IntKi), PARAMETER :: Wind5VelZ = 15 - INTEGER(IntKi), PARAMETER :: Wind6VelX = 16 - INTEGER(IntKi), PARAMETER :: Wind6VelY = 17 - INTEGER(IntKi), PARAMETER :: Wind6VelZ = 18 - INTEGER(IntKi), PARAMETER :: Wind7VelX = 19 - INTEGER(IntKi), PARAMETER :: Wind7VelY = 20 - INTEGER(IntKi), PARAMETER :: Wind7VelZ = 21 - INTEGER(IntKi), PARAMETER :: Wind8VelX = 22 - INTEGER(IntKi), PARAMETER :: Wind8VelY = 23 - INTEGER(IntKi), PARAMETER :: Wind8VelZ = 24 - INTEGER(IntKi), PARAMETER :: Wind9VelX = 25 - INTEGER(IntKi), PARAMETER :: Wind9VelY = 26 - INTEGER(IntKi), PARAMETER :: Wind9VelZ = 27 - INTEGER(IntKi), PARAMETER :: WindHubVelX = 28 - INTEGER(IntKi), PARAMETER :: WindHubVelY = 29 - INTEGER(IntKi), PARAMETER :: WindHubVelZ = 30 - INTEGER(IntKi), PARAMETER :: WindDiskVelX = 31 - INTEGER(IntKi), PARAMETER :: WindDiskVelY = 32 - INTEGER(IntKi), PARAMETER :: WindDiskVelZ = 33 + INTEGER(IntKi), PARAMETER :: Wind1VelX = 1 + INTEGER(IntKi), PARAMETER :: Wind1VelY = 2 + INTEGER(IntKi), PARAMETER :: Wind1VelZ = 3 + INTEGER(IntKi), PARAMETER :: Wind2VelX = 4 + INTEGER(IntKi), PARAMETER :: Wind2VelY = 5 + INTEGER(IntKi), PARAMETER :: Wind2VelZ = 6 + INTEGER(IntKi), PARAMETER :: Wind3VelX = 7 + INTEGER(IntKi), PARAMETER :: Wind3VelY = 8 + INTEGER(IntKi), PARAMETER :: Wind3VelZ = 9 + INTEGER(IntKi), PARAMETER :: Wind4VelX = 10 + INTEGER(IntKi), PARAMETER :: Wind4VelY = 11 + INTEGER(IntKi), PARAMETER :: Wind4VelZ = 12 + INTEGER(IntKi), PARAMETER :: Wind5VelX = 13 + INTEGER(IntKi), PARAMETER :: Wind5VelY = 14 + INTEGER(IntKi), PARAMETER :: Wind5VelZ = 15 + INTEGER(IntKi), PARAMETER :: Wind6VelX = 16 + INTEGER(IntKi), PARAMETER :: Wind6VelY = 17 + INTEGER(IntKi), PARAMETER :: Wind6VelZ = 18 + INTEGER(IntKi), PARAMETER :: Wind7VelX = 19 + INTEGER(IntKi), PARAMETER :: Wind7VelY = 20 + INTEGER(IntKi), PARAMETER :: Wind7VelZ = 21 + INTEGER(IntKi), PARAMETER :: Wind8VelX = 22 + INTEGER(IntKi), PARAMETER :: Wind8VelY = 23 + INTEGER(IntKi), PARAMETER :: Wind8VelZ = 24 + INTEGER(IntKi), PARAMETER :: Wind9VelX = 25 + INTEGER(IntKi), PARAMETER :: Wind9VelY = 26 + INTEGER(IntKi), PARAMETER :: Wind9VelZ = 27 + INTEGER(IntKi), PARAMETER :: WindHubVelX = 28 + INTEGER(IntKi), PARAMETER :: WindHubVelY = 29 + INTEGER(IntKi), PARAMETER :: WindHubVelZ = 30 + INTEGER(IntKi), PARAMETER :: WindDiskVelX = 31 + INTEGER(IntKi), PARAMETER :: WindDiskVelY = 32 + INTEGER(IntKi), PARAMETER :: WindDiskVelZ = 33 + + + ! Wind Accelerations: + + INTEGER(IntKi), PARAMETER :: Wind1AccX = 34 + INTEGER(IntKi), PARAMETER :: Wind1AccY = 35 + INTEGER(IntKi), PARAMETER :: Wind1AccZ = 36 + INTEGER(IntKi), PARAMETER :: Wind2AccX = 37 + INTEGER(IntKi), PARAMETER :: Wind2AccY = 38 + INTEGER(IntKi), PARAMETER :: Wind2AccZ = 39 + INTEGER(IntKi), PARAMETER :: Wind3AccX = 40 + INTEGER(IntKi), PARAMETER :: Wind3AccY = 41 + INTEGER(IntKi), PARAMETER :: Wind3AccZ = 42 + INTEGER(IntKi), PARAMETER :: Wind4AccX = 43 + INTEGER(IntKi), PARAMETER :: Wind4AccY = 44 + INTEGER(IntKi), PARAMETER :: Wind4AccZ = 45 + INTEGER(IntKi), PARAMETER :: Wind5AccX = 46 + INTEGER(IntKi), PARAMETER :: Wind5AccY = 47 + INTEGER(IntKi), PARAMETER :: Wind5AccZ = 48 + INTEGER(IntKi), PARAMETER :: Wind6AccX = 49 + INTEGER(IntKi), PARAMETER :: Wind6AccY = 50 + INTEGER(IntKi), PARAMETER :: Wind6AccZ = 51 + INTEGER(IntKi), PARAMETER :: Wind7AccX = 52 + INTEGER(IntKi), PARAMETER :: Wind7AccY = 53 + INTEGER(IntKi), PARAMETER :: Wind7AccZ = 54 + INTEGER(IntKi), PARAMETER :: Wind8AccX = 55 + INTEGER(IntKi), PARAMETER :: Wind8AccY = 56 + INTEGER(IntKi), PARAMETER :: Wind8AccZ = 57 + INTEGER(IntKi), PARAMETER :: Wind9AccX = 58 + INTEGER(IntKi), PARAMETER :: Wind9AccY = 59 + INTEGER(IntKi), PARAMETER :: Wind9AccZ = 60 ! Wind Magnitude and Direction: - INTEGER(IntKi), PARAMETER :: Wind1VelXY = 34 - INTEGER(IntKi), PARAMETER :: Wind2VelXY = 35 - INTEGER(IntKi), PARAMETER :: Wind3VelXY = 36 - INTEGER(IntKi), PARAMETER :: Wind4VelXY = 37 - INTEGER(IntKi), PARAMETER :: Wind5VelXY = 38 - INTEGER(IntKi), PARAMETER :: Wind6VelXY = 39 - INTEGER(IntKi), PARAMETER :: Wind7VelXY = 40 - INTEGER(IntKi), PARAMETER :: Wind8VelXY = 41 - INTEGER(IntKi), PARAMETER :: Wind9VelXY = 42 - INTEGER(IntKi), PARAMETER :: WindHubVelXY = 43 - INTEGER(IntKi), PARAMETER :: WindDiskVelXY = 44 - INTEGER(IntKi), PARAMETER :: Wind1VelMag = 45 - INTEGER(IntKi), PARAMETER :: Wind2VelMag = 46 - INTEGER(IntKi), PARAMETER :: Wind3VelMag = 47 - INTEGER(IntKi), PARAMETER :: Wind4VelMag = 48 - INTEGER(IntKi), PARAMETER :: Wind5VelMag = 49 - INTEGER(IntKi), PARAMETER :: Wind6VelMag = 50 - INTEGER(IntKi), PARAMETER :: Wind7VelMag = 51 - INTEGER(IntKi), PARAMETER :: Wind8VelMag = 52 - INTEGER(IntKi), PARAMETER :: Wind9VelMag = 53 - INTEGER(IntKi), PARAMETER :: WindHubVelMag = 54 - INTEGER(IntKi), PARAMETER :: WindDiskVelMag = 55 - INTEGER(IntKi), PARAMETER :: Wind1AngXY = 56 - INTEGER(IntKi), PARAMETER :: Wind2AngXY = 57 - INTEGER(IntKi), PARAMETER :: Wind3AngXY = 58 - INTEGER(IntKi), PARAMETER :: Wind4AngXY = 59 - INTEGER(IntKi), PARAMETER :: Wind5AngXY = 60 - INTEGER(IntKi), PARAMETER :: Wind6AngXY = 61 - INTEGER(IntKi), PARAMETER :: Wind7AngXY = 62 - INTEGER(IntKi), PARAMETER :: Wind8AngXY = 63 - INTEGER(IntKi), PARAMETER :: Wind9AngXY = 64 - INTEGER(IntKi), PARAMETER :: WindHubAngXY = 65 - INTEGER(IntKi), PARAMETER :: WindDiskAngXY = 66 + INTEGER(IntKi), PARAMETER :: Wind1VelXY = 61 + INTEGER(IntKi), PARAMETER :: Wind2VelXY = 62 + INTEGER(IntKi), PARAMETER :: Wind3VelXY = 63 + INTEGER(IntKi), PARAMETER :: Wind4VelXY = 64 + INTEGER(IntKi), PARAMETER :: Wind5VelXY = 65 + INTEGER(IntKi), PARAMETER :: Wind6VelXY = 66 + INTEGER(IntKi), PARAMETER :: Wind7VelXY = 67 + INTEGER(IntKi), PARAMETER :: Wind8VelXY = 68 + INTEGER(IntKi), PARAMETER :: Wind9VelXY = 69 + INTEGER(IntKi), PARAMETER :: WindHubVelXY = 70 + INTEGER(IntKi), PARAMETER :: WindDiskVelXY = 71 + INTEGER(IntKi), PARAMETER :: Wind1VelMag = 72 + INTEGER(IntKi), PARAMETER :: Wind2VelMag = 73 + INTEGER(IntKi), PARAMETER :: Wind3VelMag = 74 + INTEGER(IntKi), PARAMETER :: Wind4VelMag = 75 + INTEGER(IntKi), PARAMETER :: Wind5VelMag = 76 + INTEGER(IntKi), PARAMETER :: Wind6VelMag = 77 + INTEGER(IntKi), PARAMETER :: Wind7VelMag = 78 + INTEGER(IntKi), PARAMETER :: Wind8VelMag = 79 + INTEGER(IntKi), PARAMETER :: Wind9VelMag = 80 + INTEGER(IntKi), PARAMETER :: WindHubVelMag = 81 + INTEGER(IntKi), PARAMETER :: WindDiskVelMag = 82 + INTEGER(IntKi), PARAMETER :: Wind1AngXY = 83 + INTEGER(IntKi), PARAMETER :: Wind2AngXY = 84 + INTEGER(IntKi), PARAMETER :: Wind3AngXY = 85 + INTEGER(IntKi), PARAMETER :: Wind4AngXY = 86 + INTEGER(IntKi), PARAMETER :: Wind5AngXY = 87 + INTEGER(IntKi), PARAMETER :: Wind6AngXY = 88 + INTEGER(IntKi), PARAMETER :: Wind7AngXY = 89 + INTEGER(IntKi), PARAMETER :: Wind8AngXY = 90 + INTEGER(IntKi), PARAMETER :: Wind9AngXY = 91 + INTEGER(IntKi), PARAMETER :: WindHubAngXY = 92 + INTEGER(IntKi), PARAMETER :: WindDiskAngXY = 93 ! Wind Sensor Measurements: - INTEGER(IntKi), PARAMETER :: WindMeas1 = 67 - INTEGER(IntKi), PARAMETER :: WindMeas2 = 68 - INTEGER(IntKi), PARAMETER :: WindMeas3 = 69 - INTEGER(IntKi), PARAMETER :: WindMeas4 = 70 - INTEGER(IntKi), PARAMETER :: WindMeas5 = 71 + INTEGER(IntKi), PARAMETER :: WindMeas1 = 94 + INTEGER(IntKi), PARAMETER :: WindMeas2 = 95 + INTEGER(IntKi), PARAMETER :: WindMeas3 = 96 + INTEGER(IntKi), PARAMETER :: WindMeas4 = 97 + INTEGER(IntKi), PARAMETER :: WindMeas5 = 98 ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi), PARAMETER :: MaxOutPts = 71 + INTEGER(IntKi), PARAMETER :: MaxOutPts = 98 !End of code generated by Matlab script Write_ChckOutLst ! =================================================================================================== INTEGER(IntKi), PARAMETER :: WindMeas(5) = (/ WindMeas1, WindMeas2, WindMeas3, WindMeas4, WindMeas5 /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindVelX(9) = (/ Wind1VelX, Wind2VelX, Wind3VelX, Wind4VelX, Wind5VelX, Wind6VelX, Wind7VelX, Wind8VelX, Wind9VelX /) ! Array of output constants INTEGER(IntKi), PARAMETER :: WindVelY(9) = (/ Wind1VelY, Wind2VelY, Wind3VelY, Wind4VelY, Wind5VelY, Wind6VelY, Wind7VelY, Wind8VelY, Wind9VelY /) ! Array of output constants INTEGER(IntKi), PARAMETER :: WindVelZ(9) = (/ Wind1VelZ, Wind2VelZ, Wind3VelZ, Wind4VelZ, Wind5VelZ, Wind6VelZ, Wind7VelZ, Wind8VelZ, Wind9VelZ /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindAccX(9) = (/ Wind1AccX, Wind2AccX, Wind3AccX, Wind4AccX, Wind5AccX, Wind6AccX, Wind7AccX, Wind8AccX, Wind9AccX /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindAccY(9) = (/ Wind1AccY, Wind2AccY, Wind3AccY, Wind4AccY, Wind5AccY, Wind6AccY, Wind7AccY, Wind8AccY, Wind9AccY /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindAccZ(9) = (/ Wind1AccZ, Wind2AccZ, Wind3AccZ, Wind4AccZ, Wind5AccZ, Wind6AccZ, Wind7AccZ, Wind8AccZ, Wind9AccZ /) ! Array of output constants + + INTEGER(IntKi), PARAMETER :: WindVelXY( 9) = (/ Wind1VelXY, Wind2VelXY, Wind3VelXY, Wind4VelXY, Wind5VelXY, Wind6VelXY, Wind7VelXY, Wind8VelXY, Wind9VelXY /) ! Array of output constants INTEGER(IntKi), PARAMETER :: WindVelMag(9) = (/ Wind1VelMag, Wind2VelMag, Wind3VelMag, Wind4VelMag, Wind5VelMag, Wind6VelMag, Wind7VelMag, Wind8VelMag, Wind9VelMag/) ! Array of output constants INTEGER(IntKi), PARAMETER :: WindAngXY( 9) = (/ Wind1AngXY, Wind2AngXY, Wind3AngXY, Wind4AngXY, Wind5AngXY, Wind6AngXY, Wind7AngXY, Wind8AngXY, Wind9AngXY /) ! Array of output constants @@ -238,6 +262,10 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In ! VFlowAngle: Upflow angle (deg) CALL ParseVarWDefault( InFileInfo, CurLine, "VFlowAng", InputFileData%VFlowAngle, 0.0_ReKi, TmpErrStat, TmpErrMsg, UnEc ) + if (Failed()) return + + ! VelInterpCubic: Velocity interpolation order in time (1=linear; 3=cubic) [Used with WindType=2,3,4,5,7] + CALL ParseVar( InFileInfo, CurLine, "VelInterpCubic", InputFileData%VelInterpCubic, TmpErrStat, TmpErrMsg, UnEc ) if (Failed()) return ! NWindVel: Number of points to output the wind velocity (0 to 9) @@ -942,19 +970,15 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM !----------------------------------------------------------------- ! Copy over the general information that applies to everything !----------------------------------------------------------------- - p%CTTS_Flag = .FALSE. ! Copy the WindType over. - p%WindType = InputFileData%WindType - ! Convert the PropagationDir to radians and store this. For simplicity, we will shift it to be between -pi and pi + p%FlowField%PropagationDir = D2R * InputFileData%PropagationDir + CALL MPi2Pi( p%FlowField%PropagationDir ) ! Shift if necessary so that the value is between -pi and pi - p%PropagationDir = D2R * InputFileData%PropagationDir - CALL MPi2Pi( p%PropagationDir ) ! Shift if necessary so that the value is between -pi and pi - - p%VFlowAngle = D2R * InputFileData%VFlowAngle + p%FlowField%VFlowAngle = D2R * InputFileData%VFlowAngle ! Copy over the list of wind coordinates. Move the arrays to the new one. p%NWindVel = InputFileData%NWindVel @@ -979,6 +1003,14 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM IF ( ErrStat>= AbortErrLev ) RETURN m%WindViUVW = 0.0_ReKi + ! If output acceleration flag is set, allocate array to hold wind point accelerations. + IF (InitInp%OutputAccel) THEN + CALL AllocAry( m%WindAiUVW, 3, p%NWindVel, "Array of wind accelerations corresponding to the WindViLists", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) RETURN + m%WindAiUVW = 0.0_ReKi + END IF + CALL AllocAry( m%u_Hub%PositionXYZ, 3, 1, "Array of positions for hub values", TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) CALL AllocAry( m%y_Hub%VelocityUVW, 3, 1, "Array of velocities for hub values", TmpErrStat, TmpErrMsg ) @@ -1007,7 +1039,7 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM p%PositionAvg(3,i) = 0.0_ReKi end do - + p%OutputAccel = InitInp%OutputAccel ! Set the OutList CALL SetOutParam( InputFileData%OutList, p, TmpErrStat, TmpErrmsg ) @@ -1083,9 +1115,15 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! Create the rotation matrices -- rotate from XYZ to X'Y'Z' (wind aligned along X) coordinates ! Included in this rotation is the wind upflow (inclination) angle (rotation about Y axis) - p%RotToWind(1,:) = (/ COS(-p%VFlowAngle) * COS(-p%PropagationDir), COS(-p%VFlowAngle) * SIN(-p%PropagationDir), -SIN(-p%VFlowAngle) /) - p%RotToWind(2,:) = (/ -SIN(-p%PropagationDir), COS(-p%PropagationDir), 0.0_ReKi /) - p%RotToWind(3,:) = (/ SIN(-p%VFlowAngle) * COS(-p%PropagationDir), SIN(-p%VFlowAngle) * SIN(-p%PropagationDir), COS(-p%VFlowAngle) /) + p%FlowField%RotToWind(1,:) = [ COS(-p%FlowField%VFlowAngle) * COS(-p%FlowField%PropagationDir), & + COS(-p%FlowField%VFlowAngle) * SIN(-p%FlowField%PropagationDir), & + -SIN(-p%FlowField%VFlowAngle) ] + p%FlowField%RotToWind(2,:) = [ -SIN(-p%FlowField%PropagationDir), & + COS(-p%FlowField%PropagationDir), & + 0.0_ReKi ] + p%FlowField%RotToWind(3,:) = [ SIN(-p%FlowField%VFlowAngle) * COS(-p%FlowField%PropagationDir), & + SIN(-p%FlowField%VFlowAngle) * SIN(-p%FlowField%PropagationDir), & + COS(-p%FlowField%VFlowAngle) ] ! Create the rotation matrices -- rotate from X'Y'Z' (wind aligned along X) to global XYZ coordinates: this is the same as a ! rotation about the (positive) upflow angle multiplied by a rotation about the (positive) wind direction: @@ -1093,7 +1131,7 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! loal wind = R( -p%VFlowAngle) * R (-p%PropagationDir) [global wind] ! = R^T(p%VFlowAngle) * R^T(p%PropagationDir) [global wind] ! = (R(p%PropagationDir) * R(p%VFlowAngle))^T [global wind] - p%RotFromWind = TRANSPOSE(p%RotToWind) + p%FlowField%RotFromWind = TRANSPOSE(p%FlowField%RotToWind) ! Create the array used for holding the rotated list of WindViXYZ coordinates in the wind reference frame, and populate it CALL AllocAry( p%WindViXYZprime, 3, p%NWindVel, 'Array for WindViXYZ coordinates in the wind reference frame', & @@ -1106,10 +1144,10 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM p%WindViXYZprime = 0.0_ReKi ! set the output points. Note rotation is about the hub height at [0 0 H]. See InflowWind_SetParameters for details. DO I = 1,p%NWindVel - p%WindViXYZprime(:,I) = MATMUL( p%RotToWind, (p%WindViXYZ(:,I) - p%RefPosition )) + p%RefPosition + p%WindViXYZprime(:,I) = MATMUL( p%FlowField%RotToWind, (p%WindViXYZ(:,I) - p%RefPosition )) + p%RefPosition ENDDO - p%RotateWindBox = .not. (EqualRealNos (p%PropagationDir, 0.0_ReKi) .AND. EqualRealNos (p%VFlowAngle, 0.0_ReKi)) + p%FlowField%RotateWindBox = .not. (EqualRealNos (p%FlowField%PropagationDir, 0.0_ReKi) .AND. EqualRealNos (p%FlowField%VFlowAngle, 0.0_ReKi)) END SUBROUTINE InflowWind_SetParameters @@ -1134,11 +1172,11 @@ END SUBROUTINE InflowWind_SetParameters SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) !.................................................................................................................................. - IMPLICIT NONE + IMPLICIT NONE ! Passed variables - CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list out user-requested outputs + CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list of user-requested outputs TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< The module parameters INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred @@ -1147,7 +1185,6 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) INTEGER :: ErrStat2 ! temporary (local) error status INTEGER :: I ! Generic loop-counting index -! INTEGER :: J ! Generic loop-counting index INTEGER :: INDX ! Index for valid arrays LOGICAL :: CheckOutListAgain ! Flag used to determine if output parameter starting with "M" is valid (or the negative of another parameter) @@ -1155,55 +1192,71 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(71) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "WIND1ANGXY ","WIND1VELMAG ","WIND1VELX ","WIND1VELXY ","WIND1VELY ", & - "WIND1VELZ ","WIND2ANGXY ","WIND2VELMAG ","WIND2VELX ","WIND2VELXY ", & - "WIND2VELY ","WIND2VELZ ","WIND3ANGXY ","WIND3VELMAG ","WIND3VELX ", & - "WIND3VELXY ","WIND3VELY ","WIND3VELZ ","WIND4ANGXY ","WIND4VELMAG ", & - "WIND4VELX ","WIND4VELXY ","WIND4VELY ","WIND4VELZ ","WIND5ANGXY ", & + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(98) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "WIND1ACCX ","WIND1ACCY ","WIND1ACCZ ","WIND1ANGXY ","WIND1VELMAG ", & + "WIND1VELX ","WIND1VELXY ","WIND1VELY ","WIND1VELZ ","WIND2ACCX ", & + "WIND2ACCY ","WIND2ACCZ ","WIND2ANGXY ","WIND2VELMAG ","WIND2VELX ", & + "WIND2VELXY ","WIND2VELY ","WIND2VELZ ","WIND3ACCX ","WIND3ACCY ", & + "WIND3ACCZ ","WIND3ANGXY ","WIND3VELMAG ","WIND3VELX ","WIND3VELXY ", & + "WIND3VELY ","WIND3VELZ ","WIND4ACCX ","WIND4ACCY ","WIND4ACCZ ", & + "WIND4ANGXY ","WIND4VELMAG ","WIND4VELX ","WIND4VELXY ","WIND4VELY ", & + "WIND4VELZ ","WIND5ACCX ","WIND5ACCY ","WIND5ACCZ ","WIND5ANGXY ", & "WIND5VELMAG ","WIND5VELX ","WIND5VELXY ","WIND5VELY ","WIND5VELZ ", & - "WIND6ANGXY ","WIND6VELMAG ","WIND6VELX ","WIND6VELXY ","WIND6VELY ", & - "WIND6VELZ ","WIND7ANGXY ","WIND7VELMAG ","WIND7VELX ","WIND7VELXY ", & - "WIND7VELY ","WIND7VELZ ","WIND8ANGXY ","WIND8VELMAG ","WIND8VELX ", & - "WIND8VELXY ","WIND8VELY ","WIND8VELZ ","WIND9ANGXY ","WIND9VELMAG ", & - "WIND9VELX ","WIND9VELXY ","WIND9VELY ","WIND9VELZ ","WINDDISKANGXY ", & - "WINDDISKVELMAG","WINDDISKVELX ","WINDDISKVELXY ","WINDDISKVELY ","WINDDISKVELZ ", & - "WINDHUBANGXY ","WINDHUBVELMAG ","WINDHUBVELX ","WINDHUBVELXY ","WINDHUBVELY ", & - "WINDHUBVELZ ","WINDMEAS1 ","WINDMEAS2 ","WINDMEAS3 ","WINDMEAS4 ", & - "WINDMEAS5 "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(71) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - Wind1AngXY , Wind1VelMag , Wind1VelX , Wind1VelXY , Wind1VelY , & - Wind1VelZ , Wind2AngXY , Wind2VelMag , Wind2VelX , Wind2VelXY , & - Wind2VelY , Wind2VelZ , Wind3AngXY , Wind3VelMag , Wind3VelX , & - Wind3VelXY , Wind3VelY , Wind3VelZ , Wind4AngXY , Wind4VelMag , & - Wind4VelX , Wind4VelXY , Wind4VelY , Wind4VelZ , Wind5AngXY , & + "WIND6ACCX ","WIND6ACCY ","WIND6ACCZ ","WIND6ANGXY ","WIND6VELMAG ", & + "WIND6VELX ","WIND6VELXY ","WIND6VELY ","WIND6VELZ ","WIND7ACCX ", & + "WIND7ACCY ","WIND7ACCZ ","WIND7ANGXY ","WIND7VELMAG ","WIND7VELX ", & + "WIND7VELXY ","WIND7VELY ","WIND7VELZ ","WIND8ACCX ","WIND8ACCY ", & + "WIND8ACCZ ","WIND8ANGXY ","WIND8VELMAG ","WIND8VELX ","WIND8VELXY ", & + "WIND8VELY ","WIND8VELZ ","WIND9ACCX ","WIND9ACCY ","WIND9ACCZ ", & + "WIND9ANGXY ","WIND9VELMAG ","WIND9VELX ","WIND9VELXY ","WIND9VELY ", & + "WIND9VELZ ","WINDDISKANGXY ","WINDDISKVELMAG","WINDDISKVELX ","WINDDISKVELXY ", & + "WINDDISKVELY ","WINDDISKVELZ ","WINDHUBANGXY ","WINDHUBVELMAG ","WINDHUBVELX ", & + "WINDHUBVELXY ","WINDHUBVELY ","WINDHUBVELZ ","WINDMEAS1 ","WINDMEAS2 ", & + "WINDMEAS3 ","WINDMEAS4 ","WINDMEAS5 "/) + + INTEGER(IntKi), PARAMETER :: ParamIndxAry(98) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + Wind1AccX , Wind1AccY , Wind1AccZ , Wind1AngXY , Wind1VelMag , & + Wind1VelX , Wind1VelXY , Wind1VelY , Wind1VelZ , Wind2AccX , & + Wind2AccY , Wind2AccZ , Wind2AngXY , Wind2VelMag , Wind2VelX , & + Wind2VelXY , Wind2VelY , Wind2VelZ , Wind3AccX , Wind3AccY , & + Wind3AccZ , Wind3AngXY , Wind3VelMag , Wind3VelX , Wind3VelXY , & + Wind3VelY , Wind3VelZ , Wind4AccX , Wind4AccY , Wind4AccZ , & + Wind4AngXY , Wind4VelMag , Wind4VelX , Wind4VelXY , Wind4VelY , & + Wind4VelZ , Wind5AccX , Wind5AccY , Wind5AccZ , Wind5AngXY , & Wind5VelMag , Wind5VelX , Wind5VelXY , Wind5VelY , Wind5VelZ , & - Wind6AngXY , Wind6VelMag , Wind6VelX , Wind6VelXY , Wind6VelY , & - Wind6VelZ , Wind7AngXY , Wind7VelMag , Wind7VelX , Wind7VelXY , & - Wind7VelY , Wind7VelZ , Wind8AngXY , Wind8VelMag , Wind8VelX , & - Wind8VelXY , Wind8VelY , Wind8VelZ , Wind9AngXY , Wind9VelMag , & - Wind9VelX , Wind9VelXY , Wind9VelY , Wind9VelZ , WindDiskAngXY , & - WindDiskVelMag , WindDiskVelX , WindDiskVelXY , WindDiskVelY , WindDiskVelZ , & - WindHubAngXY , WindHubVelMag , WindHubVelX , WindHubVelXY , WindHubVelY , & - WindHubVelZ , WindMeas1 , WindMeas2 , WindMeas3 , WindMeas4 , & - WindMeas5 /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(71) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters - "(deg)","(m/s)","(m/s)","(m/s)","(m/s)", & - "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & - "(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & + Wind6AccX , Wind6AccY , Wind6AccZ , Wind6AngXY , Wind6VelMag , & + Wind6VelX , Wind6VelXY , Wind6VelY , Wind6VelZ , Wind7AccX , & + Wind7AccY , Wind7AccZ , Wind7AngXY , Wind7VelMag , Wind7VelX , & + Wind7VelXY , Wind7VelY , Wind7VelZ , Wind8AccX , Wind8AccY , & + Wind8AccZ , Wind8AngXY , Wind8VelMag , Wind8VelX , Wind8VelXY , & + Wind8VelY , Wind8VelZ , Wind9AccX , Wind9AccY , Wind9AccZ , & + Wind9AngXY , Wind9VelMag , Wind9VelX , Wind9VelXY , Wind9VelY , & + Wind9VelZ , WindDiskAngXY , WindDiskVelMag , WindDiskVelX , WindDiskVelXY , & + WindDiskVelY , WindDiskVelZ , WindHubAngXY , WindHubVelMag , WindHubVelX , & + WindHubVelXY , WindHubVelY , WindHubVelZ , WindMeas1 , WindMeas2 , & + WindMeas3 , WindMeas4 , WindMeas5 /) + + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(98) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters "(m/s)","(m/s)","(m/s)","(deg)","(m/s)", & - "(m/s)","(m/s)","(m/s)","(m/s)","(deg)", & "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & - "(deg)","(m/s)","(m/s)","(m/s)","(m/s)", & - "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & "(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & - "(m/s)","(m/s)","(m/s)","(deg)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(deg)","(m/s)","(m/s)","(m/s)","(m/s)", & "(m/s)","(m/s)","(m/s)","(m/s)","(deg)", & "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(deg)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & "(deg)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & - "(m/s)"/) - + "(m/s)","(m/s)","(m/s)"/) ! Initialize values ErrStat = ErrID_None @@ -1220,21 +1273,30 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) InvalidOutput( WindVelX( I) ) = .TRUE. InvalidOutput( WindVelY( I) ) = .TRUE. InvalidOutput( WindVelZ( I) ) = .TRUE. + InvalidOutput( WindAccX( I) ) = .TRUE. + InvalidOutput( WindAccY( I) ) = .TRUE. + InvalidOutput( WindAccZ( I) ) = .TRUE. InvalidOutput( WindVelXY( I) ) = .TRUE. InvalidOutput( WindVelMag(I) ) = .TRUE. InvalidOutput( WindAngXY( I) ) = .TRUE. END DO -IF (p%lidar%SensorType == SensorType_SinglePoint) THEN - DO I=p%lidar%NumBeam+1,5 - InvalidOutput( WindMeas(I) ) = .TRUE. - END DO -ELSE - DO I=p%lidar%NumPulseGate+1,5 - InvalidOutput( WindMeas(I) ) = .TRUE. - END DO - - END IF + ! Set all accelerations invalid if not requested + if (.not. p%OutputAccel) then + InvalidOutput(WindAccX) = .TRUE. + InvalidOutput(WindAccY) = .TRUE. + InvalidOutput(WindAccZ) = .TRUE. + end if + + IF (p%lidar%SensorType == SensorType_SinglePoint) THEN + DO I=p%lidar%NumBeam+1,5 + InvalidOutput( WindMeas(I) ) = .TRUE. + END DO + ELSE + DO I=p%lidar%NumPulseGate+1,5 + InvalidOutput( WindMeas(I) ) = .TRUE. + END DO + END IF ! ................. End of validity checking ................. @@ -1419,9 +1481,17 @@ SUBROUTINE SetAllOuts( p, y, m, ErrStat, ErrMsg ) else m%AllOuts( WindAngXY(I) ) = ATAN2( m%WindViUVW(2,I), m%WindViUVW(1,I) )*R2D ! in degrees end if -! m%AllOuts( WindAngVer(I) ) = ATAN2( m%WindViUVW(3,I), m%AllOuts( WindVelXY(I) ) )*R2D ! in degrees END DO + + ! Set accelerations + if (allocated(m%WindAiUVW)) then + DO I = 1,p%NWindVel + m%AllOuts( WindAccX(I) ) = m%WindAiUVW(1,I) + m%AllOuts( WindAccY(I) ) = m%WindAiUVW(2,I) + m%AllOuts( WindAccZ(I) ) = m%WindAiUVW(3,I) + END DO + end if ! DiskVel outputs: m%AllOuts( WindDiskVelX ) = y%DiskVel(1) @@ -1543,279 +1613,40 @@ END SUBROUTINE InflowWind_CloseSumFile SUBROUTINE CalculateOutput( Time, InputData, p, x, xd, z, OtherStates, y, m, FillWrOut, ErrStat, ErrMsg ) + REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds + TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time + TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(InflowWind_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(InflowWind_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time + TYPE(InflowWind_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time + TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other states at Time + TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Outputs computed at Time (IN for mesh reasons and data allocation) + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables + LOGICAL, INTENT(IN ) :: FillWrOut !< Flag to determine if we need to fill WriteOutput values + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CHARACTER(*), PARAMETER :: RoutineName="CalculateOutput" + + ! Temporary variables for error handling + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message + + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="CalcOutput" - - - ! Inputs / Outputs - - REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds - TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time - TYPE(InflowWind_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time - TYPE(InflowWind_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time - TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other states at Time - TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Outputs computed at Time (IN for mesh reasons and data allocation) - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables - LOGICAL, INTENT(IN ) :: FillWrOut !< Flag to determine if we need to fill WriteOutput values - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - REAL(ReKi), ALLOCATABLE :: PositionXYZprime(:,:) !< PositionXYZ array in the prime (wind) coordinates - - INTEGER(IntKi) :: I !< Generic counters - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - - - !----------------------------------------------------------------------- - ! Points coordinate transforms from to global to wind file coordinates - !----------------------------------------------------------------------- - - - !> Make a copy of the InputData%PositionXYZ coordinates with the applied rotation matrix... - !! This copy is made because if we translate it to the prime coordinates, then back again, we - !! may shift the points by some small amount of machine error, and we don't want to do that. - !! - !! Note that we allocate this at every call to CalcOutput. The reason is that we may call CalcOutput - !! multiple times in each timestep with different sized InputData%PositionXYZ arrays (if calling for LIDAR - !! data etc). We don't really want to have extra copies of OtherStates lying around in order to be able to - !! do this. - CALL AllocAry( PositionXYZprime, 3, SIZE(InputData%PositionXYZ,DIM=2), & - "Array for holding the XYZprime position data", TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Apply the coordinate transformation to the PositionXYZ coordinates to get the PositionXYZprime coordinate list - ! If the PropagationDir is zero, we don't need to apply this and will simply copy the data. Repeat for the WindViXYZ. - IF ( .not. p%RotateWindBox ) THEN - PositionXYZprime = InputData%PositionXYZ - ELSE - ! NOTE: rotations are about the hub at [ 0 0 H ]. See InflowWind_SetParameters for details. - DO I = 1,SIZE(InputData%PositionXYZ,DIM=2) - PositionXYZprime(:,I) = MATMUL( p%RotToWind, (InputData%PositionXYZ(:,I) - p%RefPosition) ) + p%RefPosition - ENDDO - ENDIF - - - !--------------------------------- - ! - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_UniformWind_CalcOutput( Time, PositionXYZprime, p%UniformWind, y%VelocityUVW, m%UniformWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! Call IfW_UniformWind_CalcOutput again in order to get the values needed for the OutList -- note that we do not report errors from this - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_UniformWind_CalcOutput( Time, p%WindViXYZprime, p%UniformWind, m%WindViUVW, m%UniformWind, TmpErrStat, TmpErrMsg) - ENDIF - - CASE (TSFF_WindNumber) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_TSFFWind_CalcOutput( Time, PositionXYZprime, p%TSFFWind, y%VelocityUVW, m%TSFFWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_TSFFWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_TSFFWind_CalcOutput( Time, p%WindViXYZprime, p%TSFFWind, m%WindViUVW, m%TSFFWind, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDIF - - - - CASE (BladedFF_WindNumber) !also includes BladedFF_Shr_WindNumber - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_BladedFFWind_CalcOutput( Time, PositionXYZprime, p%BladedFFWind, y%VelocityUVW, m%BladedFFWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_BladedFFWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_BladedFFWind_CalcOutput( Time, p%WindViXYZprime, p%BladedFFWind, m%WindViUVW, m%BladedFFWind, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDIF - - - CASE (User_WindNumber) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_UserWind_CalcOutput( Time, PositionXYZprime, p%UserWind, y%VelocityUVW, m%UserWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_UserWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_UserWind_CalcOutput( Time, p%WindViXYZprime, p%UserWind, m%WindViUVW, m%UserWind, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDIF - - CASE ( HAWC_WindNumber ) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_HAWCWind_CalcOutput( Time, PositionXYZprime, p%HAWCWind, y%VelocityUVW, m%HAWCWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_TSFFWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - CALL IfW_HAWCWind_CalcOutput( Time, p%WindViXYZprime, p%HAWCWind, m%WindViUVW, m%HAWCWind, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ENDIF - - - CASE ( FDext_WindNumber ) - - CALL IfW_4Dext_CalcOutput(Time, PositionXYZprime, p%FDext, y%VelocityUVW, m%FDext, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_4Dext_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_4Dext_CalcOutput(Time, p%WindViXYZprime, p%FDext, m%WindViUVW, m%FDext, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDIF - - - ! If it isn't one of the above cases, we have a problem and won't be able to continue - - CASE DEFAULT - - CALL SetErrStat( ErrID_Fatal, ' Error: Undefined wind type '//TRIM(Num2LStr(p%WindType))//'. '// & - 'Call WindInflow_Init() before calling this function.', ErrStat, ErrMsg, RoutineName ) - - y%VelocityUVW(:,:) = 0.0 - RETURN - - END SELECT - - - ! Add coherent turbulence to background wind - -!!! IF (p%CTTS_Flag) THEN -!!! -!!! DO PointCounter = 1, SIZE(InputData%Position, 2) -!!! -!!! TempWindSpeed = CTTS_GetWindSpeed( Time, InputData%Position(:,PointCounter), ErrStat, ErrMsg ) -!!! -!!! ! Error Handling -- move ErrMsg inside CTTS_GetWindSPeed and simplify -!!! IF (ErrStat >= ErrID_Severe) THEN -!!! ErrMsg = 'IfW_CalcOutput: Error in CTTS_GetWindSpeed for point number '//TRIM(Num2LStr(PointCounter)) -!!! EXIT ! Exit the loop -!!! ENDIF -!!! -!!! y%Velocity(:,PointCounter) = y%Velocity(:,PointCounter) + TempWindSpeed -!!! -!!! ENDDO -!!! -!!! ! If something went badly wrong, Return -!!! IF (ErrStat >= ErrID_Severe ) RETURN -!!! -!!! ENDIF -!!! - !ENDIF - - - - - - !----------------------------------------------------------------------- - ! Windspeed coordinate transforms from Wind file coordinates to global - !----------------------------------------------------------------------- - - ! The VelocityUVW array data that has been returned from the sub-modules is in the wind file (X'Y'Z') coordinates at - ! this point. These must be rotated to the global XYZ coordinates. So now we apply the coordinate transformation - ! to the VelocityUVW(prime) coordinates (in wind X'Y'Z' coordinate frame) returned from the submodules to the XYZ - ! coordinate frame, but only if PropagationDir is not zero. This is only a rotation of the returned wind field, so - ! UVW contains the direction components of the wind at XYZ after translation from the U'V'W' wind velocity components - ! in the X'Y'Z' (wind file) coordinate frame. - ! NOTE: rotations are about the hub at [ 0 0 H ]. See InflowWind_SetParameters for details. - IF ( p%RotateWindBox ) THEN - DO I = 1,SIZE(y%VelocityUVW,DIM=2) - y%VelocityUVW(:,I) = MATMUL( p%RotFromWind, y%VelocityUVW(:,I) ) - ENDDO - ENDIF - - ! We also need to rotate the reference frame for the WindViUVW array - ! NOTE: rotations are about the hub at [ 0 0 H ]. See InflowWind_SetParameters for details. - IF ( p%RotateWindBox .AND. FillWrOut ) THEN - DO I = 1,SIZE(m%WindViUVW,DIM=2) - m%WindViUVW(:,I) = MATMUL( p%RotFromWind, m%WindViUVW(:,I) ) - ENDDO - ENDIF - - - ! Done with the prime coordinates for the XYZ position information that was passed in. - IF (ALLOCATED(PositionXYZprime)) DEALLOCATE(PositionXYZprime) + ! Get velocities and accelerations for the given positions + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, Time, InputData%PositionXYZ, & + y%VelocityUVW, y%AccelUVW, TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev) RETURN + ! Get velocities and accelerations for OutList variables, no error check + IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, Time, p%WindViXYZ, & + m%WindViUVW, m%WindAiUVW, TmpErrStat, TmpErrMsg) + ENDIF END SUBROUTINE CalculateOutput diff --git a/modules/inflowwind/src/InflowWind_Types.f90 b/modules/inflowwind/src/InflowWind_Types.f90 index ab0149d75c..67d5089934 100644 --- a/modules/inflowwind/src/InflowWind_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Types.f90 @@ -31,12 +31,7 @@ !! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. MODULE InflowWind_Types !--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_UniformWind_Types -USE IfW_TSFFWind_Types -USE IfW_BladedFFWind_Types -USE IfW_HAWCWind_Types -USE IfW_UserWind_Types -USE IfW_4Dext_Types +USE InflowWind_IO_Types USE Lidar_Types USE NWTC_Library IMPLICIT NONE @@ -49,36 +44,16 @@ MODULE InflowWind_Types INTEGER(IntKi), PUBLIC, PARAMETER :: User_WindNumber = 6 ! User defined wind. [-] INTEGER(IntKi), PUBLIC, PARAMETER :: BladedFF_Shr_WindNumber = 7 ! Native Bladed binary full-field file. [-] INTEGER(IntKi), PUBLIC, PARAMETER :: FDext_WindNumber = 8 ! 4D wind from external souce (i.e., FAST.Farm). [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Highest_WindNumber = 8 ! Highest wind number supported. [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Point_WindNumber = 9 ! 1D wind components from ExtInflow [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Highest_WindNumber = 9 ! Highest wind number supported. [-] INTEGER(IntKi), PUBLIC, PARAMETER :: IfW_NumPtsAvg = 144 ! Number of points averaged for rotor-average wind speed [-] -! ========= WindFileMetaData ======= - TYPE, PUBLIC :: WindFileMetaData - CHARACTER(1024) :: FileName !< Name of the windfile retrieved [-] - INTEGER(IntKi) :: WindType = 0 !< Type of the windfile [-] - REAL(ReKi) :: RefHt !< Reference height given in file [meters] - LOGICAL :: RefHt_Set !< Reference height was given in file [-] - REAL(DbKi) :: DT !< TimeStep of the wind file -- zero value for none [seconds] - INTEGER(IntKi) :: NumTSteps !< Number of timesteps in the time range of wind file [-] - LOGICAL :: ConstantDT !< Timesteps are the same throughout file [-] - REAL(ReKi) , DIMENSION(1:2) :: TRange !< Time range of the wind file [seconds] - LOGICAL :: TRange_Limited !< TRange limits strictly enforced [-] - REAL(ReKi) , DIMENSION(1:2) :: YRange !< Range in y direction [meters] - LOGICAL :: YRange_Limited !< YRange limits strictly enforced [-] - REAL(ReKi) , DIMENSION(1:2) :: ZRange !< Range in z direction [meters] - LOGICAL :: ZRange_Limited !< ZRange limits strictly enforced [-] - INTEGER(IntKi) :: BinaryFormat !< Binary format identifier [-] - LOGICAL :: IsBinary !< Windfile is a binary file [-] - REAL(ReKi) , DIMENSION(1:3) :: TI !< Turbulence intensity (U,V,W) [-] - LOGICAL :: TI_listed !< Turbulence intesity given in file [-] - REAL(ReKi) :: MWS !< Approximate mean wind speed [-] - END TYPE WindFileMetaData -! ======================= ! ========= InflowWind_InputFile ======= TYPE, PUBLIC :: InflowWind_InputFile LOGICAL :: EchoFlag !< Echo the input file [-] INTEGER(IntKi) :: WindType = 0 !< Type of windfile [-] REAL(ReKi) :: PropagationDir !< Direction of wind propagation (meteorological direction) [(degrees)] REAL(ReKi) :: VFlowAngle !< Vertical (upflow) angle [degrees] + LOGICAL :: VelInterpCubic = .FALSE. !< Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] [-] INTEGER(IntKi) :: NWindVel !< Number of points to output the wind velocity (0 to 9) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WindVxiList !< List of X coordinates for wind velocity measurements [meters] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WindVyiList !< List of Y coordinates for wind velocity measurements [meters] @@ -119,7 +94,7 @@ MODULE InflowWind_Types REAL(ReKi) :: URefLid !< Reference average wind speed for the lidar [m/s] LOGICAL :: LidRadialVel !< TRUE => return radial component, FALSE => return 'x' direction estimate [-] INTEGER(IntKi) :: ConsiderHubMotion !< Flag whether or not the hub motion's impact on the Lidar measurement will be considered [0 for no, 1 for yes] [-] - TYPE(IfW_FFWind_InitInputType) :: FF !< scaling data [-] + TYPE(Grid3D_InitInputType) :: FF !< scaling data [-] END TYPE InflowWind_InputFile ! ======================= ! ========= InflowWind_InitInputType ======= @@ -135,9 +110,12 @@ MODULE InflowWind_Types TYPE(FileInfoType) :: PassedFileData !< If we don't use the input file, pass everything through this [-] LOGICAL :: WindType2UseInputFile = .TRUE. !< Flag for toggling file based IO in wind type 2. [-] TYPE(FileInfoType) :: WindType2Data !< Optional slot for wind type 2 data if file IO is not used. [-] + LOGICAL :: OutputAccel = .FALSE. !< Flag to output wind acceleration [-] TYPE(Lidar_InitInputType) :: lidar !< InitInput for lidar data [-] - TYPE(IfW_4Dext_InitInputType) :: FDext !< InitInput for 4D external wind data [-] + TYPE(Grid4D_InitInputType) :: FDext !< InitInput for 4D external wind data [-] REAL(ReKi) :: RadAvg !< Radius (from hub) used for averaging wind speed [-] + INTEGER(IntKi) :: BoxExceedAllowIdx = -1 !< Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim) [-] + LOGICAL :: BoxExceedAllowF = .FALSE. !< Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim) [-] END TYPE InflowWind_InitInputType ! ======================= ! ========= InflowWind_InitOutputType ======= @@ -145,7 +123,7 @@ MODULE InflowWind_Types CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Names of output-to-file channels [-] CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of output-to-file channels [-] TYPE(ProgDesc) :: Ver !< Version information of InflowWind module [-] - TYPE(WindFileMetaData) :: WindFileInfo !< Meta data from the wind file [-] + TYPE(WindFileDat) :: WindFileInfo !< Meta data from the wind file [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_y !< Names of the outputs used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_u !< Names of the inputs used in linearization [-] LOGICAL , DIMENSION(:), ALLOCATABLE :: RotFrame_y !< Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame [-] @@ -156,30 +134,20 @@ MODULE InflowWind_Types ! ========= InflowWind_ParameterType ======= TYPE, PUBLIC :: InflowWind_ParameterType CHARACTER(1024) :: RootFileName !< Root of the InflowWind input filename [-] - LOGICAL :: CTTS_Flag = .FALSE. !< determines if coherent turbulence is used [-] - LOGICAL :: RotateWindBox = .FALSE. !< determines if wind will be rotated [-] + INTEGER(IntKi) :: WindType = 0 !< Type of wind -- set to Undef_Wind initially [-] REAL(DbKi) :: DT !< Time step for cont. state integration & disc. state update [seconds] - REAL(ReKi) :: PropagationDir !< Direction of wind propagation [radians] - REAL(ReKi) :: VFlowAngle !< Vertical (upflow) angle [radians] - REAL(ReKi) , DIMENSION(1:3,1:3) :: RotToWind !< Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X') [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: RotFromWind !< Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViXYZprime !< List of XYZ coordinates for velocity measurements, translated to the wind coordinate system (prime coordinates). This equals MATMUL( RotToWind, ParamData%WindViXYZ ) [meters] - INTEGER(IntKi) :: WindType = 0 !< Type of wind -- set to Undef_Wind initially [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViXYZ !< List of XYZ coordinates for wind velocity measurements, 3xNWindVel [meters] + TYPE(FlowFieldType) :: FlowField !< Parameters from Full-Field [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PositionAvg !< (non-rotated) positions of points used for averaging wind speed [meters] REAL(ReKi) :: ReferenceHeight !< Height of the wind turbine [meters] REAL(ReKi) , DIMENSION(1:3) :: RefPosition !< Reference position (point where box is rotated) [meters] INTEGER(IntKi) :: NWindVel !< Number of points in the wind velocity list [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViXYZ !< List of XYZ coordinates for wind velocity measurements, 3xNWindVel [meters] - TYPE(IfW_UniformWind_ParameterType) :: UniformWind !< Parameters from UniformWind [-] - TYPE(IfW_TSFFWind_ParameterType) :: TSFFWind !< Parameters from TSFFWind -- TurbSim full-field format [-] - TYPE(IfW_BladedFFWind_ParameterType) :: BladedFFWind !< Parameters from BladedFFWind -- Bladed-style full-field format [-] - TYPE(IfW_HAWCWind_ParameterType) :: HAWCWind !< Parameters from HAWCWind [-] - TYPE(IfW_UserWind_ParameterType) :: UserWind !< Parameters from UserWind [-] - TYPE(IfW_4Dext_ParameterType) :: FDext !< Parameters from FDext [-] INTEGER(IntKi) :: NumOuts = 0 !< Number of parameters in the output list (number of outputs requested) [-] TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: OutParam !< Names and units (and other characteristics) of all requested output parameters [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: OutParamLinIndx !< Index into WriteOutput for WindViXYZ in linearization analysis [-] TYPE(Lidar_ParameterType) :: lidar !< Lidar parameter data [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PositionAvg !< (non-rotated) positions of points used for averaging wind speed [meters] + LOGICAL :: OutputAccel = .FALSE. !< Flag to output wind acceleration [-] END TYPE InflowWind_ParameterType ! ======================= ! ========= InflowWind_InputType ======= @@ -193,6 +161,7 @@ MODULE InflowWind_Types ! ========= InflowWind_OutputType ======= TYPE, PUBLIC :: InflowWind_OutputType REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: VelocityUVW !< Array holding the U,V,W velocity for a given timestep [meters/sec] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AccelUVW !< Array holding the U,V,W acceleration for a given timestep [meters/sec] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< Array with values to output to file [-] REAL(ReKi) , DIMENSION(1:3) :: DiskVel !< Vector holding the U,V,W average velocity of the disk [meters/sec] REAL(ReKi) , DIMENSION(1:3) :: HubVel !< Vector holding the U,V,W velocity at the hub [meters/sec] @@ -221,15 +190,9 @@ MODULE InflowWind_Types ! ======================= ! ========= InflowWind_MiscVarType ======= TYPE, PUBLIC :: InflowWind_MiscVarType - INTEGER(IntKi) :: TimeIndex = 0 !< An Index into the TData array [-] - TYPE(IfW_UniformWind_MiscVarType) :: UniformWind !< MiscVars from UniformWind [-] - TYPE(IfW_TSFFWind_MiscVarType) :: TSFFWind !< MiscVars from TSFFWind [-] - TYPE(IfW_HAWCWind_MiscVarType) :: HAWCWind !< MiscVars from HAWCWind [-] - TYPE(IfW_BladedFFWind_MiscVarType) :: BladedFFWind !< MiscVars from BladedFFWind [-] - TYPE(IfW_UserWind_MiscVarType) :: UserWind !< MiscVars from UserWind [-] - TYPE(IfW_4Dext_MiscVarType) :: FDext !< MiscVars from FDext [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AllOuts !< An array holding the value of all of the calculated (not only selected) output channels [see OutListParameters.xlsx spreadsheet] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViUVW !< List of UVW velocities for wind velocity measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ [meters/second] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindAiUVW !< List of UVW accelerations for wind acceleration measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ [m/s^2] TYPE(InflowWind_InputType) :: u_Avg !< inputs for computing rotor-averaged values [-] TYPE(InflowWind_OutputType) :: y_Avg !< outputs for computing rotor-averaged values [-] TYPE(InflowWind_InputType) :: u_Hub !< inputs for computing hub values [-] @@ -237,277 +200,6 @@ MODULE InflowWind_Types END TYPE InflowWind_MiscVarType ! ======================= CONTAINS - SUBROUTINE InflowWind_CopyWindFileMetaData( SrcWindFileMetaDataData, DstWindFileMetaDataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(WindFileMetaData), INTENT(IN) :: SrcWindFileMetaDataData - TYPE(WindFileMetaData), INTENT(INOUT) :: DstWindFileMetaDataData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyWindFileMetaData' -! - ErrStat = ErrID_None - ErrMsg = "" - DstWindFileMetaDataData%FileName = SrcWindFileMetaDataData%FileName - DstWindFileMetaDataData%WindType = SrcWindFileMetaDataData%WindType - DstWindFileMetaDataData%RefHt = SrcWindFileMetaDataData%RefHt - DstWindFileMetaDataData%RefHt_Set = SrcWindFileMetaDataData%RefHt_Set - DstWindFileMetaDataData%DT = SrcWindFileMetaDataData%DT - DstWindFileMetaDataData%NumTSteps = SrcWindFileMetaDataData%NumTSteps - DstWindFileMetaDataData%ConstantDT = SrcWindFileMetaDataData%ConstantDT - DstWindFileMetaDataData%TRange = SrcWindFileMetaDataData%TRange - DstWindFileMetaDataData%TRange_Limited = SrcWindFileMetaDataData%TRange_Limited - DstWindFileMetaDataData%YRange = SrcWindFileMetaDataData%YRange - DstWindFileMetaDataData%YRange_Limited = SrcWindFileMetaDataData%YRange_Limited - DstWindFileMetaDataData%ZRange = SrcWindFileMetaDataData%ZRange - DstWindFileMetaDataData%ZRange_Limited = SrcWindFileMetaDataData%ZRange_Limited - DstWindFileMetaDataData%BinaryFormat = SrcWindFileMetaDataData%BinaryFormat - DstWindFileMetaDataData%IsBinary = SrcWindFileMetaDataData%IsBinary - DstWindFileMetaDataData%TI = SrcWindFileMetaDataData%TI - DstWindFileMetaDataData%TI_listed = SrcWindFileMetaDataData%TI_listed - DstWindFileMetaDataData%MWS = SrcWindFileMetaDataData%MWS - END SUBROUTINE InflowWind_CopyWindFileMetaData - - SUBROUTINE InflowWind_DestroyWindFileMetaData( WindFileMetaDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(WindFileMetaData), INTENT(INOUT) :: WindFileMetaDataData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers - - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 - LOGICAL :: DEALLOCATEpointers_local - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyWindFileMetaData' - - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(DEALLOCATEpointers)) THEN - DEALLOCATEpointers_local = DEALLOCATEpointers - ELSE - DEALLOCATEpointers_local = .true. - END IF - - END SUBROUTINE InflowWind_DestroyWindFileMetaData - - SUBROUTINE InflowWind_PackWindFileMetaData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(WindFileMetaData), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackWindFileMetaData' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%FileName) ! FileName - Int_BufSz = Int_BufSz + 1 ! WindType - Re_BufSz = Re_BufSz + 1 ! RefHt - Int_BufSz = Int_BufSz + 1 ! RefHt_Set - Db_BufSz = Db_BufSz + 1 ! DT - Int_BufSz = Int_BufSz + 1 ! NumTSteps - Int_BufSz = Int_BufSz + 1 ! ConstantDT - Re_BufSz = Re_BufSz + SIZE(InData%TRange) ! TRange - Int_BufSz = Int_BufSz + 1 ! TRange_Limited - Re_BufSz = Re_BufSz + SIZE(InData%YRange) ! YRange - Int_BufSz = Int_BufSz + 1 ! YRange_Limited - Re_BufSz = Re_BufSz + SIZE(InData%ZRange) ! ZRange - Int_BufSz = Int_BufSz + 1 ! ZRange_Limited - Int_BufSz = Int_BufSz + 1 ! BinaryFormat - Int_BufSz = Int_BufSz + 1 ! IsBinary - Re_BufSz = Re_BufSz + SIZE(InData%TI) ! TI - Int_BufSz = Int_BufSz + 1 ! TI_listed - Re_BufSz = Re_BufSz + 1 ! MWS - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%FileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%FileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = InData%WindType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%RefHt_Set, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%DT - Db_Xferred = Db_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumTSteps - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%ConstantDT, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%TRange,1), UBOUND(InData%TRange,1) - ReKiBuf(Re_Xferred) = InData%TRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%TRange_Limited, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%YRange,1), UBOUND(InData%YRange,1) - ReKiBuf(Re_Xferred) = InData%YRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%YRange_Limited, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%ZRange,1), UBOUND(InData%ZRange,1) - ReKiBuf(Re_Xferred) = InData%ZRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%ZRange_Limited, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%BinaryFormat - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%IsBinary, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) - ReKiBuf(Re_Xferred) = InData%TI(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%TI_listed, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%MWS - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE InflowWind_PackWindFileMetaData - - SUBROUTINE InflowWind_UnPackWindFileMetaData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(WindFileMetaData), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackWindFileMetaData' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%FileName) - OutData%FileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%WindType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefHt_Set = TRANSFER(IntKiBuf(Int_Xferred), OutData%RefHt_Set) - Int_Xferred = Int_Xferred + 1 - OutData%DT = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - OutData%NumTSteps = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%ConstantDT = TRANSFER(IntKiBuf(Int_Xferred), OutData%ConstantDT) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%TRange,1) - i1_u = UBOUND(OutData%TRange,1) - DO i1 = LBOUND(OutData%TRange,1), UBOUND(OutData%TRange,1) - OutData%TRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%TRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%TRange_Limited) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%YRange,1) - i1_u = UBOUND(OutData%YRange,1) - DO i1 = LBOUND(OutData%YRange,1), UBOUND(OutData%YRange,1) - OutData%YRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%YRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%YRange_Limited) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%ZRange,1) - i1_u = UBOUND(OutData%ZRange,1) - DO i1 = LBOUND(OutData%ZRange,1), UBOUND(OutData%ZRange,1) - OutData%ZRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%ZRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%ZRange_Limited) - Int_Xferred = Int_Xferred + 1 - OutData%BinaryFormat = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%IsBinary = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsBinary) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%TI,1) - i1_u = UBOUND(OutData%TI,1) - DO i1 = LBOUND(OutData%TI,1), UBOUND(OutData%TI,1) - OutData%TI(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%TI_listed = TRANSFER(IntKiBuf(Int_Xferred), OutData%TI_listed) - Int_Xferred = Int_Xferred + 1 - OutData%MWS = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE InflowWind_UnPackWindFileMetaData - SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrStat, ErrMsg ) TYPE(InflowWind_InputFile), INTENT(IN) :: SrcInputFileData TYPE(InflowWind_InputFile), INTENT(INOUT) :: DstInputFileData @@ -517,6 +209,7 @@ SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCod ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyInputFile' @@ -527,6 +220,7 @@ SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCod DstInputFileData%WindType = SrcInputFileData%WindType DstInputFileData%PropagationDir = SrcInputFileData%PropagationDir DstInputFileData%VFlowAngle = SrcInputFileData%VFlowAngle + DstInputFileData%VelInterpCubic = SrcInputFileData%VelInterpCubic DstInputFileData%NWindVel = SrcInputFileData%NWindVel IF (ALLOCATED(SrcInputFileData%WindVxiList)) THEN i1_l = LBOUND(SrcInputFileData%WindVxiList,1) @@ -644,7 +338,7 @@ SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCod DstInputFileData%URefLid = SrcInputFileData%URefLid DstInputFileData%LidRadialVel = SrcInputFileData%LidRadialVel DstInputFileData%ConsiderHubMotion = SrcInputFileData%ConsiderHubMotion - CALL IfW_FFWind_CopyInitInput( SrcInputFileData%FF, DstInputFileData%FF, CtrlCode, ErrStat2, ErrMsg2 ) + CALL InflowWind_IO_Copygrid3d_initinputtype( SrcInputFileData%FF, DstInputFileData%FF, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE InflowWind_CopyInputFile @@ -691,7 +385,7 @@ SUBROUTINE InflowWind_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCA IF (ALLOCATED(InputFileData%FocalDistanceZ)) THEN DEALLOCATE(InputFileData%FocalDistanceZ) ENDIF - CALL IfW_FFWind_DestroyInitInput( InputFileData%FF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL InflowWind_IO_Destroygrid3d_initinputtype( InputFileData%FF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE InflowWind_DestroyInputFile @@ -734,6 +428,7 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + 1 ! WindType Re_BufSz = Re_BufSz + 1 ! PropagationDir Re_BufSz = Re_BufSz + 1 ! VFlowAngle + Int_BufSz = Int_BufSz + 1 ! VelInterpCubic Int_BufSz = Int_BufSz + 1 ! NWindVel Int_BufSz = Int_BufSz + 1 ! WindVxiList allocated yes/no IF ( ALLOCATED(InData%WindVxiList) ) THEN @@ -804,7 +499,7 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + 1 ! ConsiderHubMotion ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -855,6 +550,8 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%VFlowAngle Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%VelInterpCubic, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NWindVel Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WindVxiList) ) THEN @@ -1046,7 +743,7 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%ConsiderHubMotion Int_Xferred = Int_Xferred + 1 - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1090,6 +787,7 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackInputFile' @@ -1111,6 +809,8 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Re_Xferred = Re_Xferred + 1 OutData%VFlowAngle = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%VelInterpCubic = TRANSFER(IntKiBuf(Int_Xferred), OutData%VelInterpCubic) + Int_Xferred = Int_Xferred + 1 OutData%NWindVel = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindVxiList not allocated @@ -1358,7 +1058,7 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_FFWind_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF + CALL InflowWind_IO_Unpackgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1396,13 +1096,16 @@ SUBROUTINE InflowWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCod CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%WindType2Data, DstInitInputData%WindType2Data, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + DstInitInputData%OutputAccel = SrcInitInputData%OutputAccel CALL Lidar_CopyInitInput( SrcInitInputData%lidar, DstInitInputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_4Dext_CopyInitInput( SrcInitInputData%FDext, DstInitInputData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) + CALL InflowWind_IO_Copygrid4d_initinputtype( SrcInitInputData%FDext, DstInitInputData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN DstInitInputData%RadAvg = SrcInitInputData%RadAvg + DstInitInputData%BoxExceedAllowIdx = SrcInitInputData%BoxExceedAllowIdx + DstInitInputData%BoxExceedAllowF = SrcInitInputData%BoxExceedAllowF END SUBROUTINE InflowWind_CopyInitInput SUBROUTINE InflowWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) @@ -1432,7 +1135,7 @@ SUBROUTINE InflowWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCA CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL Lidar_DestroyInitInput( InitInputData%lidar, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_4Dext_DestroyInitInput( InitInputData%FDext, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL InflowWind_IO_Destroygrid4d_initinputtype( InitInputData%FDext, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE InflowWind_DestroyInitInput @@ -1515,6 +1218,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! OutputAccel Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype CALL Lidar_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1533,7 +1237,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! FDext: size of buffers for each call to pack subtype - CALL IfW_4Dext_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext + CALL InflowWind_IO_Packgrid4d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1550,6 +1254,8 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat DEALLOCATE(Int_Buf) END IF Re_BufSz = Re_BufSz + 1 ! RadAvg + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowIdx + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1655,6 +1361,8 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutputAccel, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 CALL Lidar_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, OnlySize ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1683,7 +1391,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL IfW_4Dext_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext + CALL InflowWind_IO_Packgrid4d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1713,6 +1421,10 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ENDIF ReKiBuf(Re_Xferred) = InData%RadAvg Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BoxExceedAllowIdx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedAllowF, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_PackInitInput SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1843,6 +1555,8 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%OutputAccel = TRANSFER(IntKiBuf(Int_Xferred), OutData%OutputAccel) + Int_Xferred = Int_Xferred + 1 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -1916,7 +1630,7 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_4Dext_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext + CALL InflowWind_IO_Unpackgrid4d_initinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1925,6 +1639,10 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) OutData%RadAvg = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%BoxExceedAllowIdx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%BoxExceedAllowF = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedAllowF) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_UnPackInitInput SUBROUTINE InflowWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -1969,7 +1687,7 @@ SUBROUTINE InflowWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, Ctrl CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_Copywindfilemetadata( SrcInitOutputData%WindFileInfo, DstInitOutputData%WindFileInfo, CtrlCode, ErrStat2, ErrMsg2 ) + CALL InflowWind_IO_Copywindfiledat( SrcInitOutputData%WindFileInfo, DstInitOutputData%WindFileInfo, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcInitOutputData%LinNames_y)) THEN @@ -2063,7 +1781,7 @@ SUBROUTINE InflowWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLO ENDIF CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL InflowWind_Destroywindfilemetadata( InitOutputData%WindFileInfo, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL InflowWind_IO_Destroywindfiledat( InitOutputData%WindFileInfo, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) @@ -2146,7 +1864,7 @@ SUBROUTINE InflowWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSta DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! WindFileInfo: size of buffers for each call to pack subtype - CALL InflowWind_Packwindfilemetadata( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, .TRUE. ) ! WindFileInfo + CALL InflowWind_IO_Packwindfiledat( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, .TRUE. ) ! WindFileInfo CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2276,7 +1994,7 @@ SUBROUTINE InflowWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSta ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL InflowWind_Packwindfilemetadata( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, OnlySize ) ! WindFileInfo + CALL InflowWind_IO_Packwindfiledat( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, OnlySize ) ! WindFileInfo CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2525,7 +2243,7 @@ SUBROUTINE InflowWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL InflowWind_Unpackwindfilemetadata( Re_Buf, Db_Buf, Int_Buf, OutData%WindFileInfo, ErrStat2, ErrMsg2 ) ! WindFileInfo + CALL InflowWind_IO_Unpackwindfiledat( Re_Buf, Db_Buf, Int_Buf, OutData%WindFileInfo, ErrStat2, ErrMsg2 ) ! WindFileInfo CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2645,13 +2363,8 @@ SUBROUTINE InflowWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrStat = ErrID_None ErrMsg = "" DstParamData%RootFileName = SrcParamData%RootFileName - DstParamData%CTTS_Flag = SrcParamData%CTTS_Flag - DstParamData%RotateWindBox = SrcParamData%RotateWindBox + DstParamData%WindType = SrcParamData%WindType DstParamData%DT = SrcParamData%DT - DstParamData%PropagationDir = SrcParamData%PropagationDir - DstParamData%VFlowAngle = SrcParamData%VFlowAngle - DstParamData%RotToWind = SrcParamData%RotToWind - DstParamData%RotFromWind = SrcParamData%RotFromWind IF (ALLOCATED(SrcParamData%WindViXYZprime)) THEN i1_l = LBOUND(SrcParamData%WindViXYZprime,1) i1_u = UBOUND(SrcParamData%WindViXYZprime,1) @@ -2666,10 +2379,6 @@ SUBROUTINE InflowWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, END IF DstParamData%WindViXYZprime = SrcParamData%WindViXYZprime ENDIF - DstParamData%WindType = SrcParamData%WindType - DstParamData%ReferenceHeight = SrcParamData%ReferenceHeight - DstParamData%RefPosition = SrcParamData%RefPosition - DstParamData%NWindVel = SrcParamData%NWindVel IF (ALLOCATED(SrcParamData%WindViXYZ)) THEN i1_l = LBOUND(SrcParamData%WindViXYZ,1) i1_u = UBOUND(SrcParamData%WindViXYZ,1) @@ -2684,24 +2393,26 @@ SUBROUTINE InflowWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, END IF DstParamData%WindViXYZ = SrcParamData%WindViXYZ ENDIF - CALL IfW_UniformWind_CopyParam( SrcParamData%UniformWind, DstParamData%UniformWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_TSFFWind_CopyParam( SrcParamData%TSFFWind, DstParamData%TSFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_BladedFFWind_CopyParam( SrcParamData%BladedFFWind, DstParamData%BladedFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_HAWCWind_CopyParam( SrcParamData%HAWCWind, DstParamData%HAWCWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_UserWind_CopyParam( SrcParamData%UserWind, DstParamData%UserWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_4Dext_CopyParam( SrcParamData%FDext, DstParamData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) + CALL IfW_FlowField_Copyflowfieldtype( SrcParamData%FlowField, DstParamData%FlowField, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcParamData%PositionAvg)) THEN + i1_l = LBOUND(SrcParamData%PositionAvg,1) + i1_u = UBOUND(SrcParamData%PositionAvg,1) + i2_l = LBOUND(SrcParamData%PositionAvg,2) + i2_u = UBOUND(SrcParamData%PositionAvg,2) + IF (.NOT. ALLOCATED(DstParamData%PositionAvg)) THEN + ALLOCATE(DstParamData%PositionAvg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%PositionAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%PositionAvg = SrcParamData%PositionAvg +ENDIF + DstParamData%ReferenceHeight = SrcParamData%ReferenceHeight + DstParamData%RefPosition = SrcParamData%RefPosition + DstParamData%NWindVel = SrcParamData%NWindVel DstParamData%NumOuts = SrcParamData%NumOuts IF (ALLOCATED(SrcParamData%OutParam)) THEN i1_l = LBOUND(SrcParamData%OutParam,1) @@ -2736,20 +2447,7 @@ SUBROUTINE InflowWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, CALL Lidar_CopyParam( SrcParamData%lidar, DstParamData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcParamData%PositionAvg)) THEN - i1_l = LBOUND(SrcParamData%PositionAvg,1) - i1_u = UBOUND(SrcParamData%PositionAvg,1) - i2_l = LBOUND(SrcParamData%PositionAvg,2) - i2_u = UBOUND(SrcParamData%PositionAvg,2) - IF (.NOT. ALLOCATED(DstParamData%PositionAvg)) THEN - ALLOCATE(DstParamData%PositionAvg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%PositionAvg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%PositionAvg = SrcParamData%PositionAvg -ENDIF + DstParamData%OutputAccel = SrcParamData%OutputAccel END SUBROUTINE InflowWind_CopyParam SUBROUTINE InflowWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) @@ -2779,18 +2477,11 @@ SUBROUTINE InflowWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointe IF (ALLOCATED(ParamData%WindViXYZ)) THEN DEALLOCATE(ParamData%WindViXYZ) ENDIF - CALL IfW_UniformWind_DestroyParam( ParamData%UniformWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_TSFFWind_DestroyParam( ParamData%TSFFWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_BladedFFWind_DestroyParam( ParamData%BladedFFWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_HAWCWind_DestroyParam( ParamData%HAWCWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_UserWind_DestroyParam( ParamData%UserWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_4Dext_DestroyParam( ParamData%FDext, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL IfW_FlowField_Destroyflowfieldtype( ParamData%FlowField, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(ParamData%PositionAvg)) THEN + DEALLOCATE(ParamData%PositionAvg) +ENDIF IF (ALLOCATED(ParamData%OutParam)) THEN DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -2803,9 +2494,6 @@ SUBROUTINE InflowWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointe ENDIF CALL Lidar_DestroyParam( ParamData%lidar, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) -IF (ALLOCATED(ParamData%PositionAvg)) THEN - DEALLOCATE(ParamData%PositionAvg) -ENDIF END SUBROUTINE InflowWind_DestroyParam SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2844,130 +2532,44 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1*LEN(InData%RootFileName) ! RootFileName - Int_BufSz = Int_BufSz + 1 ! CTTS_Flag - Int_BufSz = Int_BufSz + 1 ! RotateWindBox + Int_BufSz = Int_BufSz + 1 ! WindType Db_BufSz = Db_BufSz + 1 ! DT - Re_BufSz = Re_BufSz + 1 ! PropagationDir - Re_BufSz = Re_BufSz + 1 ! VFlowAngle - Re_BufSz = Re_BufSz + SIZE(InData%RotToWind) ! RotToWind - Re_BufSz = Re_BufSz + SIZE(InData%RotFromWind) ! RotFromWind Int_BufSz = Int_BufSz + 1 ! WindViXYZprime allocated yes/no IF ( ALLOCATED(InData%WindViXYZprime) ) THEN Int_BufSz = Int_BufSz + 2*2 ! WindViXYZprime upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WindViXYZprime) ! WindViXYZprime END IF - Int_BufSz = Int_BufSz + 1 ! WindType - Re_BufSz = Re_BufSz + 1 ! ReferenceHeight - Re_BufSz = Re_BufSz + SIZE(InData%RefPosition) ! RefPosition - Int_BufSz = Int_BufSz + 1 ! NWindVel Int_BufSz = Int_BufSz + 1 ! WindViXYZ allocated yes/no IF ( ALLOCATED(InData%WindViXYZ) ) THEN Int_BufSz = Int_BufSz + 2*2 ! WindViXYZ upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WindViXYZ) ! WindViXYZ END IF ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! UniformWind: size of buffers for each call to pack subtype - CALL IfW_UniformWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, .TRUE. ) ! UniformWind + Int_BufSz = Int_BufSz + 3 ! FlowField: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packflowfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%FlowField, ErrStat2, ErrMsg2, .TRUE. ) ! FlowField CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! UniformWind + IF(ALLOCATED(Re_Buf)) THEN ! FlowField Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! UniformWind + IF(ALLOCATED(Db_Buf)) THEN ! FlowField Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! UniformWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! TSFFWind: size of buffers for each call to pack subtype - CALL IfW_TSFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! TSFFWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! TSFFWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! TSFFWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! BladedFFWind: size of buffers for each call to pack subtype - CALL IfW_BladedFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! BladedFFWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladedFFWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladedFFWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! HAWCWind: size of buffers for each call to pack subtype - CALL IfW_HAWCWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, .TRUE. ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! HAWCWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! HAWCWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! HAWCWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! UserWind: size of buffers for each call to pack subtype - CALL IfW_UserWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, .TRUE. ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! UserWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! UserWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! UserWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! FDext: size of buffers for each call to pack subtype - CALL IfW_4Dext_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FDext - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FDext - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FDext + IF(ALLOCATED(Int_Buf)) THEN ! FlowField Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! PositionAvg allocated yes/no + IF ( ALLOCATED(InData%PositionAvg) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PositionAvg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PositionAvg) ! PositionAvg + END IF + Re_BufSz = Re_BufSz + 1 ! ReferenceHeight + Re_BufSz = Re_BufSz + SIZE(InData%RefPosition) ! RefPosition + Int_BufSz = Int_BufSz + 1 ! NWindVel Int_BufSz = Int_BufSz + 1 ! NumOuts Int_BufSz = Int_BufSz + 1 ! OutParam allocated yes/no IF ( ALLOCATED(InData%OutParam) ) THEN @@ -3014,11 +2616,7 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1 ! PositionAvg allocated yes/no - IF ( ALLOCATED(InData%PositionAvg) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! PositionAvg upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PositionAvg) ! PositionAvg - END IF + Int_BufSz = Int_BufSz + 1 ! OutputAccel IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -3050,28 +2648,10 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er IntKiBuf(Int_Xferred) = ICHAR(InData%RootFileName(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%CTTS_Flag, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%RotateWindBox, IntKiBuf(1)) + IntKiBuf(Int_Xferred) = InData%WindType Int_Xferred = Int_Xferred + 1 DbKiBuf(Db_Xferred) = InData%DT Db_Xferred = Db_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PropagationDir - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VFlowAngle - Re_Xferred = Re_Xferred + 1 - DO i2 = LBOUND(InData%RotToWind,2), UBOUND(InData%RotToWind,2) - DO i1 = LBOUND(InData%RotToWind,1), UBOUND(InData%RotToWind,1) - ReKiBuf(Re_Xferred) = InData%RotToWind(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - DO i2 = LBOUND(InData%RotFromWind,2), UBOUND(InData%RotFromWind,2) - DO i1 = LBOUND(InData%RotFromWind,1), UBOUND(InData%RotFromWind,1) - ReKiBuf(Re_Xferred) = InData%RotFromWind(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO IF ( .NOT. ALLOCATED(InData%WindViXYZprime) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -3092,16 +2672,6 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF - IntKiBuf(Int_Xferred) = InData%WindType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%ReferenceHeight - Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%RefPosition,1), UBOUND(InData%RefPosition,1) - ReKiBuf(Re_Xferred) = InData%RefPosition(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%NWindVel - Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WindViXYZ) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -3122,119 +2692,7 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF - CALL IfW_UniformWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, OnlySize ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_TSFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, OnlySize ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_BladedFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, OnlySize ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_HAWCWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, OnlySize ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_UserWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, OnlySize ) ! UserWind + CALL IfW_FlowField_Packflowfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%FlowField, ErrStat2, ErrMsg2, OnlySize ) ! FlowField CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3262,34 +2720,34 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL IfW_4Dext_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%PositionAvg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionAvg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionAvg,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionAvg,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionAvg,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF + DO i2 = LBOUND(InData%PositionAvg,2), UBOUND(InData%PositionAvg,2) + DO i1 = LBOUND(InData%PositionAvg,1), UBOUND(InData%PositionAvg,1) + ReKiBuf(Re_Xferred) = InData%PositionAvg(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%ReferenceHeight + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%RefPosition,1), UBOUND(InData%RefPosition,1) + ReKiBuf(Re_Xferred) = InData%RefPosition(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%NWindVel + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumOuts Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN @@ -3381,26 +2839,8 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%PositionAvg) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutputAccel, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionAvg,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionAvg,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionAvg,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionAvg,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%PositionAvg,2), UBOUND(InData%PositionAvg,2) - DO i1 = LBOUND(InData%PositionAvg,1), UBOUND(InData%PositionAvg,1) - ReKiBuf(Re_Xferred) = InData%PositionAvg(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF END SUBROUTINE InflowWind_PackParam SUBROUTINE InflowWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -3435,36 +2875,10 @@ SUBROUTINE InflowWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, OutData%RootFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I - OutData%CTTS_Flag = TRANSFER(IntKiBuf(Int_Xferred), OutData%CTTS_Flag) - Int_Xferred = Int_Xferred + 1 - OutData%RotateWindBox = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotateWindBox) + OutData%WindType = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%DT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - OutData%PropagationDir = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VFlowAngle = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%RotToWind,1) - i1_u = UBOUND(OutData%RotToWind,1) - i2_l = LBOUND(OutData%RotToWind,2) - i2_u = UBOUND(OutData%RotToWind,2) - DO i2 = LBOUND(OutData%RotToWind,2), UBOUND(OutData%RotToWind,2) - DO i1 = LBOUND(OutData%RotToWind,1), UBOUND(OutData%RotToWind,1) - OutData%RotToWind(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - i1_l = LBOUND(OutData%RotFromWind,1) - i1_u = UBOUND(OutData%RotFromWind,1) - i2_l = LBOUND(OutData%RotFromWind,2) - i2_u = UBOUND(OutData%RotFromWind,2) - DO i2 = LBOUND(OutData%RotFromWind,2), UBOUND(OutData%RotFromWind,2) - DO i1 = LBOUND(OutData%RotFromWind,1), UBOUND(OutData%RotFromWind,1) - OutData%RotFromWind(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViXYZprime not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -3488,18 +2902,6 @@ SUBROUTINE InflowWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO END DO END IF - OutData%WindType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%ReferenceHeight = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%RefPosition,1) - i1_u = UBOUND(OutData%RefPosition,1) - DO i1 = LBOUND(OutData%RefPosition,1), UBOUND(OutData%RefPosition,1) - OutData%RefPosition(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%NWindVel = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViXYZ not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -3556,13 +2958,62 @@ SUBROUTINE InflowWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_UniformWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%UniformWind, ErrStat2, ErrMsg2 ) ! UniformWind + CALL IfW_FlowField_Unpackflowfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%FlowField, ErrStat2, ErrMsg2 ) ! FlowField CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PositionAvg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PositionAvg)) DEALLOCATE(OutData%PositionAvg) + ALLOCATE(OutData%PositionAvg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PositionAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%PositionAvg,2), UBOUND(OutData%PositionAvg,2) + DO i1 = LBOUND(OutData%PositionAvg,1), UBOUND(OutData%PositionAvg,1) + OutData%PositionAvg(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%ReferenceHeight = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%RefPosition,1) + i1_u = UBOUND(OutData%RefPosition,1) + DO i1 = LBOUND(OutData%RefPosition,1), UBOUND(OutData%RefPosition,1) + OutData%RefPosition(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%NWindVel = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%OutParam)) DEALLOCATE(OutData%OutParam) + ALLOCATE(OutData%OutParam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%OutParam,1), UBOUND(OutData%OutParam,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3596,13 +3047,38 @@ SUBROUTINE InflowWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_TSFFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%TSFFWind, ErrStat2, ErrMsg2 ) ! TSFFWind + CALL NWTC_Library_Unpackoutparmtype( Re_Buf, Db_Buf, Int_Buf, OutData%OutParam(i1), ErrStat2, ErrMsg2 ) ! OutParam CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParamLinIndx not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%OutParamLinIndx)) DEALLOCATE(OutData%OutParamLinIndx) + ALLOCATE(OutData%OutParamLinIndx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParamLinIndx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%OutParamLinIndx,2), UBOUND(OutData%OutParamLinIndx,2) + DO i1 = LBOUND(OutData%OutParamLinIndx,1), UBOUND(OutData%OutParamLinIndx,1) + OutData%OutParamLinIndx(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3636,315 +3112,53 @@ SUBROUTINE InflowWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_BladedFFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%BladedFFWind, ErrStat2, ErrMsg2 ) ! BladedFFWind + CALL Lidar_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%lidar, ErrStat2, ErrMsg2 ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_HAWCWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%HAWCWind, ErrStat2, ErrMsg2 ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + OutData%OutputAccel = TRANSFER(IntKiBuf(Int_Xferred), OutData%OutputAccel) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_UnPackParam - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_UserWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%UserWind, ErrStat2, ErrMsg2 ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_4Dext_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - OutData%NumOuts = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%OutParam)) DEALLOCATE(OutData%OutParam) - ALLOCATE(OutData%OutParam(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParam.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%OutParam,1), UBOUND(OutData%OutParam,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackoutparmtype( Re_Buf, Db_Buf, Int_Buf, OutData%OutParam(i1), ErrStat2, ErrMsg2 ) ! OutParam - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParamLinIndx not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%OutParamLinIndx)) DEALLOCATE(OutData%OutParamLinIndx) - ALLOCATE(OutData%OutParamLinIndx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParamLinIndx.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%OutParamLinIndx,2), UBOUND(OutData%OutParamLinIndx,2) - DO i1 = LBOUND(OutData%OutParamLinIndx,1), UBOUND(OutData%OutParamLinIndx,1) - OutData%OutParamLinIndx(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL Lidar_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%lidar, ErrStat2, ErrMsg2 ) ! lidar - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PositionAvg not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%PositionAvg)) DEALLOCATE(OutData%PositionAvg) - ALLOCATE(OutData%PositionAvg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PositionAvg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%PositionAvg,2), UBOUND(OutData%PositionAvg,2) - DO i1 = LBOUND(OutData%PositionAvg,1), UBOUND(OutData%PositionAvg,1) - OutData%PositionAvg(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE InflowWind_UnPackParam - - SUBROUTINE InflowWind_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(InflowWind_InputType), INTENT(IN) :: SrcInputData - TYPE(InflowWind_InputType), INTENT(INOUT) :: DstInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyInput' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcInputData%PositionXYZ)) THEN - i1_l = LBOUND(SrcInputData%PositionXYZ,1) - i1_u = UBOUND(SrcInputData%PositionXYZ,1) - i2_l = LBOUND(SrcInputData%PositionXYZ,2) - i2_u = UBOUND(SrcInputData%PositionXYZ,2) - IF (.NOT. ALLOCATED(DstInputData%PositionXYZ)) THEN - ALLOCATE(DstInputData%PositionXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%PositionXYZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputData%PositionXYZ = SrcInputData%PositionXYZ -ENDIF - CALL Lidar_CopyInput( SrcInputData%lidar, DstInputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInputData%HubPosition = SrcInputData%HubPosition - DstInputData%HubOrientation = SrcInputData%HubOrientation - END SUBROUTINE InflowWind_CopyInput + SUBROUTINE InflowWind_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(InflowWind_InputType), INTENT(IN) :: SrcInputData + TYPE(InflowWind_InputType), INTENT(INOUT) :: DstInputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyInput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcInputData%PositionXYZ)) THEN + i1_l = LBOUND(SrcInputData%PositionXYZ,1) + i1_u = UBOUND(SrcInputData%PositionXYZ,1) + i2_l = LBOUND(SrcInputData%PositionXYZ,2) + i2_u = UBOUND(SrcInputData%PositionXYZ,2) + IF (.NOT. ALLOCATED(DstInputData%PositionXYZ)) THEN + ALLOCATE(DstInputData%PositionXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%PositionXYZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%PositionXYZ = SrcInputData%PositionXYZ +ENDIF + CALL Lidar_CopyInput( SrcInputData%lidar, DstInputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInputData%HubPosition = SrcInputData%HubPosition + DstInputData%HubOrientation = SrcInputData%HubOrientation + END SUBROUTINE InflowWind_CopyInput SUBROUTINE InflowWind_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_InputType), INTENT(INOUT) :: InputData @@ -4260,6 +3474,20 @@ SUBROUTINE InflowWind_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrSta END IF DstOutputData%VelocityUVW = SrcOutputData%VelocityUVW ENDIF +IF (ALLOCATED(SrcOutputData%AccelUVW)) THEN + i1_l = LBOUND(SrcOutputData%AccelUVW,1) + i1_u = UBOUND(SrcOutputData%AccelUVW,1) + i2_l = LBOUND(SrcOutputData%AccelUVW,2) + i2_u = UBOUND(SrcOutputData%AccelUVW,2) + IF (.NOT. ALLOCATED(DstOutputData%AccelUVW)) THEN + ALLOCATE(DstOutputData%AccelUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%AccelUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%AccelUVW = SrcOutputData%AccelUVW +ENDIF IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN i1_l = LBOUND(SrcOutputData%WriteOutput,1) i1_u = UBOUND(SrcOutputData%WriteOutput,1) @@ -4303,6 +3531,9 @@ SUBROUTINE InflowWind_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpoin IF (ALLOCATED(OutputData%VelocityUVW)) THEN DEALLOCATE(OutputData%VelocityUVW) ENDIF +IF (ALLOCATED(OutputData%AccelUVW)) THEN + DEALLOCATE(OutputData%AccelUVW) +ENDIF IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -4350,6 +3581,11 @@ SUBROUTINE InflowWind_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_BufSz = Int_BufSz + 2*2 ! VelocityUVW upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%VelocityUVW) ! VelocityUVW END IF + Int_BufSz = Int_BufSz + 1 ! AccelUVW allocated yes/no + IF ( ALLOCATED(InData%AccelUVW) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! AccelUVW upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AccelUVW) ! AccelUVW + END IF Int_BufSz = Int_BufSz + 1 ! WriteOutput allocated yes/no IF ( ALLOCATED(InData%WriteOutput) ) THEN Int_BufSz = Int_BufSz + 2*1 ! WriteOutput upper/lower bounds for each dimension @@ -4422,6 +3658,26 @@ SUBROUTINE InflowWind_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%AccelUVW) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccelUVW,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccelUVW,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccelUVW,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccelUVW,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%AccelUVW,2), UBOUND(InData%AccelUVW,2) + DO i1 = LBOUND(InData%AccelUVW,1), UBOUND(InData%AccelUVW,1) + ReKiBuf(Re_Xferred) = InData%AccelUVW(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%WriteOutput) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4526,6 +3782,29 @@ SUBROUTINE InflowWind_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AccelUVW not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AccelUVW)) DEALLOCATE(OutData%AccelUVW) + ALLOCATE(OutData%AccelUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AccelUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%AccelUVW,2), UBOUND(OutData%AccelUVW,2) + DO i1 = LBOUND(OutData%AccelUVW,1), UBOUND(OutData%AccelUVW,1) + OutData%AccelUVW(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutput not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -5162,25 +4441,6 @@ SUBROUTINE InflowWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, Err ! ErrStat = ErrID_None ErrMsg = "" - DstMiscData%TimeIndex = SrcMiscData%TimeIndex - CALL IfW_UniformWind_CopyMisc( SrcMiscData%UniformWind, DstMiscData%UniformWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_TSFFWind_CopyMisc( SrcMiscData%TSFFWind, DstMiscData%TSFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_HAWCWind_CopyMisc( SrcMiscData%HAWCWind, DstMiscData%HAWCWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_BladedFFWind_CopyMisc( SrcMiscData%BladedFFWind, DstMiscData%BladedFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_UserWind_CopyMisc( SrcMiscData%UserWind, DstMiscData%UserWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_4Dext_CopyMisc( SrcMiscData%FDext, DstMiscData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcMiscData%AllOuts)) THEN i1_l = LBOUND(SrcMiscData%AllOuts,1) i1_u = UBOUND(SrcMiscData%AllOuts,1) @@ -5206,6 +4466,20 @@ SUBROUTINE InflowWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, Err END IF END IF DstMiscData%WindViUVW = SrcMiscData%WindViUVW +ENDIF +IF (ALLOCATED(SrcMiscData%WindAiUVW)) THEN + i1_l = LBOUND(SrcMiscData%WindAiUVW,1) + i1_u = UBOUND(SrcMiscData%WindAiUVW,1) + i2_l = LBOUND(SrcMiscData%WindAiUVW,2) + i2_u = UBOUND(SrcMiscData%WindAiUVW,2) + IF (.NOT. ALLOCATED(DstMiscData%WindAiUVW)) THEN + ALLOCATE(DstMiscData%WindAiUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%WindAiUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%WindAiUVW = SrcMiscData%WindAiUVW ENDIF CALL InflowWind_CopyInput( SrcMiscData%u_Avg, DstMiscData%u_Avg, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) @@ -5242,23 +4516,14 @@ SUBROUTINE InflowWind_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers DEALLOCATEpointers_local = .true. END IF - CALL IfW_UniformWind_DestroyMisc( MiscData%UniformWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_TSFFWind_DestroyMisc( MiscData%TSFFWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_HAWCWind_DestroyMisc( MiscData%HAWCWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_BladedFFWind_DestroyMisc( MiscData%BladedFFWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_UserWind_DestroyMisc( MiscData%UserWind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL IfW_4Dext_DestroyMisc( MiscData%FDext, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%AllOuts)) THEN DEALLOCATE(MiscData%AllOuts) ENDIF IF (ALLOCATED(MiscData%WindViUVW)) THEN DEALLOCATE(MiscData%WindViUVW) +ENDIF +IF (ALLOCATED(MiscData%WindAiUVW)) THEN + DEALLOCATE(MiscData%WindAiUVW) ENDIF CALL InflowWind_DestroyInput( MiscData%u_Avg, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -5305,110 +4570,6 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! TimeIndex - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! UniformWind: size of buffers for each call to pack subtype - CALL IfW_UniformWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, .TRUE. ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! UniformWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! UniformWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! UniformWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! TSFFWind: size of buffers for each call to pack subtype - CALL IfW_TSFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! TSFFWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! TSFFWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! TSFFWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! HAWCWind: size of buffers for each call to pack subtype - CALL IfW_HAWCWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, .TRUE. ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! HAWCWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! HAWCWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! HAWCWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! BladedFFWind: size of buffers for each call to pack subtype - CALL IfW_BladedFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! BladedFFWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladedFFWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladedFFWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! UserWind: size of buffers for each call to pack subtype - CALL IfW_UserWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, .TRUE. ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! UserWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! UserWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! UserWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! FDext: size of buffers for each call to pack subtype - CALL IfW_4Dext_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FDext - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FDext - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FDext - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF Int_BufSz = Int_BufSz + 1 ! AllOuts allocated yes/no IF ( ALLOCATED(InData%AllOuts) ) THEN Int_BufSz = Int_BufSz + 2*1 ! AllOuts upper/lower bounds for each dimension @@ -5419,6 +4580,12 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = Int_BufSz + 2*2 ! WindViUVW upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WindViUVW) ! WindViUVW END IF + Int_BufSz = Int_BufSz + 1 ! WindAiUVW allocated yes/no + IF ( ALLOCATED(InData%WindAiUVW) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WindAiUVW upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WindAiUVW) ! WindAiUVW + END IF + ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! u_Avg: size of buffers for each call to pack subtype CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Avg, ErrStat2, ErrMsg2, .TRUE. ) ! u_Avg CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -5514,176 +4681,6 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%TimeIndex - Int_Xferred = Int_Xferred + 1 - CALL IfW_UniformWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, OnlySize ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_TSFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, OnlySize ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_HAWCWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, OnlySize ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_BladedFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, OnlySize ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_UserWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, OnlySize ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_4Dext_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF IF ( .NOT. ALLOCATED(InData%AllOuts) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -5719,91 +4716,27 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err END DO END DO END IF - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Avg, ErrStat2, ErrMsg2, OnlySize ) ! u_Avg - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Avg, ErrStat2, ErrMsg2, OnlySize ) ! y_Avg - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Hub, ErrStat2, ErrMsg2, OnlySize ) ! u_Hub - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%WindAiUVW) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindAiUVW,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindAiUVW,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindAiUVW,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindAiUVW,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Hub, ErrStat2, ErrMsg2, OnlySize ) ! y_Hub + DO i2 = LBOUND(InData%WindAiUVW,2), UBOUND(InData%WindAiUVW,2) + DO i1 = LBOUND(InData%WindAiUVW,1), UBOUND(InData%WindAiUVW,1) + ReKiBuf(Re_Xferred) = InData%WindAiUVW(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Avg, ErrStat2, ErrMsg2, OnlySize ) ! u_Avg CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5814,295 +4747,137 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err DEALLOCATE(Re_Buf) ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE InflowWind_PackMisc - - SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%TimeIndex = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_UniformWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%UniformWind, ErrStat2, ErrMsg2 ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_TSFFWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%TSFFWind, ErrStat2, ErrMsg2 ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_HAWCWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%HAWCWind, ErrStat2, ErrMsg2 ) ! HAWCWind + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Avg, ErrStat2, ErrMsg2, OnlySize ) ! y_Avg CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_BladedFFWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%BladedFFWind, ErrStat2, ErrMsg2 ) ! BladedFFWind + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Hub, ErrStat2, ErrMsg2, OnlySize ) ! u_Hub CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_UserWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%UserWind, ErrStat2, ErrMsg2 ) ! UserWind + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Hub, ErrStat2, ErrMsg2, OnlySize ) ! y_Hub CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_4Dext_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE InflowWind_PackMisc - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackMisc' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AllOuts not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6143,6 +4918,29 @@ SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = Re_Xferred + 1 END DO END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindAiUVW not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WindAiUVW)) DEALLOCATE(OutData%WindAiUVW) + ALLOCATE(OutData%WindAiUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindAiUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WindAiUVW,2), UBOUND(OutData%WindAiUVW,2) + DO i1 = LBOUND(OutData%WindAiUVW,1), UBOUND(OutData%WindAiUVW,1) + OutData%WindAiUVW(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 @@ -6612,6 +5410,14 @@ SUBROUTINE InflowWind_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, END DO END DO END IF ! check if allocated +IF (ALLOCATED(y_out%AccelUVW) .AND. ALLOCATED(y1%AccelUVW)) THEN + DO i2 = LBOUND(y_out%AccelUVW,2),UBOUND(y_out%AccelUVW,2) + DO i1 = LBOUND(y_out%AccelUVW,1),UBOUND(y_out%AccelUVW,1) + b = -(y1%AccelUVW(i1,i2) - y2%AccelUVW(i1,i2)) + y_out%AccelUVW(i1,i2) = y1%AccelUVW(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = -(y1%WriteOutput(i1) - y2%WriteOutput(i1)) @@ -6696,6 +5502,15 @@ SUBROUTINE InflowWind_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrS END DO END DO END IF ! check if allocated +IF (ALLOCATED(y_out%AccelUVW) .AND. ALLOCATED(y1%AccelUVW)) THEN + DO i2 = LBOUND(y_out%AccelUVW,2),UBOUND(y_out%AccelUVW,2) + DO i1 = LBOUND(y_out%AccelUVW,1),UBOUND(y_out%AccelUVW,1) + b = (t(3)**2*(y1%AccelUVW(i1,i2) - y2%AccelUVW(i1,i2)) + t(2)**2*(-y1%AccelUVW(i1,i2) + y3%AccelUVW(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*y1%AccelUVW(i1,i2) + t(3)*y2%AccelUVW(i1,i2) - t(2)*y3%AccelUVW(i1,i2) ) * scaleFactor + y_out%AccelUVW(i1,i2) = y1%AccelUVW(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = (t(3)**2*(y1%WriteOutput(i1) - y2%WriteOutput(i1)) + t(2)**2*(-y1%WriteOutput(i1) + y3%WriteOutput(i1)))* scaleFactor diff --git a/modules/inflowwind/tests/ifw_test_tools.F90 b/modules/inflowwind/tests/ifw_test_tools.F90 index c6241b2ddd..109fd36f77 100644 --- a/modules/inflowwind/tests/ifw_test_tools.F90 +++ b/modules/inflowwind/tests/ifw_test_tools.F90 @@ -13,7 +13,7 @@ function getInputFileData() INTEGER :: ErrStat CHARACTER(ErrMsgLen) :: ErrMsg TYPE(FileInfoType) :: getInputFileData - CHARACTER(1024), DIMENSION(68) :: data = (/ & + CHARACTER(1024), DIMENSION(69) :: data = (/ & '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & '--------------------------------------------------------------------------------------------------------------- ', & @@ -21,6 +21,7 @@ function getInputFileData() ' 1 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) ', & ' 0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) ', & ' 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) ', & + ' false VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] ', & ' 1 NWindVel - Number of points to output the wind velocity (0 to 9) ', & ' 0 WindVxiList - List of coordinates in the inertial X direction (m) ', & ' 0 WindVyiList - List of coordinates in the inertial Y direction (m) ', & @@ -93,7 +94,7 @@ function getInputFileDataWindType2() INTEGER :: ErrStat CHARACTER(ErrMsgLen) :: ErrMsg TYPE(FileInfoType) :: getInputFileDataWindType2 - CHARACTER(1024), DIMENSION(68) :: data = (/ & + CHARACTER(1024), DIMENSION(69) :: data = (/ & '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & '--------------------------------------------------------------------------------------------------------------- ', & @@ -101,6 +102,7 @@ function getInputFileDataWindType2() ' 2 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) ', & ' 0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) ', & ' 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) ', & + ' false VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] ', & ' 1 NWindVel - Number of points to output the wind velocity (0 to 9) ', & ' 0 WindVxiList - List of coordinates in the inertial X direction (m) ', & ' 0 WindVyiList - List of coordinates in the inertial Y direction (m) ', & diff --git a/modules/inflowwind/tests/test_outputs.F90 b/modules/inflowwind/tests/test_outputs.F90 index ee5d3fab97..a5acd741c5 100644 --- a/modules/inflowwind/tests/test_outputs.F90 +++ b/modules/inflowwind/tests/test_outputs.F90 @@ -44,7 +44,7 @@ subroutine test_outputs_parsing_alternate() PriPath = "" InFileInfo = getInputFileData() - InFileInfo%Lines(64:66) = (/ & + InFileInfo%Lines(65:67) = (/ & 'True SumPrint - Print summary data to .IfW.sum (flag) ', & ' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)', & '"Wind1VelX,Wind1VelY" - Wind velocity at point WindVxiList(1),WindVyiList(1),WindVziList(1). X, Y, and Z direction components. ' & diff --git a/modules/inflowwind/tests/test_steady_wind.F90 b/modules/inflowwind/tests/test_steady_wind.F90 index 3f6def1a54..6b0578402e 100644 --- a/modules/inflowwind/tests/test_steady_wind.F90 +++ b/modules/inflowwind/tests/test_steady_wind.F90 @@ -43,7 +43,7 @@ subroutine test_steady_wind_input_mult_heights() PriPath = "" InFileInfo = getInputFileData() - InFileInfo%Lines(8:11) = (/ & + InFileInfo%Lines(9:12) = (/ & ' 2 NWindVel - Number of points to output the wind velocity (0 to 9) ', & ' 0,0 WindVxiList - List of coordinates in the inertial X direction (m) ', & ' 0,0 WindVyiList - List of coordinates in the inertial Y direction (m) ', & diff --git a/modules/inflowwind/tests/test_uniform_wind.F90 b/modules/inflowwind/tests/test_uniform_wind.F90 index f5525cfb7e..13421e5da4 100644 --- a/modules/inflowwind/tests/test_uniform_wind.F90 +++ b/modules/inflowwind/tests/test_uniform_wind.F90 @@ -90,13 +90,13 @@ subroutine test_uniform_wind_direct_data() ! Results @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') - @assertEqual(0.0, p%UniformWind%TData(1)) - @assertEqual(0.1, p%UniformWind%TData(2)) - @assertEqual(999.9, p%UniformWind%TData(3)) + @assertEqual(0.0, p%FlowField%Uniform%Time(1)) + @assertEqual(0.1, p%FlowField%Uniform%Time(2)) + @assertEqual(999.9, p%FlowField%Uniform%Time(3)) - @assertEqual(12.0, p%UniformWind%V(1)) - @assertEqual(12.0, p%UniformWind%V(2)) - @assertEqual(12.0, p%UniformWind%V(3)) + @assertEqual(12.0, p%FlowField%Uniform%VelH(1)) + @assertEqual(12.0, p%FlowField%Uniform%VelH(2)) + @assertEqual(12.0, p%FlowField%Uniform%VelH(3)) end subroutine diff --git a/modules/nwtc-library/src/NWTC_Library.f90 b/modules/nwtc-library/src/NWTC_Library.f90 index 232c9c971a..77d1388f8c 100644 --- a/modules/nwtc-library/src/NWTC_Library.f90 +++ b/modules/nwtc-library/src/NWTC_Library.f90 @@ -71,6 +71,7 @@ MODULE NWTC_Library !! (without this, it is possible [depending on the Sys*.f90 file used] that the screen output will be written to a !! file called "fort.7") + USE NWTC_Library_Types USE NWTC_Num ! technically we don't need to specify this if we have ModMesh (because ModMesh USEs NWTC_Num) USE ModMesh diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 3cae98a120..567fed052f 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -560,6 +560,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_IfW%RootName = TRIM(p_FAST%OutFileRoot)//'.'//TRIM(y_FAST%Module_Abrev(Module_IfW)) Init%InData_IfW%UseInputFile = .TRUE. Init%InData_IfW%FixedWindFileRootName = .FALSE. + Init%InData_IfW%OutputAccel = p_FAST%MHK > 0 Init%InData_IfW%NumWindPoints = 0 IF ( p_FAST%CompServo == Module_SrvD ) Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + 1 @@ -568,6 +569,11 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ELSEIF ( p_FAST%CompAero == Module_AD ) THEN ! Number of Wind points from AeroDyn, see AeroDyn.f90 Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + AD_NumWindPoints(AD%Input(1), AD%OtherSt(STATE_CURR)) + ! Wake -- we allow the wake positions to exceed the wind box + if (allocated(AD%OtherSt(STATE_CURR)%WakeLocationPoints)) then + Init%InData_IfW%BoxExceedAllowF = .true. + Init%InData_IfW%BoxExceedAllowIdx = min(Init%InData_IfW%BoxExceedAllowIdx, AD_BoxExceedPointsIdx(AD%Input(1), AD%OtherSt(STATE_CURR))) + endif END IF ! lidar diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 0bea1964e7..54fe6af445 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -381,6 +381,8 @@ sd_regression("SD_AnsysComp3_PinBeamCable" "subdyn;offshore") # InflowWind regression tests ifw_regression("ifw_turbsimff" "inflowwind") +ifw_regression("ifw_BoxExceed" "inflowwind") +ifw_regression("ifw_BoxExceedTwr" "inflowwind") # Py-InflowWind regression tests py_ifw_regression("py_ifw_turbsimff" "inflowwind;python") diff --git a/reg_tests/executeInflowwindRegressionCase.py b/reg_tests/executeInflowwindRegressionCase.py index d06b802e12..096ebe291c 100644 --- a/reg_tests/executeInflowwindRegressionCase.py +++ b/reg_tests/executeInflowwindRegressionCase.py @@ -92,7 +92,8 @@ # and initialize it with input files for all test cases if not os.path.isdir(testBuildDirectory): os.makedirs(testBuildDirectory) - for file in glob.glob(os.path.join(inputsDirectory,"*inp")): + for file in (glob.glob(os.path.join(inputsDirectory,"*inp")) + + glob.glob(os.path.join(inputsDirectory,"*bts"))): filename = file.split(os.path.sep)[-1] shutil.copy(os.path.join(inputsDirectory,filename), os.path.join(testBuildDirectory,filename)) diff --git a/reg_tests/r-test b/reg_tests/r-test index 2c2483b52c..3a61da3eec 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 2c2483b52c028614a7666d624141a2b63a650bdf +Subproject commit 3a61da3eec9233b308604c7dc055f06f118d5126 diff --git a/vs-build/AeroDyn/AeroDyn_Driver.vfproj b/vs-build/AeroDyn/AeroDyn_Driver.vfproj index 51fe9aa8d6..6ec860c422 100644 --- a/vs-build/AeroDyn/AeroDyn_Driver.vfproj +++ b/vs-build/AeroDyn/AeroDyn_Driver.vfproj @@ -376,32 +376,32 @@ - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -410,202 +410,32 @@ - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -682,13 +512,8 @@ - - - - - - - + + diff --git a/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj b/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj index 06eca6093b..f2bb6a0f86 100644 --- a/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj +++ b/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj @@ -442,32 +442,32 @@ - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -476,202 +476,32 @@ - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -748,13 +578,8 @@ - - - - - - - + + diff --git a/vs-build/FASTlib/FASTlib.vfproj b/vs-build/FASTlib/FASTlib.vfproj index 925cf1d7ac..438848eb42 100644 --- a/vs-build/FASTlib/FASTlib.vfproj +++ b/vs-build/FASTlib/FASTlib.vfproj @@ -1217,36 +1217,36 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -1255,226 +1255,36 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -1559,13 +1369,8 @@ - - - - - - - + + diff --git a/vs-build/InflowWind/InflowWind_driver.vfproj b/vs-build/InflowWind/InflowWind_driver.vfproj index 7ef4ac242d..267e49a877 100644 --- a/vs-build/InflowWind/InflowWind_driver.vfproj +++ b/vs-build/InflowWind/InflowWind_driver.vfproj @@ -90,131 +90,41 @@ - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -251,54 +161,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/vs-build/InflowWind_c_binding/InflowWind_c_binding.vfproj b/vs-build/InflowWind_c_binding/InflowWind_c_binding.vfproj index 09ec865b54..97c406319a 100644 --- a/vs-build/InflowWind_c_binding/InflowWind_c_binding.vfproj +++ b/vs-build/InflowWind_c_binding/InflowWind_c_binding.vfproj @@ -90,131 +90,41 @@ - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -251,54 +161,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/vs-build/MAPlib/MAP_dll.vcxproj b/vs-build/MAPlib/MAP_dll.vcxproj index 22373bf523..c3aef0510f 100644 --- a/vs-build/MAPlib/MAP_dll.vcxproj +++ b/vs-build/MAPlib/MAP_dll.vcxproj @@ -22,32 +22,32 @@ {BF86702A-CB17-4050-8AE9-078CDC5910D3} Win32Proj MAP_DLL - 8.1 + 10.0 StaticLibrary true - v140 + v143 Unicode StaticLibrary true - v140 + v143 Unicode StaticLibrary false - v140 + v143 true Unicode StaticLibrary false - v140 + v143 true Unicode @@ -214,4 +214,4 @@ - + \ No newline at end of file diff --git a/vs-build/Registry/FAST_Registry.vcxproj b/vs-build/Registry/FAST_Registry.vcxproj index 90fb08b2c6..9c5785a464 100644 --- a/vs-build/Registry/FAST_Registry.vcxproj +++ b/vs-build/Registry/FAST_Registry.vcxproj @@ -22,33 +22,34 @@ {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16} Win32Proj FAST_Registry_c + 10.0 Application true Unicode - v140 + v143 Application true Unicode - v140 + v143 Application false true Unicode - v140 + v143 Application false true Unicode - v140 + v143 @@ -176,4 +177,4 @@ - + \ No newline at end of file diff --git a/vs-build/RunRegistry.bat b/vs-build/RunRegistry.bat index 5a5034fc90..d3dfcbe2f7 100644 --- a/vs-build/RunRegistry.bat +++ b/vs-build/RunRegistry.bat @@ -118,13 +118,8 @@ SET Output_Loc=%CURR_LOC% %REGISTRY% "%CURR_LOC%\%ModuleName%.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -O "%Output_Loc%" GOTO checkError -:IfW_TSFFWind -:IfW_HAWCWind -:IfW_BladedFFWind -:IfW_UserWind -:IfW_4Dext -:IfW_FFWind_Base -:IfW_UniformWind +:IfW_FlowField +:InflowWind_IO SET CURR_LOC=%IfW_Loc% SET Output_Loc=%CURR_LOC% %REGISTRY% "%CURR_LOC%\%ModuleName%.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -noextrap -O "%Output_Loc%" diff --git a/vs-build/SubDyn/SubDyn.sln b/vs-build/SubDyn/SubDyn.sln index d497e8bd4a..817a37d8cd 100644 --- a/vs-build/SubDyn/SubDyn.sln +++ b/vs-build/SubDyn/SubDyn.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33205.214 MinimumVisualStudioVersion = 10.0.40219.1 Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = "SubDyn", "SubDyn.vfproj", "{815C302F-A93D-4C22-9329-717B085113C0}" ProjectSection(ProjectDependencies) = postProject @@ -38,10 +38,18 @@ Global {815C302F-A93D-4C22-9329-717B085113C0}.Release|Win32.Build.0 = Release|Win32 {815C302F-A93D-4C22-9329-717B085113C0}.Release|x64.ActiveCfg = Release|x64 {815C302F-A93D-4C22-9329-717B085113C0}.Release|x64.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|Win32.ActiveCfg = Debug|Win32 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|Win32.Build.0 = Debug|Win32 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|x64.ActiveCfg = Debug|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|x64.Build.0 = Debug|x64 {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|Win32.ActiveCfg = Release|Win32 {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|Win32.Build.0 = Release|Win32 {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|x64.ActiveCfg = Release|Win32 {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|x64.Build.0 = Release|Win32 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|Win32.ActiveCfg = Release|Win32 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|Win32.Build.0 = Release|Win32 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|x64.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|x64.Build.0 = Release|x64 {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release|Win32.ActiveCfg = Release|Win32 {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release|Win32.Build.0 = Release|Win32 {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release|x64.ActiveCfg = Release|Win32 @@ -50,4 +58,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BC2FB3AB-97DC-4701-90B3-DDAF966FAB07} + EndGlobalSection EndGlobal