From 3a27bda68ce2dbbd5f8f2e6b5e6b9ead7b0244c1 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Wed, 12 Jul 2023 17:07:02 +0000 Subject: [PATCH 01/91] Migrated FSI changes to 4.0.0-dev Existing branch at https://github.com/gantech/OpenFAST/tree/f/br_fsi_2 This commit extends the C++ API --- CMakeLists.txt | 1 + cmake/FindNetCDF.cmake | 124 + docs/_static/references.bib | 122 + docs/source/dev/cppapi/api.rst | 11 + docs/source/dev/cppapi/files/FAST_Prog.cpp | 54 + .../files/actuatorLine_illustrationViz.pdf | Bin 0 -> 251323 bytes .../dev/cppapi/files/css_actuatorline.pdf | Bin 0 -> 202965 bytes .../files/thrustXActuatorForcePoints.png | Bin 0 -> 41122 bytes .../files/torqueXActuatorForcePoints.png | Bin 0 -> 29483 bytes docs/source/dev/cppapi/index.rst | 205 + docs/source/dev/index.rst | 11 + docs/source/user/cppapi/files/cDriver.i | 67 +- docs/source/user/cppapi/index.rst | 34 +- docs/source/zrefs.rst | 6 + glue-codes/openfast-cpp/CMakeLists.txt | 11 +- glue-codes/openfast-cpp/src/FAST_Prog.cpp | 267 +- glue-codes/openfast-cpp/src/OpenFAST.H | 728 +- glue-codes/openfast-cpp/src/OpenFAST.cpp | 3622 ++++++-- glue-codes/simulink/CMakeLists.txt | 5 +- modules/beamdyn/src/BeamDyn.f90 | 5 + modules/beamdyn/src/BeamDyn_Types.f90 | 54 + modules/beamdyn/src/Registry_BeamDyn.txt | 1 + modules/elastodyn/src/ElastoDyn.f90 | 2 +- modules/elastodyn/src/ElastoDyn_Registry.txt | 2 +- modules/elastodyn/src/ElastoDyn_Types.f90 | 10 +- modules/externalinflow/CMakeLists.txt | 3 +- modules/extloads/CMakeLists.txt | 39 + modules/extloads/src/ExtLoads.f90 | 931 ++ modules/extloads/src/ExtLoadsDX_Registry.txt | 44 + modules/extloads/src/ExtLoadsDX_Types.f90 | 2674 ++++++ modules/extloads/src/ExtLoadsDX_Types.h | 57 + modules/extloads/src/ExtLoads_Registry.txt | 103 + modules/extloads/src/ExtLoads_Types.f90 | 4274 +++++++++ modules/nwtc-library/src/NWTC_IO.f90 | 34 + modules/openfast-library/CMakeLists.txt | 1 + modules/openfast-library/src/FAST_Library.f90 | 783 +- modules/openfast-library/src/FAST_Library.h | 35 +- modules/openfast-library/src/FAST_Mods.f90 | 2 + .../openfast-library/src/FAST_Registry.txt | 208 +- modules/openfast-library/src/FAST_Solver.f90 | 454 +- modules/openfast-library/src/FAST_Subs.f90 | 2836 +++++- modules/openfast-library/src/FAST_Types.f90 | 7656 ++++++++++++++--- 42 files changed, 23198 insertions(+), 2278 deletions(-) create mode 100644 cmake/FindNetCDF.cmake create mode 100644 docs/_static/references.bib create mode 100644 docs/source/dev/cppapi/api.rst create mode 100644 docs/source/dev/cppapi/files/FAST_Prog.cpp create mode 100644 docs/source/dev/cppapi/files/actuatorLine_illustrationViz.pdf create mode 100644 docs/source/dev/cppapi/files/css_actuatorline.pdf create mode 100644 docs/source/dev/cppapi/files/thrustXActuatorForcePoints.png create mode 100644 docs/source/dev/cppapi/files/torqueXActuatorForcePoints.png create mode 100644 docs/source/dev/cppapi/index.rst create mode 100644 docs/source/zrefs.rst create mode 100644 modules/extloads/CMakeLists.txt create mode 100644 modules/extloads/src/ExtLoads.f90 create mode 100644 modules/extloads/src/ExtLoadsDX_Registry.txt create mode 100644 modules/extloads/src/ExtLoadsDX_Types.f90 create mode 100644 modules/extloads/src/ExtLoadsDX_Types.h create mode 100644 modules/extloads/src/ExtLoads_Registry.txt create mode 100644 modules/extloads/src/ExtLoads_Types.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ae72886d1..305226269f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,7 @@ set(OPENFAST_MODULES nwtc-library version inflowwind + extloads aerodyn aerodyn14 servodyn diff --git a/cmake/FindNetCDF.cmake b/cmake/FindNetCDF.cmake new file mode 100644 index 0000000000..f3d64cdeff --- /dev/null +++ b/cmake/FindNetCDF.cmake @@ -0,0 +1,124 @@ +# +# This file was copied from the VTK repository: +# https://github.com/Kitware/VTK/blob/master/CMake/FindNetCDF.cmake +# VTK is distributed under the OSI-approved BSD 3-clause License. +# +# +# - Find NetCDF +# Find the native NetCDF includes and library +# +# NETCDF_INCLUDE_DIR - user modifiable choice of where netcdf headers are +# NETCDF_LIBRARY - user modifiable choice of where netcdf libraries are +# +# Your package can require certain interfaces to be FOUND by setting these +# +# NETCDF_CXX - require the C++ interface and link the C++ library +# NETCDF_F77 - require the F77 interface and link the fortran library +# NETCDF_F90 - require the F90 interface and link the fortran library +# +# Or equivalently by calling FindNetCDF with a COMPONENTS argument containing one or +# more of "CXX;F77;F90". +# +# When interfaces are requested the user has access to interface specific hints: +# +# NETCDF_${LANG}_INCLUDE_DIR - where to search for interface header files +# NETCDF_${LANG}_LIBRARY - where to search for interface libraries +# +# This module returns these variables for the rest of the project to use. +# +# NETCDF_FOUND - True if NetCDF found including required interfaces (see below) +# NETCDF_LIBRARIES - All netcdf related libraries. +# NETCDF_INCLUDE_DIRS - All directories to include. +# NETCDF_HAS_INTERFACES - Whether requested interfaces were found or not. +# NETCDF_${LANG}_INCLUDE_DIRS/NETCDF_${LANG}_LIBRARIES - C/C++/F70/F90 only interface +# +# Normal usage would be: +# set (NETCDF_F90 "YES") +# find_package (NetCDF REQUIRED) +# target_link_libraries (uses_everthing ${NETCDF_LIBRARIES}) +# target_link_libraries (only_uses_f90 ${NETCDF_F90_LIBRARIES}) + +#search starting from user editable cache var +if (NETCDF_INCLUDE_DIR AND NETCDF_LIBRARY) + # Already in cache, be silent + set (NETCDF_FIND_QUIETLY TRUE) +endif () + +set(USE_DEFAULT_PATHS "NO_DEFAULT_PATH") +if(NETCDF_USE_DEFAULT_PATHS) + set(USE_DEFAULT_PATHS "") +endif() + +find_path (NETCDF_INCLUDE_DIR netcdf.h + HINTS "${NETCDF_DIR}/include") +mark_as_advanced (NETCDF_INCLUDE_DIR) +set (NETCDF_C_INCLUDE_DIRS ${NETCDF_INCLUDE_DIR}) + +find_library (NETCDF_LIBRARY NAMES netcdf + HINTS "${NETCDF_DIR}/lib") +mark_as_advanced (NETCDF_LIBRARY) + +set (NETCDF_C_LIBRARIES ${NETCDF_LIBRARY}) + +#start finding requested language components +set (NetCDF_libs "") +set (NetCDF_includes "${NETCDF_INCLUDE_DIR}") + +get_filename_component (NetCDF_lib_dirs "${NETCDF_LIBRARY}" PATH) +set (NETCDF_HAS_INTERFACES "YES") # will be set to NO if we're missing any interfaces + +macro (NetCDF_check_interface lang header libs) + if (NETCDF_${lang}) + #search starting from user modifiable cache var + find_path (NETCDF_${lang}_INCLUDE_DIR NAMES ${header} + HINTS "${NETCDF_INCLUDE_DIR}" + HINTS "${NETCDF_${lang}_ROOT}/include" + ${USE_DEFAULT_PATHS}) + + find_library (NETCDF_${lang}_LIBRARY NAMES ${libs} + HINTS "${NetCDF_lib_dirs}" + HINTS "${NETCDF_${lang}_ROOT}/lib" + ${USE_DEFAULT_PATHS}) + + mark_as_advanced (NETCDF_${lang}_INCLUDE_DIR NETCDF_${lang}_LIBRARY) + + #export to internal varS that rest of project can use directly + set (NETCDF_${lang}_LIBRARIES ${NETCDF_${lang}_LIBRARY}) + set (NETCDF_${lang}_INCLUDE_DIRS ${NETCDF_${lang}_INCLUDE_DIR}) + + if (NETCDF_${lang}_INCLUDE_DIR AND NETCDF_${lang}_LIBRARY) + list (APPEND NetCDF_libs ${NETCDF_${lang}_LIBRARY}) + list (APPEND NetCDF_includes ${NETCDF_${lang}_INCLUDE_DIR}) + else () + set (NETCDF_HAS_INTERFACES "NO") + message (STATUS "Failed to find NetCDF interface for ${lang}") + endif () + endif () +endmacro () + +list (FIND NetCDF_FIND_COMPONENTS "CXX" _nextcomp) +if (_nextcomp GREATER -1) + set (NETCDF_CXX 1) +endif () +list (FIND NetCDF_FIND_COMPONENTS "F77" _nextcomp) +if (_nextcomp GREATER -1) + set (NETCDF_F77 1) +endif () +list (FIND NetCDF_FIND_COMPONENTS "F90" _nextcomp) +if (_nextcomp GREATER -1) + set (NETCDF_F90 1) +endif () +NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++) +NetCDF_check_interface (F77 netcdf.inc netcdff) +NetCDF_check_interface (F90 netcdf.mod netcdff) + +#export accumulated results to internal varS that rest of project can depend on +list (APPEND NetCDF_libs "${NETCDF_C_LIBRARIES}") +set (NETCDF_LIBRARIES ${NetCDF_libs}) +set (NETCDF_INCLUDE_DIRS ${NetCDF_includes}) + +# handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if +# all listed variables are TRUE +include (FindPackageHandleStandardArgs) +find_package_handle_standard_args (NetCDF + DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDE_DIRS NETCDF_HAS_INTERFACES) diff --git a/docs/_static/references.bib b/docs/_static/references.bib new file mode 100644 index 0000000000..34192e55d0 --- /dev/null +++ b/docs/_static/references.bib @@ -0,0 +1,122 @@ +%% This BibTeX bibliography file was created using BibDesk. +%% http://bibdesk.sourceforge.net/ + +%% Created for Vijayakumar, Ganesh at 2016-12-07 16:45:28 -0700 + + +%% Saved with string encoding Unicode (UTF-8) + +@inbook{churchfield2012, + Annote = {doi:10.2514/6.2012-537}, + Author = {Churchfield, Matthew and Lee, Sang and Moriarty, Patrick and Martinez, Luis and Leonardi, Stefano and Vijayakumar, Ganesh and Brasseur, James}, + Booktitle = {50th AIAA Aerospace Sciences Meeting including the New Horizons Forum and Aerospace Exposition}, + Doi = {doi:10.2514/6.2012-537}, + Month = {2017/07/18}, + Publisher = {American Institute of Aeronautics and Astronautics}, + Title = {A Large-Eddy Simulation of Wind-Plant Aerodynamics}, + Title1 = {Aerospace Sciences Meeting}, + Ty = {CHAP}, + Url = {https://doi.org/10.2514/6.2012-537}, + Year = {2012}} + + +@techreport{beamdynManual, + Author = {Wang, Q and Jonkman, Jason and Sprague, Michael A, and Jonkman, Bonnie}, + Date-Added = {2016-12-07 23:35:57 +0000}, + Date-Modified = {2016-12-07 23:37:15 +0000}, + Institution = {National Renewable Energy Laboratory}, + Month = {March}, + Title = {BeamDyn User's Guide and Theory Manual}, + Year = {2016}} + +@article{martinez2016, + Author = {Luis A. Martinez-Tossas and Matthew J. Churchfield and Charles Meneveau}, + Journal = {Journal of Physics: Conference Series}, + Number = {8}, + Pages = {082014}, + Title = {A Highly Resolved Large-Eddy Simulation of a Wind Turbine using an Actuator Line Model with Optimal Body Force Projection}, + Url = {http://stacks.iop.org/1742-6596/753/i=8/a=082014}, + Volume = {753}, + Year = {2016}} + +@techreport{fastProgrammersHandbook, + Author = {B.J. Jonkman and J. Michalakes and J.M. Jonkman and M.L. Buhl and Jr. and A. Platt and and M.A. Sprague}, + Institution = {National Renewable Energy Laboratory}, + Month = {July}, + Title = {NWTC Programmer's Handbook: A Guide for Software Development Within the FAST Computer-Aided Engineering Tool}, + Year = {2013}} + +@techreport{aerodynV15Manual, + Author = {J.M. Jonkman}, + Institution = {National Renewable Energy Laboratory}, + Month = {April}, + Title = {AeroDyn v15 User's Guide and Theory Manual}, + Year = {2016}} + +@techreport{naluDoc, + Address = {https://github.com/spdomin/NaluDoc}, + Author = {Stefan Domino}, + Institution = {Sandia National Laboratories Unclassified Unlimited Release (UUR)}, + Number = {SAND2015-3107W}, + Title = {Sierra Low Mach Module: Nalu Theory Manual 1.0}, + Year = {2015}} + +@techreport{fastv8AlgorithmsExamples, + Author = {Michael A. Sprague and Jason M. Jonkman and Bonnie J. Jonkman}, + Institution = {National Renewable Energy Laboratory}, + Month = {January}, + Number = {NREL/CP-2C00-63203}, + Title = {FAST Modular Framework for Wind Turbine Simulation: New Algorithms and Numerical Examples}, + Year = {2015}} + +@techreport{fastv8ModFramework, + Author = {Jason M. Jonkman}, + Date-Added = {2016-07-21 19:25:11 +0000}, + Date-Modified = {2016-07-21 19:26:24 +0000}, + Institution = {National Renewable Energy Laboratory}, + Month = {January}, + Number = {NREL/CP-5000-57228}, + Title = {The New Modularization Framework for the FAST Wind Turbine CAE Tool}, + Year = {2013}} + +@techreport{fastv8, + Author = {Jason M. Jonkman and Bonnie J. Jonkman}, + Date-Added = {2016-07-21 19:15:10 +0000}, + Date-Modified = {2016-07-21 19:28:31 +0000}, + Institution = {National Renewable Energy Laboratory}, + Month = {April}, + Title = {FAST v8: Changelog}, + Year = {2016}} + +@techreport{fastv7, + Author = {Jason M. Jonkman and Marshall L. Buhl Jr.}, + Date-Added = {2016-07-21 18:11:47 +0000}, + Date-Modified = {2016-07-21 18:13:07 +0000}, + Institution = {National Renewable Energy Laboratory}, + Month = {August}, + Number = {NREL/EL-500-38230}, + Title = {FAST User's Guide}, + Year = {2005}} + +@techreport{fleming2013, + Author = {Paul Fleming and Sang Lee and Matthew J. Churchfield and Andrew Scholbrock and John Michalakes and Kathryn Johnson and and Patrick Moriarty}, + Date-Added = {2016-07-21 18:05:29 +0000}, + Date-Modified = {2016-07-21 19:30:03 +0000}, + Institution = {National Renewable Energy Laboratory}, + Month = {January}, + Number = {NREL/CP-5000-57175}, + Title = {The SOWFA Super-Controller: A High-Fidelity Tool for Evaluating Wind Plant Control Approaches}, + Year = {2013}} + +@misc{MPI-3.1, + Author = {MPI Forum}, + Month = {June}, + Note = {available at: http://www.mpi-forum.org (Jun. 2015)}, + Title = {MPI: A Message-Passing Interface Standard. Version 3.1}, + Year = {2015}} + +@misc{hdf5, + Author = {The HDF Group}, + Note = {http://www.hdfgroup.org/HDF5/}, + Title = {Hierarchical Data Format, version 5}, + Year = {1997}} diff --git a/docs/source/dev/cppapi/api.rst b/docs/source/dev/cppapi/api.rst new file mode 100644 index 0000000000..063d97d035 --- /dev/null +++ b/docs/source/dev/cppapi/api.rst @@ -0,0 +1,11 @@ +C++ API Documentation +===================== + +OpenFAST +-------- + +.. doxygenclass:: fast::OpenFAST + :members: + :protected-members: + :undoc-members: + diff --git a/docs/source/dev/cppapi/files/FAST_Prog.cpp b/docs/source/dev/cppapi/files/FAST_Prog.cpp new file mode 100644 index 0000000000..91a21447b8 --- /dev/null +++ b/docs/source/dev/cppapi/files/FAST_Prog.cpp @@ -0,0 +1,54 @@ +#include "OpenFAST.H" +#include "yaml-cpp/yaml.h" +#include +#include + +void readTurbineData(int iTurb, fast::fastInputs & fi, YAML::Node turbNode) { + //Read turbine data for a given turbine using the YAML node +} + +void readInputFile(fast::fastInputs & fi, std::string cInterfaceInputFile, double * tEnd) { + //Read input data for a given turbine using the YAML node +} + +int main() { + int iErr; + int nProcs; + int rank; + + iErr = MPI_Init(NULL, NULL); + iErr = MPI_Comm_size( MPI_COMM_WORLD, &nProcs); + iErr = MPI_Comm_rank( MPI_COMM_WORLD, &rank); + + double tEnd ; // This doesn't belong in the OpenFAST - C++ API + int ntEnd ; // This doesn't belong in the OpenFAST - C++ API + + std::string cDriverInputFile="cDriver.i"; + fast::OpenFAST FAST; + fast::fastInputs fi ; + readInputFile(fi, cDriverInputFile, &tEnd); + ntEnd = tEnd/fi.dtFAST; //Calculate the last time step + + FAST.setInputs(fi); + // In a parallel simulation, multiple turbines have to be allocated to processors. + // The C++ API can handle any allocation of turbines on an arbitrary number of processors + FAST.allocateTurbinesToProcsSimple(); // Use this for a simple round robin allocation of turbines to processors. + // Or allocate turbines to procs by calling "setTurbineProcNo(iTurbGlob, procId)" for each turbine. + + FAST.init(); + if (FAST.isTimeZero()) { + FAST.solution0(); + } + + if( !FAST.isDryRun() ) { + for (int nt = FAST.get_ntStart(); nt < ntEnd; nt++) { + FAST.step(); + } + } + + FAST.end() ; + MPI_Finalize() ; + + return 0; + +} diff --git a/docs/source/dev/cppapi/files/actuatorLine_illustrationViz.pdf b/docs/source/dev/cppapi/files/actuatorLine_illustrationViz.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fbb1fd5b4b6dee4ff40c4020ccc4b72661fdf82f GIT binary patch literal 251323 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μ5d|9Ei$ZuqUeKAx>O0wxQ&yZ2Km2&q;E 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%0AMQIxKzM{F`euk;Q!ef>kwn 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

YT>1G*$`>zF6i`8A_Vb)NlQVCPEE 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 Z`_ is provided as a demonstration of the usage of the C++ API. The glue-code allows for the simulation of multiple turbines using OpenFAST in serial or in parallel over multiple processors. The message passing interface (MPI) is used to run the different instances of turbines in parallel. An abbrievated version of FAST_Prog.cpp is shown below. The highlighted lines indicate the use of the OpenFAST class. + +.. literalinclude:: files/FAST_Prog.cpp + :emphasize-lines: 1,27,28,32,36,38,40,45,49 + :language: C++ + +All inputs to the OpenFAST class are expected through an object of the :class:`fast::fastInputs`. + + +.. doxygenclass:: fast::fastInputs + :members: + :private-members: + :protected-members: + :undoc-members: + +The object of :class:`~fast::fastInputs` class is expected hold a struct vector of type :class:`~fast::turbineDataType` and size of the number of turbines in the simulation. + +.. doxygenstruct:: fast::turbineDataType + :members: + :private-members: + + +Use of C++ API for Actuator Line Simulations +-------------------------------------------- + +The C++ API was developed mainly to integrate OpenFAST with Computational Fluid Dynamics (CFD) solvers for Fluid-Structure Interaction (FSI) applications. The workhorse FSI algorithm for wind energy applications today is the Actuator Line algorithm :cite:`churchfield2012`. The Actuator Line algorithm represents the effect of a turbine on a flow field as a series of point forces at **actuator points** along aerodynamic surfaces. The use of Blade Element Momentum theory in AeroDyn is modified to interface OpenFAST with CFD solvers for actuator line simulations. The CFD solver becomes the inflow module for OpenFAST that provides velocity information near the turbine. The calculation of the induction factors is turned off in OpenFAST and AeroDyn simply uses look up tables and an optional dynamic stall model to calculate the loads on the turbine based on the inflow field information received from the CFD solver. The induction model should be turned off in OpenFAST by selecting :samp:`WakeMod=0` in the AeroDyn input file. OpenFAST lumps the line forces along the blades and tower into a series of point forces for the actuator line algorithm. :numref:`actuatorline-viz` illustrates the transfer of information between OpenFAST and a CFD solver for actuator line applications. + +.. _actuatorline-viz: + +.. figure:: files/actuatorLine_illustrationViz.pdf + :align: center + :width: 100% + + Illustration of transfer of velocity, loads and deflection between a CFD solver and OpenFAST through the C++ API for actuator line applications. + +The CFD solver is expected to be the *driver program* for actuator line FSI simulations coupled to OpenFAST. The C++ API allows for *substepping* where the driver timestep is an integral multiple of the OpenFAST time step (:math:`\Delta_t^{CFD} = n \Delta_t^{OpenFAST}`). The current implementation of the C++ API for OpenFAST allows for a serial staggered FSI scheme between the fluid (CFD) and structural (OpenFAST) solver. :numref:`actuatorline-css` shows a suggested implementation of a loosely coupled serial staggered FSI scheme to move the simulation from time step `n` to `n+1` for actuator line applications. A strongly coupled FSI scheme can be constructed through the repetition of the coupling algorithm in :numref:`actuatorline-css` through "outer" iterations. + +.. _actuatorline-css: + +.. figure:: files/css_actuatorline.pdf + :align: center + :width: 100% + + A conventional serial staggered FSI scheme that can be constructed through the C++ API for actuator line applications. + + +OpenFAST uses different spatial meshes for the various modules :cite:`fastv8ModFramework`. We define the actuator points to be along the mesh defined in the structural model (ElastoDyn/BeamDyn) of the turbine. The user defines the required number of actuator points along each blade and the tower through the input parameters :samp:`numForcePtsBlade` and :samp:`numForcePtsTower` for each turbine. The number of actuator points have to be the same on all blades. The C++ API uses OpenFAST to create the requested number of actuator points through linear interpolation of the nodes in the structural model. The mesh mapping algorithm in OpenFAST :cite:`fastv8AlgorithmsExamples` is used to transfer deflections from the structural model and loads from AeroDyn to the actuator points. To distinguish the *actuator points* from the Aerodyn points, the OpenFAST C++ uses the term :samp:`forceNodes` for the actuator points and :samp:`velNodes` (velocity nodes) for the Aerodyn points. The following piece of code illustrates how one can use the C++ API to implement a strongly coupled FSI scheme with "outer" iterations for actuator line applications. This sample piece of code sets the velocity at the :samp:`velNodes` and access the coordinates and the lumped forces at the :samp:`forceNodes`. + +.. code-block:: c++ + + std::vector currentCoords(3); + std::vector sampleVel(3); + + for (int iOuter=0; iOuter < nOuterIterations; iOuter++) { + + FAST.predict_states(); //Predict the location and force at the actuator points at time step 'n+1'. + + for(iTurb=0; iTurb < nTurbines; iTurb++) { + for(int i=0; i < FAST.get_numVelPts(iTurb); i++) { + // Get actuator node co-ordinates at time step 'n+1' + FAST.getForceNodeCoordinates(currentCoords, i, iTurb, fast::np1); + //Move the actuator point to this co-ordinate if necessary + // Get force at actuator node at time step 'n+1' + FAST.getForce(actForce, i, iTurb, fast::np1); + //Do something with this force + } + } + + // Predict CFD solver to next time step here + + for(iTurb=0; iTurb < nTurbines; iTurb++) { + for(int i=0; i < FAST.get_numVelPts(iTurb); i++) { + // Get velocity node co-ordinates at time step 'n+1' + FAST.getVelNodeCoordinates(currentCoords, i, iTurb, fast::np1); + //Sample velocity from CFD solver at currentCoords into sampleVel here + // Set velocity at the velocity nodes at time step 'n+1' + FAST.setVelocity(sampleVel, i, iTurb, fast::np1); + } + } + + FAST.update_states_driver_time_step(); // Predict the state of OpenFAST at the next time step + + } + + // Move OpenFAST to next CFD time step + FAST.advance_to_next_driver_time_step(); + +.. toctree:: + :maxdepth: 1 + + api.rst + + +Implementation +-------------- + +The C++ API uses the C-Fortran interface to call the same functions as the Fortran driver internally to advance the OpenFAST in time. FAST_Library.f90 contains all the functions that can be called from the C++ API. Some of the corresponding functions between the C++ API and the Fortran module are shown in the following table. + +.. table:: + + +------------------------------------+---------------------------------+-------------------------------+ + | C++ API - OpenFAST.cpp | Fortran - FAST_Library.f90 | FAST_Subs.f90 | + +====================================+=================================+===============================+ + | init() | FAST_AL_CFD_Init | FAST_InitializeAll_T | + +------------------------------------+---------------------------------+-------------------------------+ + | solution0() | FAST_CFD_Solution0 | FAST_Solution0_T | + +------------------------------------+---------------------------------+-------------------------------+ + | prework() | FAST_CFD_Prework | FAST_Prework_T | + +------------------------------------+---------------------------------+-------------------------------+ + | | FAST_CFD_Store_SS | FAST_Store_SS | + +------------------------------------+---------------------------------+-------------------------------+ + | update_states_driver_time_step() | FAST_CFD_UpdateStates | FAST_UpdateStates_T | + +------------------------------------+---------------------------------+-------------------------------+ + | | FAST_CFD_Reset_SS | FAST_Reset_SS | + +------------------------------------+---------------------------------+-------------------------------+ + | advance_to_next_driver_time_step() | FAST_CFD_AdvanceToNextTimeStep | FAST_AdvanceToNextTimeStep_T | + +------------------------------------+---------------------------------+-------------------------------+ + +The `FAST_Solution_T` subroutine in `FAST_Subs.f90` is split into three different subroutines `FAST_Prework_T`, `FAST_UpdateStates_T` and `FAST_AdvanceToNextTimeStep_T` to allow for multiple *outer* iterations with external driver programs. Extra subroutines `FAST_Store_SS` and `FAST_Reset_SS` are introduced to move OpenFAST back by more than 1 time step when using *sub-stepping* with external driver programs. The typical order in which the Fortran subroutines will be accessed when using the C++ API from an external driver program is shown below. + +.. code-block:: fortran + + call FAST_AL_CFD_Init + + call FAST_CFD_Solution0 + + do i=1, nTimesteps + + if (nSubsteps .gt. 1) + call FAST_CFD_Store_SS + else + call FAST_CFD_Prework + end if + + do iOuter=1, nOuterIterations + + if (nSubsteps .gt. 1) + + if (iOuter .ne. 1) then + ! Reset OpenFAST back when not the first pass + call FAST_CFD_Reset_SS + + end if + + do j=1, nSubsteps + + ! Set external inputs into modules here for the substep + call FAST_CFD_Prework + call FAST_CFD_UpdateStates + call FAST_CFD_AdvanceToNextTimeStep + + end do !Substeps + + else + + call FAST_CFD_UpdateStates + + end if + + end do !Outer iterations + + if (nSubsteps .gt. 1) then + + ! Nothing to do here + + else + + call FAST_CFD_AdvanceToNextTimeStep + + end if + + end do + + + +The mapping of loads and deflections to the actuator points is performed in the :class:`ExternalInflow` module in OpenFAST. The C++ API supports the use of both BeamDyn and ElastoDyn to model the blades. When using BeamDyn to model the blade, the C++ API requires the use of only 1 finite element for each blade along with the choice of trapezoidal quadrature for actuator line simulations. + +Test for mapping procedure +-------------------------- + +The test for the implementation of the mapping procedure is as follows. OpenFAST is run using the C++ API to simulate the NREL-5MW turbine for one time step with a prescribed velocity of :math:`8 m/s` at all the velocity nodes and no induction (:samp:`WakeMod=0`). The number of actuator force nodes is varied from 10 to 100 while the number of velocity nodes is fixed at 17. :numref:`actuator-force-nodes-mapping-test-thrust` and :numref:`actuator-force-nodes-mapping-test-torque` show that the thrust and torque vary by less than :math:`1.1 \times 10^{-6}\%` and :math:`2 \times 10^{-6}\%` respectively when the number of actuator force nodes is varied from :math:`10-100`. + + +.. _actuator-force-nodes-mapping-test-thrust: + +.. figure:: files/thrustXActuatorForcePoints.png + :align: center + :width: 100% + + Variation of thrust using different number of actuator force nodes in `OpenFAST` for the same number of velocity nodes. + +.. _actuator-force-nodes-mapping-test-torque: + +.. figure:: files/torqueXActuatorForcePoints.png + :align: center + :width: 100% + + Variation of torque using different number of actuator force nodes in `OpenFAST` for the same number of velocity nodes. diff --git a/docs/source/dev/index.rst b/docs/source/dev/index.rst index a10aced968..dd833c8ef6 100644 --- a/docs/source/dev/index.rst +++ b/docs/source/dev/index.rst @@ -253,6 +253,17 @@ be found in the following pages: - `Index of Types <../../html/classes.html>`_ - `Source Files <../../html/files.html>`_ +C++ API Reference +~~~~~~~~~~~~~~~~~~~ +C++ API documentation is available. + +.. toctree:: + :maxdepth: 1 + + cppapi/index.rst + + + Other Documentation ~~~~~~~~~~~~~~~~~~~ Additional documentation exists that may be useful for developers seeking deeper diff --git a/docs/source/user/cppapi/files/cDriver.i b/docs/source/user/cppapi/files/cDriver.i index 6a13912191..917208c312 100644 --- a/docs/source/user/cppapi/files/cDriver.i +++ b/docs/source/user/cppapi/files/cDriver.i @@ -3,38 +3,45 @@ # C++ glue-code for OpenFAST - Example input file # -#Total number of turbines in the simulation -nTurbinesGlob: 3 -#Enable debug outputs if set to true -debug: False -#The simulation will not run if dryRun is set to true -dryRun: False -#Flag indicating whether the simulation starts from scratch or restart -simStart: init # init/trueRestart/restartDriverInitFAST -#Start time of the simulation -tStart: 0.0 -#End time of the simulation. tEnd <= tMax -tEnd: 1.0 -#Max time of the simulation -tMax: 4.0 -#Time step for FAST. All turbines should have the same time step. -dtFAST: 0.00625 -#Restart files will be written every so many time steps -nEveryCheckPoint: 160 +n_turbines_glob: 3 # Total number of turbines in the simulation + +debug: False # Enable debug outputs if set to true + +dry_run: False # The simulation will not run if dryRun is set to true + +sim_start: init # Flag indicating whether the simulation starts from scratch or restart + # [init | trueRestart | restartDriverInitFAST] + +coupling_mode: strong # Coupling mode + # [strong | classic] + +t_start: 0.0 # Start time of the simulation + +t_end: 1.0 # End time of the simulation; tEnd <= tMax. + +t_max: 4.0 # Max time of the simulation + +dt_FAST: 0.00625 # Time step for FAST. All turbines should have the same time step. + +n_substeps: 1 # Number of substeps per timestep of the glue-code + +n_checkpoint: 160 # Restart files will be written every so many time steps + +set_exp_law_wind: false # Set velocity at the the turbine using an exponential law profile. Turbine0: - #The position of the turbine base for actuator-line simulations - turbine_base_pos: [ 0.0, 0.0, 0.0 ] - #The number of actuator points along each blade for actuator-line simulations - num_force_pts_blade: 0 - #The number of actuator points along the tower for actuator-line simulations. - num_force_pts_tower: 0 - #The checkpoint file for this turbine when restarting a simulation - restart_filename: "banana" - #The FAST input file for this turbine - FAST_input_filename: "t1_Test05.fst" - #A unique turbine id for each turbine - turb_id: 1 + + turbine_base_pos: [ 0.0, 0.0, 0.0 ] # The position of the turbine base for actuator-line simulations + + num_force_pts_blade: 0 # The number of actuator points along each blade for actuator-line simulations + + num_force_pts_tower: 0 # The number of actuator points along the tower for actuator-line simulations. + + restart_filename: "banana" # The checkpoint file for this turbine when restarting a simulation + + FAST_input_filename: "t1_Test05.fst" # The FAST input file for this turbine + + turb_id: 1 # A unique turbine id for each turbine Turbine1: turbine_base_pos: [ 0.0, 0.0, 0.0 ] diff --git a/docs/source/user/cppapi/index.rst b/docs/source/user/cppapi/index.rst index f364465560..fe970d5aeb 100644 --- a/docs/source/user/cppapi/index.rst +++ b/docs/source/user/cppapi/index.rst @@ -26,7 +26,7 @@ Command line invocation Common input file options ------------------------- -.. confval:: nTurbinesGlob +.. confval:: n_turbines_glob Total number of turbines in the simulation. The input file must contain a number of turbine specific sections (`Turbine0`, `Turbine1`, ..., `Turbine(n-1)`) that is consistent with `nTurbinesGlob`. @@ -34,37 +34,49 @@ Common input file options Enable debug outputs if set to true -.. confval:: dryRun +.. confval:: dry_run The simulation will not run if dryRun is set to true. However, the simulation will read the input files, allocate turbines to processors and prepare to run the individual turbine instances. This flag is useful to test the setup of the simulation before running it. -.. confval:: simStart +.. confval:: sim_start - Flag indicating whether the simulation starts from scratch or restart. ``simStart`` takes on one of three values: + Flag indicating whether the simulation starts from scratch or restart. ``sim_start`` takes on one of three values: * ``init`` - Use this option when starting a simulation from `t=0s`. * ``trueRestart`` - While OpenFAST allows for restart of a turbine simulation, external components like the Bladed style controller may not. Use this option when all components of the simulation are known to restart. * ``restartDriverInitFAST`` - When the ``restartDriverInitFAST`` option is selected, the individual turbine models start from `t=0s` and run up to the specified restart time using the inflow data stored at the actuator nodes from a hdf5 file. The C++ API stores the inflow data at the actuator nodes in a hdf5 file at every OpenFAST time step and then reads it back when using this restart option. This restart option is especially useful when the glue code is a CFD solver. + +.. confval:: coupling_mode + + Choice of coupling mode. ``coupling_mode`` takes one of two values: ``strong`` or ``classic``. ``strong`` coupling mode uses 2 outer iterations for every driver time step while ``classic`` coupling mode calls the `step()` function to use the loose coupling mode. -.. confval:: tStart +.. confval:: t_start Start time of the simulation -.. confval:: tEnd +.. confval:: t_end - End time of the simulation. tEnd <= tMax + End time of the simulation. t_end <= t_max -.. confval:: tMax +.. confval:: t_max Max time of the simulation -.. confval:: dtFAST +.. confval:: dt_fast Time step for FAST. All turbines should have the same time step. -.. confval:: nEveryCheckPoint +.. confval:: n_substeps + + Number of sub-timesteps of OpenFAST per time step of the driver program. + +.. confval:: n_checkpoint + + Restart files will be written every so many time steps + +.. confval:: set_exp_law_wind - Restart files will be written every so many time steps + Boolean value of True/False. When true, set velocity at the Aerodyn nodes using a power law wind profile using an exponent of 0.2 and a reference wind speed of 10 m/s at 90 meters. This option is useful to test the setup for actuator line simulations in individual mode before running massive CFD simulations. Turbine specific input options ------------------------------ diff --git a/docs/source/zrefs.rst b/docs/source/zrefs.rst new file mode 100644 index 0000000000..0bacbc412e --- /dev/null +++ b/docs/source/zrefs.rst @@ -0,0 +1,6 @@ +.. only:: html + + References + ---------- + +.. bibliography:: ../_static/references.bib diff --git a/glue-codes/openfast-cpp/CMakeLists.txt b/glue-codes/openfast-cpp/CMakeLists.txt index 2d23a99790..55823e0465 100644 --- a/glue-codes/openfast-cpp/CMakeLists.txt +++ b/glue-codes/openfast-cpp/CMakeLists.txt @@ -26,7 +26,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(MPI REQUIRED) find_package(LibXml2 REQUIRED) find_package(ZLIB REQUIRED) -find_package(HDF5 REQUIRED COMPONENTS C HL) +find_package(HDF5 REQUIRED) +find_package(NetCDF REQUIRED COMPONENTS C) find_package(yaml-cpp REQUIRED) add_library(openfastcpplib @@ -36,15 +37,15 @@ add_library(openfastcpplib set_property(TARGET openfastcpplib PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(openfastcpplib openfastlib - ${HDF5_C_LIBRARIES} - ${HDF5_HL_LIBRARIES} + ${HDF5_LIBRARIES} + ${NETCDF_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBXML2_LIBRARIES} ${MPI_LIBRARIES} ) target_include_directories(openfastcpplib PUBLIC - ${HDF5_INCLUDES} - ${HDF5_INCLUDE_DIR} + ${HDF5_INCLUDE_DIRS} + ${NETCDF_INCLUDE_DIRS} ${ZLIB_INCLUDES} ${LIBXML2_INCLUDE_DIR} ${MPI_INCLUDE_PATH} diff --git a/glue-codes/openfast-cpp/src/FAST_Prog.cpp b/glue-codes/openfast-cpp/src/FAST_Prog.cpp index b46514c56d..ab68e388ef 100644 --- a/glue-codes/openfast-cpp/src/FAST_Prog.cpp +++ b/glue-codes/openfast-cpp/src/FAST_Prog.cpp @@ -1,94 +1,178 @@ #include "OpenFAST.H" #include "yaml-cpp/yaml.h" #include +#include #include inline bool checkFileExists(const std::string& name) { - struct stat buffer; - return (stat (name.c_str(), &buffer) == 0); + struct stat buffer; + return (stat (name.c_str(), &buffer) == 0); } -void readTurbineData(int iTurb, fast::fastInputs & fi, YAML::Node turbNode) { - //Read turbine data for a given turbine using the YAML node - fi.globTurbineData[iTurb].TurbID = turbNode["turb_id"].as(); - fi.globTurbineData[iTurb].FASTInputFileName = turbNode["FAST_input_filename"].as(); - fi.globTurbineData[iTurb].FASTRestartFileName = turbNode["restart_filename"].as(); - if (turbNode["turbine_base_pos"].IsSequence() ) { - fi.globTurbineData[iTurb].TurbineBasePos = turbNode["turbine_base_pos"].as >(); +/// Optionally read in a value from a yaml node if present, else set it to a default value. Copied from github.com/Exawind/nalu-wind/include/NaluParsing.h +template +void get_if_present(const YAML::Node & node, const std::string& key, T& result, const T& default_if_not_present = T()) +{ + if (node[key]) { + const YAML::Node value = node[key]; + result = value.as(); } - if (turbNode["turbine_hub_pos"].IsSequence() ) { - fi.globTurbineData[iTurb].TurbineHubPos = turbNode["turbine_hub_pos"].as >(); + else { + int rank; + int iErr = MPI_Comm_rank( MPI_COMM_WORLD, &rank); + if(!rank) + std::cout << key << " is missing in the input file. Proceeding with assumption " << key << " = " << default_if_not_present << std::endl ; + result = default_if_not_present; } - fi.globTurbineData[iTurb].numForcePtsBlade = turbNode["num_force_pts_blade"].as(); - fi.globTurbineData[iTurb].numForcePtsTwr = turbNode["num_force_pts_tower"].as(); - if (turbNode["nacelle_cd"]) fi.globTurbineData[iTurb].nacelle_cd = turbNode["nacelle_cd"].as(); - if (turbNode["nacelle_area"]) fi.globTurbineData[iTurb].nacelle_area = turbNode["nacelle_area"].as(); - if (turbNode["air_density"]) fi.globTurbineData[iTurb].air_density = turbNode["air_density"].as(); } -void readInputFile(fast::fastInputs & fi, std::string cInterfaceInputFile, double * tEnd) { +/// Read a 'key' from a yaml node if it exists, else throw an error +template +void get_required(const YAML::Node & node, const std::string& key, T& result) +{ + if (node[key]) { + const YAML::Node value = node[key]; + result = value.as(); + } + else { + throw std::runtime_error("Error: parsing missing required key: " + key); + } +} - fi.comm = MPI_COMM_WORLD; +void readTurbineData(int iTurb, fast::fastInputs & fi, YAML::Node turbNode) { - // Check if the input file exists and read it - if ( checkFileExists(cInterfaceInputFile) ) { + //Read turbine data for a given turbine using the YAML node - YAML::Node cDriverInp = YAML::LoadFile(cInterfaceInputFile); + get_if_present(turbNode, "turb_id", fi.globTurbineData[iTurb].TurbID, iTurb); + std::string simType; + get_if_present(turbNode, "sim_type", simType, std::string("ext-inflow")); + if (simType == "ext-loads") + fi.globTurbineData[iTurb].sType = fast::EXTLOADS; + else + fi.globTurbineData[iTurb].sType = fast::EXTINFLOW; - fi.nTurbinesGlob = cDriverInp["nTurbinesGlob"].as(); + std::string emptyString = ""; + get_if_present(turbNode, "FAST_input_filename", fi.globTurbineData[iTurb].FASTInputFileName); + get_if_present(turbNode, "restart_filename", fi.globTurbineData[iTurb].FASTRestartFileName); + if ( (fi.globTurbineData[iTurb].FASTRestartFileName == emptyString) && (fi.globTurbineData[iTurb].FASTInputFileName == emptyString) ) + throw std::runtime_error("Both FAST_input_filename and restart_filename are empty or not specified for Turbine " + std::to_string(iTurb)); - if (fi.nTurbinesGlob > 0) { + if (turbNode["turbine_base_pos"].IsSequence() ) { + fi.globTurbineData[iTurb].TurbineBasePos = turbNode["turbine_base_pos"].as >() ; + } else { + fi.globTurbineData[iTurb].TurbineBasePos = std::vector(3,0.0); + } - if(cDriverInp["dryRun"]) { - fi.dryRun = cDriverInp["dryRun"].as(); - } + if (turbNode["turbine_hub_pos"].IsSequence() ) { + fi.globTurbineData[iTurb].TurbineHubPos = turbNode["turbine_hub_pos"].as >() ; + } else { + fi.globTurbineData[iTurb].TurbineHubPos = std::vector(3,0.0); + } - if(cDriverInp["debug"]) { - fi.debug = cDriverInp["debug"].as(); - } + get_if_present(turbNode, "num_force_pts_blade", fi.globTurbineData[iTurb].numForcePtsBlade, 0); + get_if_present(turbNode, "num_force_pts_tower", fi.globTurbineData[iTurb].numForcePtsTwr, 0); - if(cDriverInp["simStart"]) { - if (cDriverInp["simStart"].as() == "init") { - fi.simStart = fast::init; - } else if(cDriverInp["simStart"].as() == "trueRestart") { - fi.simStart = fast::trueRestart; - } else if(cDriverInp["simStart"].as() == "restartDriverInitFAST") { - fi.simStart = fast::restartDriverInitFAST; - } else { - throw std::runtime_error("simStart is not well defined in the input file"); - } - } + float fZero = 0.0; + get_if_present(turbNode, "nacelle_cd", fi.globTurbineData[iTurb].nacelle_cd, fZero); + get_if_present(turbNode, "nacelle_area", fi.globTurbineData[iTurb].nacelle_area, fZero); + get_if_present(turbNode, "air_density", fi.globTurbineData[iTurb].air_density, fZero); + + if (simType == "ext-loads") { + + get_if_present(turbNode, "az_blend_mean", fi.globTurbineData[iTurb].azBlendMean, 20*360.0*M_PI/180.0); //20 revs + get_if_present(turbNode, "az_blend_delta", fi.globTurbineData[iTurb].azBlendDelta, 3.0*360.0*M_PI/180.0); // 3 rev + get_required(turbNode, "vel_mean", fi.globTurbineData[iTurb].velMean); + get_required(turbNode, "wind_dir", fi.globTurbineData[iTurb].windDir); + get_required(turbNode, "z_ref", fi.globTurbineData[iTurb].zRef); + get_required(turbNode, "shear_exp", fi.globTurbineData[iTurb].shearExp); + + } + +} - fi.tStart = cDriverInp["tStart"].as(); - *tEnd = cDriverInp["tEnd"].as(); - fi.nEveryCheckPoint = cDriverInp["nEveryCheckPoint"].as(); - fi.dtFAST = cDriverInp["dtFAST"].as(); - fi.tMax = cDriverInp["tMax"].as(); // tMax is the total duration to which you want to run FAST. This should be the same or greater than the max time given in the FAST fst file. Choose this carefully as FAST writes the output file only at this point if you choose the binary file output. +void readInputFile(fast::fastInputs & fi, std::string cInterfaceInputFile, double *tStart, double * tEnd, int * couplingMode, bool * setExpLawWind, bool * setUniformXBladeForces, int * nIter, double *xBladeForce) { - if(cDriverInp["superController"]) { - fi.scStatus = cDriverInp["superController"].as(); - fi.scLibFile = cDriverInp["scLibFile"].as(); + fi.comm = MPI_COMM_WORLD; + + // Check if the input file exists and read it + if ( checkFileExists(cInterfaceInputFile) ) { + + YAML::Node cDriverInp = YAML::LoadFile(cInterfaceInputFile); + get_required(cDriverInp, "n_turbines_glob", fi.nTurbinesGlob); + + if (fi.nTurbinesGlob > 0) { + + get_if_present(cDriverInp, "dry_run", fi.dryRun, false); + get_if_present(cDriverInp, "debug", fi.debug, false); + + *couplingMode = 0; //CLASSIC is default + if(cDriverInp["coupling_mode"]) { + if ( cDriverInp["coupling_mode"].as() == "strong" ) { + *couplingMode = 1; + } else if ( cDriverInp["coupling_mode"].as() == "classic" ) { + *couplingMode = 0; + } else { + throw std::runtime_error("coupling_mode is not well defined in the input file"); } + } + if (cDriverInp["n_iter"]) { + *nIter = cDriverInp["n_iter"].as(); + if (*nIter < 0) { + *nIter = 1; + } + } else { + *nIter = 1; + } - fi.globTurbineData.resize(fi.nTurbinesGlob); - for (int iTurb=0; iTurb < fi.nTurbinesGlob; iTurb++) { - if (cDriverInp["Turbine" + std::to_string(iTurb)]) { - readTurbineData(iTurb, fi, cDriverInp["Turbine" + std::to_string(iTurb)] ); - } else { - throw std::runtime_error("Node for Turbine" + std::to_string(iTurb) + " not present in input file or I cannot read it"); - } + if(cDriverInp["sim_start"]) { + if (cDriverInp["sim_start"].as() == "init") { + fi.simStart = fast::init; + } else if(cDriverInp["sim_start"].as() == "trueRestart") { + fi.simStart = fast::trueRestart; + } else if(cDriverInp["sim_start"].as() == "restartDriverInitFAST") { + fi.simStart = fast::restartDriverInitFAST; + } else { + throw std::runtime_error("sim_start is not well defined in the input file"); } + } - } else { - throw std::runtime_error("Number of turbines <= 0 "); + get_required(cDriverInp, "t_start", *tStart); + get_required(cDriverInp, "t_end", *tEnd); + get_required(cDriverInp, "restart_freq", fi.restartFreq); + get_if_present(cDriverInp, "output_freq", fi.outputFreq, 100); + get_required(cDriverInp, "dt_driver", fi.dtDriver); + get_required(cDriverInp, "t_max", fi.tMax); // t_max is the total duration to which you want to run FAST. This should be the same or greater than the max time given in the FAST fst file. + get_if_present(cDriverInp, "set_exp_law_wind", *setExpLawWind, false); + get_if_present(cDriverInp, "set_uniform_x_blade_forces", *setUniformXBladeForces, false); + if (setUniformXBladeForces) + get_required(cDriverInp, "x_blade_force", *xBladeForce); + + get_if_present(cDriverInp, "super_controller", fi.scStatus, false); + if(fi.scStatus) { + get_required(cDriverInp, "sc_libfile", fi.scLibFile); + } + + fi.globTurbineData.resize(fi.nTurbinesGlob); + for (int iTurb=0; iTurb < fi.nTurbinesGlob; iTurb++) { + if (cDriverInp["Turbine" + std::to_string(iTurb)]) { + readTurbineData(iTurb, fi, cDriverInp["Turbine" + std::to_string(iTurb)] ); + } else { + throw std::runtime_error("Node for Turbine" + std::to_string(iTurb) + " not present in input file or I cannot read it"); + } } } else { - throw std::runtime_error("Input file " + cInterfaceInputFile + " does not exist or I cannot access it"); + throw std::runtime_error("Number of turbines <= 0 "); } + + } else { + throw std::runtime_error("Input file " + cInterfaceInputFile + " does not exist or I cannot access it"); + } + } int main(int argc, char** argv) { + if (argc != 2) { std::cerr << "Incorrect syntax. Try: openfastcpp inputfile.yaml" << std::endl ; return 1; @@ -98,36 +182,40 @@ int main(int argc, char** argv) { int nProcs; int rank; std::vector torque (3, 0.0); - std::vector thrust (3, 0.0); + std::vector thrust (3, 0.0); iErr = MPI_Init(NULL, NULL); iErr = MPI_Comm_size( MPI_COMM_WORLD, &nProcs); iErr = MPI_Comm_rank( MPI_COMM_WORLD, &rank); - double tEnd ; // This doesn't belong in the FAST - C++ interface - int ntEnd ; // This doesn't belong in the FAST - C++ interface - + int couplingMode ; //CLASSIC (SOWFA style = 0) or STRONG (Conventional Serial Staggered - allow for outer iterations = 1) + double tStart; // This doesn't belong in the C++ API + double tEnd ; // This doesn't belong in the FAST - C++ interface + int ntStart, ntEnd ; // This doesn't belong in the FAST - C++ interface + int nSubsteps; // + bool setExpLawWind; // Set wind speed at Aerodyn nodes based on an exponential profile. Useful for testing the C++ API before running actuator line simulations. + bool setUniformXBladeForces; // Set uniform X blade forces on all blade nodes + int nIter; + double xBladeForce = 0.0; + std::string cDriverInputFile=argv[1]; fast::OpenFAST FAST; fast::fastInputs fi ; try { - readInputFile(fi, cDriverInputFile, &tEnd); + readInputFile(fi, cDriverInputFile, &tStart, &tEnd, &couplingMode, &setExpLawWind, &setUniformXBladeForces, &nIter, &xBladeForce); } catch( const std::runtime_error & ex) { std::cerr << ex.what() << std::endl ; std::cerr << "Program quitting now" << std::endl ; return 1; } - // Calculate the last time step - ntEnd = tEnd/fi.dtFAST; - FAST.setInputs(fi); - FAST.allocateTurbinesToProcsSimple(); + FAST.allocateTurbinesToProcsSimple(); // Or allocate turbines to procs by calling "setTurbineProcNo(iTurbGlob, procId)" for turbine. FAST.init(); - if (FAST.isTimeZero()) FAST.solution0(); + nSubsteps = fi.dtDriver/FAST.get_timestep(); if ( FAST.isDryRun() ) { FAST.end() ; @@ -135,8 +223,46 @@ int main(int argc, char** argv) { return 0; } - for (int nt = FAST.get_ntStart(); nt < ntEnd; nt++) { - FAST.step(); + if (FAST.isTimeZero()) { + if (setExpLawWind) + FAST.setExpLawWindSpeed(0.0); + + FAST.solution0(); + } + + + ntStart = tStart/fi.dtDriver; //Calculate the first time step + ntEnd = tEnd/fi.dtDriver; //Calculate the last time step + + for (int nt = ntStart; nt < ntEnd; nt++) { + if (couplingMode == 0) { + // If running with a CFD solver, sample velocities at the actuator/velocity nodes here + if (setExpLawWind) + FAST.setExpLawWindSpeed( (nt+1)*fi.dtDriver ); + if (setUniformXBladeForces) { + FAST.setUniformXBladeForces(xBladeForce); + } + + for (int iSubstep=1; iSubstep < nSubsteps; iSubstep++) { + FAST.step(); + std::cout << "iSubstep = " << iSubstep << std::endl ; + } + // Get forces at actuator nodes and advance CFD solve by one time step here + } else { + for (int j=0; j < nIter; j++) { + // If running with a CFD solver, use 'FAST.predict_states()' to predict position and force at actuator nodes at the next time step on the first pass + // Run a CFD time step as a 'predictor' to get velocity at the next time step + // Sample and set velocity at the actuator/velocity nodes after the first cfd predictor + if (setExpLawWind) + FAST.setExpLawWindSpeed( (nt+1)*fi.dtDriver ); + if (setUniformXBladeForces) { + FAST.setUniformXBladeForces(xBladeForce); + } + FAST.update_states_driver_time_step(); + } + // Call this after enough outer iterations have been done + FAST.advance_to_next_driver_time_step(); + } if (FAST.isDebug()) { FAST.computeTorqueThrust(0,torque,thrust); std::cout.precision(16); @@ -149,5 +275,4 @@ int main(int argc, char** argv) { MPI_Finalize() ; return 0; - } diff --git a/glue-codes/openfast-cpp/src/OpenFAST.H b/glue-codes/openfast-cpp/src/OpenFAST.H index 21ed980aa3..0f1895944e 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.H +++ b/glue-codes/openfast-cpp/src/OpenFAST.H @@ -6,8 +6,11 @@ #include #include #include +#include #include #include +#include +#include "netcdf.h" #include "dlfcn.h" //TODO: The skip MPICXX is put in place primarily to get around errors in OpenFOAM. This will cause problems if the driver program uses C++ API for MPI. #ifndef OMPI_SKIP_MPICXX @@ -22,20 +25,74 @@ namespace fast { -struct globTurbineDataType { - int TurbID; - std::string FASTInputFileName; - std::string FASTRestartFileName; - std::vector TurbineBasePos; - std::vector TurbineHubPos; - std::string forcePtsBladeDistributionType; - int numForcePtsBlade; - int numForcePtsTwr; - float nacelle_cd{0.0}; - float nacelle_area{0.0}; - float air_density{0.0}; +//! An id to indicate the type of simulation for each turbine - Simple/Actuator with optional externally specified inflow or Blade-Resolved with externally specified loads +enum simType { + EXTINFLOW = 0, + EXTLOADS = 1, + simType_END }; +//! A data structure to hold all turbine related information +struct turbineDataType { + //!Integer id for every turbine + int TurbID; + //! The FAST Input file name. Typically a .fst file. + std::string FASTInputFileName; + //! The restart/checkpoint file name. + std::string FASTRestartFileName; + //! Output file root + std::string outFileRoot; + //! The time step for OpenFAST for this turbine + double dt; + //! The position of the base of the turbine in global coordinates + std::vector TurbineBasePos; + //! The approximate position of the hub of the turbine in global coordinates + std::vector TurbineHubPos; + //! Simulation type + simType sType; + //! Number of blades + int numBlades; + //! Number of velocity nodes (AeroDyn) per blade + int numVelPtsBlade; + //! Number of velocity nodes (AeroDyn) on the tower + int numVelPtsTwr; + //! Total number of velocity nodes (AeroDyn) + int numVelPts; + //! Desired number of actuator points on each blade + int numForcePtsBlade; + //! Desired number of actuator points on the tower + int numForcePtsTwr; + //! Total number of actuator points + int numForcePts; + //! Inflow Type - 1 (InflowWind) or 2 (Externally specified) + int inflowType; + //! Drag coefficient of nacelle + float nacelle_cd; + //! Frontal area of the nacelle + float nacelle_area; + //! Air density around this turbine + float air_density; + //! Number of nodes at which the forces and deflections are computed for blade-resolved FSI on each blade + std::vector nBRfsiPtsBlade; + //! Total number of BR fsi points on all blades combined + int nTotBRfsiPtsBlade; + //! Number of nodes at which the forces and deflections are computed for blade-resolved FSI on the tower + int nBRfsiPtsTwr; + //! The mean azimuth at which the loads are blended between AeroDyn and CFD + double azBlendMean; + //! The delta azimuth over which the the loads are blended between AeroDyn and CFD + double azBlendDelta; + //! Mean velocity at reference height + double velMean; + //! Compass angle of wind direction (in degrees) + double windDir; + //! Reference height for velocity profile + double zRef; + //! Shear exponent of velocity profile + double shearExp; +}; + +//! An id to indicate whether a particular actuator point is on the hub, node or tower enum ActuatorNodeType { HUB = 0, BLADE = 1, @@ -43,6 +100,11 @@ enum ActuatorNodeType { ActuatorNodeType_END }; +/** An id to indicate the start type of a simulation. + * init - Start the simulation from scratch + * trueRestart - Restart from a checkpoint file. Code expects checkpoint files for all parts of the simulation including the controller. + * restartDriverInitFAST - Start all turbines from scratch and use the velocity data in 'velData.h5' file to run upto desired restart time, then continue the simulation like ''trueRestart'. + */ enum simStartType { init = 0, trueRestart = 1, @@ -50,24 +112,133 @@ enum simStartType { simStartType_END }; +//! A data structure to hold all velocity and force node information +struct turbVelForceNodeDataType { + //! Blade location at velocity nodes + std::vector x_vel; + //! Blade velocity at velocity nodes + std::vector xdot_vel; + //! Sampled velocity at velocity nodes + std::vector vel_vel; + //! Reference location at force nodes + std::vector xref_force; + //! Blade location at force nodes + std::vector x_force; + //! Blade velocity at force nodes + std::vector xdot_force; + //! Blade orientation at force nodes + std::vector orient_force; + //! Sampled velocity at force nodes + std::vector vel_force; + //! Actuator force at force nodes + std::vector force; + double x_vel_resid; + double xdot_vel_resid; + double vel_vel_resid; + double x_force_resid; + double xdot_force_resid; + double orient_force_resid; + double vel_force_resid; + double force_resid; +}; + +//! An enum to keep track of information stored at different time steps +enum timeStep { + STATE_NM2 = 0, + STATE_NM1 = 1, + STATE_N = 2, + STATE_NP1 = 3, + timeStep_END +}; + +//! A data structure to hold all loads and deflections information for blade-resolved FSI simulations +struct turbBRfsiDataType { + //! Tower reference position + std::vector twr_ref_pos; + //! Tower deflections + std::vector twr_def; + //! Tower velocity + std::vector twr_vel; + //! Blade radial location + std::vector bld_rloc; + //! Blade chord + std::vector bld_chord; + //! Blade reference position + std::vector bld_ref_pos; + //! Blade deflections + std::vector bld_def; + //! Blade velocity + std::vector bld_vel; + //! Hub reference position + std::vector hub_ref_pos; + //! Hub deflections + std::vector hub_def; + //! Hub velocity + std::vector hub_vel; + //! Nacelle reference position + std::vector nac_ref_pos; + //! Nacelle deflections + std::vector nac_def; + //! Nacelle velocity + std::vector nac_vel; + //! Blade root reference position + std::vector bld_root_ref_pos; + //! Blade root deformation + std::vector bld_root_def; + //! Blade pitch + std::vector bld_pitch; + + //! Tower loads + std::vector twr_ld; + //! Blade loads + std::vector bld_ld; + double twr_def_resid; + double twr_vel_resid; + double bld_def_resid; + double bld_vel_resid; + double twr_ld_resid; + double bld_ld_resid; +}; +/** + * A class to hold all input data for a simulation run through a OpenFAST C++ glue code + */ class fastInputs { public: + //! MPI Communicator MPI_Comm comm; - int nTurbinesGlob; - bool dryRun; - bool debug; - double tStart; + //! Total number of turbines in the simulation + int nTurbinesGlob{0}; + //! The simulation will not run if dryRun is set to true. However, the simulation will read the input files, allocate turbines to processors and prepare to run the individual turbine instances. This flag is useful to test the setup of the simulation before running it. + bool dryRun{false}; + //! Enable debug outputs if set to true + bool debug{false}; + //! Start time of the simulation + double tStart{-1.0}; + //! Start type of the simulation: 'INIT', 'TRUERESTART' or 'RESTARTDRIVERINITFAST'. simStartType simStart; - int nEveryCheckPoint; - double tMax; - double dtFAST; - - bool scStatus; - std::string scLibFile; - std::vector globTurbineData; + //!Restart files will be written every so many time stneps + int restartFreq{-1}; + //!Output files will be written every so many time stneps + int outputFreq{100}; + //! Max time of the simulation + double tMax{0.0}; + //! Time step for driver. + double dtDriver{0.0}; + //! Time step for openfast. + double dtFAST{0.0}; + //! Supercontroller status: True/False. + bool scStatus{false}; + //! Name of the dynamic library containing the supercontroller implementation + std::string scLibFile{""}; + //! Number of inputs and output to the supercontroller from/to each turbine + int numScInputs{0}; + int numScOutputs{0}; + + //! Vector of turbine specific input data + std::vector globTurbineData; // Constructor fastInputs() ; @@ -78,84 +249,180 @@ class fastInputs { }; +/** + * A class to interface OpenFAST's fortran backend with a C++ driver program + */ class OpenFAST { private: + //! MPI Communicator MPI_Comm mpiComm; - bool dryRun; // If this is true, class will simply go through allocation and deallocation of turbine data - bool debug; // Write out extra information if this flags is turned on - std::vector globTurbineData; - int nTurbinesProc; - int nTurbinesGlob; - simStartType simStart; - bool timeZero; - double dtFAST; - double tMax; - std::vector > TurbineBasePos; - std::vector > TurbineHubPos; - std::vector TurbID; - std::vector FASTInputFileName; - std::vector CheckpointFileRoot; - std::vector nacelle_cd; - std::vector nacelle_area; - std::vector air_density; - double tStart; - int nt_global; - int ntStart; // The time step to start the FAST simulation - int nEveryCheckPoint; // Check point files will be written every 'nEveryCheckPoint' time steps - std::vector numBlades; // Number of blades - std::vector forcePtsBladeDistributionType; - std::vector numForcePtsBlade; - std::vector numForcePtsTwr; - std::vector numVelPtsBlade; - std::vector numVelPtsTwr; - + //! The simulation will not run if dryRun is set to true. However, the simulation will read the input files, allocate turbines to processors and prepare to run the individual turbine instances. This flag is useful to test the setup of the simulation before running it. + bool dryRun{false}; // If this is true, class will simply go through allocation and deallocation of turbine data + //! Enable debug outputs if set to true + bool debug{false}; // Write out extra information if this flags is turned on + //! Number of turbines on this MPI rank + int nTurbinesProc{0}; + //! Total number of turbines in the simulation + int nTurbinesGlob{0}; + //! Start type of the simulation: 'INIT', 'TRUERESTART' or 'RESTARTDRIVERINITFAST'. + simStartType simStart{fast::init}; + //! Offset between driver and openfast simulation time - t_driver - t_openfast + double driverOpenfastOffset_{0.0}; + //! Is the time now zero: True/False + bool timeZero{false}; + //! Time step for FAST. All turbines on a given processor should have the same time step. + double dtFAST{-1.0}; + //! Time step for Driver. + double dtDriver{-1.0}; + //! Number of OpenFAST time steps per unit time step of the driver program + int nSubsteps_{-1}; + //! Is this the first pass through a time step + bool firstPass_{true}; + //! Max time of the simulation + double tMax{-1.0}; + //! Start time of the simulation + double tStart{-1.0}; + + //! The current time step number + int nt_global{0}; + //! The current nonlinear iteration + int nlinIter_{0}; + //! The starting time step number + int ntStart{0}; + //! Restart files will be written every so many time steps + int restartFreq_{-1}; + //! Output files will be written every so many time steps + int outputFreq_{100}; + + //! Map of `{variableName : netCDF_ID}` obtained from the NetCDF C interface + std::vector ncOutVarNames_; + std::unordered_map ncOutVarIDs_; + + //! Map of `{dimName : netCDF_ID}` obtained from the NetCDF C interface + std::vector ncOutDimNames_; + std::unordered_map ncOutDimIDs_; + + //! Map of `{variableName : netCDF_ID}` obtained from the NetCDF C interface + std::vector ncRstVarNames_; + std::unordered_map ncRstVarIDs_; + + //! Map of `{dimName : netCDF_ID}` obtained from the NetCDF C interface + std::vector ncRstDimNames_; + std::unordered_map ncRstDimIDs_; + + std::vector globTurbineData; //All turbines + std::vector turbineData; // Only for turbines on the proc + + //! Velocity at force nodes - Store temporarily to interpolate to the velocity nodes std::vector > > forceNodeVel; // Velocity at force nodes - Store temporarily to interpolate to the velocity nodes + //! Position and velocity data at the velocity (aerodyn) nodes - (nTurbines, nTimesteps * nPoints * 6) std::vector > velNodeData; // Position and velocity data at the velocity (aerodyn) nodes - (nTurbines, nTimesteps * nPoints * 6) - hid_t velNodeDataFile; // HDF-5 tag of file containing velocity (aerodyn) node data file + //! Array containing data at the velocity and force nodes + std::vector> velForceNodeData; + //! Array containing forces and deflections data for blade-resolved FSI simulations. + std::vector> brFSIData; - std::vector cDriver_Input_from_FAST; - std::vector cDriver_Output_to_FAST; + //! Data structure to get forces and deflections from ExternalInflow module in OpenFAST + std::vector extinfw_i_f_FAST; // Input from OpenFAST + //! Data structure to send velocity information to ExternalInflow module in OpenFAST + std::vector extinfw_o_t_FAST; // Output to OpenFAST + + //! Data structure to get deflections from ExternalLoads module in OpenFAST + std::vector extld_i_f_FAST; // Input from OpenFAST + //! Data structure to send force information to ExternalLoads module in OpenFAST + std::vector extld_o_t_FAST; // Output to OpenFAST - // Turbine Number is DIFFERENT from TurbID. Turbine Number simply runs from 0:n-1 locally and globally. - std::map turbineMapGlobToProc; // Mapping global turbine number to processor number - std::map turbineMapProcToGlob; // Mapping local to global turbine number - std::map reverseTurbineMapProcToGlob; // Reverse Mapping global turbine number to local turbine number - std::set turbineSetProcs; // Set of processors containing at least one turbine - std::vector turbineProcs; // Same as the turbineSetProcs, but as an integer array - - //Supercontroller stuff - bool scStatus; - SuperController sc; scInitOutData scio; - int fastMPIGroupSize; + // Mapping of local turbine number to global turbine and processor number + // Turbine Number is DIFFERENT from TurbID. Turbine Number simply runs from 0:n-1 locally and globally. + //! Mapping global turbine number to processor number + std::map turbineMapGlobToProc; + //! Mapping local to global turbine number + std::map turbineMapProcToGlob; + //! Reverse Mapping global turbine number to local turbine number + std::map reverseTurbineMapProcToGlob; + //! Set of processors containing atleast one turbine + std::set turbineSetProcs; + //! Same as the turbineSetProcs, but as an integer array + std::vector turbineProcs; + + // Supercontroller stuff + bool scStatus{false}; + std::string scLibFile; + // Dynamic load stuff copied from 'C++ dlopen mini HOWTO' on tldp.org + void *scLibHandle ; + typedef SuperController* create_sc_t(); + create_sc_t * create_SuperController; + typedef void destroy_sc_t(SuperController *); + destroy_sc_t * destroy_SuperController; + std::unique_ptr sc; + + // MPI related book keeping for all processors containing turbines + //! Number of processors in a fastMPIGroup + int fastMPIGroupSize{-1}; + //! An MPI group created among all processors that simulate atleast one turbine MPI_Group fastMPIGroup; + //! An MPI communicator for the MPI group created among all processors that simulate atleast one turbine MPI_Comm fastMPIComm; - int fastMPIRank; + //! MPI rank of processor on the fastMPIComm + int fastMPIRank{-1}; + //! Global MPI group MPI_Group worldMPIGroup; - int worldMPIRank; + //! MPI rank of processor on global MPI Comm + int worldMPIRank{-1}; - static int AbortErrLev; - int ErrStat; + //! Error status and Error message to communicate with OpenFAST + int ErrStat{0}; char ErrMsg[INTERFACE_STRING_LENGTH]; // make sure this is the same size as IntfStrLen in FAST_Library.f90 + static int AbortErrLev; public: - // Constructor + //! Constructor OpenFAST() ; - // Destructor - ~OpenFAST() ; + //! Destructor + ~OpenFAST() {} ; + //! Set inputs to OpenFAST through an object of the class fastInputs. Should be called on all MPI ranks. void setInputs(const fastInputs &); + //! Check and set the number of sub-timesteps + int checkAndSetSubsteps(); + + //! Set driver time step and check point + void setDriverTimeStep(double dt_driver); + void setDriverCheckpoint(int nt_checkpoint_driver); + + //! Initialize the simulation - allocate memory for all data structures and initialize all turbines. Safe to call on all MPI ranks. void init(); - void solution0(); - void step(); - void stepNoWrite(); + //! Call FAST->solution0 for all turbines. Safe to call on all MPI ranks. + void solution0(bool writeFiles=true); + //! Initialize velocity and force node data. Safe to call on all MPI ranks. + void init_velForceNodeData(); + //! Set up before every OpenFAST time step. Safe to call on all MPI ranks. + void prework(); + //! Update states to next time step by calling FAST_AdvanceStates_T and CalcOutputs_And_SolveForInputs. Safe to call on all MPI ranks. + void update_states_driver_time_step(bool writeFiles=true); + //! Copy the final predicted states from step t_global_next to actual states for that step. Safe to call on all MPI ranks. + void advance_to_next_driver_time_step(bool writeFiles=true); + //! Set external inputs for OpenFAST modules by interpolating to substep. Safe to call on all MPI ranks. + void send_data_to_openfast(double ss_time); + //! Set external inputs for OpenFAST modules at time step 't'. Safe to call on all MPI ranks. + void send_data_to_openfast(fast::timeStep t); + //! Get ouput data from OpenFAST modules. Safe to call on all MPI ranks. + void get_data_from_openfast(fast::timeStep t); + //! Extrapolate velocity and force node data to time step 'n+1' using data at 'n', 'n-1' and 'n-2'. Safe to call on all MPI ranks. + void predict_states(); + //! Advance all turbines by 1 OpenFAST timestep. Safe to call on all MPI ranks. + void step(bool writeFiles=true); + //! Step function to be used with sub-stepping fast between time steps of the driver program. Safe to call on all MPI ranks. + void step(double ss_time); + //! Call FAST->end for all turbines. Safe to call on all MPI ranks. void end(); // Compute the nacelle force @@ -169,125 +436,334 @@ class OpenFAST { float & fy, float & fz); - hid_t openVelocityDataFile(bool createFile); - void readVelocityData(int nTimesteps); - void writeVelocityData(hid_t h5file, int iTurb, int iTimestep, OpFM_InputType_t iData, OpFM_OutputType_t oData); - herr_t closeVelocityDataFile(int nt_global, hid_t velDataFile); - void backupVelocityDataFile(int curTimeStep, hid_t & velDataFile); - + //! Allocate turbine number 'iTurbGlob' to the processor with global MPI rank 'procNo'. MUST be called from every MPI rank. void setTurbineProcNo(int iTurbGlob, int procNo) { turbineMapGlobToProc[iTurbGlob] = procNo; } + //! Allocate all turbines to processors in a round-robin fashion. MUST be called from every MPI rank. void allocateTurbinesToProcsSimple(); + + //! Get fast time step on this processor + double get_timestep() { return dtFAST; } + + //! Get the approximate hub position for turbine number 'iTurbGlob'. This is the value specified in the input to OpenFAST. Must be called only from the processor containing the turbine. void getApproxHubPos(double* currentCoords, int iTurbGlob, int nSize=3); - void getHubPos(double* currentCoords, int iTurbGlob, int nSize=3); - void getHubShftDir(double* hubShftVec, int iTurbGlob, int nSize=3); + //! Get the exact hub position for turbine number 'iTurbGlob'. This is avaiable only after OpenFAST has been initialized for a given turbine. Must be called only from the processor containing the turbine. + void getHubPos(double* currentCoords, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=3); + //! Get a vector pointing downstream along the hub for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. + void getHubShftDir(double* hubShftVec, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=3); + + //! Get the node type (HUB, BLADE, TOWER) of velocity node number 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. ActuatorNodeType getVelNodeType(int iTurbGlob, int iNode); - void getVelNodeCoordinates(double* currentCoords, int iNode, int iTurbGlob, int nSize=3); + //! Get the coordinates of velocity node number 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. + void getVelNodeCoordinates(double* currentCoords, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=3); + //! Set the velocity at velocity node 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. void setVelocity(double* velocity, int iNode, int iTurbGlob, int nSize=3); + //! Set the velocity at force node 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. void setVelocityForceNode(double* velocity, int iNode, int iTurbGlob, int nSize=3); + //! Map the velocity from the force nodes to the velocity nodes using linear interpolation along each blade and the tower. Safe to call from every MPI rank. void interpolateVel_ForceToVelNodes(); + //! Get the node type (HUB, BLADE, TOWER) of force node number 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. ActuatorNodeType getForceNodeType(int iTurbGlob, int iNode); - void getForceNodeCoordinates(double* currentCoords, int iNode, int iTurbGlob, int nSize=3); - void getForceNodeOrientation(double* currentOrientation, int iNode, int iTurbGlob, int nSize=9); - void getForce(double* force, int iNode, int iTurbGlob, int nSize=3); - void getRelativeVelForceNode(double* vel, int iNode, int iTurbGlob, int nSize=3); - double getChord(int iNode, int iTurbGlob); + //! Get the coordinates of force node number 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. + void getForceNodeCoordinates(double* currentCoords, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=3); + //! Get the tensor orientation of force node number 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. + void getForceNodeOrientation(double* currentOrientation, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=3); + //! Get the actuator force at force node 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. + void getForce(double* force, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=3); + void getRelativeVelForceNode(double* vel, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=3); + + //! Get the chord at force node 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. + double getChord(int iNode, int iTurbGlob); + //! Get the radial location/height along blade/tower at force node 'iNode' for turbine number 'iTurbGlob'. Must be called only from the processor containing the turbine. + double getRHloc(int iNode, int iTurbGlob); + + //! Get processor containing turbine 'iTurbGlob' + int getProc(int iTurbGlob) {return turbineMapGlobToProc[iTurbGlob];} + + //! Get the blade chord array 'bldRloc' of turbine number 'iTurbGlob' + void getBladeChord(double * bldChord, int iTurbGlob); + //! Get the blade node radial locations array 'bldRloc' of turbine number 'iTurbGlob' + void getBladeRloc(double * bldRloc, int iTurbGlob); + //! Get the blade reference positions array 'bldRefPos' of turbine number 'iTurbGlob' + void getBladeRefPositions(double* bldRefPos, int iTurbGlob, int nSize=6); + //! Get the blade root reference positions array 'bldRootRefPos' of turbine number 'iTurbGlob' + void getBladeRootRefPositions(double* bldRootRefPos, int iTurbGlob, int nSize=6); + //! Get the blade deflections array 'bldDefl' of turbine number 'iTurbGlob' at time step 't' + void getBladeDisplacements(double* bldDefl, double* bldVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=6); + //! Get the blade root deflections array 'bldRootDefl' of turbine number 'iTurbGlob' at time step 't' + void getBladeRootDisplacements(double* bldRootDefl, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=6); + //! Get the blade pitch 'bldPitch' of turbine number 'iTurbGlob' + void getBladePitch(double* bldPitch, int iTurbGlob, int nSize=3); + //! Get the tower reference positions array 'twrRefPos' of turbine number 'iTurbGlob' + void getTowerRefPositions(double* twrRefPos, int iTurbGlob, int nSize=6); + //! Get the tower deflections array 'twrDefl' of turbine number 'iTurbGlob' at time step 't' + void getTowerDisplacements(double* twrDefl, double* twrVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=6); + //! Get the hub reference position array 'hubRefPos' of turbine number 'iTurbGlob' + void getHubRefPosition(double* hubRefPos, int iTurbGlob, int nSize=6); + //! Get the hub deflections array 'hubDefl' of turbine number 'iTurbGlob' at time step 't' + void getHubDisplacement(double* hubDefl, double* hubVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=6); + //! Get the nacelle reference position array 'nacRefPos' of turbine number 'iTurbGlob' + void getNacelleRefPosition(double* nacRefPos, int iTurbGlob, int nSize=6); + //! Get the nacelle deflections array 'nacDefl' of turbine number 'iTurbGlob' at time step 't' + void getNacelleDisplacement(double* nacDefl, double* nacVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=6); + + //! Set the blade forces array 'bldForce' for blade 'iBlade' of turbine number 'iTurbGlob' at time step 't' + void setBladeForces(double* bldForce, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=6); + //! Set the tower force array 'twrForce' of turbine number 'iTurbGlob' at time step 't' + void setTowerForces(double* twrForce, int iTurbGlob, fast::timeStep t = fast::STATE_NP1, int nSize=6); + + + //! Get all turbine parametric data + void get_turbineParams(int iTurbGlob, turbineDataType & turbData); + //! Get the starting time step of the simulation. Safe to call from every MPI rank. int get_ntStart() { return ntStart; } + //! Return a boolean flag whether the simulation is dryRun. Safe to call from every MPI rank. bool isDryRun() { return dryRun; } + //! Return a boolean flag whether the simulation is debug. Safe to call from every MPI rank. bool isDebug() { return debug; } + //! Get an enum of type 'simStartType' indicating the start type of the simulation. Safe to call from every MPI rank. simStartType get_simStartType() { return simStart; } + //! Is the simulation time zero right now? Safe to call from every MPI rank. bool isTimeZero() { return timeZero; } - int get_procNo(int iTurbGlob) { return turbineMapGlobToProc[iTurbGlob] ; } // Get processor number of a turbine with global id 'iTurbGlob' + //! Get the global MPI rank of the processor containing turbine number 'iTurbGlob'. Safe to call from every MPI rank. + int get_procNo(int iTurbGlob) { return turbineMapGlobToProc[iTurbGlob] ; } + //! Get the local turbine number of the turbine number 'iTurbGlob'. Safe to call from every MPI rank. int get_localTurbNo(int iTurbGlob) { return reverseTurbineMapProcToGlob[iTurbGlob]; } + //! Get the total number of turbines in the simulation. Safe to call from every MPI rank. int get_nTurbinesGlob() { return nTurbinesGlob; } + //! Get the nacelle area of turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. float get_nacelleArea(int iTurbGlob) { return get_nacelleAreaLoc(get_localTurbNo(iTurbGlob)); } + //! Get the nacelle drag coefficient of turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. float get_nacelleCd(int iTurbGlob) { return get_nacelleCdLoc(get_localTurbNo(iTurbGlob)); } + //! Get the air density around turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. float get_airDensity(int iTurbGlob) { return get_airDensityLoc(get_localTurbNo(iTurbGlob)); } + + //! Get the number of blades in turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. int get_numBlades(int iTurbGlob) { return get_numBladesLoc(get_localTurbNo(iTurbGlob)); } + //! Get the number of Aerodyn/velocity nodes on each blade in turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. int get_numVelPtsBlade(int iTurbGlob) { return get_numVelPtsBladeLoc(get_localTurbNo(iTurbGlob)); } + //! Get the number of Aerodyn/velocity nodes on the tower in turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. int get_numVelPtsTwr(int iTurbGlob) { return get_numVelPtsTwrLoc(get_localTurbNo(iTurbGlob)); } + //! Get the total number of Aerodyn/velocity nodes in turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. int get_numVelPts(int iTurbGlob) { return get_numVelPtsLoc(get_localTurbNo(iTurbGlob)); } + //! Get the number of Actuator/force nodes on each blade in turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. int get_numForcePtsBlade(int iTurbGlob) { return get_numForcePtsBladeLoc(get_localTurbNo(iTurbGlob)); } + //! Get the number of Actuator/force nodes on the tower in turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. int get_numForcePtsTwr(int iTurbGlob) { return get_numForcePtsTwrLoc(get_localTurbNo(iTurbGlob)); } + //! Get the total number of Actuator/force nodes in turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. int get_numForcePts(int iTurbGlob) { return get_numForcePtsLoc(get_localTurbNo(iTurbGlob)); } - void computeTorqueThrust(int iTurGlob, std::vector & torque, std::vector & thrust); - + //! Compute the torque and thrust for turbine number 'iTurbGlob'. Must be called only from processor containing the turbine. + void computeTorqueThrust(int iTurGlob, double* torque, double* thrust, int nSize); inline - void getHubPos(std::vector & currentCoords, int iTurbGlob) { - getHubPos(currentCoords.data(), iTurbGlob, currentCoords.size()); + void getApproxHubPos(std::vector& currentCoords, int iTurbGlob) { + getApproxHubPos(currentCoords.data(), iTurbGlob, currentCoords.size()); } inline - void getApproxHubPos(std::vector& currentCoords, int iTurbGlob) { - getApproxHubPos(currentCoords.data(), iTurbGlob, currentCoords.size()); + void getHubPos(std::vector& currentCoords, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) { + getHubPos(currentCoords.data(), iTurbGlob, t, currentCoords.size()); } + inline - void getHubShftDir(std::vector & hubShftVec, int iTurbGlob) { - getHubShftDir(hubShftVec.data(), iTurbGlob, hubShftVec.size()); + void getHubShftDir(std::vector & hubShftVec, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) { + getHubShftDir(hubShftVec.data(), iTurbGlob, t, hubShftVec.size()); } inline - void getVelNodeCoordinates(std::vector & currentCoords, int iNode, int iTurbGlob) { - getVelNodeCoordinates(currentCoords.data(), iNode, iTurbGlob, currentCoords.size()); + void getVelNodeCoordinates(std::vector & currentCoords, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) { + getVelNodeCoordinates(currentCoords.data(), iNode, iTurbGlob, t, currentCoords.size()); } inline void setVelocity(std::vector & currentVelocity, int iNode, int iTurbGlob) { - setVelocity(currentVelocity.data(), iNode, iTurbGlob, currentVelocity.size()); + setVelocity(currentVelocity.data(), iNode, iTurbGlob, currentVelocity.size()); } inline void setVelocityForceNode(std::vector & currentVelocity, int iNode, int iTurbGlob) { - setVelocityForceNode(currentVelocity.data(), iNode, iTurbGlob, currentVelocity.size()); + setVelocityForceNode(currentVelocity.data(), iNode, iTurbGlob, currentVelocity.size()); } inline - void getForceNodeCoordinates(std::vector & currentCoords, int iNode, int iTurbGlob) { - getForceNodeCoordinates(currentCoords.data(), iNode, iTurbGlob, currentCoords.size()); + void getForceNodeCoordinates(std::vector & currentCoords, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) { + getForceNodeCoordinates(currentCoords.data(), iNode, iTurbGlob, t, currentCoords.size()); } inline - void getForceNodeOrientation(std::vector & currentOrientation, int iNode, int iTurbGlob) { - getForceNodeOrientation(currentOrientation.data(), iNode, iTurbGlob, currentOrientation.size()); + void getForceNodeOrientation(std::vector & currentOrientation, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) { + getForceNodeOrientation(currentOrientation.data(), iNode, iTurbGlob, t, currentOrientation.size()); } inline - void getForce(std::vector & currentForce, int iNode, int iTurbGlob) { - getForce(currentForce.data(), iNode, iTurbGlob, currentForce.size()); + void getForce(std::vector & currentForce, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) { + getForce(currentForce.data(), iNode, iTurbGlob, t, currentForce.size()); } inline - void getRelativeVelForceNode(std::vector & currentVelocity, int iNode, int iTurbGlob) { - getRelativeVelForceNode(currentVelocity.data(), iNode, iTurbGlob, currentVelocity.size()); + void getRelativeVelForceNode(std::vector & currentVelocity, int iNode, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) { + getRelativeVelForceNode(currentVelocity.data(), iNode, iTurbGlob, t, currentVelocity.size()); } - private: - + inline + void getBladeRefPositions(std::vector & bldRefPos, int iTurbGlob){ + getBladeRefPositions(bldRefPos.data(), nTurbinesGlob); + } + inline + void getBladeDisplacements(std::vector & bldDefl, std::vector & bldVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) + { + getBladeDisplacements(bldDefl.data(), bldVel.data(), iTurbGlob, t, bldDefl.size()); + } + inline + void getBladeRootRefPositions(std::vector & bldRootRefPos, int iTurbGlob){ + getBladeRootRefPositions(bldRootRefPos.data(), iTurbGlob); + } + void getBladeRootDisplacements(std::vector & bldRootDefl, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) + { + getBladeRootDisplacements(bldRootDefl.data(), iTurbGlob, t, bldRootDefl.size()); + } + inline + void getBladePitch(std::vector & bldPitch, int iTurbGlob) + { + getBladePitch(bldPitch.data(), iTurbGlob, bldPitch.size()); + } + inline + void getTowerRefPositions(std::vector & twrRefPos, int iTurbGlob) + { + getTowerRefPositions(twrRefPos.data(), iTurbGlob, 6); + } + inline + void getTowerDisplacements(std::vector & twrDefl, std::vector & twrVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) + { + getTowerDisplacements(twrDefl.data(), twrVel.data(), iTurbGlob, t, twrDefl.size()); + } + inline + void getHubRefPosition(std::vector & hubRefPos, int iTurbGlob) + { + getHubRefPosition(hubRefPos.data(), iTurbGlob, hubRefPos.size()); + } + inline + void getHubDisplacement(std::vector & hubDefl, std::vector & hubVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) + { + getHubDisplacement(hubDefl.data(), hubVel.data(), iTurbGlob, t, hubDefl.size()); + } + inline + void getNacelleRefPosition(std::vector & nacRefPos, int iTurbGlob) + { + getNacelleRefPosition(nacRefPos.data(), iTurbGlob, nacRefPos.size()); + } + inline + void getNacelleDisplacement(std::vector & nacDefl, std::vector & nacVel, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) + { + getNacelleDisplacement(nacDefl.data(), nacVel.data(), iTurbGlob, t, nacDefl.size()); + } + + inline + void setBladeForces(std::vector & bldForce, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) + { + setBladeForces(bldForce.data(), iTurbGlob, t, 6); + } + inline + void setTowerForces(std::vector & twrForce, int iTurbGlob, fast::timeStep t = fast::STATE_NP1) + { + setTowerForces(twrForce.data(), iTurbGlob, t, 6); + } + inline + void computeTorqueThrust(int iTurbGlob, std::vector & torque, std::vector & thrust) + { + computeTorqueThrust(iTurbGlob, torque.data(), thrust.data(), torque.size()); + } + + //! An example function to set velocities at the Aerodyn nodes using a power law wind profile using an exponent of 0.2 and a reference wind speed of 10 m/s at 90 meters. Safe to call from every MPI rank. + void setExpLawWindSpeed(double t) ; // An example to set velocities at the Aerodyn nodes + + //! An example function to set a uniform X force at all blade nodes. Safe to call from every MPI rank. + void setUniformXBladeForces(double loadX); + + +private: + + //! Set state from another state + void set_state_from_state(fast::timeStep fromState, fast::timeStep toState); + + //! Preprare the C+++ output file for a new OpenFAST simulation + void prepareOutputFile(int iTurbLoc); + //! Find the C++ output file for a restarted simulation + void findOutputFile(int iTurbLoc); + //! Write output data to file + void writeOutputFile(int iTurbLoc, int n_t_global); + + //! Find the OpenFAST restart file from the C++ restart file for a restarted simulation + void findRestartFile(int iTurbLoc); + //! Preprare the C+++ restart file for a new OpenFAST simulation + void prepareRestartFile(int iTurbLoc); + + //! Read velocity and force node data at time step 'n', 'n-1' and 'n-2' to allow for a clean restart + void readRestartFile(int iTurbLoc, int n_t_global); + //! Write velocity and force node data at time step 'n', 'n-1' and 'n-2' to allow for a clean restart + void writeRestartFile(int iTurbLoc, int n_t_global); + + //! Create velocity data file in preparation to write velocity data + void prepareVelocityDataFile(int iTurb); + //! Open velocity data file to read velocity data + int openVelocityDataFile(int iTurb); + //! Read the number of nonlinear iterations for a given driver time step + int read_nlin_iters(int iTurb, int iTimestep, int ncid); + //! Read velocity data at the Aerodyn nodes from velocity data file + void readVelocityData(int iTurb, int iTimestep, int iNlinIter, int ncid); + //! Write velocity data at the Aerodyn nodes from velocity data file + void writeVelocityData(int iTurb, int iTimestep, int nlinIter); + + //! Check whether the error status is ok. If not quit gracefully by printing the error message void checkError(const int ErrStat, const char * ErrMsg); + //! Check whether a file with name "name" exists inline bool checkFileExists(const std::string& name); - void allocateMemory(); - - float get_nacelleCdLoc(int iTurbLoc) { return nacelle_cd[iTurbLoc]; } - float get_nacelleAreaLoc(int iTurbLoc) { return nacelle_area[iTurbLoc]; } - float get_airDensityLoc(int iTurbLoc) { return air_density[iTurbLoc]; } - int get_numBladesLoc(int iTurbLoc) { return numBlades[iTurbLoc]; } - int get_numVelPtsBladeLoc(int iTurbLoc) { return numVelPtsBlade[iTurbLoc]; } - int get_numVelPtsTwrLoc(int iTurbLoc) { return numVelPtsTwr[iTurbLoc]; } - int get_numVelPtsLoc(int iTurbLoc) { return 1 + numBlades[iTurbLoc]*numVelPtsBlade[iTurbLoc] + numVelPtsTwr[iTurbLoc]; } - int get_numForcePtsBladeLoc(int iTurbLoc) { return numForcePtsBlade[iTurbLoc]; } - int get_numForcePtsTwrLoc(int iTurbLoc) { return numForcePtsTwr[iTurbLoc]; } - int get_numForcePtsLoc(int iTurbLoc) { return 1 + numBlades[iTurbLoc]*numForcePtsBlade[iTurbLoc] + numForcePtsTwr[iTurbLoc]; } + //! Allocate memory for data structures for all turbines on this processor + void allocateMemory_preInit(); + //! Allocate more memory for each turbine after intialization/restart + void allocateMemory_postInit(int iTurbLoc); + + //! Get the nacelle drag coefficient of local turbine number 'iTurbLoc' + float get_nacelleCdLoc(int iTurbLoc) { return turbineData[iTurbLoc].nacelle_cd; } + //! Get the nacelle area of local turbine number 'iTurbLoc' + float get_nacelleAreaLoc(int iTurbLoc) { return turbineData[iTurbLoc].nacelle_area; } + //! Get the air density around local turbine number 'iTurbLoc' + float get_airDensityLoc(int iTurbLoc) { return turbineData[iTurbLoc].air_density; } + + //! Get the number of blades in local turbine number 'iTurbLoc' + int get_numBladesLoc(int iTurbLoc) { return turbineData[iTurbLoc].numBlades; } + //! Get the number of Aerodyn/velocity nodes on each blade in local turbine number 'iTurbLoc' + int get_numVelPtsBladeLoc(int iTurbLoc) { return turbineData[iTurbLoc].numVelPtsBlade; } + //! Get the number of Aerodyn/velocity nodes on the tower in local turbine number 'iTurbLoc' + int get_numVelPtsTwrLoc(int iTurbLoc) { return turbineData[iTurbLoc].numVelPtsTwr; } + //! Get the total number of Aerodyn/velocity nodes in local turbine number 'iTurbLoc' + int get_numVelPtsLoc(int iTurbLoc) { return turbineData[iTurbLoc].numVelPts; } + //! Get the number of Actuator/force nodes on each blade in local turbine number 'iTurbLoc' + int get_numForcePtsBladeLoc(int iTurbLoc) { return turbineData[iTurbLoc].numForcePtsBlade; } + //! Get the number of Actuator/force nodes on the tower in local turbine number 'iTurbLoc' + int get_numForcePtsTwrLoc(int iTurbLoc) { return turbineData[iTurbLoc].numForcePtsTwr; } + //! Get the total number of Actuator/force nodes in local turbine number 'iTurbLoc' + int get_numForcePtsLoc(int iTurbLoc) { return turbineData[iTurbLoc].numForcePts; } + + //! Get reference positions of blade-resolved FSI nodes from OpenFAST + void get_ref_positions_from_openfast(int iTurb); void loadSuperController(const fastInputs & fi); - void setOutputsToFAST(OpFM_InputType_t cDriver_Input_from_FAST, OpFM_OutputType_t cDriver_Output_to_FAST) ; // An example to set velocities at the Aerodyn nodes - void applyVelocityData(int iPrestart, int iTurb, OpFM_OutputType_t cDriver_Output_to_FAST, std::vector & velData) ; + //! Apply the velocity data at the Aerodyn nodes in 'velData' to turbine number 'iTurb' at time step 'iPrestart' through the data structure 'cDriver_Output_to_FAST' + void applyVelocityData(int iPrestart, int iTurb, ExtInfw_OutputType_t o_t_FAST, std::vector & velData) ; + + //! Compute cross product a x b and store it into aCrossB + void cross(double * a, double * b, double * aCrossB); + //! Apply a Wiener-Milenkovic rotation 'wm' to a vector 'r' into 'rRot'. To optionally transpose the rotation, set 'tranpose=-1.0'. + void applyWMrotation(double * wm, double * r, double *rRot, double transpose = 1.0); + //! Apply a Direction Cosine Matrix rotation 'dcm' to a vector 'r' into 'rRot'. To optionally transpose the rotation, set 'tranpose=-1.0'. + void applyDCMrotation(double * dcm, double * r, double *rRot, double transpose = 1.0); }; diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 7a26e2017d..308506a78c 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -1,54 +1,632 @@ #include "OpenFAST.H" #include +#include #include +#include #include #include #include +#include + +inline void check_nc_error(int code, std::string msg) { + if (code != 0) + throw std::runtime_error("OpenFAST C++ API:: NetCDF error: " + msg); +} int fast::OpenFAST::AbortErrLev = ErrID_Fatal; // abort error level; compare with NWTC Library //Constructor fast::fastInputs::fastInputs(): -nTurbinesGlob(0), -dryRun(false), -debug(false), -tStart(-1.0), -nEveryCheckPoint(-1), -tMax(0.0), -dtFAST(0.0), -scStatus(false), -scLibFile("") + nTurbinesGlob(0), + dryRun(false), + debug(false), + tStart(-1.0), + restartFreq(-1), + tMax(0.0), + dtDriver(0.0), + scStatus(false), + scLibFile("") { - //Nothing to do here + //Nothing to do here } +//Constructor +fast::OpenFAST::OpenFAST() +{ + sc = std::unique_ptr(new SuperController); + ncRstVarNames_ = {"time", "rst_filename", "twr_ref_pos", "bld_ref_pos", "nac_ref_pos", "hub_ref_pos", "twr_def", "twr_vel", "twr_ld", "bld_def", "bld_vel", "bld_ld", "hub_def", "hub_vel", "nac_def", "nac_vel", "bld_root_def", "bld_pitch", "x_vel", "xdot_vel", "vel_vel", "x_force", "xdot_force", "orient_force", "vel_force", "force"}; + ncRstDimNames_ = {"n_tsteps", "n_states", "n_twr_data", "n_bld_data", "n_pt_data", "n_bld_root_data", "n_bld_pitch_data", "n_vel_pts_data", "n_force_pts_data", "n_force_pts_orient_data"}; - - -//Constructor -fast::OpenFAST::OpenFAST(): -nTurbinesGlob(0), -nTurbinesProc(0), -scStatus(false), -simStart(fast::init), -timeZero(false) -{ + ncOutVarNames_ = {"time", "twr_ref_pos", "twr_ref_orient", "bld_chord", "bld_rloc", "bld_ref_pos", "bld_ref_orient", "hub_ref_pos", "hub_ref_orient", "nac_ref_pos", "nac_ref_orient", "twr_disp", "twr_orient", "twr_vel", "twr_rotvel", "twr_ld", "twr_moment", "bld_disp", "bld_orient", "bld_vel", "bld_rotvel", "bld_ld", "bld_ld_loc", "bld_moment", "hub_disp", "hub_orient", "hub_vel", "hub_rotvel", "nac_disp", "nac_orient", "nac_vel", "nac_rotvel", "bld_root_ref_pos", "bld_root_ref_orient", "bld_root_disp", "bld_root_orient"}; + ncOutDimNames_ = {"n_tsteps", "n_dim", "n_twr_nds", "n_blds", "n_bld_nds"}; } -fast::OpenFAST::~OpenFAST(){ } - inline bool fast::OpenFAST::checkFileExists(const std::string& name) { struct stat buffer; return (stat (name.c_str(), &buffer) == 0); } +void fast::OpenFAST::findRestartFile(int iTurbLoc) { + + int ncid; + size_t n_tsteps; + size_t count1 = 1; + double latest_time; + + //Find the file and open it in read only mode + std::stringstream rstfile_ss; + rstfile_ss << "turb_" ; + rstfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; + rstfile_ss << "_rst.nc"; + std::string rst_filename = rstfile_ss.str(); + int ierr = nc_open(rst_filename.c_str(), NC_NOWRITE, &ncid); + check_nc_error(ierr, "nc_open"); + + + for (auto const& dim_name: ncRstDimNames_) { + int tmpDimID; + ierr = nc_inq_dimid(ncid, dim_name.data(), &tmpDimID); + if (ierr == NC_NOERR) + ncRstDimIDs_[dim_name] = tmpDimID; + } + + for (auto const& var_name: ncRstVarNames_) { + int tmpVarID; + ierr = nc_inq_varid(ncid, var_name.data(), &tmpVarID); + if (ierr == NC_NOERR) + ncRstVarIDs_[var_name] = tmpVarID; + } + + ierr = nc_inq_dimlen(ncid, ncRstDimIDs_["n_tsteps"], &n_tsteps); + check_nc_error(ierr, "nc_inq_dimlen"); + n_tsteps -= 1; //To account for 0 based indexing + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["time"], &n_tsteps, &count1, &latest_time); + check_nc_error(ierr, "nc_get_vara_double - getting latest time"); + tStart = latest_time; + + char tmpOutFileRoot[INTERFACE_STRING_LENGTH]; + ierr = nc_get_att_text(ncid, NC_GLOBAL, "out_file_root", tmpOutFileRoot); + turbineData[iTurbLoc].outFileRoot.assign(tmpOutFileRoot); + + ierr = nc_get_att_double(ncid, NC_GLOBAL, "dt_fast", &dtFAST); + check_nc_error(ierr, "nc_get_att_double"); + + ierr = nc_get_att_double(ncid, NC_GLOBAL, "dt_driver", &dtDriver); + check_nc_error(ierr, "nc_get_att_double"); + + ierr = nc_get_att_int(ncid, NC_GLOBAL, "output_freq", &outputFreq_); + check_nc_error(ierr, "nc_get_att_int"); + + ierr = nc_get_att_int(ncid, NC_GLOBAL, "restart_freq", &restartFreq_); + check_nc_error(ierr, "nc_get_att_int"); + + int tstep = std::round(latest_time/dtFAST); + + std::stringstream rstfilename; + rstfilename << turbineData[iTurbLoc].outFileRoot << "." << tstep ; + turbineData[iTurbLoc].FASTRestartFileName = rstfilename.str(); + + std::cout << "Restarting from time " << latest_time << " at time step " << tstep << " from file name " << turbineData[iTurbLoc].FASTRestartFileName << std::endl ; + + nc_close(ncid); + +} + +void fast::OpenFAST::prepareRestartFile(int iTurbLoc) { + + int ncid; + //This will destroy any existing file + std::stringstream rstfile_ss; + rstfile_ss << "turb_" ; + rstfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; + rstfile_ss << "_rst.nc"; + std::string rst_filename = rstfile_ss.str(); + int ierr = nc_create(rst_filename.c_str(), NC_CLOBBER, &ncid); + check_nc_error(ierr, "nc_create"); + + nc_put_att_text(ncid, NC_GLOBAL, "out_file_root", turbineData[iTurbLoc].outFileRoot.size()+1, turbineData[iTurbLoc].outFileRoot.c_str()); + nc_put_att_double(ncid, NC_GLOBAL, "dt_fast", NC_DOUBLE, 1, &dtFAST); + nc_put_att_double(ncid, NC_GLOBAL, "dt_driver", NC_DOUBLE, 1, &dtDriver); + nc_put_att_int(ncid,NC_GLOBAL,"output_freq", NC_INT, 1, &outputFreq_); + nc_put_att_int(ncid,NC_GLOBAL,"restart_freq", NC_INT, 1, &restartFreq_); + + //Define dimensions + int tmpDimID; + ierr = nc_def_dim(ncid, "n_tsteps", NC_UNLIMITED, &tmpDimID); + ncRstDimIDs_["n_tsteps"] = tmpDimID; + ierr = nc_def_dim(ncid, "n_states", 4, &tmpDimID); + ncRstDimIDs_["n_states"] = tmpDimID; + + //Define variables + int tmpVarID; + ierr = nc_def_var(ncid, "time", NC_DOUBLE, 1, &ncRstDimIDs_["n_tsteps"], &tmpVarID); + ncRstVarIDs_["time"] = tmpVarID; + + if (turbineData[iTurbLoc].sType == EXTLOADS) { + + ierr = nc_def_dim(ncid, "n_twr_data", turbineData[iTurbLoc].nBRfsiPtsTwr*6, &tmpDimID); + ncRstDimIDs_["n_twr_data"] = tmpDimID; + ierr = nc_def_dim(ncid,"n_bld_data", turbineData[iTurbLoc].nTotBRfsiPtsBlade*6, &tmpDimID); + ncRstDimIDs_["n_bld_data"] = tmpDimID; + ierr = nc_def_dim(ncid,"n_bld_root_data", turbineData[iTurbLoc].numBlades*6, &tmpDimID); + ncRstDimIDs_["n_bld_root_data"] = tmpDimID; + ierr = nc_def_dim(ncid,"n_bld_pitch_data", turbineData[iTurbLoc].numBlades, &tmpDimID); + ncRstDimIDs_["n_bld_pitch_data"] = tmpDimID; + ierr = nc_def_dim(ncid,"n_pt_data", 6, &tmpDimID); + ncRstDimIDs_["n_pt_data"] = tmpDimID; + + const std::vector twrDefLoadsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_twr_data"]}; + const std::vector bldDefLoadsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_bld_data"]}; + const std::vector bldRootDefsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_bld_root_data"]}; + const std::vector bldPitchDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_bld_pitch_data"]}; + const std::vector ptDefLoadsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_pt_data"],}; + + ierr = nc_def_var(ncid, "twr_def", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["twr_def"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_vel", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["twr_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_ld", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["twr_ld"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_def", NC_DOUBLE, 3, bldDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["bld_def"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_vel", NC_DOUBLE, 3, bldDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["bld_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_ld", NC_DOUBLE, 3, bldDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["bld_ld"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_def", NC_DOUBLE, 3, ptDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["hub_def"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_vel", NC_DOUBLE, 3, ptDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["hub_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_def", NC_DOUBLE, 3, ptDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["nac_def"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_vel", NC_DOUBLE, 3, ptDefLoadsDims.data(), &tmpVarID); + ncRstVarIDs_["nac_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_root_def", NC_DOUBLE, 3, bldRootDefsDims.data(), &tmpVarID); + ncRstVarIDs_["bld_root_def"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_pitch", NC_DOUBLE, 3, bldPitchDims.data(), &tmpVarID); + ncRstVarIDs_["bld_pitch"] = tmpVarID; + + } else if (turbineData[iTurbLoc].sType == EXTINFLOW) { + + ierr = nc_def_dim(ncid, "n_vel_pts_data", turbineData[iTurbLoc].numVelPts*3, &tmpDimID); + ncRstDimIDs_["n_vel_pts_data"] = tmpDimID; + ierr = nc_def_dim(ncid, "n_force_pts_data", turbineData[iTurbLoc].numForcePts*3, &tmpDimID); + ncRstDimIDs_["n_force_pts_data"] = tmpDimID; + ierr = nc_def_dim(ncid, "n_force_pts_orient_data", turbineData[iTurbLoc].numForcePts*9, &tmpDimID); + ncRstDimIDs_["n_force_pts_orient_data"] = tmpDimID; + + const std::vector velPtsDataDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_vel_pts_data"]}; + const std::vector forcePtsDataDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_force_pts_data"],}; + const std::vector forcePtsOrientDataDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_force_pts_orient_data"],}; + + ierr = nc_def_var(ncid, "x_vel", NC_DOUBLE, 3, velPtsDataDims.data(), &tmpVarID); + ncRstVarIDs_["x_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "xdot_vel", NC_DOUBLE, 3, velPtsDataDims.data(), &tmpVarID); + ncRstVarIDs_["xdot_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "vel_vel", NC_DOUBLE, 3, velPtsDataDims.data(), &tmpVarID); + ncRstVarIDs_["vel_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "xref_force", NC_DOUBLE, 1, &ncRstDimIDs_["n_force_pts_data"], &tmpVarID); + ncRstVarIDs_["xref_force"] = tmpVarID; + ierr = nc_def_var(ncid, "x_force", NC_DOUBLE, 3, forcePtsDataDims.data(), &tmpVarID); + ncRstVarIDs_["x_force"] = tmpVarID; + ierr = nc_def_var(ncid, "xdot_force", NC_DOUBLE, 3, forcePtsDataDims.data(), &tmpVarID); + ncRstVarIDs_["xdot_force"] = tmpVarID; + ierr = nc_def_var(ncid, "vel_force", NC_DOUBLE, 3, forcePtsDataDims.data(), &tmpVarID); + ncRstVarIDs_["vel_force"] = tmpVarID; + ierr = nc_def_var(ncid, "force", NC_DOUBLE, 3, forcePtsDataDims.data(), &tmpVarID); + ncRstVarIDs_["force"] = tmpVarID; + ierr = nc_def_var(ncid, "orient_force", NC_DOUBLE, 3, forcePtsOrientDataDims.data(), &tmpVarID); + ncRstVarIDs_["orient_force"] = tmpVarID; + + } + + //! Indicate that we are done defining variables, ready to write data + ierr = nc_enddef(ncid); + check_nc_error(ierr, "nc_enddef"); + + if (turbineData[iTurbLoc].sType == EXTINFLOW) { + int nfpts_data = 3*get_numForcePtsLoc(iTurbLoc); + int ierr = nc_put_var_double(ncid, ncRstVarIDs_["xref_force"], velForceNodeData[iTurbLoc][fast::STATE_NP1].xref_force.data()); + } + + ierr = nc_close(ncid); + check_nc_error(ierr, "nc_close"); + + +} + +void fast::OpenFAST::findOutputFile(int iTurbLoc) { + + int ncid; + size_t n_tsteps; + size_t count1 = 1; + double latest_time; + + //Find the file and open it in read only mode + std::stringstream outfile_ss; + outfile_ss << "turb_" ; + outfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; + outfile_ss << "_output.nc"; + std::string out_filename = outfile_ss.str(); + int ierr = nc_open(out_filename.c_str(), NC_NOWRITE, &ncid); + check_nc_error(ierr, "nc_open"); + + + for (auto const& dim_name: ncOutDimNames_) { + int tmpDimID; + ierr = nc_inq_dimid(ncid, dim_name.data(), &tmpDimID); + if (ierr == NC_NOERR) + ncOutDimIDs_[dim_name] = tmpDimID; + } + + for (auto const& var_name: ncOutVarNames_) { + int tmpVarID; + ierr = nc_inq_varid(ncid, var_name.data(), &tmpVarID); + if (ierr == NC_NOERR) + ncOutVarIDs_[var_name] = tmpVarID; + } + + ierr = nc_inq_dimlen(ncid, ncOutDimIDs_["n_tsteps"], &n_tsteps); + check_nc_error(ierr, "nc_inq_dimlen"); + n_tsteps -= 1; //To account for 0 based indexing + ierr = nc_get_vara_double(ncid, ncOutVarIDs_["time"], &n_tsteps, &count1, &latest_time); + check_nc_error(ierr, "nc_get_vara_double - getting latest time"); + nc_close(ncid); + +} + +void fast::OpenFAST::prepareOutputFile(int iTurbLoc) { + + int ncid; + //Create the file - this will destory any file + std::stringstream defloads_fstream; + defloads_fstream << "turb_" ; + defloads_fstream << std::setfill('0') << std::setw(2) << iTurbLoc; + defloads_fstream << "_output.nc"; + std::string defloads_filename = defloads_fstream.str(); + int ierr = nc_create(defloads_filename.c_str(), NC_CLOBBER, &ncid); + check_nc_error(ierr, "nc_create"); + + //Define dimensions + int tmpDimID; + ierr = nc_def_dim(ncid, "n_dim", 3, &tmpDimID); + ncOutDimIDs_["n_dim"] = tmpDimID; + ierr = nc_def_dim(ncid, "n_tsteps", NC_UNLIMITED, &tmpDimID); + ncOutDimIDs_["n_tsteps"] = tmpDimID; + + //Now define variables + int tmpVarID; + ierr = nc_def_var(ncid, "time", NC_DOUBLE, 1, &ncOutDimIDs_["n_tsteps"], &tmpVarID); + ncOutVarIDs_["time"] = tmpVarID; + + if (turbineData[iTurbLoc].sType == EXTLOADS) { + + int nBlades = turbineData[iTurbLoc].numBlades; + int nTwrPts = turbineData[iTurbLoc].nBRfsiPtsTwr; + int nTotBldPts = turbineData[iTurbLoc].nTotBRfsiPtsBlade; + int nBldPts = nTotBldPts/nBlades; + + ierr = nc_def_dim(ncid, "n_twr_nds", nTwrPts, &tmpDimID); + ncOutDimIDs_["n_twr_nds"] = tmpDimID; + ierr = nc_def_dim(ncid,"n_blds", nBlades, &tmpDimID); + ncOutDimIDs_["n_blds"] = tmpDimID; + ierr = nc_def_dim(ncid, "n_bld_nds", nBldPts, &tmpDimID); + ncOutDimIDs_["n_bld_nds"] = tmpDimID; + + const std::vector twrRefDims{ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_twr_nds"]}; + const std::vector twrDefLoadsDims{ncOutDimIDs_["n_tsteps"], ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_twr_nds"]}; + const std::vector bldParamDims{ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_bld_nds"]}; + const std::vector bldRefDims{ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_bld_nds"]}; + const std::vector bldRootRefDims{ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_dim"]}; + const std::vector bldDefLoadsDims{ncOutDimIDs_["n_tsteps"], ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_bld_nds"]}; + const std::vector bldRootDefDims{ncOutDimIDs_["n_tsteps"], ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_dim"]}; + const std::vector ptRefDims{ncOutDimIDs_["n_dim"]}; + const std::vector ptDefLoadsDims{ncOutDimIDs_["n_tsteps"], ncOutDimIDs_["n_dim"]}; + + ierr = nc_def_var(ncid, "twr_ref_pos", NC_DOUBLE, 2, twrRefDims.data(), &tmpVarID); + ncOutVarIDs_["twr_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_ref_orient", NC_DOUBLE, 2, twrRefDims.data(), &tmpVarID); + ncOutVarIDs_["twr_ref_orient"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_chord", NC_DOUBLE, 2, bldParamDims.data(), &tmpVarID); + ncOutVarIDs_["bld_chord"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_rloc", NC_DOUBLE, 2, bldParamDims.data(), &tmpVarID); + ncOutVarIDs_["bld_rloc"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_ref_pos", NC_DOUBLE, 3, bldRefDims.data(), &tmpVarID); + ncOutVarIDs_["bld_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_ref_orient", NC_DOUBLE, 3, bldRefDims.data(), &tmpVarID); + ncOutVarIDs_["bld_ref_orient"] = tmpVarID; + + ierr = nc_def_var(ncid, "bld_root_ref_pos", NC_DOUBLE, 2, bldRootRefDims.data(), &tmpVarID); + ncOutVarIDs_["bld_root_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_root_ref_orient", NC_DOUBLE, 2, bldRootRefDims.data(), &tmpVarID); + ncOutVarIDs_["bld_root_ref_orient"] = tmpVarID; + + ierr = nc_def_var(ncid, "hub_ref_pos", NC_DOUBLE, 1, ptRefDims.data(), &tmpVarID); + ncOutVarIDs_["hub_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_ref_orient", NC_DOUBLE, 1, ptRefDims.data(), &tmpVarID); + ncOutVarIDs_["hub_ref_orient"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_ref_pos", NC_DOUBLE, 1, ptRefDims.data(), &tmpVarID); + ncOutVarIDs_["nac_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_ref_orient", NC_DOUBLE, 1, ptRefDims.data(), &tmpVarID); + ncOutVarIDs_["nac_ref_orient"] = tmpVarID; + + ierr = nc_def_var(ncid, "twr_disp", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["twr_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_orient", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["twr_orient"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_vel", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["twr_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_rotvel", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["twr_rotvel"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_ld", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["twr_ld"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_moment", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["twr_moment"] = tmpVarID; + + ierr = nc_def_var(ncid, "bld_disp", NC_DOUBLE, 4, bldDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["bld_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_orient", NC_DOUBLE, 4, bldDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["bld_orient"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_vel", NC_DOUBLE, 4, bldDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["bld_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_rotvel", NC_DOUBLE, 4, bldDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["bld_rotvel"] = tmpVarID; + + ierr = nc_def_var(ncid, "bld_root_disp", NC_DOUBLE, 3, bldRootDefDims.data(), &tmpVarID); + ncOutVarIDs_["bld_root_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_root_orient", NC_DOUBLE, 3, bldRootDefDims.data(), &tmpVarID); + ncOutVarIDs_["bld_root_orient"] = tmpVarID; + + ierr = nc_def_var(ncid, "bld_ld", NC_DOUBLE, 4, bldDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["bld_ld"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_ld_loc", NC_DOUBLE, 4, bldDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["bld_ld_loc"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_moment", NC_DOUBLE, 4, bldDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["bld_moment"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_disp", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["hub_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_orient", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["hub_orient"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_vel", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["hub_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_rotvel", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["hub_rotvel"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_disp", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["nac_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_orient", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["nac_orient"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_vel", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["nac_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_rotvel", NC_DOUBLE, 2, ptDefLoadsDims.data(), &tmpVarID); + ncOutVarIDs_["nac_rotvel"] = tmpVarID; + + } else if (turbineData[iTurbLoc].sType == EXTINFLOW) { + + int nBlades = get_numBladesLoc(iTurbLoc); + int nBldPts = get_numForcePtsBladeLoc(iTurbLoc); + int nTwrPts = get_numForcePtsTwrLoc(iTurbLoc); + + ierr = nc_def_dim(ncid, "n_twr_nds", nTwrPts, &tmpDimID); + ncOutDimIDs_["n_twr_nds"] = tmpDimID; + ierr = nc_def_dim(ncid,"n_blds", nBlades, &tmpDimID); + ncOutDimIDs_["n_blds"] = tmpDimID; + ierr = nc_def_dim(ncid, "n_bld_nds", nBldPts, &tmpDimID); + ncOutDimIDs_["n_bld_nds"] = tmpDimID; + + const std::vector twrRefDataDims{ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_twr_nds"]}; + const std::vector twrDataDims{ncOutDimIDs_["n_tsteps"], ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_twr_nds"]}; + const std::vector bldParamDims{ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_bld_nds"]}; + const std::vector bldRefDataDims{ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_bld_nds"]}; + const std::vector bldDataDims{ncOutDimIDs_["n_tsteps"], ncOutDimIDs_["n_blds"], ncOutDimIDs_["n_dim"], ncOutDimIDs_["n_bld_nds"]}; + const std::vector ptRefDataDims{ncOutDimIDs_["n_dim"]}; + const std::vector ptDataDims{ncOutDimIDs_["n_tsteps"], ncOutDimIDs_["n_dim"]}; + + ierr = nc_def_var(ncid, "bld_chord", NC_DOUBLE, 2, bldParamDims.data(), &tmpVarID); + ncOutVarIDs_["bld_chord"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_rloc", NC_DOUBLE, 2, bldParamDims.data(), &tmpVarID); + ncOutVarIDs_["bld_rloc"] = tmpVarID; + + ierr = nc_def_var(ncid, "twr_ref_pos", NC_DOUBLE, 2, twrRefDataDims.data(), &tmpVarID); + ncOutVarIDs_["twr_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_disp", NC_DOUBLE, 3, twrDataDims.data(), &tmpVarID); + ncOutVarIDs_["twr_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_vel", NC_DOUBLE, 3, twrDataDims.data(), &tmpVarID); + ncOutVarIDs_["twr_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "twr_ld", NC_DOUBLE, 3, twrDataDims.data(), &tmpVarID); + ncOutVarIDs_["twr_ld"] = tmpVarID; + + ierr = nc_def_var(ncid, "bld_ref_pos", NC_DOUBLE, 3, bldRefDataDims.data(), &tmpVarID); + ncOutVarIDs_["bld_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_disp", NC_DOUBLE, 4, bldDataDims.data(), &tmpVarID); + ncOutVarIDs_["bld_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_vel", NC_DOUBLE, 4, bldDataDims.data(), &tmpVarID); + ncOutVarIDs_["bld_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_ld", NC_DOUBLE, 4, bldDataDims.data(), &tmpVarID); + ncOutVarIDs_["bld_ld"] = tmpVarID; + ierr = nc_def_var(ncid, "bld_ld_loc", NC_DOUBLE, 4, bldDataDims.data(), &tmpVarID); + ncOutVarIDs_["bld_ld_loc"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_ref_pos", NC_DOUBLE, 2, ptRefDataDims.data(), &tmpVarID); + ncOutVarIDs_["hub_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_disp", NC_DOUBLE, 2, ptDataDims.data(), &tmpVarID); + ncOutVarIDs_["hub_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_vel", NC_DOUBLE, 2, ptDataDims.data(), &tmpVarID); + ncOutVarIDs_["hub_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "hub_rotvel", NC_DOUBLE, 2, ptDataDims.data(), &tmpVarID); + ncOutVarIDs_["hub_rotvel"] = tmpVarID; + + ierr = nc_def_var(ncid, "nac_ref_pos", NC_DOUBLE, 2, ptRefDataDims.data(), &tmpVarID); + ncOutVarIDs_["nac_ref_pos"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_disp", NC_DOUBLE, 2, ptDataDims.data(), &tmpVarID); + ncOutVarIDs_["nac_disp"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_vel", NC_DOUBLE, 2, ptDataDims.data(), &tmpVarID); + ncOutVarIDs_["nac_vel"] = tmpVarID; + ierr = nc_def_var(ncid, "nac_rotvel", NC_DOUBLE, 2, ptDataDims.data(), &tmpVarID); + ncOutVarIDs_["nac_rotvel"] = tmpVarID; + + } + + //! Indicate that we are done defining variables, ready to write data + ierr = nc_enddef(ncid); + check_nc_error(ierr, "nc_enddef"); + + if (turbineData[iTurbLoc].sType == EXTLOADS) { + + int nBlades = turbineData[iTurbLoc].numBlades; + int nTwrPts = turbineData[iTurbLoc].nBRfsiPtsTwr; + int nTotBldPts = turbineData[iTurbLoc].nTotBRfsiPtsBlade; + int nBldPts = nTotBldPts/nBlades; + + std::vector tmpArray; + + tmpArray.resize(nTwrPts); + { + std::vector count_dim{1,static_cast(nTwrPts)}; + for (size_t idim=0;idim < 3; idim++) { + for (size_t i=0; i < nTwrPts; i++) + tmpArray[i] = brFSIData[iTurbLoc][3].twr_ref_pos[i*6+idim]; + std::vector start_dim{idim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_ref_pos"], start_dim.data(), + count_dim.data(), tmpArray.data()); + } + for (size_t idim=0;idim < 3; idim++) { + for (size_t i=0; i < nTwrPts; i++) + tmpArray[i] = brFSIData[iTurbLoc][3].twr_ref_pos[i*6+3+idim]; + std::vector start_dim{idim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_ref_orient"], start_dim.data(), + count_dim.data(), tmpArray.data()); + } + } + + tmpArray.resize(nBldPts); + { + std::vector count_dim{1,1,static_cast(nBldPts)}; + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_ref_pos[(iStart*6)+iDim]; + iStart++; + } + std::vector start_dim{iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_ref_pos"], start_dim.data(), + count_dim.data(), tmpArray.data()); + } + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_ref_pos[(iStart*6)+iDim+3]; + iStart++; + } + std::vector start_dim{iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_ref_orient"], start_dim.data(), + count_dim.data(), tmpArray.data()); + } + } + + std::vector param_count_dim{1,static_cast(nBldPts)}; + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (size_t i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_chord[iStart]; + iStart++; + } + std::vector start_dim{iBlade,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_chord"], start_dim.data(), + param_count_dim.data(), tmpArray.data()); + } + iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (size_t i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_rloc[iStart]; + iStart++; + } + std::vector start_dim{iBlade,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_rloc"], start_dim.data(), + param_count_dim.data(), tmpArray.data()); + } + } + + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + std::vector start_dim{iBlade,0}; + std::vector count_dim{1,3}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_root_ref_pos"], + start_dim.data(), + count_dim.data(), + &brFSIData[iTurbLoc][3].bld_root_ref_pos[iBlade*6+0]); + + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_root_ref_orient"], + start_dim.data(), + count_dim.data(), + &brFSIData[iTurbLoc][3].bld_root_ref_pos[iBlade*6+3]); + } + + ierr = nc_put_var_double(ncid, ncOutVarIDs_["nac_ref_pos"], + &brFSIData[iTurbLoc][3].nac_ref_pos[0]); + ierr = nc_put_var_double(ncid, ncOutVarIDs_["nac_ref_orient"], + &brFSIData[iTurbLoc][3].nac_ref_pos[3]); + + ierr = nc_put_var_double(ncid, ncOutVarIDs_["hub_ref_pos"], + &brFSIData[iTurbLoc][3].hub_ref_pos[0]); + ierr = nc_put_var_double(ncid, ncOutVarIDs_["hub_ref_orient"], + &brFSIData[iTurbLoc][3].hub_ref_pos[3]); + + } else if (turbineData[iTurbLoc].sType == EXTINFLOW) { + + int nBlades = get_numBladesLoc(iTurbLoc); + int nBldPts = get_numForcePtsBladeLoc(iTurbLoc); + int nTwrPts = get_numForcePtsTwrLoc(iTurbLoc); + + std::vector tmpArray; + + { + + tmpArray.resize(nBldPts); + std::vector count_dim{1,1,static_cast(nBldPts)}; + for (size_t iDim=0;iDim < 3; iDim++) { + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + int node_bld_start = (1 + iBlade * nBldPts); + for (auto i=0; i < nBldPts; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].x_force[(node_bld_start+i)*3+iDim] ; + std::vector start_dim{iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_ref_pos"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + + std::vector param_count_dim{1,static_cast(nBldPts)}; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + int iStart = 1 + iBlade*nBldPts; + for (size_t i=0; i < nBldPts; i++) + tmpArray[i] = extinfw_i_f_FAST[iTurbLoc].forceNodesChord[iStart+i]; + std::vector start_dim{iBlade,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_chord"], start_dim.data(), + param_count_dim.data(), tmpArray.data()); + } + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + int iStart = 1 + iBlade*nBldPts; + for (size_t i=0; i < nBldPts; i++) + tmpArray[i] = extinfw_i_f_FAST[iTurbLoc].forceRHloc[iStart+i]; + std::vector start_dim{iBlade,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_rloc"], start_dim.data(), + param_count_dim.data(), tmpArray.data()); + } + } + } + + ierr = nc_close(ncid); + check_nc_error(ierr, "nc_close"); + +} + + void fast::OpenFAST::init() { - // Temporary buffer to pass filenames to OpenFAST fortran subroutines - char currentFileName[INTERFACE_STRING_LENGTH]; + // Temporary buffer to pass filenames to OpenFAST fortran subroutines + char currentFileName[INTERFACE_STRING_LENGTH]; - allocateMemory(); + allocateMemory_preInit(); if (!dryRun) { switch (simStart) { @@ -56,36 +634,31 @@ void fast::OpenFAST::init() { case fast::trueRestart: for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - /* note that this will set nt_global inside the FAST library */ - std::copy( - CheckpointFileRoot[iTurb].data(), - CheckpointFileRoot[iTurb].data() + (CheckpointFileRoot[iTurb].size() + 1), - currentFileName - ); - FAST_OpFM_Restart( - &iTurb, - currentFileName, - &AbortErrLev, - &dtFAST, - &numBlades[iTurb], - &numVelPtsBlade[iTurb], - &ntStart, - &cDriver_Input_from_FAST[iTurb], - &cDriver_Output_to_FAST[iTurb], - &sc.ip_from_FAST[iTurb], - &sc.op_to_FAST[iTurb], - &ErrStat, - ErrMsg - ); - checkError(ErrStat, ErrMsg); + + findRestartFile(iTurb); + findOutputFile(iTurb); + char tmpRstFileRoot[INTERFACE_STRING_LENGTH]; + strncpy(tmpRstFileRoot, turbineData[iTurb].FASTRestartFileName.c_str(), turbineData[iTurb].FASTRestartFileName.size()); + tmpRstFileRoot[turbineData[iTurb].FASTRestartFileName.size()] = '\0'; + if (turbineData[iTurb].sType == EXTINFLOW) { + /* note that this will set nt_global inside the FAST library */ + FAST_AL_CFD_Restart(&iTurb, tmpRstFileRoot, &AbortErrLev, &turbineData[iTurb].dt, &turbineData[iTurb].inflowType, &turbineData[iTurb].numBlades, &turbineData[iTurb].numVelPtsBlade, &turbineData[iTurb].numVelPtsTwr, &ntStart, &extinfw_i_f_FAST[iTurb], &extinfw_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + + } else if(turbineData[iTurb].sType == EXTLOADS) { + FAST_BR_CFD_Restart(&iTurb, tmpRstFileRoot, &AbortErrLev, &turbineData[iTurb].dt, &turbineData[iTurb].numBlades, &ntStart, &extld_i_f_FAST[iTurb], &extld_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + turbineData[iTurb].inflowType = 0; + } + nt_global = ntStart; + allocateMemory_postInit(iTurb); - int nfpts = get_numForcePtsLoc(iTurb); - forceNodeVel[iTurb].resize(nfpts); - for (int k = 0; k < nfpts; k++) forceNodeVel[iTurb][k].resize(3) ; - } + get_ref_positions_from_openfast(iTurb); + + readRestartFile(iTurb, nt_global); - if (nTurbinesProc > 0) velNodeDataFile = openVelocityDataFile(false); + } + checkAndSetSubsteps(); if(scStatus) { std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; @@ -96,373 +669,796 @@ void fast::OpenFAST::init() { case fast::init: - sc.init(scio, nTurbinesProc); + sc->init(scio, nTurbinesProc); if(scStatus) { std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; // sc.init_sc(scio, nTurbinesProc, turbineMapProcToGlob, fastMPIComm); // sc.calcOutputs_n(0.0); - } - - // this calls the Init() routines of each module + } // this calls the Init() routines of each module for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - int nodeClusterType = 0; - if (forcePtsBladeDistributionType[iTurb] == "chordClustered") - { - nodeClusterType = 1; - } - std::copy( - FASTInputFileName[iTurb].data(), - FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), - currentFileName - ); - FAST_OpFM_Init( - &iTurb, - &tMax, - currentFileName, - &TurbID[iTurb], - &scio.nSC2CtrlGlob, - &scio.nSC2Ctrl, - &scio.nCtrl2SC, - scio.from_SCglob.data(), - scio.from_SC[iTurb].data(), - &numForcePtsBlade[iTurb], - &numForcePtsTwr[iTurb], - TurbineBasePos[iTurb].data(), - &AbortErrLev, - &dtFAST, - &numBlades[iTurb], - &numVelPtsBlade[iTurb], - &nodeClusterType, - &cDriver_Input_from_FAST[iTurb], - &cDriver_Output_to_FAST[iTurb], - &sc.ip_from_FAST[iTurb], - &sc.op_to_FAST[iTurb], - &ErrStat, - ErrMsg - ); - checkError(ErrStat, ErrMsg); - timeZero = true; + char tmpOutFileRoot[INTERFACE_STRING_LENGTH]; + if (turbineData[iTurb].sType == EXTINFLOW) { + + std::copy( + turbineData[iTurb].FASTInputFileName.data(), + turbineData[iTurb].FASTInputFileName.data() + (turbineData[iTurb].FASTInputFileName.size() + 1), + currentFileName + ); + FAST_AL_CFD_Init( &iTurb, &tMax, turbineData[iTurb].FASTInputFileName.data(), &turbineData[iTurb].TurbID, tmpOutFileRoot, &scio.nSC2CtrlGlob, &scio.nSC2Ctrl, &scio.nCtrl2SC, scio.from_SCglob.data(), scio.from_SC[iTurb].data(), &turbineData[iTurb].numForcePtsBlade, &turbineData[iTurb].numForcePtsTwr, turbineData[iTurb].TurbineBasePos.data(), &AbortErrLev, &dtDriver, &turbineData[iTurb].dt, &turbineData[iTurb].inflowType, &turbineData[iTurb].numBlades, &turbineData[iTurb].numVelPtsBlade, &turbineData[iTurb].numVelPtsTwr, &extinfw_i_f_FAST[iTurb], &extinfw_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + + turbineData[iTurb].numVelPtsTwr = extinfw_o_t_FAST[iTurb].u_Len - turbineData[iTurb].numBlades*turbineData[iTurb].numVelPtsBlade - 1; + if(turbineData[iTurb].numVelPtsTwr == 0) { + turbineData[iTurb].numForcePtsTwr = 0; + std::cout << "Aerodyn doesn't want to calculate forces on the tower. All actuator points on the tower are turned off for turbine " << turbineMapProcToGlob[iTurb] << "." << std::endl ; + } - numVelPtsTwr[iTurb] = cDriver_Output_to_FAST[iTurb].u_Len - numBlades[iTurb]*numVelPtsBlade[iTurb] - 1; - if(numVelPtsTwr[iTurb] == 0) { - numForcePtsTwr[iTurb] = 0; - std::cout << "Aerodyn doesn't want to calculate forces on the tower. All actuator points on the tower are turned off for turbine " << turbineMapProcToGlob[iTurb] << "." << std::endl ; - } + } else if(turbineData[iTurb].sType == EXTLOADS) { - int nfpts = get_numForcePtsLoc(iTurb); - forceNodeVel[iTurb].resize(nfpts); - for (int k = 0; k < nfpts; k++) forceNodeVel[iTurb][k].resize(3) ; + FAST_BR_CFD_Init(&iTurb, &tMax, turbineData[iTurb].FASTInputFileName.data(), &turbineData[iTurb].TurbID, tmpOutFileRoot, turbineData[iTurb].TurbineBasePos.data(), &AbortErrLev, &dtDriver, &turbineData[iTurb].dt, &turbineData[iTurb].numBlades, &turbineData[iTurb].azBlendMean, &turbineData[iTurb].azBlendDelta, &turbineData[iTurb].velMean, &turbineData[iTurb].windDir, &turbineData[iTurb].zRef, &turbineData[iTurb].shearExp, &extld_i_f_FAST[iTurb], &extld_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + + turbineData[iTurb].inflowType = 0; - if ( isDebug() ) { - for (int iNode=0; iNode < get_numVelPtsLoc(iTurb); iNode++) { - std::cout << "Node " << iNode << " Position = " << cDriver_Input_from_FAST[iTurb].pxVel[iNode] << " " << cDriver_Input_from_FAST[iTurb].pyVel[iNode] << " " << cDriver_Input_from_FAST[iTurb].pzVel[iNode] << " " << std::endl ; - } } - } + timeZero = true; + + turbineData[iTurb].outFileRoot.assign(tmpOutFileRoot, strlen(tmpOutFileRoot)); + + allocateMemory_postInit(iTurb); - if (nTurbinesProc > 0) velNodeDataFile = openVelocityDataFile(true); + get_data_from_openfast(fast::STATE_NM2); + get_data_from_openfast(fast::STATE_NM1); + get_data_from_openfast(fast::STATE_N); + get_data_from_openfast(fast::STATE_NP1); + + get_ref_positions_from_openfast(iTurb); + + } + timeZero = true; + checkAndSetSubsteps(); break ; case fast::restartDriverInitFAST: - sc.init(scio, nTurbinesProc); + //sc->init(scio, nTurbinesProc); if(scStatus) { std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; // sc.init_sc(scio, nTurbinesProc, turbineMapProcToGlob, fastMPIComm); // sc.calcOutputs_n(0.0); } - + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - int nodeClusterType = 0; - if (forcePtsBladeDistributionType[iTurb] == "chordClustered") - { - nodeClusterType = 1; - } - std::copy( - FASTInputFileName[iTurb].data(), - FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), - currentFileName - ); - FAST_OpFM_Init( - &iTurb, - &tMax, - currentFileName, - &TurbID[iTurb], - &scio.nSC2CtrlGlob, - &scio.nSC2Ctrl, - &scio.nCtrl2SC, - scio.from_SCglob.data(), - scio.from_SC[iTurb].data(), - &numForcePtsBlade[iTurb], - &numForcePtsTwr[iTurb], - TurbineBasePos[iTurb].data(), - &AbortErrLev, - &dtFAST, - &numBlades[iTurb], - &numVelPtsBlade[iTurb], - &nodeClusterType, - &cDriver_Input_from_FAST[iTurb], - &cDriver_Output_to_FAST[iTurb], - &sc.ip_from_FAST[iTurb], - &sc.op_to_FAST[iTurb], - &ErrStat, - ErrMsg - ); - checkError(ErrStat, ErrMsg); - timeZero = true; + findOutputFile(iTurb); + findRestartFile(iTurb); + char tmpOutFileRoot[INTERFACE_STRING_LENGTH]; + if (turbineData[iTurb].sType == EXTINFLOW) { - numVelPtsTwr[iTurb] = cDriver_Output_to_FAST[iTurb].u_Len - numBlades[iTurb]*numVelPtsBlade[iTurb] - 1; - if(numVelPtsTwr[iTurb] == 0) { - numForcePtsTwr[iTurb] = 0; - std::cout << "Aerodyn doesn't want to calculate forces on the tower. All actuator points on the tower are turned off for turbine " << turbineMapProcToGlob[iTurb] << "." << std::endl ; - } + std::copy( + turbineData[iTurb].FASTInputFileName.data(), + turbineData[iTurb].FASTInputFileName.data() + (turbineData[iTurb].FASTInputFileName.size() + 1), + currentFileName + ); + FAST_AL_CFD_Init( &iTurb, &tMax, turbineData[iTurb].FASTInputFileName.data(), &turbineData[iTurb].TurbID, tmpOutFileRoot, &scio.nSC2CtrlGlob, &scio.nSC2Ctrl, &scio.nCtrl2SC, scio.from_SCglob.data(), scio.from_SC[iTurb].data(), &turbineData[iTurb].numForcePtsBlade, &turbineData[iTurb].numForcePtsTwr, turbineData[iTurb].TurbineBasePos.data(), &AbortErrLev, &dtDriver, &turbineData[iTurb].dt, &turbineData[iTurb].inflowType, &turbineData[iTurb].numBlades, &turbineData[iTurb].numVelPtsBlade, &turbineData[iTurb].numVelPtsTwr, &extinfw_i_f_FAST[iTurb], &extinfw_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); - int nfpts = get_numForcePtsLoc(iTurb); - forceNodeVel[iTurb].resize(nfpts); - for (int k = 0; k < nfpts; k++) forceNodeVel[iTurb][k].resize(3) ; + checkError(ErrStat, ErrMsg); - if ( isDebug() ) { - for (int iNode=0; iNode < get_numVelPtsLoc(iTurb); iNode++) { - std::cout << "Node " << iNode << " Position = " << cDriver_Input_from_FAST[iTurb].pxVel[iNode] << " " << cDriver_Input_from_FAST[iTurb].pyVel[iNode] << " " << cDriver_Input_from_FAST[iTurb].pzVel[iNode] << " " << std::endl ; + timeZero = true; + + turbineData[iTurb].numVelPtsTwr = extinfw_o_t_FAST[iTurb].u_Len - turbineData[iTurb].numBlades*turbineData[iTurb].numVelPtsBlade - 1; + if(turbineData[iTurb].numVelPtsTwr == 0) { + turbineData[iTurb].numForcePtsTwr = 0; + std::cout << "Aerodyn doesn't want to calculate forces on the tower. All actuator points on the tower are turned off for turbine " << turbineMapProcToGlob[iTurb] << "." << std::endl ; } - } - } - int nTimesteps; + allocateMemory_postInit(iTurb); - if (nTurbinesProc > 0) { - readVelocityData(ntStart); - } - for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - applyVelocityData(0, iTurb, cDriver_Output_to_FAST[iTurb], velNodeData[iTurb]); - } - solution0() ; + get_data_from_openfast(fast::STATE_NM2); + get_data_from_openfast(fast::STATE_NM1); + get_data_from_openfast(fast::STATE_N); + get_data_from_openfast(fast::STATE_NP1); - for (int iPrestart=0 ; iPrestart < ntStart; iPrestart++) { - for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - applyVelocityData(iPrestart, iTurb, cDriver_Output_to_FAST[iTurb], velNodeData[iTurb]); + get_ref_positions_from_openfast(iTurb); + + checkAndSetSubsteps(); + + ntStart = int(tStart/dtFAST); + int ntStartDriver; + if( (dtFAST > 0) && (nSubsteps_ > 0)) + ntStartDriver = int(tStart/dtFAST/nSubsteps_); + else + ntStartDriver = 0; //Typically for processors that don't contain any turbines + + std::vector velfile_ncid; + velfile_ncid.resize(nTurbinesProc); + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + velfile_ncid[iTurb] = openVelocityDataFile(iTurb); + readVelocityData(iTurb, 0, 0, velfile_ncid[iTurb]); + } + + int nVelPts = get_numVelPtsLoc(iTurb); + std::cout << std::endl ; + std::cout << "nt_global = " << 0 << " nlin_iter = " << 0 << std::endl ; + for (size_t k = 0; k < nVelPts; k++) + std::cout << k << ", " << velForceNodeData[iTurb][3].vel_vel[k*3 + 0] << " " << velForceNodeData[iTurb][3].vel_vel[k*3 + 1] << " " << velForceNodeData[iTurb][3].vel_vel[k*3 + 2] << " " << std::endl ; + + init_velForceNodeData(); + + solution0(false) ; + + for (int iPrestart=0 ; iPrestart < ntStartDriver; iPrestart++) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + int nlinIters = read_nlin_iters(iTurb, iPrestart+1, velfile_ncid[iTurb]); + for (int iNlin=0; iNlin < nlinIters; iNlin++) { + readVelocityData(iTurb, iPrestart+1, iNlin, velfile_ncid[iTurb]); + update_states_driver_time_step(false); + } + advance_to_next_driver_time_step(false); + } + } + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) + nc_close(velfile_ncid[iTurb]); + + readRestartFile(iTurb, nt_global); + + } else { + + throw std::runtime_error("RESTARTDRIVERINITFAST option not supported for blade-resolved FSI yet"); } - stepNoWrite(); } - if (nTurbinesProc > 0) velNodeDataFile = openVelocityDataFile(false); - break; case fast::simStartType_END: break; - } + } } -void fast::OpenFAST::solution0() { +void fast::OpenFAST::solution0(bool writeFiles) { if (!dryRun) { - // set wind speeds at initial locations - // for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - // setOutputsToFAST(cDriver_Input_from_FAST[iTurb], cDriver_Output_to_FAST[iTurb]); - // } if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; // sc.fastSCInputOutput(); } + if (writeFiles) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + prepareRestartFile(iTurb); + prepareOutputFile(iTurb); + prepareVelocityDataFile(iTurb); + } + } + + // Unfortunately setVelocity only sets the velocity at 'n+1'. Need to copy 'n+1' to 'n' + init_velForceNodeData() ; + send_data_to_openfast(fast::STATE_NP1); + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - FAST_OpFM_Solution0(&iTurb, &ErrStat, ErrMsg); + + FAST_CFD_Solution0(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + + FAST_CFD_InitIOarrays_SS(&iTurb, &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); } + get_data_from_openfast(fast::STATE_N); + get_data_from_openfast(fast::STATE_NM1); + get_data_from_openfast(fast::STATE_NM2); + + if (writeFiles) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + if (turbineData[iTurb].inflowType == 2) + writeVelocityData(iTurb, -nSubsteps_, 0); + } + } + timeZero = false; if (scStatus) { - std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; // sc.calcOutputs_n(0.0); // sc.fastSCInputOutput(); } } -} -void fast::OpenFAST::step() { +} - /* ****************************** - set inputs from this code and call FAST: - ********************************* */ +void fast::OpenFAST::set_state_from_state(fast::timeStep fromState, fast::timeStep toState) { for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - // set wind speeds at original locations - // setOutputsToFAST(cDriver_Input_from_FAST[iTurb], cDriver_Output_to_FAST[iTurb]); - - // this advances the states, calls CalcOutput, and solves for next inputs. Predictor-corrector loop is imbeded here: - // (note OpenFOAM could do subcycling around this step) - - writeVelocityData(velNodeDataFile, iTurb, nt_global, cDriver_Input_from_FAST[iTurb], cDriver_Output_to_FAST[iTurb]); - - if ( isDebug() ) { - - std::ofstream fastcpp_velocity_file; - fastcpp_velocity_file.open("fastcpp_velocity.csv") ; - fastcpp_velocity_file << "# x, y, z, Vx, Vy, Vz" << std::endl ; - for (int iNode=0; iNode < get_numVelPtsLoc(iTurb); iNode++) { - fastcpp_velocity_file << cDriver_Input_from_FAST[iTurb].pxVel[iNode] << ", " << cDriver_Input_from_FAST[iTurb].pyVel[iNode] << ", " << cDriver_Input_from_FAST[iTurb].pzVel[iNode] << ", " << cDriver_Output_to_FAST[iTurb].u[iNode] << ", " << cDriver_Output_to_FAST[iTurb].v[iNode] << ", " << cDriver_Output_to_FAST[iTurb].w[iNode] << " " << std::endl ; + if (turbineData[iTurb].sType == EXTINFLOW) { + int nvelpts = get_numVelPtsLoc(iTurb); + int nfpts = get_numForcePtsLoc(iTurb); + for (int i=0; i0.) { - calc_nacelle_force ( - cDriver_Output_to_FAST[iTurb].u[0], - cDriver_Output_to_FAST[iTurb].v[0], - cDriver_Output_to_FAST[iTurb].w[0], - nacelle_cd[iTurb], - nacelle_area[iTurb], - air_density[iTurb], - cDriver_Input_from_FAST[iTurb].fx[0], - cDriver_Input_from_FAST[iTurb].fy[0], - cDriver_Input_from_FAST[iTurb].fz[0] - ); - } - - if ( isDebug() ) { - std::ofstream actuatorForcesFile; - actuatorForcesFile.open("actuator_forces.csv") ; - actuatorForcesFile << "# x, y, z, fx, fy, fz" << std::endl ; - for (int iNode=0; iNode < get_numForcePtsLoc(iTurb); iNode++) { - actuatorForcesFile << cDriver_Input_from_FAST[iTurb].pxForce[iNode] << ", " << cDriver_Input_from_FAST[iTurb].pyForce[iNode] << ", " << cDriver_Input_from_FAST[iTurb].pzForce[iNode] << ", " << cDriver_Input_from_FAST[iTurb].fx[iNode] << ", " << cDriver_Input_from_FAST[iTurb].fy[iNode] << ", " << cDriver_Input_from_FAST[iTurb].fz[iNode] << " " << std::endl ; + for (int i=0; i. - char dummyCheckPointRoot[INTERFACE_STRING_LENGTH] = " "; - // Ensure that we have a null character - dummyCheckPointRoot[1] = 0; +void fast::OpenFAST::init_velForceNodeData() { - if (nTurbinesProc > 0) backupVelocityDataFile(nt_global, velNodeDataFile); + set_state_from_state(fast::STATE_NP1, fast::STATE_N); + set_state_from_state(fast::STATE_NP1, fast::STATE_NM1); + set_state_from_state(fast::STATE_NP1, fast::STATE_NM2); - for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - FAST_CreateCheckpoint(&iTurb, dummyCheckPointRoot, &ErrStat, ErrMsg); - checkError(ErrStat, ErrMsg); - } - if(scStatus) { - std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; - // if (fastMPIRank == 0) { - // sc.writeRestartFile(nt_global); - // } - } - } } -void fast::OpenFAST::stepNoWrite() { +//! Dot product of two vectors +double dot(double * a, double * b) { - /* ****************************** - set inputs from this code and call FAST: - ********************************* */ + return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); - for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { +} - // set wind speeds at original locations - // setOutputsToFAST(cDriver_Input_from_FAST[iTurb], cDriver_Output_to_FAST[iTurb]); +//! Cross product of two vectors +void cross(double * a, double * b, double * aCrossb) { - // this advances the states, calls CalcOutput, and solves for next inputs. Predictor-corrector loop is imbeded here: - // (note OpenFOAM could do subcycling around this step) - FAST_OpFM_Step(&iTurb, &ErrStat, ErrMsg); - checkError(ErrStat, ErrMsg); + aCrossb[0] = a[1]*b[2] - a[2]*b[1]; + aCrossb[1] = a[2]*b[0] - a[0]*b[2]; + aCrossb[2] = a[0]*b[1] - a[1]*b[0]; - } +} - if(scStatus) { - std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; - // sc.updateStates( nt_global * dtFAST); // Predict state at 'n+1' based on inputs - // sc.calcOutputs_np1( (nt_global+1) * dtFAST); - // sc.fastSCInputOutput(); - } +//! Compose Wiener-Milenkovic parameters 'p' and 'q' into 'pPlusq'. If a transpose of 'p' is required, set tranposeP to '-1', else leave blank or set to '+1' +void composeWM(double * p, double * q, double * pPlusq, double transposeP, double transposeQ) { - nt_global = nt_global + 1; + double p0 = 2.0 - 0.125*dot(p,p); + double q0 = 2.0 - 0.125*dot(q,q); + std::vector pCrossq(3,0.0); + cross(p, q, pCrossq.data()); + + double delta1 = (4.0-p0)*(4.0-q0); + double delta2 = p0*q0 - transposeP*dot(p,q); + double premultFac = 0.0; + if (delta2 < 0) + premultFac = -4.0/(delta1 - delta2); + else + premultFac = 4.0/(delta1 + delta2); + + for (size_t i=0; i < 3; i++) + pPlusq[i] = premultFac * (transposeQ * p0 * q[i] + transposeP * q0 * p[i] + transposeP * transposeQ * pCrossq[i] ); - if(scStatus) { - std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; - // sc.advanceTime(); // Advance states, inputs and outputs from 'n' to 'n+1' - } } -void fast::OpenFAST::calc_nacelle_force(const float & u, const float & v, const float & w, const float & cd, const float & area, const float & rho, float & fx, float & fy, float & fz) { - // Calculate the force on the nacelle (fx,fy,fz) given the - // velocity sampled at the nacelle point (u,v,w), - // drag coefficient 'cd' and nacelle area 'area' +//! Extrapolate Wiener-Milenkovic parameters from state 'nm2', 'nm1', 'n' to 'np1' +void extrapRotation(double *rnm2, double *rnm1, double *rn, double *rnp1) { - // The velocity magnitude - float Vmag = std::sqrt(u * u + v * v + w * w); + std::array rrnm1{ {0.0,0.0,0.0} }; + std::array rrn{ {0.0,0.0,0.0} }; + std::array rrnp1{ {0.0,0.0,0.0} }; - // Velocity correction based on Martinez-Tossas PhD Thesis 2017 - // The correction samples the velocity at the center of the - // Gaussian kernel and scales it to obtain the inflow velocity - float epsilon_d = std::sqrt(2.0 / M_PI * cd * area); - float correction = 1. / (1.0 - cd * area / (4.0 * M_PI * epsilon_d * epsilon_d)); + composeWM(rnm2, rnm1, rrnm1.data(), -1.0, 1.0); // Remove rigid body rotaiton of rnm2 from rnm1 + composeWM(rnm2, rn, rrn.data(), -1.0, 1.0); // Remove rigid body rotaiton of rnm2 from rnm1 + for(int i=0; i<3; i++) { + rrnp1[i] = 3.0 * ( rrn[i] - rrnm1[i]) ; + } + composeWM(rnm2, rrnp1.data(), rnp1, 1.0, 1.0); //Add rigid body rotation of nm2 back - // Compute the force for each velocity component - fx = rho * 1./2. * cd * area * Vmag * u * correction * correction; - fy = rho * 1./2. * cd * area * Vmag * v * correction * correction; - fz = rho * 1./2. * cd * area * Vmag * w * correction * correction; } -void fast::OpenFAST::setInputs(const fast::fastInputs & fi ) { - mpiComm = fi.comm; +void fast::OpenFAST::predict_states() { - MPI_Comm_rank(mpiComm, &worldMPIRank); + if (firstPass_) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + int nvelpts = get_numVelPtsLoc(iTurb); + int nfpts = get_numForcePtsLoc(iTurb); + for (int i=0; i 1) { + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_CFD_Store_SS(&iTurb, &nt_global, &ErrStat, ErrMsg) ; + checkError(ErrStat, ErrMsg); + } + + } else { + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + } + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_CFD_Prework(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + } + } +} + +void fast::OpenFAST::update_states_driver_time_step(bool writeFiles) { + + if (firstPass_) + prework(); + + if (nSubsteps_ > 1) { + + if (!firstPass_) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_CFD_Reset_SS(&iTurb, &nSubsteps_, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + } + } + + for (int iSubstep=1; iSubstep < nSubsteps_+1; iSubstep++) { + double ss_time = double(iSubstep)/double(nSubsteps_); + step(ss_time); + } + + get_data_from_openfast(fast::STATE_NP1); + + if (writeFiles) { + if ( isDebug() ) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + std::ofstream fastcpp_velocity_file; + fastcpp_velocity_file.open("fastcpp_residual." + std::to_string(turbineMapProcToGlob[iTurb]) + ".csv", std::ios_base::app) ; + fastcpp_velocity_file << "Time step " << nt_global << " Velocity residual at the force nodes = " << velForceNodeData[iTurb][fast::STATE_NP1].vel_force_resid << std::endl ; + fastcpp_velocity_file << " " << nt_global << " Position residual at the force nodes = " << velForceNodeData[iTurb][fast::STATE_NP1].x_force_resid << std::endl ; + fastcpp_velocity_file << " " << nt_global << " Force residual at the force nodes = " << velForceNodeData[iTurb][fast::STATE_NP1].force_resid << std::endl ; + fastcpp_velocity_file.close() ; + } + } + } + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + velForceNodeData[iTurb][fast::STATE_NP1].x_vel_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].xdot_vel_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].vel_vel_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].x_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].xdot_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].orient_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].vel_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].force_resid = 0.0; + } + } else { + + send_data_to_openfast(fast::STATE_NP1); + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_CFD_UpdateStates(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + + // Compute the force from the nacelle only if the drag coefficient is + // greater than zero + if (get_nacelleCdLoc(iTurb) > 0.) { + + calc_nacelle_force ( + + extinfw_o_t_FAST[iTurb].u[0], + extinfw_o_t_FAST[iTurb].v[0], + extinfw_o_t_FAST[iTurb].w[0], + get_nacelleCdLoc(iTurb), + get_nacelleAreaLoc(iTurb), + get_airDensityLoc(iTurb), + extinfw_i_f_FAST[iTurb].fx[0], + extinfw_i_f_FAST[iTurb].fy[0], + extinfw_i_f_FAST[iTurb].fz[0] + + ); + + } + + } + + get_data_from_openfast(fast::STATE_NP1); + + if ( writeFiles ) { + if ( isDebug() ) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + std::ofstream fastcpp_velocity_file; + fastcpp_velocity_file.open("fastcpp_residual." + std::to_string(turbineMapProcToGlob[iTurb]) + ".csv", std::ios_base::app) ; + fastcpp_velocity_file << "Time step " << nt_global << " Velocity residual at the force nodes = " << velForceNodeData[iTurb][fast::STATE_NP1].vel_force_resid << std::endl ; + fastcpp_velocity_file << " " << nt_global << " Position residual at the force nodes = " << velForceNodeData[iTurb][fast::STATE_NP1].x_force_resid << std::endl ; + fastcpp_velocity_file << " " << nt_global << " Force residual at the force nodes = " << velForceNodeData[iTurb][fast::STATE_NP1].force_resid << std::endl ; + fastcpp_velocity_file.close() ; + } + } + } + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + velForceNodeData[iTurb][fast::STATE_NP1].x_vel_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].xdot_vel_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].vel_vel_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].x_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].xdot_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].orient_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].vel_force_resid = 0.0; + velForceNodeData[iTurb][fast::STATE_NP1].force_resid = 0.0; + } + + } + + if (writeFiles) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + if (turbineData[iTurb].inflowType == 2) + writeVelocityData(iTurb, nt_global, nlinIter_); + } + } + + firstPass_ = false; + nlinIter_ +=1 ; +} + +void fast::OpenFAST::advance_to_next_driver_time_step(bool writeFiles) { + + if (nSubsteps_ > 1) { + //Nothing to do here + + } else { + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_CFD_AdvanceToNextTimeStep(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + } + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + } + + } + + nt_global = nt_global + nSubsteps_; + + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_CFD_WriteOutput(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + } + + set_state_from_state(fast::STATE_NM1, fast::STATE_NM2); + set_state_from_state(fast::STATE_N, fast::STATE_NM1); + set_state_from_state(fast::STATE_NP1, fast::STATE_N); + + if (writeFiles) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + int tStepRatio = dtDriver/dtFAST; + if ( (((nt_global - ntStart) % (restartFreq_*tStepRatio)) == 0 ) && (nt_global != ntStart) ) { + turbineData[iTurb].FASTRestartFileName = " "; // if blank, it will use FAST convention .nt_global + FAST_CreateCheckpoint(&iTurb, turbineData[iTurb].FASTRestartFileName.data(), &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + writeRestartFile(iTurb, nt_global); + } + if(scStatus) { + if (fastMPIRank == 0) { + sc->writeRestartFile(nt_global); + } + } + + if ( (((nt_global - ntStart) % (outputFreq_ * tStepRatio) ) == 0 ) && (nt_global != ntStart) ) { + writeOutputFile(iTurb, nt_global); + } + } + + } + + nlinIter_ = 0; + firstPass_ = true ; // Set firstPass_ to true for the next time step +} + +void fast::OpenFAST::calc_nacelle_force(const float & u, const float & v, const float & w, const float & cd, const float & area, const float & rho, float & fx, float & fy, float & fz) { + // Calculate the force on the nacelle (fx,fy,fz) given the + // velocity sampled at the nacelle point (u,v,w), + // drag coefficient 'cd' and nacelle area 'area' + // The velocity magnitude + float Vmag = std::sqrt(u * u + v * v + w * w); + + // Velocity correction based on Martinez-Tossas PhD Thesis 2017 + // The correction samples the velocity at the center of the + // Gaussian kernel and scales it to obtain the inflow velocity + float epsilon_d = std::sqrt(2.0 / M_PI * cd * area); + float correction = 1. / (1.0 - cd * area / (4.0 * M_PI * epsilon_d * epsilon_d)); + + // Compute the force for each velocity component + fx = rho * 1./2. * cd * area * Vmag * u * correction * correction; + fy = rho * 1./2. * cd * area * Vmag * v * correction * correction; + fz = rho * 1./2. * cd * area * Vmag * w * correction * correction; + +} + +/* A version of step allowing for sub-timesteps when the driver program has a larger time step than OpenFAST */ +void fast::OpenFAST::step(double ss_time) { + + /* ****************************** + set inputs from this code and call FAST: + ********************************* */ + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + } + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + + // this advances the states, calls CalcOutput, and solves for next inputs. Predictor-corrector loop is imbeded here: + FAST_CFD_Prework(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + send_data_to_openfast(ss_time); + FAST_CFD_UpdateStates(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + FAST_CFD_AdvanceToNextTimeStep(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + + } + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + } + +} + +void fast::OpenFAST::step(bool writeFiles) { + + /* ****************************** + set inputs from this code and call FAST: + ********************************* */ + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + + // this advances the states, calls CalcOutput, and solves for next inputs. Predictor-corrector loop is imbeded here: + // (note CFD could do subcycling around this step) + + if (turbineData[iTurb].inflowType == 2) + + writeVelocityData(iTurb, nt_global, 0); + + if (writeFiles) { + if ( isDebug() && (turbineData[iTurb].inflowType == 2) ) { + + std::ofstream fastcpp_velocity_file; + fastcpp_velocity_file.open("fastcpp_velocity." + std::to_string(turbineMapProcToGlob[iTurb]) + ".csv") ; + fastcpp_velocity_file << "# x, y, z, Vx, Vy, Vz" << std::endl ; + for (int iNode=0; iNode < get_numVelPtsLoc(iTurb); iNode++) { + fastcpp_velocity_file << extinfw_i_f_FAST[iTurb].pxVel[iNode] << ", " << extinfw_i_f_FAST[iTurb].pyVel[iNode] << ", " << extinfw_i_f_FAST[iTurb].pzVel[iNode] << ", " << extinfw_o_t_FAST[iTurb].u[iNode] << ", " << extinfw_o_t_FAST[iTurb].v[iNode] << ", " << extinfw_o_t_FAST[iTurb].w[iNode] << " " << std::endl ; + } + fastcpp_velocity_file.close() ; + } + } + + FAST_CFD_Prework(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + send_data_to_openfast(fast::STATE_NP1); + FAST_CFD_UpdateStates(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + get_data_from_openfast(fast::STATE_NP1); + FAST_CFD_AdvanceToNextTimeStep(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + + // Compute the force from the nacelle only if the drag coefficient is + // greater than zero + if (get_nacelleCdLoc(iTurb) > 0.) { + + calc_nacelle_force ( + + extinfw_o_t_FAST[iTurb].u[0], + extinfw_o_t_FAST[iTurb].v[0], + extinfw_o_t_FAST[iTurb].w[0], + get_nacelleCdLoc(iTurb), + get_nacelleAreaLoc(iTurb), + get_airDensityLoc(iTurb), + extinfw_i_f_FAST[iTurb].fx[0], + extinfw_i_f_FAST[iTurb].fy[0], + extinfw_i_f_FAST[iTurb].fz[0] + + ); + + } + + if (writeFiles) { + if ( isDebug() && (turbineData[iTurb].inflowType == 2) ) { + std::ofstream actuatorForcesFile; + actuatorForcesFile.open("actuator_forces." + std::to_string(turbineMapProcToGlob[iTurb]) + ".csv") ; + actuatorForcesFile << "# x, y, z, fx, fy, fz" << std::endl ; + for (int iNode=0; iNode < get_numForcePtsLoc(iTurb); iNode++) { + actuatorForcesFile << extinfw_i_f_FAST[iTurb].pxForce[iNode] << ", " << extinfw_i_f_FAST[iTurb].pyForce[iNode] << ", " << extinfw_i_f_FAST[iTurb].pzForce[iNode] << ", " << extinfw_i_f_FAST[iTurb].fx[iNode] << ", " << extinfw_i_f_FAST[iTurb].fy[iNode] << ", " << extinfw_i_f_FAST[iTurb].fz[iNode] << " " << std::endl ; + } + actuatorForcesFile.close() ; + } + } + + } + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + // sc.updateStates(nt_global * dtFAST); // Predict state at 'n+1' based on inputs + // sc.calcOutputs_np1( (nt_global + 1) * dtFAST); + // sc.fastSCInputOutput(); + } + + nt_global = nt_global + 1; + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_CFD_WriteOutput(&iTurb, &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + } + + if (writeFiles) { + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + int tStepRatio = dtDriver/dtFAST; + if ( (((nt_global - ntStart) % (restartFreq_ * tStepRatio)) == 0 ) && (nt_global != ntStart) ) { + turbineData[iTurb].FASTRestartFileName = " "; // if blank, it will use FAST convention .nt_global + FAST_CreateCheckpoint(&iTurb, turbineData[iTurb].FASTRestartFileName.data(), &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); + writeRestartFile(iTurb, nt_global); + } + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + // if (fastMPIRank == 0) { + // sc.writeRestartFile(nt_global); + // } + } + + if ( (((nt_global - ntStart) % (outputFreq_ * tStepRatio) ) == 0 ) && (nt_global != ntStart) ) { + writeOutputFile(iTurb, nt_global); + } + } + } + +} + +void fast::OpenFAST::setInputs(const fast::fastInputs & fi ) { + + mpiComm = fi.comm; + + MPI_Comm_rank(mpiComm, &worldMPIRank); MPI_Comm_group(mpiComm, &worldMPIGroup); nTurbinesGlob = fi.nTurbinesGlob; if (nTurbinesGlob > 0) { - dryRun = fi.dryRun; + debug = fi.debug; tStart = fi.tStart; simStart = fi.simStart; - nEveryCheckPoint = fi.nEveryCheckPoint; + restartFreq_ = fi.restartFreq; + outputFreq_ = fi.outputFreq; tMax = fi.tMax; loadSuperController(fi); - dtFAST = fi.dtFAST; + dtDriver = fi.dtDriver; - ntStart = int(tStart/dtFAST); - - if (simStart == fast::restartDriverInitFAST) { - nt_global = 0; - } else { - nt_global = ntStart; - } + ///TODO: Check if this is right and necessary + // if (simStart == fast::restartDriverInitFAST) { + // nt_global = 0; + // } else { + // nt_global = ntStart; + // } globTurbineData.resize(nTurbinesGlob); globTurbineData = fi.globTurbineData; @@ -472,568 +1468,1706 @@ void fast::OpenFAST::setInputs(const fast::fastInputs & fi ) { } } -void fast::OpenFAST::checkError(const int ErrStat, const char * ErrMsg){ - if (ErrStat != ErrID_None){ - if (ErrStat >= AbortErrLev){ - throw std::runtime_error(ErrMsg); +int fast::OpenFAST::checkAndSetSubsteps() { + + if ( nTurbinesProc > 0) { + if (dtDriver > 0) { + dtFAST = turbineData[0].dt; + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + if (dtFAST != turbineData[iTurb].dt) { + throw std::runtime_error("All turbines don't have the same time step "); + } + } + if (dtFAST > 0) { + int tStepRatio = dtDriver/dtFAST; + if (std::abs(dtDriver - tStepRatio * dtFAST) < 0.001) {// TODO: Fix arbitrary number 0.001 + nSubsteps_ = tStepRatio; + return 1; + } else { + return -1; + } + } else { + throw std::runtime_error("FAST time step is zero"); + } + + } else { + throw std::runtime_error("Driver time step is not set or set to zero"); } + } else { + return 1; } + } -void fast::OpenFAST::setOutputsToFAST(OpFM_InputType_t cDriver_Input_from_FAST, OpFM_OutputType_t cDriver_Output_to_FAST){ - // routine sets the u-v-w wind speeds used in FAST and the SuperController inputs +void fast::OpenFAST::setDriverTimeStep(double dt_driver) { + dtDriver = dt_driver; +} - for (int j = 0; j < cDriver_Output_to_FAST.u_Len; j++){ - cDriver_Output_to_FAST.u[j] = (float) 10.0*pow((cDriver_Input_from_FAST.pzVel[j] / 90.0), 0.2); // 0.2 power law wind profile using reference 10 m/s at 90 meters - cDriver_Output_to_FAST.v[j] = 0.0; - cDriver_Output_to_FAST.w[j] = 0.0; - } -} +void fast::OpenFAST::setDriverCheckpoint(int nt_checkpoint_driver) { -void fast::OpenFAST::getApproxHubPos(double* currentCoords, int iTurbGlob, int nSize) { - assert(nSize==3); - // Get hub position of Turbine 'iTurbGlob' - for(int i =0; i 0) { + if (nSubsteps_ > 0) { + restartFreq_ = nt_checkpoint_driver; + } else { + throw std::runtime_error("Trying to set driver checkpoint when nSubsteps_ is zero. Set driver time step first may be?"); + } } } -void fast::OpenFAST::getHubPos(double* currentCoords, int iTurbGlob, int nSize) { - assert(nSize==3); - // Get hub position of Turbine 'iTurbGlob' - int iTurbLoc = get_localTurbNo(iTurbGlob); - currentCoords[0] = cDriver_Input_from_FAST[iTurbLoc].pxVel[0] + TurbineBasePos[iTurbLoc][0] ; - currentCoords[1] = cDriver_Input_from_FAST[iTurbLoc].pyVel[0] + TurbineBasePos[iTurbLoc][1] ; - currentCoords[2] = cDriver_Input_from_FAST[iTurbLoc].pzVel[0] + TurbineBasePos[iTurbLoc][2] ; -} +void fast::OpenFAST::get_turbineParams(int iTurbGlob, turbineDataType & turbData) { -void fast::OpenFAST::getHubShftDir(double* hubShftVec, int iTurbGlob, int nSize) { - assert(nSize==3); - // Get hub shaft direction of current turbine - pointing downwind + //TODO: Figure out a better copy operator for the turbineDataType struct int iTurbLoc = get_localTurbNo(iTurbGlob); - for(int i=0; i 0) { + turbData.TurbineBasePos.resize(turbineData[iTurbLoc].TurbineBasePos.size()); + for(int i=0; i < turbineData[iTurbLoc].TurbineBasePos.size(); i++) + turbData.TurbineBasePos[i] = turbineData[iTurbLoc].TurbineBasePos[i]; + } + if(turbineData[iTurbLoc].TurbineHubPos.size() > 0) { + turbData.TurbineHubPos.resize(turbineData[iTurbLoc].TurbineHubPos.size()); + for(int i=0; i < turbineData[iTurbLoc].TurbineHubPos.size(); i++) + turbData.TurbineHubPos[i] = turbineData[iTurbLoc].TurbineHubPos[i]; + } + turbData.sType = turbineData[iTurbLoc].sType; + turbData.numBlades = turbineData[iTurbLoc].numBlades; + turbData.numVelPtsBlade = turbineData[iTurbLoc].numVelPtsBlade; + turbData.numVelPtsTwr = turbineData[iTurbLoc].numVelPtsTwr; + turbData.numVelPts = turbineData[iTurbLoc].numVelPts; + turbData.numForcePtsBlade = turbineData[iTurbLoc].numForcePtsBlade; + turbData.numForcePtsTwr = turbineData[iTurbLoc].numForcePtsTwr; + turbData.numForcePts = turbineData[iTurbLoc].numForcePts; + turbData.inflowType = turbineData[iTurbLoc].inflowType; + turbData.nacelle_cd = turbineData[iTurbLoc].nacelle_cd; + turbData.nacelle_area = turbineData[iTurbLoc].nacelle_area; + turbData.air_density = turbineData[iTurbLoc].air_density; + turbData.nBRfsiPtsBlade.resize(turbData.numBlades); + turbData.nTotBRfsiPtsBlade = 0; + for (int i=0; i < turbData.numBlades; i++) { + turbData.nBRfsiPtsBlade[i] = turbineData[iTurbLoc].nBRfsiPtsBlade[i]; + turbData.nTotBRfsiPtsBlade += turbData.nBRfsiPtsBlade[i]; } + turbData.nBRfsiPtsTwr = turbineData[iTurbLoc].nBRfsiPtsTwr; + turbData.azBlendMean = turbineData[iTurbLoc].azBlendMean; + turbData.azBlendDelta = turbineData[iTurbLoc].azBlendDelta; + turbData.velMean = turbineData[iTurbLoc].velMean; + turbData.windDir = turbineData[iTurbLoc].windDir; + turbData.zRef = turbineData[iTurbLoc].zRef; + turbData.shearExp = turbineData[iTurbLoc].shearExp; + } -void fast::OpenFAST::getVelNodeCoordinates(double* currentCoords, int iNode, int iTurbGlob, int nSize) { - assert(nSize==3); - // Set coordinates at current node of current turbine - int iTurbLoc = get_localTurbNo(iTurbGlob); +void fast::OpenFAST::checkError(const int ErrStat, const char * ErrMsg) +{ + if (ErrStat != ErrID_None){ + + if (ErrStat >= AbortErrLev){ + throw std::runtime_error(std::string(ErrMsg)); + } else { + std::cout << "Warning from OpenFAST: " << ErrMsg << std::endl; + } + } +} + +// Actuator stuff + +void fast::OpenFAST::setExpLawWindSpeed(double t){ + + double sinOmegat = 0.1 * std::sin(10.0*t); + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + // routine sets the u-v-w wind speeds used in FAST + int nVelPts = get_numVelPts(iTurb); + int iTurbGlob = turbineMapProcToGlob[iTurb]; + for (int j = 0; j < nVelPts; j++){ + std::vector coords(3,0.0); + std::vector tmpVel(3,0.0); + getVelNodeCoordinates(coords, j, iTurbGlob, fast::STATE_NP1); + tmpVel[0] = (float) 10.0*pow((coords[2] / 90.0), 0.2) + sinOmegat; // 0.2 power law wind profile using reference 10 m/s at 90 meters + a perturbation + setVelocity(tmpVel, j, iTurbGlob); + } + } +} + +void fast::OpenFAST::getApproxHubPos(double* currentCoords, int iTurbGlob, int nSize) { + assert(nSize==3); + // Get hub position of Turbine 'iTurbGlob' + for(int i =0; i rDistForce(nForcePtsBlade) ; + for(int j=0; j < nForcePtsBlade; j++) { + int iNodeForce = 1 + iBlade * nForcePtsBlade + j ; //The number of actuator force points is always the same for all blades + rDistForce[j] = sqrt( + (extinfw_i_f_FAST[iTurb].pxForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pxForce[0])*(extinfw_i_f_FAST[iTurb].pxForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pxForce[0]) + + (extinfw_i_f_FAST[iTurb].pyForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pyForce[0])*(extinfw_i_f_FAST[iTurb].pyForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pyForce[0]) + + (extinfw_i_f_FAST[iTurb].pzForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pzForce[0])*(extinfw_i_f_FAST[iTurb].pzForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pzForce[0]) + ); + } + + // Interpolate to the velocity nodes + int nVelPtsBlade = get_numVelPtsBladeLoc(iTurb); + for(int j=0; j < nVelPtsBlade; j++) { + int iNodeVel = 1 + iBlade * nVelPtsBlade + j ; //Assumes the same number of velocity (Aerodyn) nodes for all blades + double rDistVel = sqrt( + (extinfw_i_f_FAST[iTurb].pxVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pxVel[0])*(extinfw_i_f_FAST[iTurb].pxVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pxVel[0]) + + (extinfw_i_f_FAST[iTurb].pyVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pyVel[0])*(extinfw_i_f_FAST[iTurb].pyVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pyVel[0]) + + (extinfw_i_f_FAST[iTurb].pzVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pzVel[0])*(extinfw_i_f_FAST[iTurb].pzVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pzVel[0]) + ); + //Find nearest two force nodes + int jForceLower = 0; + while ( (rDistForce[jForceLower+1] < rDistVel) && ( jForceLower < (nForcePtsBlade-2)) ) { + jForceLower = jForceLower + 1; + } + int iNodeForceLower = 1 + iBlade * nForcePtsBlade + jForceLower ; + double rInterp = (rDistVel - rDistForce[jForceLower])/(rDistForce[jForceLower+1]-rDistForce[jForceLower]); + + for (int k=0; k < 3; k++) { + double tmp = velForceNodeData[iTurb][fast::STATE_NP1].vel_force[iNodeForceLower*3+k] + rInterp * (velForceNodeData[iTurb][fast::STATE_NP1].vel_force[(iNodeForceLower+1)*3+k] - velForceNodeData[iTurb][fast::STATE_NP1].vel_force[iNodeForceLower*3+k]); + velForceNodeData[iTurb][fast::STATE_NP1].vel_vel_resid += (velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+k] - tmp)*(velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+k] - tmp); + velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+k] = tmp; + } + } + } + + // Now the tower if present and used + int nVelPtsTower = get_numVelPtsTwrLoc(iTurb); + if ( nVelPtsTower > 0 ) { + + // Create interpolating parameter - Distance from first node from ground + int nForcePtsTower = get_numForcePtsTwrLoc(iTurb); + std::vector hDistForce(nForcePtsTower) ; + int iNodeBotTowerForce = 1 + nBlades * get_numForcePtsBladeLoc(iTurb); // The number of actuator force points is always the same for all blades + for(int j=0; j < nForcePtsTower; j++) { + int iNodeForce = iNodeBotTowerForce + j ; + hDistForce[j] = sqrt( + (extinfw_i_f_FAST[iTurb].pxForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pxForce[iNodeBotTowerForce])*(extinfw_i_f_FAST[iTurb].pxForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pxForce[iNodeBotTowerForce]) + + (extinfw_i_f_FAST[iTurb].pyForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pyForce[iNodeBotTowerForce])*(extinfw_i_f_FAST[iTurb].pyForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pyForce[iNodeBotTowerForce]) + + (extinfw_i_f_FAST[iTurb].pzForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pzForce[iNodeBotTowerForce])*(extinfw_i_f_FAST[iTurb].pzForce[iNodeForce] - extinfw_i_f_FAST[iTurb].pzForce[iNodeBotTowerForce]) + ); + } + + int iNodeBotTowerVel = 1 + nBlades * get_numVelPtsBladeLoc(iTurb); // Assumes the same number of velocity (Aerodyn) nodes for all blades + for(int j=0; j < nVelPtsTower; j++) { + int iNodeVel = iNodeBotTowerVel + j ; + double hDistVel = sqrt( + (extinfw_i_f_FAST[iTurb].pxVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pxVel[iNodeBotTowerVel])*(extinfw_i_f_FAST[iTurb].pxVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pxVel[iNodeBotTowerVel]) + + (extinfw_i_f_FAST[iTurb].pyVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pyVel[iNodeBotTowerVel])*(extinfw_i_f_FAST[iTurb].pyVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pyVel[iNodeBotTowerVel]) + + (extinfw_i_f_FAST[iTurb].pzVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pzVel[iNodeBotTowerVel])*(extinfw_i_f_FAST[iTurb].pzVel[iNodeVel] - extinfw_i_f_FAST[iTurb].pzVel[iNodeBotTowerVel]) + ); + //Find nearest two force nodes + int jForceLower = 0; + while ( (hDistForce[jForceLower+1] < hDistVel) && ( jForceLower < (nForcePtsTower-2)) ) { + jForceLower = jForceLower + 1; + } + int iNodeForceLower = iNodeBotTowerForce + jForceLower ; + double rInterp = (hDistVel - hDistForce[jForceLower])/(hDistForce[jForceLower+1]-hDistForce[jForceLower]); + for (int k=0; k < 3; k++) { + double tmp = velForceNodeData[iTurb][fast::STATE_NP1].vel_force[iNodeForceLower*3+k] + rInterp * (velForceNodeData[iTurb][fast::STATE_NP1].vel_force[(iNodeForceLower+1)*3+k] - velForceNodeData[iTurb][fast::STATE_NP1].vel_force[iNodeForceLower*3+k]); + velForceNodeData[iTurb][fast::STATE_NP1].vel_vel_resid += (velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+k] - tmp)*(velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+k] - tmp); + velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+k] = tmp; + } + } + } + + } // End loop over turbines + +} + +void fast::OpenFAST::computeTorqueThrust(int iTurbGlob, double* torque, double* thrust, int nSize) { + + int iTurbLoc = get_localTurbNo(iTurbGlob) ; + if (turbineData[iTurbLoc].sType != EXTINFLOW) + return; + + //Compute the torque and thrust based on the forces at the actuator nodes + std::vector relLoc(3,0.0); + std::vector rPerpShft(3); + thrust[0] = 0.0; thrust[1] = 0.0; thrust[2] = 0.0; + torque[0] = 0.0; torque[1] = 0.0; torque[2] = 0.0; + + std::vector hubShftVec(3); + getHubShftDir(hubShftVec, iTurbGlob, fast::STATE_NP1); + + int nfpts = get_numForcePtsBlade(iTurbLoc); + for (int k=0; k < get_numBladesLoc(iTurbLoc); k++) { + for (int j=0; j < nfpts; j++) { + int iNode = 1 + nfpts*k + j ; + + thrust[0] = thrust[0] + extinfw_i_f_FAST[iTurbLoc].fx[iNode] ; + thrust[1] = thrust[1] + extinfw_i_f_FAST[iTurbLoc].fy[iNode] ; + thrust[2] = thrust[2] + extinfw_i_f_FAST[iTurbLoc].fz[iNode] ; + + relLoc[0] = extinfw_i_f_FAST[iTurbLoc].pxForce[iNode] - extinfw_i_f_FAST[iTurbLoc].pxForce[0] ; + relLoc[1] = extinfw_i_f_FAST[iTurbLoc].pyForce[iNode] - extinfw_i_f_FAST[iTurbLoc].pyForce[0]; + relLoc[2] = extinfw_i_f_FAST[iTurbLoc].pzForce[iNode] - extinfw_i_f_FAST[iTurbLoc].pzForce[0]; + + double rDotHubShftVec = relLoc[0]*hubShftVec[0] + relLoc[1]*hubShftVec[1] + relLoc[2]*hubShftVec[2]; + for (int j=0; j < 3; j++) rPerpShft[j] = relLoc[j] - rDotHubShftVec * hubShftVec[j]; + + torque[0] = torque[0] + rPerpShft[1] * extinfw_i_f_FAST[iTurbLoc].fz[iNode] - rPerpShft[2] * extinfw_i_f_FAST[iTurbLoc].fy[iNode] + extinfw_i_f_FAST[iTurbLoc].momentx[iNode] ; + torque[1] = torque[1] + rPerpShft[2] * extinfw_i_f_FAST[iTurbLoc].fx[iNode] - rPerpShft[0] * extinfw_i_f_FAST[iTurbLoc].fz[iNode] + extinfw_i_f_FAST[iTurbLoc].momenty[iNode] ; + torque[2] = torque[2] + rPerpShft[0] * extinfw_i_f_FAST[iTurbLoc].fy[iNode] - rPerpShft[1] * extinfw_i_f_FAST[iTurbLoc].fx[iNode] + extinfw_i_f_FAST[iTurbLoc].momentz[iNode] ; + + } + } +} + +fast::ActuatorNodeType fast::OpenFAST::getVelNodeType(int iTurbGlob, int iNode) { + // Return the type of velocity node for the given node number. The node ordering (from FAST) is + // Node 0 - Hub node + // Blade 1 nodes + // Blade 2 nodes + // Blade 3 nodes + // Tower nodes + + int iTurbLoc = get_localTurbNo(iTurbGlob); + for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numVelPtsLoc(iTurbGlob); + if (iNode) { + if ( (iNode + 1 - (get_numVelPts(iTurbLoc) - get_numVelPtsTwr(iTurbLoc)) ) > 0) { + return TOWER; + } + else { + return BLADE; + } + } + else { + return HUB; + } + +} + +fast::ActuatorNodeType fast::OpenFAST::getForceNodeType(int iTurbGlob, int iNode) { + // Return the type of actuator force node for the given node number. The node ordering (from FAST) is + // Node 0 - Hub node + // Blade 1 nodes + // Blade 2 nodes + // Blade 3 nodes + // Tower nodes + + int iTurbLoc = get_localTurbNo(iTurbGlob); + for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numForcePtsLoc(iTurbGlob); + if (iNode) { + if ( (iNode + 1 - (get_numForcePts(iTurbLoc) - get_numForcePtsTwr(iTurbLoc)) ) > 0) { + return TOWER; + } + else { + return BLADE; + } + } + else { + return HUB; + } +} + +void fast::OpenFAST::allocateMemory_preInit() { + + for (int iTurb=0; iTurb < nTurbinesGlob; iTurb++) { + if (dryRun) { + if(worldMPIRank == 0) { + std::cout << "iTurb = " << iTurb << " turbineMapGlobToProc[iTurb] = " << turbineMapGlobToProc[iTurb] << std::endl ; + } + } + if(worldMPIRank == turbineMapGlobToProc[iTurb]) { + turbineMapProcToGlob[nTurbinesProc] = iTurb; + reverseTurbineMapProcToGlob[iTurb] = nTurbinesProc; + nTurbinesProc++ ; + } + turbineSetProcs.insert(turbineMapGlobToProc[iTurb]); + } + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + // scio.from_SC.resize(nTurbinesProc); + } + + int nProcsWithTurbines=0; + turbineProcs.resize(turbineSetProcs.size()); + + for (std::set::const_iterator p = turbineSetProcs.begin(); p != turbineSetProcs.end(); p++) { + turbineProcs[nProcsWithTurbines] = *p; + nProcsWithTurbines++ ; + } + + if (dryRun) { + if (nTurbinesProc > 0) { + std::ofstream turbineAllocFile; + turbineAllocFile.open("turbineAlloc." + std::to_string(worldMPIRank) + ".txt") ; + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + turbineAllocFile << "Proc " << worldMPIRank << " loc iTurb " << iTurb << " glob iTurb " << turbineMapProcToGlob[iTurb] << std::endl ; + } + turbineAllocFile.flush(); + turbineAllocFile.close() ; + } + } + + // // Construct a group containing all procs running atleast 1 turbine in FAST + // MPI_Group_incl(worldMPIGroup, nProcsWithTurbines, &turbineProcs[0], &fastMPIGroup) ; + // int fastMPIcommTag = MPI_Comm_create(mpiComm, fastMPIGroup, &fastMPIComm); + // if (MPI_COMM_NULL != fastMPIComm) { + // MPI_Comm_rank(fastMPIComm, &fastMPIRank); + // } + + turbineData.resize(nTurbinesProc); + velForceNodeData.resize(nTurbinesProc); + brFSIData.resize(nTurbinesProc); + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + + turbineData[iTurb].TurbineBasePos.resize(3); + turbineData[iTurb].TurbineHubPos.resize(3); + + int iTurbGlob = turbineMapProcToGlob[iTurb]; + turbineData[iTurb].TurbID = globTurbineData[iTurbGlob].TurbID; + turbineData[iTurb].sType = globTurbineData[iTurbGlob].sType; + turbineData[iTurb].FASTInputFileName = globTurbineData[iTurbGlob].FASTInputFileName ; + turbineData[iTurb].FASTRestartFileName = globTurbineData[iTurbGlob].FASTRestartFileName ; + for(int i=0;i<3;i++) { + turbineData[iTurb].TurbineBasePos[i] = globTurbineData[iTurbGlob].TurbineBasePos[i]; + turbineData[iTurb].TurbineHubPos[i] = globTurbineData[iTurbGlob].TurbineHubPos[i]; + } + turbineData[iTurb].numForcePtsBlade = globTurbineData[iTurbGlob].numForcePtsBlade; + turbineData[iTurb].numForcePtsTwr = globTurbineData[iTurbGlob].numForcePtsTwr; + turbineData[iTurb].azBlendMean = globTurbineData[iTurbGlob].azBlendMean; + turbineData[iTurb].azBlendDelta = globTurbineData[iTurbGlob].azBlendDelta; + turbineData[iTurb].velMean = globTurbineData[iTurbGlob].velMean; + turbineData[iTurb].windDir = globTurbineData[iTurbGlob].windDir; + turbineData[iTurb].zRef = globTurbineData[iTurbGlob].zRef; + turbineData[iTurb].shearExp = globTurbineData[iTurbGlob].shearExp; + + velForceNodeData[iTurb].resize(4); // To hold data for 4 time steps + brFSIData[iTurb].resize(4); + + } + + // Allocate memory for Turbine datastructure for all turbines + FAST_AllocateTurbines(&nTurbinesProc, &ErrStat, ErrMsg); + + // Allocate memory for ExtInfw Input types in FAST + extinfw_i_f_FAST.resize(nTurbinesProc) ; + extinfw_o_t_FAST.resize(nTurbinesProc) ; + + // Allocate memory for ExtLd Input types in FAST + extld_i_f_FAST.resize(nTurbinesProc) ; + extld_o_t_FAST.resize(nTurbinesProc) ; + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + // scio.from_SC.resize(nTurbinesProc); + } + +} + +void fast::OpenFAST::allocateMemory_postInit(int iTurbLoc) { + + if (turbineData[iTurbLoc].sType == EXTINFLOW) { + turbineData[iTurbLoc].nBRfsiPtsBlade = std::vector(turbineData[iTurbLoc].numBlades,0); + turbineData[iTurbLoc].nBRfsiPtsTwr = 0; + + if ( turbineData[iTurbLoc].inflowType == 1) { + // Inflow data is coming from inflow module + turbineData[iTurbLoc].numForcePtsTwr = 0; + turbineData[iTurbLoc].numForcePtsBlade = 0; + turbineData[iTurbLoc].numForcePts = 0; + turbineData[iTurbLoc].numVelPtsTwr = 0; + turbineData[iTurbLoc].numVelPtsBlade = 0; + turbineData[iTurbLoc].numVelPts = 0; + } else { + //Inflow data is coming from external program like a CFD solver + turbineData[iTurbLoc].numForcePts = 1 + turbineData[iTurbLoc].numForcePtsTwr + turbineData[iTurbLoc].numBlades * turbineData[iTurbLoc].numForcePtsBlade ; + turbineData[iTurbLoc].numVelPts = 1 + turbineData[iTurbLoc].numVelPtsTwr + turbineData[iTurbLoc].numBlades * turbineData[iTurbLoc].numVelPtsBlade ; + + int nfpts = get_numForcePtsLoc(iTurbLoc); + int nvelpts = get_numVelPtsLoc(iTurbLoc); + + velForceNodeData[iTurbLoc][3].xref_force.resize(3*nfpts); + for(int k=0; k<4; k++) { + velForceNodeData[iTurbLoc][k].x_vel.resize(3*nvelpts) ; + velForceNodeData[iTurbLoc][k].xdot_vel.resize(3*nvelpts) ; + velForceNodeData[iTurbLoc][k].vel_vel.resize(3*nvelpts) ; + velForceNodeData[iTurbLoc][k].x_force.resize(3*nfpts) ; + velForceNodeData[iTurbLoc][k].xdot_force.resize(3*nfpts) ; + velForceNodeData[iTurbLoc][k].orient_force.resize(9*nfpts) ; + velForceNodeData[iTurbLoc][k].vel_force.resize(3*nfpts) ; + velForceNodeData[iTurbLoc][k].force.resize(3*nfpts) ; + } + + if ( isDebug() ) { + for (int iNode=0; iNode < get_numVelPtsLoc(iTurbLoc); iNode++) { + std::cout << "Node " << iNode << " Position = " << extinfw_i_f_FAST[iTurbLoc].pxVel[iNode] << " " << extinfw_i_f_FAST[iTurbLoc].pyVel[iNode] << " " << extinfw_i_f_FAST[iTurbLoc].pzVel[iNode] << " " << std::endl ; + } + } + } + + } else if (turbineData[iTurbLoc].sType == EXTLOADS) { + turbineData[iTurbLoc].nBRfsiPtsBlade.resize(turbineData[iTurbLoc].numBlades); + int nTotBldNds = 0; + for(int i=0; i < turbineData[iTurbLoc].numBlades; i++) { + nTotBldNds += extld_i_f_FAST[iTurbLoc].nBladeNodes[i]; + turbineData[iTurbLoc].nBRfsiPtsBlade[i] = extld_i_f_FAST[iTurbLoc].nBladeNodes[i]; + turbineData[iTurbLoc].nTotBRfsiPtsBlade += turbineData[iTurbLoc].nBRfsiPtsBlade[i]; + } + turbineData[iTurbLoc].nBRfsiPtsTwr = extld_i_f_FAST[iTurbLoc].nTowerNodes[0]; + + // Allocate memory for reference position only for 1 time step - np1 + for(int k=0; k<4; k++) { + brFSIData[iTurbLoc][k].twr_ref_pos.resize(6*turbineData[iTurbLoc].nBRfsiPtsTwr); + brFSIData[iTurbLoc][k].twr_def.resize(6*turbineData[iTurbLoc].nBRfsiPtsTwr); + brFSIData[iTurbLoc][k].twr_vel.resize(6*turbineData[iTurbLoc].nBRfsiPtsTwr); + brFSIData[iTurbLoc][k].bld_rloc.resize(nTotBldNds); + brFSIData[iTurbLoc][k].bld_chord.resize(nTotBldNds); + brFSIData[iTurbLoc][k].bld_ref_pos.resize(6*nTotBldNds); + brFSIData[iTurbLoc][k].bld_def.resize(6*nTotBldNds); + brFSIData[iTurbLoc][k].bld_vel.resize(6*nTotBldNds); + brFSIData[iTurbLoc][k].twr_ld.resize(6*turbineData[iTurbLoc].nBRfsiPtsTwr); + brFSIData[iTurbLoc][k].bld_ld.resize(6*nTotBldNds); + brFSIData[iTurbLoc][k].hub_ref_pos.resize(6); + brFSIData[iTurbLoc][k].hub_def.resize(6); + brFSIData[iTurbLoc][k].hub_vel.resize(6); + brFSIData[iTurbLoc][k].nac_ref_pos.resize(6); + brFSIData[iTurbLoc][k].nac_def.resize(6); + brFSIData[iTurbLoc][k].nac_vel.resize(6); + brFSIData[iTurbLoc][k].hub_ref_pos.resize(6); + brFSIData[iTurbLoc][k].bld_pitch.resize(turbineData[iTurbLoc].numBlades); + brFSIData[iTurbLoc][k].bld_root_ref_pos.resize(6*turbineData[iTurbLoc].numBlades); + brFSIData[iTurbLoc][k].bld_root_def.resize(6*turbineData[iTurbLoc].numBlades); + } + } + +} + +void fast::OpenFAST::allocateTurbinesToProcsSimple() { + // Allocate turbines to each processor - round robin fashion + int nProcs ; + MPI_Comm_size(mpiComm, &nProcs); + for(int j = 0; j < nTurbinesGlob; j++) turbineMapGlobToProc[j] = j % nProcs ; +} + +void fast::OpenFAST::end() { + + // Deallocate types we allocated earlier + + if ( !dryRun) { + bool stopTheProgram = false; + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + FAST_End(&iTurb, &stopTheProgram); + } + } + + // MPI_Group_free(&fastMPIGroup); + // if (MPI_COMM_NULL != fastMPIComm) { + // MPI_Comm_free(&fastMPIComm); + // } + // MPI_Group_free(&worldMPIGroup); + + if(scStatus) { + std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; + // sc.end(); + } + +} + +int fast::OpenFAST::read_nlin_iters(int iTurb, int n_t_global, int ncid) { + + int nlin_iters = 0; + size_t count1 = 1; + size_t n_tsteps = n_t_global; + int ierr = nc_get_vara_int(ncid, 1, &n_tsteps, &count1, &nlin_iters); + + return nlin_iters; + +} + + +void fast::OpenFAST::readVelocityData(int iTurb, int n_t_global, int nlinIter, int ncid) { + + size_t n_tsteps = n_t_global; + const std::vector start_dim{n_tsteps, static_cast(nlinIter), 0}; + int nVelPts = get_numVelPtsLoc(iTurb); + const std::vector velPtsDataDims{1, 1, static_cast(3*nVelPts)}; + int ierr = nc_get_vara_double(ncid, 2, start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurb][fast::STATE_NP1].vel_vel.data()); +} + +int fast::OpenFAST::openVelocityDataFile(int iTurb) { + + int ncid; + std::stringstream velfile_fstream; + velfile_fstream << "turb_" ; + velfile_fstream << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurb]; + velfile_fstream << "_veldata.nc"; + std::string velfile_filename = velfile_fstream.str(); + int ierr = nc_open(velfile_filename.c_str(), NC_WRITE, &ncid); + check_nc_error(ierr, "nc_open"); + return ncid; + +} + +void fast::OpenFAST::prepareVelocityDataFile(int iTurb) { + + // Open the file in create mode - this will destory any file + int ncid; + std::stringstream velfile_fstream; + velfile_fstream << "turb_" ; + velfile_fstream << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurb]; + velfile_fstream << "_veldata.nc"; + std::string velfile_filename = velfile_fstream.str(); + int ierr = nc_create(velfile_filename.c_str(), NC_CLOBBER, &ncid); + check_nc_error(ierr, "nc_create"); + + //Define dimensions + int tmpDimID; + ierr = nc_def_dim(ncid, "n_tsteps", NC_UNLIMITED, &tmpDimID); + ierr = nc_def_dim(ncid, "n_nonlin_iters_max", 2, &tmpDimID); + ierr = nc_def_dim(ncid, "n_vel_pts_data", turbineData[iTurb].numVelPts*3, &tmpDimID); + + int tmpVarID; + tmpDimID = 0; + ierr = nc_def_var(ncid, "time", NC_DOUBLE, 1, &tmpDimID, &tmpVarID); + ierr = nc_def_var(ncid, "nlin_iters", NC_INT, 1, &tmpDimID, &tmpVarID); + const std::vector velPtsDataDims{0, 1, 2}; + ierr = nc_def_var(ncid, "vel_vel", NC_DOUBLE, 3, velPtsDataDims.data(), &tmpVarID); + + //! Indicate that we are done defining variables, ready to write data + ierr = nc_enddef(ncid); + check_nc_error(ierr, "nc_enddef"); + ierr = nc_close(ncid); + check_nc_error(ierr, "nc_close"); +} + +void fast::OpenFAST::writeVelocityData(int iTurb, int n_t_global, int nlinIter) { + + /* // NetCDF stuff to write velocity data to file */ + int ncid; + //Find the file and open it in append mode + std::stringstream velfile_ss; + velfile_ss << "turb_" ; + velfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurb]; + velfile_ss << "_veldata.nc"; + std::string vel_filename = velfile_ss.str(); + int ierr = nc_open(vel_filename.c_str(), NC_WRITE, &ncid); + check_nc_error(ierr, "nc_open"); + + size_t count1=1; + size_t n_tsteps = (n_t_global/nSubsteps_)+1; + double curTime = (n_t_global + nSubsteps_) * dtFAST; + ierr = nc_put_vara_double(ncid, 0, &n_tsteps, &count1, &curTime); + int nVelPts = get_numVelPtsLoc(iTurb) ; + const std::vector velPtsDataDims{1, 1, static_cast(3*nVelPts)}; + const std::vector start_dim{static_cast(n_tsteps),static_cast(nlinIter),0}; + + std::cout << "Writing velocity data at time step " << n_tsteps << ", nonlinear iteration " << nlinIter << std::endl ; + ierr = nc_put_vara_double(ncid, 2, start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurb][3].vel_vel.data()); + nlinIter += 1; // To account for 0-based indexing + ierr = nc_put_vara_int(ncid, 1, &n_tsteps, &count1, &nlinIter); + + nc_close(ncid); + } -void fast::OpenFAST::getForceNodeOrientation(double* currentOrientation, int iNode, int iTurbGlob, int nSize) { - assert(nSize==9); - // Set orientation at current node of current turbine - int iTurbLoc = get_localTurbNo(iTurbGlob); - for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numForcePtsLoc(iTurbLoc); - for(int i=0;i<9;i++) { - currentOrientation[i] = cDriver_Input_from_FAST[iTurbLoc].pOrientation[iNode*9+i] ; +void fast::OpenFAST::send_data_to_openfast(fast::timeStep t) { + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + if ( (turbineData[iTurb].sType == EXTINFLOW) && (turbineData[iTurb].inflowType == 2) ) { + int nvelpts = get_numVelPtsLoc(iTurb); + for (int iNodeVel=0; iNodeVel < nvelpts; iNodeVel++) { + extinfw_o_t_FAST[iTurb].u[iNodeVel] = velForceNodeData[iTurb][t].vel_vel[iNodeVel*3+0]; + extinfw_o_t_FAST[iTurb].v[iNodeVel] = velForceNodeData[iTurb][t].vel_vel[iNodeVel*3+1]; + extinfw_o_t_FAST[iTurb].w[iNodeVel] = velForceNodeData[iTurb][t].vel_vel[iNodeVel*3+2]; + } + } else if(turbineData[iTurb].sType == EXTLOADS) { + + int nBlades = turbineData[iTurb].numBlades; + int iRunTot = 0; + for(int i=0; i < nBlades; i++) { + int nPtsBlade = turbineData[iTurb].nBRfsiPtsBlade[i]; + for (int j=0; j < nPtsBlade; j++) { + for (int k=0; k<6; k++) { + extld_o_t_FAST[iTurb].bldLd[iRunTot*6+k] = brFSIData[iTurb][t].bld_ld[iRunTot*6+k]; + } + iRunTot++; + } + } + + int nPtsTwr = turbineData[iTurb].nBRfsiPtsTwr; + for (int i=0; i < nPtsTwr*6; i++) + extld_o_t_FAST[iTurb].twrLd[i] = brFSIData[iTurb][t].twr_ld[i]; + + } + + } +} + +void fast::OpenFAST::send_data_to_openfast(double ss_time) { + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + if (turbineData[iTurb].inflowType == 2) { + int nvelpts = get_numVelPtsLoc(iTurb); + for (int iNodeVel=0; iNodeVel < nvelpts; iNodeVel++) { + extinfw_o_t_FAST[iTurb].u[iNodeVel] = velForceNodeData[iTurb][fast::STATE_N].vel_vel[iNodeVel*3+0] + ss_time * (velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+0] - velForceNodeData[iTurb][fast::STATE_N].vel_vel[iNodeVel*3+0]); + extinfw_o_t_FAST[iTurb].v[iNodeVel] = velForceNodeData[iTurb][fast::STATE_N].vel_vel[iNodeVel*3+1] + ss_time * (velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+1] - velForceNodeData[iTurb][fast::STATE_N].vel_vel[iNodeVel*3+1]); + extinfw_o_t_FAST[iTurb].w[iNodeVel] = velForceNodeData[iTurb][fast::STATE_N].vel_vel[iNodeVel*3+2] + ss_time * (velForceNodeData[iTurb][fast::STATE_NP1].vel_vel[iNodeVel*3+2] - velForceNodeData[iTurb][fast::STATE_N].vel_vel[iNodeVel*3+2]); + } + } else if(turbineData[iTurb].sType == EXTLOADS) { + + int nBlades = turbineData[iTurb].numBlades; + int iRunTot = 0; + for(int i=0; i < nBlades; i++) { + int nPtsBlade = turbineData[iTurb].nBRfsiPtsBlade[i]; + for (int j=0; j < nPtsBlade; j++) { + for (int k=0; k<6; k++) { + extld_o_t_FAST[iTurb].bldLd[iRunTot*6+k] = brFSIData[iTurb][fast::STATE_N].bld_ld[iRunTot*6+k] + ss_time * (brFSIData[iTurb][fast::STATE_NP1].bld_ld[iRunTot*6+k] - brFSIData[iTurb][fast::STATE_N].bld_ld[iRunTot*6+k]); + } + iRunTot++; + } + } + + int nPtsTwr = turbineData[iTurb].nBRfsiPtsTwr; + for (int i=0; i < nPtsTwr*6; i++) + extld_o_t_FAST[iTurb].twrLd[i] = brFSIData[iTurb][fast::STATE_N].twr_ld[i] + ss_time * (brFSIData[iTurb][fast::STATE_NP1].twr_ld[i] - brFSIData[iTurb][fast::STATE_N].twr_ld[i]); + + } + } + +} + +void fast::OpenFAST::get_data_from_openfast(timeStep t) { + + + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + + if(turbineData[iTurb].sType == EXTINFLOW) { + + if (turbineData[iTurb].inflowType == 2) { + int nvelpts = get_numVelPtsLoc(iTurb); + int nfpts = get_numForcePtsLoc(iTurb); + for (int i=0; i velPtsDataDims{1, 1, static_cast(3*nvelpts)}; + const std::vector forcePtsDataDims{1, 1, static_cast(3*nfpts)}; + const std::vector forcePtsOrientDataDims{1, 1, static_cast(9*nfpts)}; + + ierr = nc_get_var_double(ncid, ncRstVarIDs_["xref_force"], velForceNodeData[iTurbLoc][fast::STATE_NP1].xref_force.data()); + + for (size_t j=0; j < 4; j++) { // Loop over states - NM2, STATE_NM1, N, NP1 + + const std::vector start_dim{n_tsteps,j,0}; + + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["x_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_vel.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["xdot_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_vel.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["vel_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].vel_vel.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["x_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_force.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["xdot_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_force.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["vel_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].vel_force.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].force.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["orient_force"], start_dim.data(), forcePtsOrientDataDims.data(), velForceNodeData[iTurbLoc][j].orient_force.data()); + + } + + } else if (turbineData[iTurbLoc].sType == EXTLOADS) { + + int nBRfsiPtsTwr = turbineData[iTurbLoc].nBRfsiPtsTwr; + int nTotBRfsiPtsBlade = turbineData[iTurbLoc].nTotBRfsiPtsBlade; + int nBlades = turbineData[iTurbLoc].numBlades; + const std::vector twrDataDims{1, 1, static_cast(6*nBRfsiPtsTwr)}; + const std::vector bldDataDims{1, 1, static_cast(6*nTotBRfsiPtsBlade)}; + const std::vector bldRootDataDims{1, 1, static_cast(6*nBlades)}; + const std::vector bldPitchDataDims{1, 1, static_cast(nBlades)}; + const std::vector ptDataDims{1, 1, 6}; + + for (size_t j=0; j < 4; j++) { // Loop over states - NM2, STATE_NM1, N, NP1 + + const std::vector start_dim{n_tsteps, j, 0}; + + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["twr_def"], start_dim.data(), twrDataDims.data(), brFSIData[iTurbLoc][j].twr_def.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["twr_vel"], start_dim.data(), twrDataDims.data(), brFSIData[iTurbLoc][j].twr_vel.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["twr_ld"], start_dim.data(), twrDataDims.data(), brFSIData[iTurbLoc][j].twr_ld.data()); + + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["bld_def"], start_dim.data(), bldDataDims.data(), brFSIData[iTurbLoc][j].bld_def.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["bld_vel"], start_dim.data(), bldDataDims.data(), brFSIData[iTurbLoc][j].bld_vel.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["bld_ld"], start_dim.data(), bldDataDims.data(), brFSIData[iTurbLoc][j].bld_ld.data()); + + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["hub_def"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].hub_def.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["hub_vel"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].hub_vel.data()); + + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["nac_def"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].nac_def.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["nac_vel"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].nac_vel.data()); + + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["bld_root_def"], start_dim.data(), bldRootDataDims.data(), brFSIData[iTurbLoc][j].bld_root_def.data()); + ierr = nc_get_vara_double(ncid, ncRstVarIDs_["bld_pitch"], start_dim.data(), bldPitchDataDims.data(), brFSIData[iTurbLoc][j].bld_pitch.data()); + + } + + + + } + + nc_close(ncid); + +} + +void fast::OpenFAST::cross(double * a, double * b, double * aCrossb) { + + aCrossb[0] = a[1]*b[2] - a[2]*b[1]; + aCrossb[1] = a[2]*b[0] - a[0]*b[2]; + aCrossb[2] = a[0]*b[1] - a[1]*b[0]; + +} + + +//! Apply a DCM rotation 'dcm' to a vector 'r' into 'rRot'. To optionally transpose the rotation, set 'tranpose=-1.0'. +void fast::OpenFAST::applyDCMrotation(double * dcm, double * r, double *rRot, double transpose) { + + if (transpose > 0) { + for(size_t i=0; i < 3; i++) { + rRot[i] = 0.0; + for(size_t j=0; j < 3; j++) + rRot[i] += dcm[i*3+j] * r[j]; + } + } else { + for(size_t i=0; i < 3; i++) { + rRot[i] = 0.0; + for(size_t j=0; j < 3; j++) + rRot[i] += dcm[j*3+i] * r[j]; + } + } +} + +//! Apply a Wiener-Milenkovic rotation 'wm' to a vector 'r' into 'rRot'. To optionally transpose the rotation, set 'tranpose=-1.0'. +void fast::OpenFAST::applyWMrotation(double * wm, double * r, double *rRot, double transpose) { + + double wm0 = 2.0-0.125*dot(wm, wm); + double nu = 2.0/(4.0-wm0); + double cosPhiO2 = 0.5*wm0*nu; + std::vector wmCrossR(3,0.0); + cross(wm, r, wmCrossR.data()); + std::vector wmCrosswmCrossR(3,0.0); + cross(wm, wmCrossR.data(), wmCrosswmCrossR.data()); + + for(size_t i=0; i < 3; i++) + rRot[i] = r[i] + transpose * nu * cosPhiO2 * wmCrossR[i] + 0.5 * nu * nu * wmCrosswmCrossR[i]; + +} + + +void fast::OpenFAST::writeOutputFile(int iTurbLoc, int n_t_global) { + + int ncid; + //Open the file in append mode + std::stringstream outfile_ss; + outfile_ss << "turb_" ; + outfile_ss << std::setfill('0') << std::setw(2) << iTurbLoc; + outfile_ss << "_output.nc"; + std::string defloads_filename = outfile_ss.str(); + int ierr = nc_open(defloads_filename.c_str(), NC_WRITE, &ncid); + check_nc_error(ierr, "nc_open"); + + size_t count1=1; + int tStepRatio = dtDriver/dtFAST; + size_t n_tsteps = n_t_global/tStepRatio/outputFreq_ - 1; + double curTime = n_t_global * dtFAST; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["time"], &n_tsteps, &count1, &curTime); + + if (turbineData[iTurbLoc].sType == EXTINFLOW) { + + // Nothing to do here yet + int nBlades = get_numBladesLoc(iTurbLoc); + int nBldPts = get_numForcePtsBladeLoc(iTurbLoc); + int nTwrPts = get_numForcePtsTwrLoc(iTurbLoc); + std::vector tmpArray; + + tmpArray.resize(nTwrPts); + { + int node_twr_start = (1 + nBlades * nBldPts)*3; + std::vector count_dim{1,1,static_cast(nTwrPts)}; + for (size_t iDim=0; iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].x_force[node_twr_start+i*3+iDim] - velForceNodeData[iTurbLoc][3].xref_force[node_twr_start+i*3+iDim] ; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_disp"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + for (size_t iDim=0; iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].xdot_force[node_twr_start+i*3+iDim] ; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_vel"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + for (size_t iDim=0;iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].force[node_twr_start+i*3+iDim] ; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_ld"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + + tmpArray.resize(nBldPts); + { + std::vector count_dim{1,1,1,static_cast(nBldPts)}; + for (size_t iDim=0;iDim < 3; iDim++) { + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + int node_bld_start = (1 + iBlade * nBldPts); + for (auto i=0; i < nBldPts; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].x_force[(node_bld_start+i)*3+iDim] - velForceNodeData[iTurbLoc][3].xref_force[(node_bld_start+i)*3+iDim] ; + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_disp"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + int node_bld_start = (1 + iBlade * nBldPts); + for (auto i=0; i < nBldPts; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].xdot_force[(node_bld_start+i)*3+iDim] ; + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_vel"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + int node_bld_start = (1 + iBlade * nBldPts); + for (auto i=0; i < nBldPts; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].force[(node_bld_start+i)*3+iDim] ; + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_ld"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + + std::vector ld_loc(3*nBlades*nBldPts,0.0); + for (auto iBlade=0; iBlade < nBlades; iBlade++) { + int node_bld_start = (1 + iBlade * nBldPts); + for (auto i=0; i < nBldPts; i++) { + applyDCMrotation(&velForceNodeData[iTurbLoc][3].orient_force[(node_bld_start + i)*9], &velForceNodeData[iTurbLoc][3].force[(node_bld_start+i)*3], &ld_loc[(node_bld_start-1)*3]); + } + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + int node_bld_start = (iBlade * nBldPts); + for (auto i=0; i < nBldPts; i++) + tmpArray[i] = ld_loc[(node_bld_start+i)*3+iDim]; + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_ld_loc"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + } + + tmpArray.resize(3); + for (auto i=0; i < 3; i++) + tmpArray[i] = velForceNodeData[iTurbLoc][3].x_force[i] - velForceNodeData[iTurbLoc][3].xref_force[i]; + std::vector start_dim{n_tsteps, 0}; + std::vector count_dim{1,3}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["hub_disp"], start_dim.data(), count_dim.data(), tmpArray.data()); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["hub_vel"], start_dim.data(), count_dim.data(), &velForceNodeData[iTurbLoc][3].xdot_force[0]); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["hub_ld"], start_dim.data(), count_dim.data(), &velForceNodeData[iTurbLoc][3].force[0]); + + } else if (turbineData[iTurbLoc].sType == EXTLOADS) { + + int nBlades = turbineData[iTurbLoc].numBlades; + int nTwrPts = turbineData[iTurbLoc].nBRfsiPtsTwr; + int nTotBldPts = turbineData[iTurbLoc].nTotBRfsiPtsBlade; + int nBldPts = nTotBldPts/nBlades; + + std::vector tmpArray; + tmpArray.resize(nTwrPts); + std::vector count_dim{1,1,static_cast(nTwrPts)}; + for (size_t iDim=0;iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].twr_def[i*6+iDim] ; + // std::cerr << "Twr displacement Node " << i << ", dimension " << iDim << " = " + // << brFSIData[iTurbLoc][3].twr_ref_pos[i*6+iDim] << " " + // << brFSIData[iTurbLoc][3].twr_def[i*6+iDim] << std::endl; + } + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_disp"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + + for (size_t iDim=0;iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = brFSIData[iTurbLoc][3].twr_def[i*6+3+iDim] ; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_orient"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + for (size_t iDim=0;iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = brFSIData[iTurbLoc][3].twr_vel[i*6+iDim] ; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_vel"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + for (size_t iDim=0;iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = brFSIData[iTurbLoc][3].twr_vel[i*6+3+iDim] ; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_rotvel"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + + for (size_t iDim=0;iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = brFSIData[iTurbLoc][3].twr_ld[i*6+iDim] ; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_ld"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + for (size_t iDim=0;iDim < 3; iDim++) { + for (auto i=0; i < nTwrPts; i++) + tmpArray[i] = brFSIData[iTurbLoc][3].twr_ld[i*6+3+iDim]; + std::vector start_dim{n_tsteps,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["twr_moment"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + + tmpArray.resize(nBldPts); + { + std::vector count_dim{1,1,1,static_cast(nBldPts)}; + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_def[(iStart*6)+iDim]; + iStart++; + } + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_disp"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_def[(iStart*6)+3+iDim]; + iStart++; + } + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_orient"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_vel[(iStart*6)+iDim]; + iStart++; + } + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_vel"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + for (size_t iDim=0; iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_vel[(iStart*6)+3+iDim]; + iStart++; + } + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_rotvel"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_ld[(iStart*6)+iDim]; + iStart++; + } + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_ld"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + + std::vector ld_loc(3*nTotBldPts,0.0); + for (auto i=0; i < nTotBldPts; i++) { + applyWMrotation(&brFSIData[iTurbLoc][3].bld_def[i*6+3], &brFSIData[iTurbLoc][3].bld_ld[i*6], &ld_loc[i*3]); + } + for (size_t iDim=0;iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = ld_loc[iStart*3+iDim]; + iStart++; + } + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_ld_loc"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + + for (size_t iDim=0; iDim < 3; iDim++) { + int iStart = 0 ; + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + for (auto i=0; i < nBldPts; i++) { + tmpArray[i] = brFSIData[iTurbLoc][3].bld_ld[(iStart*6)+3+iDim]; + iStart++; + } + std::vector start_dim{n_tsteps,iBlade,iDim,0}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_moment"], start_dim.data(), count_dim.data(), tmpArray.data()); + } + } + + } + + { + for (size_t iBlade=0; iBlade < nBlades; iBlade++) { + + std::vector start_dim{n_tsteps, iBlade, 0}; + std::vector count_dim{1,1,3}; + + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_root_disp"], + start_dim.data(), + count_dim.data(), + &brFSIData[iTurbLoc][3].bld_root_def[iBlade*6+0]); + + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_root_orient"], + start_dim.data(), + count_dim.data(), + &brFSIData[iTurbLoc][3].bld_root_def[iBlade*6+3]); + } + } + + { + std::vector start_dim{n_tsteps, 0}; + std::vector count_dim{1,3}; + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["hub_disp"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].hub_def[0]); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["hub_orient"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].hub_def[3]); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["hub_vel"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].hub_vel[0]); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["hub_rotvel"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].hub_vel[3]); + + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["nac_disp"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].nac_def[0]); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["nac_orient"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].nac_def[3]); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["nac_vel"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].nac_vel[0]); + ierr = nc_put_vara_double(ncid, ncOutVarIDs_["nac_rotvel"], start_dim.data(), count_dim.data(), &brFSIData[iTurbLoc][3].nac_vel[3]); } -} -void fast::OpenFAST::getRelativeVelForceNode(double* currentVelocity, int iNode, int iTurbGlob, int nSize) { - assert(nSize==3); - // Get relative velocity at current node of current turbine - int iTurbLoc = get_localTurbNo(iTurbGlob); - for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numForcePtsLoc(iTurbLoc); + } - currentVelocity[0] = forceNodeVel[iTurbLoc][iNode][0] - cDriver_Input_from_FAST[iTurbLoc].xdotForce[iNode]; - currentVelocity[1] = forceNodeVel[iTurbLoc][iNode][1] - cDriver_Input_from_FAST[iTurbLoc].ydotForce[iNode]; - currentVelocity[2] = forceNodeVel[iTurbLoc][iNode][2] - cDriver_Input_from_FAST[iTurbLoc].zdotForce[iNode]; -} + nc_close(ncid); -void fast::OpenFAST::getForce(double* currentForce, int iNode, int iTurbGlob, int nSize) { - assert(nSize==3); - // Set forces at current node of current turbine - int iTurbLoc = get_localTurbNo(iTurbGlob); - for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numForcePtsLoc(iTurbLoc); - currentForce[0] = -cDriver_Input_from_FAST[iTurbLoc].fx[iNode] ; - currentForce[1] = -cDriver_Input_from_FAST[iTurbLoc].fy[iNode] ; - currentForce[2] = -cDriver_Input_from_FAST[iTurbLoc].fz[iNode] ; -} -double fast::OpenFAST::getChord(int iNode, int iTurbGlob) { - // Return blade chord/tower diameter at current node of current turbine - int iTurbLoc = get_localTurbNo(iTurbGlob); - for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numForcePtsLoc(iTurbLoc); - return cDriver_Input_from_FAST[iTurbLoc].forceNodesChord[iNode] ; -} -void fast::OpenFAST::setVelocity(double* currentVelocity, int iNode, int iTurbGlob, int nSize) { - assert(nSize==3); - // Set velocity at current node of current turbine - - int iTurbLoc = get_localTurbNo(iTurbGlob); - for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numVelPtsLoc(iTurbLoc); - cDriver_Output_to_FAST[iTurbLoc].u[iNode] = currentVelocity[0]; - cDriver_Output_to_FAST[iTurbLoc].v[iNode] = currentVelocity[1]; - cDriver_Output_to_FAST[iTurbLoc].w[iNode] = currentVelocity[2]; } -void fast::OpenFAST::setVelocityForceNode(double* currentVelocity, int iNode, int iTurbGlob, int nSize) { - assert(nSize==3); - // Set velocity at current node of current turbine - - int iTurbLoc = get_localTurbNo(iTurbGlob); - for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numForcePtsLoc(iTurbLoc); +void fast::OpenFAST::writeRestartFile(int iTurbLoc, int n_t_global) { - for(int i=0; i rDistForce(nForcePtsBlade) ; - for(int j=0; j < nForcePtsBlade; j++) { - int iNodeForce = 1 + iBlade * nForcePtsBlade + j ; //The number of actuator force points is always the same for all blades - rDistForce[j] = std::sqrt( - (cDriver_Input_from_FAST[iTurb].pxForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pxForce[0])*(cDriver_Input_from_FAST[iTurb].pxForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pxForce[0]) - + (cDriver_Input_from_FAST[iTurb].pyForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pyForce[0])*(cDriver_Input_from_FAST[iTurb].pyForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pyForce[0]) - + (cDriver_Input_from_FAST[iTurb].pzForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pzForce[0])*(cDriver_Input_from_FAST[iTurb].pzForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pzForce[0]) - ); - } + int nvelpts = get_numVelPtsLoc(iTurbLoc); + int nfpts = get_numForcePtsLoc(iTurbLoc); - // Interpolate to the velocity nodes - int nVelPtsBlade = get_numVelPtsBladeLoc(iTurb); - for(int j=0; j < nVelPtsBlade; j++) { - int iNodeVel = 1 + iBlade * nVelPtsBlade + j ; //Assumes the same number of velocity (Aerodyn) nodes for all blades - double rDistVel = std::sqrt( - (cDriver_Input_from_FAST[iTurb].pxVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pxVel[0])*(cDriver_Input_from_FAST[iTurb].pxVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pxVel[0]) - + (cDriver_Input_from_FAST[iTurb].pyVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pyVel[0])*(cDriver_Input_from_FAST[iTurb].pyVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pyVel[0]) - + (cDriver_Input_from_FAST[iTurb].pzVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pzVel[0])*(cDriver_Input_from_FAST[iTurb].pzVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pzVel[0]) - ); - //Find nearest two force nodes - int jForceLower = 0; - while ( (rDistForce[jForceLower+1] < rDistVel) && ( jForceLower < (nForcePtsBlade-2)) ) { - jForceLower = jForceLower + 1; - } - int iNodeForceLower = 1 + iBlade * nForcePtsBlade + jForceLower ; - double rInterp = (rDistVel - rDistForce[jForceLower])/(rDistForce[jForceLower+1]-rDistForce[jForceLower]); - cDriver_Output_to_FAST[iTurb].u[iNodeVel] = forceNodeVel[iTurb][iNodeForceLower][0] + rInterp * (forceNodeVel[iTurb][iNodeForceLower+1][0] - forceNodeVel[iTurb][iNodeForceLower][0] ); - cDriver_Output_to_FAST[iTurb].v[iNodeVel] = forceNodeVel[iTurb][iNodeForceLower][1] + rInterp * (forceNodeVel[iTurb][iNodeForceLower+1][1] - forceNodeVel[iTurb][iNodeForceLower][1] ); - cDriver_Output_to_FAST[iTurb].w[iNodeVel] = forceNodeVel[iTurb][iNodeForceLower][2] + rInterp * (forceNodeVel[iTurb][iNodeForceLower+1][2] - forceNodeVel[iTurb][iNodeForceLower][2] ); - } + const std::vector velPtsDataDims{1, 1, static_cast(3*nvelpts)}; + const std::vector forcePtsDataDims{1, 1, static_cast(3*nfpts)}; + const std::vector forcePtsOrientDataDims{1, 1, static_cast(9*nfpts)}; + + for (size_t j=0; j < 4; j++) { // Loop over states - NM2, STATE_NM1, N, NP1 + + const std::vector start_dim{n_tsteps,j,0}; + + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["x_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_vel.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["xdot_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_vel.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["vel_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].vel_vel.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["x_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_force.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["xdot_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_force.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["vel_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].vel_force.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].force.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["orient_force"], start_dim.data(), forcePtsOrientDataDims.data(), velForceNodeData[iTurbLoc][j].orient_force.data()); } - // Now the tower if present and used - int nVelPtsTower = get_numVelPtsTwrLoc(iTurb); - if ( nVelPtsTower > 0 ) { + } else if (turbineData[iTurbLoc].sType == EXTLOADS) { - // Create interpolating parameter - Distance from first node from ground - int nForcePtsTower = get_numForcePtsTwrLoc(iTurb); - std::vector hDistForce(nForcePtsTower) ; - int iNodeBotTowerForce = 1 + nBlades * get_numForcePtsBladeLoc(iTurb); // The number of actuator force points is always the same for all blades - for(int j=0; j < nForcePtsTower; j++) { - int iNodeForce = iNodeBotTowerForce + j ; - hDistForce[j] = std::sqrt( - (cDriver_Input_from_FAST[iTurb].pxForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pxForce[iNodeBotTowerForce])*(cDriver_Input_from_FAST[iTurb].pxForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pxForce[iNodeBotTowerForce]) - + (cDriver_Input_from_FAST[iTurb].pyForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pyForce[iNodeBotTowerForce])*(cDriver_Input_from_FAST[iTurb].pyForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pyForce[iNodeBotTowerForce]) - + (cDriver_Input_from_FAST[iTurb].pzForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pzForce[iNodeBotTowerForce])*(cDriver_Input_from_FAST[iTurb].pzForce[iNodeForce] - cDriver_Input_from_FAST[iTurb].pzForce[iNodeBotTowerForce]) - ); - } + int nPtsTwr = turbineData[iTurbLoc].nBRfsiPtsTwr; + int nTotBldPts = turbineData[iTurbLoc].nTotBRfsiPtsBlade; + int nBlades = turbineData[iTurbLoc].numBlades; + const std::vector twrDataDims{1, 1, static_cast(6*nPtsTwr)}; + const std::vector bldDataDims{1, 1, static_cast(6*nTotBldPts)}; + const std::vector bldRootDataDims{1, 1, static_cast(6*nBlades)}; + const std::vector bldPitchDataDims{1, 1, static_cast(nBlades)}; + const std::vector ptDataDims{1, 1, 6}; - int iNodeBotTowerVel = 1 + nBlades * get_numVelPtsBladeLoc(iTurb); // Assumes the same number of velocity (Aerodyn) nodes for all blades - for(int j=0; j < nVelPtsTower; j++) { - int iNodeVel = iNodeBotTowerVel + j ; - double hDistVel = std::sqrt( - (cDriver_Input_from_FAST[iTurb].pxVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pxVel[iNodeBotTowerVel])*(cDriver_Input_from_FAST[iTurb].pxVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pxVel[iNodeBotTowerVel]) - + (cDriver_Input_from_FAST[iTurb].pyVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pyVel[iNodeBotTowerVel])*(cDriver_Input_from_FAST[iTurb].pyVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pyVel[iNodeBotTowerVel]) - + (cDriver_Input_from_FAST[iTurb].pzVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pzVel[iNodeBotTowerVel])*(cDriver_Input_from_FAST[iTurb].pzVel[iNodeVel] - cDriver_Input_from_FAST[iTurb].pzVel[iNodeBotTowerVel]) - ); - //Find nearest two force nodes - int jForceLower = 0; - while ( (hDistForce[jForceLower+1] < hDistVel) && ( jForceLower < (nForcePtsTower-2)) ) { - jForceLower = jForceLower + 1; - } - int iNodeForceLower = iNodeBotTowerForce + jForceLower ; - double rInterp = (hDistVel - hDistForce[jForceLower])/(hDistForce[jForceLower+1]-hDistForce[jForceLower]); - cDriver_Output_to_FAST[iTurb].u[iNodeVel] = forceNodeVel[iTurb][iNodeForceLower][0] + rInterp * (forceNodeVel[iTurb][iNodeForceLower+1][0] - forceNodeVel[iTurb][iNodeForceLower][0] ); - cDriver_Output_to_FAST[iTurb].v[iNodeVel] = forceNodeVel[iTurb][iNodeForceLower][1] + rInterp * (forceNodeVel[iTurb][iNodeForceLower+1][1] - forceNodeVel[iTurb][iNodeForceLower][1] ); - cDriver_Output_to_FAST[iTurb].w[iNodeVel] = forceNodeVel[iTurb][iNodeForceLower][2] + rInterp * (forceNodeVel[iTurb][iNodeForceLower+1][2] - forceNodeVel[iTurb][iNodeForceLower][2] ); - } + for (size_t j=0; j < 4; j++) { // Loop over states - STATE_NM2, STATE_NM1, STATE_N, STATE_NP1 + + const std::vector start_dim{n_tsteps, j, 0}; + + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["twr_def"], start_dim.data(), twrDataDims.data(), brFSIData[iTurbLoc][j].twr_def.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["twr_vel"], start_dim.data(), twrDataDims.data(), brFSIData[iTurbLoc][j].twr_vel.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["twr_ld"], start_dim.data(), twrDataDims.data(), brFSIData[iTurbLoc][j].twr_ld.data()); + + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["bld_def"], start_dim.data(), bldDataDims.data(), brFSIData[iTurbLoc][j].bld_def.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["bld_vel"], start_dim.data(), bldDataDims.data(), brFSIData[iTurbLoc][j].bld_vel.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["bld_ld"], start_dim.data(), bldDataDims.data(), brFSIData[iTurbLoc][j].bld_ld.data()); + + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["hub_def"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].hub_def.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["hub_vel"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].hub_vel.data()); + + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["nac_def"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].nac_def.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["nac_vel"], start_dim.data(), ptDataDims.data(), brFSIData[iTurbLoc][j].nac_vel.data()); + + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["bld_root_def"], start_dim.data(), bldRootDataDims.data(), brFSIData[iTurbLoc][j].bld_root_def.data()); + ierr = nc_put_vara_double(ncid, ncRstVarIDs_["bld_pitch"], start_dim.data(), bldPitchDataDims.data(), brFSIData[iTurbLoc][j].bld_pitch.data()); } + } + + nc_close(ncid); + + } -void fast::OpenFAST::computeTorqueThrust(int iTurbGlob, std::vector & torque, std::vector & thrust) { +// Mostly Blade-resolved stuff after this - //Compute the torque and thrust based on the forces at the actuator nodes - std::vector relLoc(3,0.0); - std::vector rPerpShft(3); - thrust[0] = 0.0; thrust[1] = 0.0; thrust[2] = 0.0; - torque[0] = 0.0; torque[1] = 0.0; torque[2] = 0.0; +void fast::OpenFAST::get_ref_positions_from_openfast(int iTurb) { - std::vector hubShftVec(3); - getHubShftDir(hubShftVec, iTurbGlob); + if(turbineData[iTurb].sType == EXTLOADS) { - int iTurbLoc = get_localTurbNo(iTurbGlob) ; - for (int k=0; k < get_numBladesLoc(iTurbLoc); k++) { - for (int j=0; j < numForcePtsBlade[iTurbLoc]; j++) { - int iNode = 1 + numForcePtsBlade[iTurbLoc]*k + j ; + for (int i=0; i < 3; i++) { + brFSIData[iTurb][fast::STATE_NP1].hub_ref_pos[i] = extld_i_f_FAST[iTurb].hubRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; + brFSIData[iTurb][fast::STATE_NP1].nac_ref_pos[i] = extld_i_f_FAST[iTurb].nacRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; + } + + int nBlades = turbineData[iTurb].numBlades; + int iRunTot = 0; + for (int i=0; i < nBlades; i++) { + int nPtsBlade = turbineData[iTurb].nBRfsiPtsBlade[i]; + for (int j=0; j < nPtsBlade; j++) { + for (int k=0; k < 3; k++) { + brFSIData[iTurb][fast::STATE_NP1].bld_ref_pos[iRunTot*6+k] = extld_i_f_FAST[iTurb].bldRefPos[iRunTot*6+k] + turbineData[iTurb].TurbineBasePos[k]; + brFSIData[iTurb][fast::STATE_NP1].bld_ref_pos[iRunTot*6+k+3] = extld_i_f_FAST[iTurb].bldRefPos[iRunTot*6+k+3]; + } + brFSIData[iTurb][fast::STATE_NP1].bld_chord[iRunTot] = extld_i_f_FAST[iTurb].bldChord[iRunTot]; + brFSIData[iTurb][fast::STATE_NP1].bld_rloc[iRunTot] = extld_i_f_FAST[iTurb].bldRloc[iRunTot]; + iRunTot++; + } - thrust[0] = thrust[0] + cDriver_Input_from_FAST[iTurbLoc].fx[iNode] ; - thrust[1] = thrust[1] + cDriver_Input_from_FAST[iTurbLoc].fy[iNode] ; - thrust[2] = thrust[2] + cDriver_Input_from_FAST[iTurbLoc].fz[iNode] ; + for (int k=0; k < 3; k++) { + brFSIData[iTurb][fast::STATE_NP1].bld_root_ref_pos[i*6+k] = extld_i_f_FAST[iTurb].bldRootRefPos[i*6+k] + turbineData[iTurb].TurbineBasePos[k]; + brFSIData[iTurb][fast::STATE_NP1].bld_root_ref_pos[i*6+k+3] = extld_i_f_FAST[iTurb].bldRootRefPos[i*6+k+3]; + } - relLoc[0] = cDriver_Input_from_FAST[iTurbLoc].pxForce[iNode] - cDriver_Input_from_FAST[iTurbLoc].pxForce[0]; - relLoc[1] = cDriver_Input_from_FAST[iTurbLoc].pyForce[iNode] - cDriver_Input_from_FAST[iTurbLoc].pyForce[0]; - relLoc[2] = cDriver_Input_from_FAST[iTurbLoc].pzForce[iNode] - cDriver_Input_from_FAST[iTurbLoc].pzForce[0]; + } - double rDotHubShftVec = relLoc[0]*hubShftVec[0] + relLoc[1]*hubShftVec[1] + relLoc[2]*hubShftVec[2]; - for (int j=0; j < 3; j++) rPerpShft[j] = relLoc[j] - rDotHubShftVec * hubShftVec[j]; + int nPtsTwr = turbineData[iTurb].nBRfsiPtsTwr; + for (int i=0; i < nPtsTwr; i++) { + for (int j = 0; j < 3; j++) { + brFSIData[iTurb][fast::STATE_NP1].twr_ref_pos[i*6+j] = extld_i_f_FAST[iTurb].twrRefPos[i*6+j] + turbineData[iTurb].TurbineBasePos[j]; + brFSIData[iTurb][fast::STATE_NP1].twr_ref_pos[i*6+j+3] = extld_i_f_FAST[iTurb].twrRefPos[i*6+j+3]; + } + } - torque[0] = torque[0] + rPerpShft[1] * cDriver_Input_from_FAST[iTurbLoc].fz[iNode] - rPerpShft[2] * cDriver_Input_from_FAST[iTurbLoc].fy[iNode] + cDriver_Input_from_FAST[iTurbLoc].momentx[iNode] ; - torque[1] = torque[1] + rPerpShft[2] * cDriver_Input_from_FAST[iTurbLoc].fx[iNode] - rPerpShft[0] * cDriver_Input_from_FAST[iTurbLoc].fz[iNode] + cDriver_Input_from_FAST[iTurbLoc].momenty[iNode] ; - torque[2] = torque[2] + rPerpShft[0] * cDriver_Input_from_FAST[iTurbLoc].fy[iNode] - rPerpShft[1] * cDriver_Input_from_FAST[iTurbLoc].fx[iNode] + cDriver_Input_from_FAST[iTurbLoc].momentz[iNode] ; + } else if(turbineData[iTurb].sType == EXTINFLOW) { + + if (turbineData[iTurb].inflowType == 2) { + int nfpts = get_numForcePtsLoc(iTurb); + for (auto i=0; i 0 ) { - return TOWER; - } else { - return BLADE; + int nBlades = get_numBladesLoc(iTurbLoc); + int iRunTot = 0; + for (int i=0; i < nBlades; i++) { + int nPtsBlade = turbineData[iTurbLoc].nBRfsiPtsBlade[i]; + for(int j=0; j 0 ) { - return TOWER; - } else { - return BLADE; + int nBlades = get_numBladesLoc(iTurbLoc); + int iRunTot = 0; + for (int i=0; i < nBlades; i++) { + int nPtsBlade = turbineData[iTurbLoc].nBRfsiPtsBlade[i]; + for(int j=0; j 0) closeVelocityDataFile(nt_global, velNodeDataFile); +} - if ( !dryRun) { - bool stopTheProgram = false; - for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - FAST_End(&iTurb, &stopTheProgram); - } - FAST_DeallocateTurbines(&ErrStat, ErrMsg); - } +void fast::OpenFAST::getTowerRefPositions(double* twrRefPos, int iTurbGlob, int nSize) { - MPI_Group_free(&fastMPIGroup); - if (MPI_COMM_NULL != fastMPIComm) { - MPI_Comm_free(&fastMPIComm); + int iTurbLoc = get_localTurbNo(iTurbGlob); + int nPtsTwr = turbineData[iTurbLoc].nBRfsiPtsTwr; + for (int i=0; i < nPtsTwr; i++) { + for (int j=0; j < nSize; j++) { + twrRefPos[i*6+j] = brFSIData[iTurbLoc][fast::STATE_NP1].twr_ref_pos[i*6+j]; + } } - MPI_Group_free(&worldMPIGroup); - if(scStatus) { - std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; - // sc.end(); - } } -void fast::OpenFAST::readVelocityData(int nTimesteps) { +void fast::OpenFAST::getTowerDisplacements(double* twrDefl, double* twrVel, int iTurbGlob, fast::timeStep t, int nSize) { - int nTurbines; - - hid_t velDataFile = H5Fopen(("velDatafile." + std::to_string(worldMPIRank) + ".h5").c_str(), H5F_ACC_RDWR, H5P_DEFAULT); - - { - hid_t attr = H5Aopen(velDataFile, "nTurbines", H5P_DEFAULT); - herr_t ret = H5Aread(attr, H5T_NATIVE_INT, &nTurbines) ; - H5Aclose(attr); + int iTurbLoc = get_localTurbNo(iTurbGlob); + int nPtsTwr = turbineData[iTurbLoc].nBRfsiPtsTwr; + for (int i=0; i < nPtsTwr; i++) { + for (int j=0; j < nSize; j++) { + twrDefl[i*6+j] = brFSIData[iTurbLoc][t].twr_def[i*6+j]; + twrVel[i*6+j] = brFSIData[iTurbLoc][t].twr_vel[i*6+j]; + } } - // Allocate memory and read the velocity data. - velNodeData.resize(nTurbines); - for (int iTurb=0; iTurb < nTurbines; iTurb++) { - int nVelPts = get_numVelPtsLoc(iTurb) ; - velNodeData[iTurb].resize(nTimesteps*nVelPts*6) ; - hid_t dset_id = H5Dopen2(velDataFile, ("/turbine" + std::to_string(iTurb)).c_str(), H5P_DEFAULT); - hid_t dspace_id = H5Dget_space(dset_id); +} - hsize_t start[3]; start[1] = 0; start[2] = 0; - hsize_t count[3]; count[0] = 1; count[1] = nVelPts; count[2] = 6; - hid_t mspace_id = H5Screate_simple(3, count, NULL); +void fast::OpenFAST::getHubRefPosition(double* hubRefPos, int iTurbGlob, int nSize) { - for (int iStep=0; iStep < nTimesteps; iStep++) { - start[0] = iStep; - H5Sselect_hyperslab(dspace_id, H5S_SELECT_SET, start, NULL, count, NULL); - herr_t status = H5Dread(dset_id, H5T_NATIVE_DOUBLE, mspace_id, dspace_id, H5P_DEFAULT, &velNodeData[iTurb][iStep*nVelPts*6] ); - } + int iTurbLoc = get_localTurbNo(iTurbGlob); + for (int j=0; j < nSize; j++) + hubRefPos[j] = brFSIData[iTurbLoc][fast::STATE_NP1].hub_ref_pos[j]; - herr_t status = H5Dclose(dset_id); - } } -hid_t fast::OpenFAST::openVelocityDataFile(bool createFile) { +void fast::OpenFAST::getHubDisplacement(double* hubDefl, double* hubVel, int iTurbGlob, fast::timeStep t, int nSize) { - hid_t velDataFile; - if (createFile) { - // Open the file in create mode - velDataFile = H5Fcreate(("velDatafile." + std::to_string(worldMPIRank) + ".h5").c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + int iTurbLoc = get_localTurbNo(iTurbGlob); + for (int j=0; j < nSize; j++) { + hubDefl[j] = brFSIData[iTurbLoc][t].hub_def[j]; + hubVel[j] = brFSIData[iTurbLoc][t].hub_vel[j]; + } - { - hsize_t dims[1]; - dims[0] = 1; - hid_t dataSpace = H5Screate_simple(1, dims, NULL); - hid_t attr = H5Acreate2(velDataFile, "nTurbines", H5T_NATIVE_INT, dataSpace, H5P_DEFAULT, H5P_DEFAULT) ; - herr_t status = H5Awrite(attr, H5T_NATIVE_INT, &nTurbinesProc); - status = H5Aclose(attr); - status = H5Sclose(dataSpace); - - dataSpace = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(velDataFile, "nTimesteps", H5T_NATIVE_INT, dataSpace, H5P_DEFAULT, H5P_DEFAULT) ; - status = H5Aclose(attr); - status = H5Sclose(dataSpace); - } +} - int ntMax = tMax/dtFAST ; +void fast::OpenFAST::getNacelleRefPosition(double* nacRefPos, int iTurbGlob, int nSize) { - for (int iTurb = 0; iTurb < nTurbinesProc; iTurb++) { - int nVelPts = get_numVelPtsLoc(iTurb); - hsize_t dims[3]; - dims[0] = ntMax; dims[1] = nVelPts; dims[2] = 6 ; + int iTurbLoc = get_localTurbNo(iTurbGlob); + for (int j=0; j < nSize; j++) + nacRefPos[j] = brFSIData[iTurbLoc][fast::STATE_NP1].nac_ref_pos[j]; - hsize_t chunk_dims[3]; - chunk_dims[0] = 1; chunk_dims[1] = nVelPts; chunk_dims[2] = 6; - hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE); - H5Pset_chunk(dcpl_id, 3, chunk_dims); +} - hid_t dataSpace = H5Screate_simple(3, dims, NULL); - hid_t dataSet = H5Dcreate(velDataFile, ("/turbine" + std::to_string(iTurb)).c_str(), H5T_NATIVE_DOUBLE, dataSpace, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); - herr_t status = H5Pclose(dcpl_id); - status = H5Dclose(dataSet); - status = H5Sclose(dataSpace); - } +void fast::OpenFAST::getNacelleDisplacement(double* nacDefl, double* nacVel, int iTurbGlob, fast::timeStep t, int nSize) { - } else { - // Open the file in append mode - velDataFile = H5Fopen(("velDatafile." + std::to_string(worldMPIRank) + ".h5").c_str(), H5F_ACC_RDWR, H5P_DEFAULT); + int iTurbLoc = get_localTurbNo(iTurbGlob); + for (int j=0; j < nSize; j++) { + nacDefl[j] = brFSIData[iTurbLoc][t].nac_def[j]; + nacVel[j] = brFSIData[iTurbLoc][t].nac_vel[j]; } - return velDataFile; - } -herr_t fast::OpenFAST::closeVelocityDataFile(int nt_global, hid_t velDataFile) { - herr_t status = H5Fclose(velDataFile) ; - return status; -} +void fast::OpenFAST::setBladeForces(double* bldForces, int iTurbGlob, fast::timeStep t, int nSize) { -void fast::OpenFAST::backupVelocityDataFile(int curTimeStep, hid_t & velDataFile) { + int iTurbLoc = get_localTurbNo(iTurbGlob); + int nBlades = get_numBladesLoc(iTurbLoc); + int iRunTot = 0; + for (int i=0; i < nBlades; i++) { + int nPtsBlade = turbineData[iTurbLoc].nBRfsiPtsBlade[i]; + for(int j=0; j < nPtsBlade; j++) { + for(int k=0; k < nSize; k++) { + brFSIData[iTurbLoc][t].bld_ld[6*iRunTot+k] = bldForces[6*iRunTot+k]; + } + iRunTot++; + } + } - closeVelocityDataFile(curTimeStep, velDataFile); + //TODO: May be calculate the residual as well. +} - std::ifstream source("velDatafile." + std::to_string(worldMPIRank) + ".h5", std::ios::binary); - std::ofstream dest("velDatafile." + std::to_string(worldMPIRank) + ".h5." + std::to_string(curTimeStep) + ".bak", std::ios::binary); +void fast::OpenFAST::setTowerForces(double* twrForces, int iTurbGlob, fast::timeStep t, int nSize) { - dest << source.rdbuf(); - source.close(); - dest.close(); + int iTurbLoc = get_localTurbNo(iTurbGlob); + int nPtsTwr = turbineData[iTurbLoc].nBRfsiPtsTwr; + for (int i=0; i < nPtsTwr; i++) + for (int j=0; j < nSize; j++) + brFSIData[iTurbLoc][t].twr_ld[i*6+j] = twrForces[i*6+j]; + //TODO: May be calculate the residual as well. - velDataFile = openVelocityDataFile(false); } -void fast::OpenFAST::writeVelocityData(hid_t h5File, int iTurb, int iTimestep, OpFM_InputType_t iData, OpFM_OutputType_t oData) { +//! Sets a uniform X force at all blade nodes +void fast::OpenFAST::setUniformXBladeForces(double loadX) { - hsize_t start[3]; start[0] = iTimestep; start[1] = 0; start[2] = 0; - int nVelPts = get_numVelPtsLoc(iTurb) ; - hsize_t count[3]; count[0] = 1; count[1] = nVelPts; count[2] = 6; - - std::vector tmpVelData; - tmpVelData.resize(nVelPts * 6); + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + int iTurbGlob = turbineMapProcToGlob[iTurb]; + int nPtsTwr = turbineData[iTurb].nBRfsiPtsTwr; + std::vector fsiForceTower(6*nPtsTwr,0.0); + setTowerForces(fsiForceTower, iTurbGlob, fast::STATE_NP1); - for (int iNode=0 ; iNode < nVelPts; iNode++) { - tmpVelData[iNode*6 + 0] = iData.pxVel[iNode]; - tmpVelData[iNode*6 + 1] = iData.pyVel[iNode]; - tmpVelData[iNode*6 + 2] = iData.pzVel[iNode]; - tmpVelData[iNode*6 + 3] = oData.u[iNode]; - tmpVelData[iNode*6 + 4] = oData.v[iNode]; - tmpVelData[iNode*6 + 5] = oData.w[iNode]; - } + size_t nBlades = get_numBladesLoc(iTurb); + size_t nTotPtsBlade = 0; + for(int iBlade=0; iBlade < nBlades; iBlade++) + nTotPtsBlade += turbineData[iTurb].nBRfsiPtsBlade[iBlade]; - hid_t dset_id = H5Dopen2(h5File, ("/turbine" + std::to_string(iTurb)).c_str(), H5P_DEFAULT); - hid_t dspace_id = H5Dget_space(dset_id); - H5Sselect_hyperslab(dspace_id, H5S_SELECT_SET, start, NULL, count, NULL); - hid_t mspace_id = H5Screate_simple(3, count, NULL); - H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, mspace_id, dspace_id, H5P_DEFAULT, tmpVelData.data()); + std::vector fsiForceBlade(6*nTotPtsBlade, 0.0); + std::vector dr(nTotPtsBlade, 0.0); - H5Dclose(dset_id); - H5Sclose(dspace_id); - H5Sclose(mspace_id); + size_t iNode=0; + for(int iBlade=0; iBlade < nBlades; iBlade++) { + int nBldPts = turbineData[iTurb].nBRfsiPtsBlade[iBlade]; + dr[iNode] = 0.5*(brFSIData[iTurb][3].bld_rloc[iNode+1] - brFSIData[iTurb][3].bld_rloc[iNode]); + iNode++; + + for(int i=1; i < nBldPts-1; i++) { + dr[iNode] = 0.5*(brFSIData[iTurb][3].bld_rloc[iNode+1] - brFSIData[iTurb][3].bld_rloc[iNode-1]); + iNode++; + } + dr[iNode] = 0.5*(brFSIData[iTurb][3].bld_rloc[iNode] - brFSIData[iTurb][3].bld_rloc[iNode-1]); + iNode++; + } - hid_t attr_id = H5Aopen_by_name(h5File, ".", "nTimesteps", H5P_DEFAULT, H5P_DEFAULT); - herr_t status = H5Awrite(attr_id, H5T_NATIVE_INT, &iTimestep); - status = H5Aclose(attr_id); + for(int i=0; i < nTotPtsBlade; i++) + fsiForceBlade[i*6] = loadX * dr[i]; // X component of force -} + setBladeForces(fsiForceBlade, iTurbGlob, fast::STATE_NP1); -void fast::OpenFAST::applyVelocityData(int iPrestart, int iTurb, OpFM_OutputType_t cDriver_Output_to_FAST, std::vector & velData) { - int nVelPts = get_numVelPtsLoc(iTurb); - for (int j = 0; j < nVelPts; j++){ - cDriver_Output_to_FAST.u[j] = velData[(iPrestart*nVelPts+j)*6 + 3]; - cDriver_Output_to_FAST.v[j] = velData[(iPrestart*nVelPts+j)*6 + 4]; - cDriver_Output_to_FAST.w[j] = velData[(iPrestart*nVelPts+j)*6 + 5]; } } @@ -1045,6 +3179,8 @@ void fast::OpenFAST::loadSuperController(const fast::fastInputs & fi) { // sc.load(fi.nTurbinesGlob, fi.scLibFile, scio); } else { + scStatus = false; } + } diff --git a/glue-codes/simulink/CMakeLists.txt b/glue-codes/simulink/CMakeLists.txt index f4251c35cd..0951880194 100644 --- a/glue-codes/simulink/CMakeLists.txt +++ b/glue-codes/simulink/CMakeLists.txt @@ -34,11 +34,12 @@ matlab_add_mex( $ $ $ + $ $ $ $ $ - $ + $ $ $ $ @@ -50,7 +51,7 @@ matlab_add_mex( $ # MATLAB Specific $ $ - $ + $ $ ${LAPACK_LIBRARIES} ${CMAKE_DL_LIBS} diff --git a/modules/beamdyn/src/BeamDyn.f90 b/modules/beamdyn/src/BeamDyn.f90 index 9f84c675b2..e91e5c9fde 100644 --- a/modules/beamdyn/src/BeamDyn.f90 +++ b/modules/beamdyn/src/BeamDyn.f90 @@ -882,6 +882,11 @@ subroutine SetInitOut(p, InitOut, ErrStat, ErrMsg) InitOut%Ver = BeamDyn_Ver + call AllocAry(InitOut%QPtN, p%nqp, 'InitOut%QPtN', ErrStat2,ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if(ErrStat >= AbortErrLev) return + + InitOut%QPtN = (p%QPtN + 1.0)*0.5 ! Set the info in WriteOutputHdr and WriteOutputUnt for BldNd sections. CALL BldNdOuts_InitOut( InitOut, p, ErrStat2, ErrMsg2 ) diff --git a/modules/beamdyn/src/BeamDyn_Types.f90 b/modules/beamdyn/src/BeamDyn_Types.f90 index 2855508d9e..baa88b5194 100644 --- a/modules/beamdyn/src/BeamDyn_Types.f90 +++ b/modules/beamdyn/src/BeamDyn_Types.f90 @@ -63,6 +63,7 @@ MODULE BeamDyn_Types TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: kp_coordinate !< Key point coordinates array [-] INTEGER(IntKi) :: kp_total !< Total number of key points [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: QPtN !< Quadrature (QuadPt) point locations in natural frame [-1, 1] [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_y !< Names of the outputs used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_x !< Names of the continuous states used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_u !< Names of the inputs used in linearization [-] @@ -685,6 +686,18 @@ SUBROUTINE BD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er DstInitOutputData%kp_coordinate = SrcInitOutputData%kp_coordinate ENDIF DstInitOutputData%kp_total = SrcInitOutputData%kp_total +IF (ALLOCATED(SrcInitOutputData%QPtN)) THEN + i1_l = LBOUND(SrcInitOutputData%QPtN,1) + i1_u = UBOUND(SrcInitOutputData%QPtN,1) + IF (.NOT. ALLOCATED(DstInitOutputData%QPtN)) THEN + ALLOCATE(DstInitOutputData%QPtN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%QPtN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%QPtN = SrcInitOutputData%QPtN +ENDIF IF (ALLOCATED(SrcInitOutputData%LinNames_y)) THEN i1_l = LBOUND(SrcInitOutputData%LinNames_y,1) i1_u = UBOUND(SrcInitOutputData%LinNames_y,1) @@ -815,6 +828,9 @@ SUBROUTINE BD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpoin IF (ALLOCATED(InitOutputData%kp_coordinate)) THEN DEALLOCATE(InitOutputData%kp_coordinate) ENDIF +IF (ALLOCATED(InitOutputData%QPtN)) THEN + DEALLOCATE(InitOutputData%QPtN) +ENDIF IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) ENDIF @@ -910,6 +926,11 @@ SUBROUTINE BD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_BufSz = Db_BufSz + SIZE(InData%kp_coordinate) ! kp_coordinate END IF Int_BufSz = Int_BufSz + 1 ! kp_total + Int_BufSz = Int_BufSz + 1 ! QPtN allocated yes/no + IF ( ALLOCATED(InData%QPtN) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! QPtN upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%QPtN) ! QPtN + END IF Int_BufSz = Int_BufSz + 1 ! LinNames_y allocated yes/no IF ( ALLOCATED(InData%LinNames_y) ) THEN Int_BufSz = Int_BufSz + 2*1 ! LinNames_y upper/lower bounds for each dimension @@ -1061,6 +1082,21 @@ SUBROUTINE BD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs END IF IntKiBuf(Int_Xferred) = InData%kp_total Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%QPtN) ) 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%QPtN,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%QPtN,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%QPtN,1), UBOUND(InData%QPtN,1) + DbKiBuf(Db_Xferred) = InData%QPtN(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF IF ( .NOT. ALLOCATED(InData%LinNames_y) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1322,6 +1358,24 @@ SUBROUTINE BD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er END IF OutData%kp_total = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! QPtN 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%QPtN)) DEALLOCATE(OutData%QPtN) + ALLOCATE(OutData%QPtN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%QPtN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%QPtN,1), UBOUND(OutData%QPtN,1) + OutData%QPtN(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinNames_y not allocated Int_Xferred = Int_Xferred + 1 ELSE diff --git a/modules/beamdyn/src/Registry_BeamDyn.txt b/modules/beamdyn/src/Registry_BeamDyn.txt index 108a743e24..0593f22ba8 100644 --- a/modules/beamdyn/src/Registry_BeamDyn.txt +++ b/modules/beamdyn/src/Registry_BeamDyn.txt @@ -44,6 +44,7 @@ typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - typedef ^ InitOutputType R8Ki kp_coordinate {:}{:} - - "Key point coordinates array" - typedef ^ InitOutputType IntKi kp_total - - - "Total number of key points" - +typedef ^ InitOutputType R8Ki QPtN {:} - - "Quadrature (QuadPt) point locations in natural frame [-1, 1]" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - #typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_z {:} - - "Names of the constraint states used in linearization" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_x {:} - - "Names of the continuous states used in linearization" - diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index 36d7222ce6..0183457854 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -287,7 +287,7 @@ SUBROUTINE ED_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut InitOut%Ver = ED_Ver InitOut%NumBl = p%NumBl InitOut%BladeLength = p%TipRad - p%HubRad - InitOut%TowerHeight = p%TwrFlexL + InitOut%TowerFlexL = p%TwrFlexL InitOut%TowerBaseHeight = p%TowerBsHt ! Platform reference point wrt to global origin (0,0,0) diff --git a/modules/elastodyn/src/ElastoDyn_Registry.txt b/modules/elastodyn/src/ElastoDyn_Registry.txt index 4d1038aebf..935d2ccc46 100644 --- a/modules/elastodyn/src/ElastoDyn_Registry.txt +++ b/modules/elastodyn/src/ElastoDyn_Registry.txt @@ -36,7 +36,7 @@ typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and da typedef ^ InitOutputType IntKi NumBl - - - "Number of blades on the turbine" - typedef ^ InitOutputType ReKi BlPitch {:} - - "Initial blade pitch angles" radians typedef ^ InitOutputType ReKi BladeLength - - - "Blade length (for AeroDyn)" meters -typedef ^ InitOutputType ReKi TowerHeight - - - "Tower Height" meters +typedef ^ InitOutputType ReKi TowerFlexL - - - "Tower Flexible Length" meters typedef ^ InitOutputType ReKi TowerBaseHeight - - - "Tower Base Height" meters typedef ^ InitOutputType ReKi HubHt - - - "Height of the hub" meters typedef ^ InitOutputType ReKi BldRNodes {:} - - "Radius to analysis nodes relative to hub ( 0 < RNodes(:) < BldFlexL )" diff --git a/modules/elastodyn/src/ElastoDyn_Types.f90 b/modules/elastodyn/src/ElastoDyn_Types.f90 index e4831db34a..a49c29ed6b 100644 --- a/modules/elastodyn/src/ElastoDyn_Types.f90 +++ b/modules/elastodyn/src/ElastoDyn_Types.f90 @@ -56,7 +56,7 @@ MODULE ElastoDyn_Types INTEGER(IntKi) :: NumBl !< Number of blades on the turbine [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlPitch !< Initial blade pitch angles [radians] REAL(ReKi) :: BladeLength !< Blade length (for AeroDyn) [meters] - REAL(ReKi) :: TowerHeight !< Tower Height [meters] + REAL(ReKi) :: TowerFlexL !< Tower Flexible Length [meters] REAL(ReKi) :: TowerBaseHeight !< Tower Base Height [meters] REAL(ReKi) :: HubHt !< Height of the hub [meters] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BldRNodes !< Radius to analysis nodes relative to hub ( 0 < RNodes(:) < BldFlexL ) [-] @@ -1093,7 +1093,7 @@ SUBROUTINE ED_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er DstInitOutputData%BlPitch = SrcInitOutputData%BlPitch ENDIF DstInitOutputData%BladeLength = SrcInitOutputData%BladeLength - DstInitOutputData%TowerHeight = SrcInitOutputData%TowerHeight + DstInitOutputData%TowerFlexL = SrcInitOutputData%TowerFlexL DstInitOutputData%TowerBaseHeight = SrcInitOutputData%TowerBaseHeight DstInitOutputData%HubHt = SrcInitOutputData%HubHt IF (ALLOCATED(SrcInitOutputData%BldRNodes)) THEN @@ -1361,7 +1361,7 @@ SUBROUTINE ED_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = Re_BufSz + SIZE(InData%BlPitch) ! BlPitch END IF Re_BufSz = Re_BufSz + 1 ! BladeLength - Re_BufSz = Re_BufSz + 1 ! TowerHeight + Re_BufSz = Re_BufSz + 1 ! TowerFlexL Re_BufSz = Re_BufSz + 1 ! TowerBaseHeight Re_BufSz = Re_BufSz + 1 ! HubHt Int_BufSz = Int_BufSz + 1 ! BldRNodes allocated yes/no @@ -1531,7 +1531,7 @@ SUBROUTINE ED_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs END IF ReKiBuf(Re_Xferred) = InData%BladeLength Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TowerHeight + ReKiBuf(Re_Xferred) = InData%TowerFlexL Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TowerBaseHeight Re_Xferred = Re_Xferred + 1 @@ -1857,7 +1857,7 @@ SUBROUTINE ED_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er END IF OutData%BladeLength = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%TowerHeight = ReKiBuf(Re_Xferred) + OutData%TowerFlexL = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%TowerBaseHeight = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 diff --git a/modules/externalinflow/CMakeLists.txt b/modules/externalinflow/CMakeLists.txt index eba5bbf1e4..6c730023a1 100644 --- a/modules/externalinflow/CMakeLists.txt +++ b/modules/externalinflow/CMakeLists.txt @@ -35,8 +35,7 @@ set_target_properties(extinflowlib PROPERTIES PUBLIC_HEADER src/ExternalInflow_T install(TARGETS extinflowtypeslib extinflowlib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib PUBLIC_HEADER DESTINATION include ) - diff --git a/modules/extloads/CMakeLists.txt b/modules/extloads/CMakeLists.txt new file mode 100644 index 0000000000..b649f69557 --- /dev/null +++ b/modules/extloads/CMakeLists.txt @@ -0,0 +1,39 @@ +# +# Copyright 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. +# + +if (GENERATE_TYPES) + generate_f90_types(src/ExtLoadsDX_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/ExtLoadsDX_Types.f90 -ccode) + generate_f90_types(src/ExtLoads_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/ExtLoads_Types.f90) +endif() + +add_library(extloadslib STATIC + src/ExtLoads.f90 + src/ExtLoads_Types.f90 + src/ExtLoadsDX_Types.f90 +) +target_include_directories(extloadslib PUBLIC + $ +) +target_link_libraries(extloadslib beamdynlib nwtclibs versioninfolib) +set_target_properties(extloadslib PROPERTIES PUBLIC_HEADER "src/ExtLoadsDX_Types.h") + +install(TARGETS extloadslib + EXPORT "${CMAKE_PROJECT_NAME}Libraries" + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include +) diff --git a/modules/extloads/src/ExtLoads.f90 b/modules/extloads/src/ExtLoads.f90 new file mode 100644 index 0000000000..84f034f13b --- /dev/null +++ b/modules/extloads/src/ExtLoads.f90 @@ -0,0 +1,931 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2015-2016 National Renewable Energy Laboratory +! +! This file is part of ExtLoads. +! +! 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$ +! (File) Revision #: $Rev$ +! URL: $HeadURL$ +!********************************************************************************************************************************** +!> ExtLoads is a time-domain loads module for horizontal-axis wind turbines. +module ExtLoads + + use NWTC_Library + use ExtLoads_Types + + implicit none + + private + + ! ..... Public Subroutines ................................................................................................... + + public :: ExtLd_Init ! Initialization routine + public :: ExtLd_End ! Ending routine (includes clean up) + public :: ExtLd_UpdateStates ! Loose coupling routine for solving for constraint states, integrating + ! continuous states, and updating discrete states + public :: ExtLd_CalcOutput ! Routine for computing outputs + public :: ExtLd_ConvertOpDataForOpenFAST ! Routine to convert Output data for OpenFAST + public :: ExtLd_ConvertInpDataForExtProg ! Routine to convert Input data for external programs + +contains +!---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine sets the initialization output data structure, which contains data to be returned to the calling program (e.g., +!! FAST) +subroutine ExtLd_SetInitOut(p, InitOut, errStat, errMsg) + + type(ExtLd_InitOutputType), intent( out) :: InitOut ! output data + type(ExtLd_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 + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'ExtLd_SetInitOut' + + + + integer(IntKi) :: i, j, k, f + integer(IntKi) :: NumCoords +#ifdef DBG_OUTS + integer(IntKi) :: m + character(5) ::chanPrefix +#endif + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + +end subroutine ExtLd_SetInitOut + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine is called at the start of the simulation to perform initialization steps. +!! The parameters are set here and not changed during the simulation. +!! The initial states and initial guess for the input are defined. +subroutine ExtLd_Init( InitInp, u, xd, p, y, m, interval, InitOut, ErrStat, ErrMsg ) +!.................................................................................................................................. + + type(ExtLd_InitInputType), intent(in ) :: InitInp !< Input data for initialization routine + type(ExtLd_InputType), intent( out) :: u !< An initial guess for the input; input mesh must be defined + type(ExtLd_DiscreteStateType), intent( out) :: xd !< An initial guess for the discrete states + type(ExtLd_OutputType), intent( out) :: y !< Initial system outputs (outputs are not calculated; + type(ExtLd_MiscVarType), intent( out) :: m !< Miscellaneous variables + type(ExtLd_ParameterType), intent( out) :: p !< Parameter variables + !! only the output mesh is initialized) + real(DbKi), intent(inout) :: interval !< Coupling interval in seconds: the rate that + !! (1) ExtLd_UpdateStates() is called in loose coupling & + !! (2) ExtLd_UpdateDiscState() is called in tight coupling. + !! Input is the suggested time from the glue code; + !! Output is the actual coupling interval that will be used + !! by the glue code. + type(ExtLd_InitOutputType), intent( out) :: InitOut !< Output for initialization routine + 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 ! loop counter + + integer(IntKi) :: errStat2 ! temporary error status of the operation + character(ErrMsgLen) :: errMsg2 ! temporary error message + + character(*), parameter :: RoutineName = 'ExtLd_Init' + + + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + + ! Initialize the NWTC Subroutine Library + + ! Set parameters here + p%NumBlds = InitInp%NumBlades + call AllocAry(p%NumBldNds, p%NumBlds, 'NumBldNds', ErrStat2,ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + end if + p%NumBldNds(:) = InitInp%NumBldNodes(:) + p%nTotBldNds = sum(p%NumBldNds(:)) + p%NumTwrNds = InitInp%NumTwrNds + p%TwrAero = .true. + + p%az_blend_mean = InitInp%az_blend_mean + p%az_blend_delta = InitInp%az_blend_delta + p%vel_mean = InitInp%vel_mean + p%wind_dir = InitInp%wind_dir + p%z_ref = InitInp%z_ref + p%shear_exp = InitInp%shear_exp + + !............................................................................................ + ! Define and initialize inputs here + !............................................................................................ + + write(*,*) 'Initializing U ' + + call Init_u( u, p, InitInp, errStat2, errMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + end if + + + ! Initialize discrete states + m%az = 0.0 + m%phi_cfd = 0.0 + + write(*,*) 'Initializing y ' + ! + !............................................................................................ + ! Define outputs here + !............................................................................................ + call Init_y(y, u, m, p, errStat2, errMsg2) ! do this after input meshes have been initialized + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + end if + + write(*,*) 'Initializing InitOut ' + + !............................................................................................ + ! Define initialization output here + !............................................................................................ + call ExtLd_SetInitOut(p, InitOut, errStat2, errMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + call Cleanup() + +contains + subroutine Cleanup() + + end subroutine Cleanup + +end subroutine ExtLd_Init +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine initializes ExtLoads meshes and output array variables for use during the simulation. +subroutine Init_y(y, u, m, p, errStat, errMsg) + type(ExtLd_OutputType), intent( out) :: y !< Module outputs + type(ExtLd_InputType), intent(inout) :: u !< Module inputs -- intent(out) because of mesh sibling copy + type(ExtLd_MiscVarType), intent(inout) :: m !< Module misc var + type(ExtLd_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 + integer(intKi) :: k ! loop counter for blades + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'Init_y' + + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + + if (p%TwrAero) then + + call MeshCopy ( SrcMesh = u%TowerMotion & + , DestMesh = y%TowerLoad & + , CtrlCode = MESH_SIBLING & + , IOS = COMPONENT_OUTPUT & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) RETURN + + call MeshCopy ( SrcMesh = u%TowerMotion & + , DestMesh = y%TowerLoadAD & + , CtrlCode = MESH_COUSIN & + , IOS = COMPONENT_OUTPUT & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) RETURN + + !call MeshCommit(y%TowerLoadAD, errStat2, errMsg2 ) + !call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + !y%TowerLoad%force = 0.0_ReKi ! shouldn't have to initialize this + !y%TowerLoad%moment= 0.0_ReKi ! shouldn't have to initialize this + else + y%TowerLoad%nnodes = 0 + y%TowerLoadAD%nnodes = 0 + end if + + allocate( y%BladeLoad(p%NumBlds), stat=ErrStat2 ) + if (errStat2 /= 0) then + call SetErrStat( ErrID_Fatal, 'Error allocating y%BladeLoad.', ErrStat, ErrMsg, RoutineName ) + return + end if + + allocate( y%BladeLoadAD(p%NumBlds), stat=ErrStat2 ) + if (errStat2 /= 0) then + call SetErrStat( ErrID_Fatal, 'Error allocating y%BladeLoad.', ErrStat, ErrMsg, RoutineName ) + return + end if + + do k = 1, p%NumBlds + + call MeshCopy ( SrcMesh = u%BladeMotion(k) & + , DestMesh = y%BladeLoad(k) & + , CtrlCode = MESH_SIBLING & + , IOS = COMPONENT_OUTPUT & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + call MeshCopy ( SrcMesh = u%BladeMotion(k) & + , DestMesh = y%BladeLoadAD(k) & + , CtrlCode = MESH_COUSIN & + , IOS = COMPONENT_OUTPUT & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + !call MeshCommit(y%BladeLoadAD(k), errStat2, errMsg2 ) + !call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + + end do + + CALL AllocPAry( y%DX_y%twrLd, p%NumTwrNds*6, 'twrLd', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( y%DX_y%bldLd, p%nTotBldNds*6, 'bldLd', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! make sure the C versions are synced with these arrays + y%DX_y%c_obj%twrLd_Len = p%NumTwrNds*6; y%DX_y%c_obj%twrLd = C_LOC( y%DX_y%twrLd(1) ) + y%DX_y%c_obj%bldLd_Len = p%nTotBldNds*6; y%DX_y%c_obj%bldLd = C_LOC( y%DX_y%bldLd(1) ) + + call ExtLd_ConvertOpDataForOpenFAST(y, u, m, p, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + +end subroutine Init_y +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine initializes ExtLoads meshes and input array variables for use during the simulation. +subroutine Init_u( u, p, InitInp, errStat, errMsg ) +!.................................................................................................................................. + + USE BeamDyn_IO, ONLY: BD_CrvExtractCrv + + type(ExtLd_InputType), intent( out) :: u !< Input data + type(ExtLd_ParameterType), intent(in ) :: p !< Parameters + type(ExtLd_InitInputType), intent(in ) :: InitInp !< Input data for ExtLd initialization routine + integer(IntKi), intent( out) :: errStat !< Error status of the operation + character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None + + + ! Local variables + real(reKi) :: position(3) ! node reference position + real(reKi) :: positionL(3) ! node local position + real(R8Ki) :: theta(3) ! Euler angles + real(R8Ki) :: orientation(3,3) ! node reference orientation + real(R8Ki) :: orientationL(3,3) ! node local orientation + + real(R8Ki) :: wm_crv(3) ! Wiener-Milenkovic parameters + integer(IntKi) :: j ! counter for nodes + integer(IntKi) :: jTot ! counter for blade nodes + integer(IntKi) :: k ! counter for blades + + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'Init_u' + + ! Initialize variables for this routine + + ErrStat = ErrID_None + ErrMsg = "" + + + u%az = 0.0 + ! Meshes for motion inputs (ElastoDyn and/or BeamDyn) + !................ + ! tower + !................ + if (p%NumTwrNds > 0) then + + call MeshCreate ( BlankMesh = u%TowerMotion & + ,IOS = COMPONENT_INPUT & + ,Nnodes = p%NumTwrNds & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Orientation = .true. & + ,TranslationDisp = .true. & + ,TranslationVel = .true. & + ,RotationVel = .true. & + ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + ! set node initial position/orientation + position = 0.0_ReKi + do j=1,p%NumTwrNds + position(:) = InitInp%TwrPos(:,j) + + call MeshPositionNode(u%TowerMotion, j, position, errStat2, errMsg2) ! orientation is identity by default + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + end do !j + + ! create point elements + do j=1,p%NumTwrNds + call MeshConstructElement( u%TowerMotion, ELEMENT_POINT, errStat2, errMsg2, p1=j ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + end do !j + + call MeshCommit(u%TowerMotion, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + + u%TowerMotion%Orientation = u%TowerMotion%RefOrientation + u%TowerMotion%TranslationDisp = 0.0_R8Ki + u%TowerMotion%TranslationVel = 0.0_ReKi + u%TowerMotion%RotationVel = 0.0_ReKi + + end if ! we compute tower loads + + !................ + ! hub + !................ + + call MeshCreate ( BlankMesh = u%HubMotion & + ,IOS = COMPONENT_INPUT & + ,Nnodes = 1 & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Orientation = .true. & + ,TranslationDisp = .true. & + ,TranslationVel = .true. & + ,RotationVel = .true. & + ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + call MeshPositionNode(u%HubMotion, 1, InitInp%HubPos, errStat2, errMsg2, InitInp%HubOrient) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + call MeshConstructElement( u%HubMotion, ELEMENT_POINT, errStat2, errMsg2, p1=1 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + call MeshCommit(u%HubMotion, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + + u%HubMotion%Orientation = u%HubMotion%RefOrientation + u%HubMotion%TranslationDisp = 0.0_R8Ki + u%HubMotion%TranslationVel = 0.0_R8Ki + u%HubMotion%RotationVel = 0.0_R8Ki + + !................ + ! nacelle + !................ + + call MeshCreate ( BlankMesh = u%NacelleMotion & + ,IOS = COMPONENT_INPUT & + ,Nnodes = 1 & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Orientation = .true. & + ,TranslationDisp = .true. & + ,TranslationVel = .true. & + ,RotationVel = .true. & + ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + call MeshPositionNode(u%NacelleMotion, 1, InitInp%NacellePos, errStat2, errMsg2, InitInp%NacelleOrient) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + call MeshConstructElement( u%NacelleMotion, ELEMENT_POINT, errStat2, errMsg2, p1=1 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + call MeshCommit(u%NacelleMotion, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + + u%NacelleMotion%Orientation = u%NacelleMotion%RefOrientation + u%NacelleMotion%TranslationDisp = 0.0_R8Ki + u%NacelleMotion%TranslationVel = 0.0_R8Ki + u%NacelleMotion%RotationVel = 0.0_R8Ki + + !................ + ! blades + !................ + + allocate( u%BladeRootMotion(p%NumBlds), STAT = ErrStat2 ) + if (ErrStat2 /= 0) then + call SetErrStat( ErrID_Fatal, 'Error allocating u%BladeRootMotion array.', ErrStat, ErrMsg, RoutineName ) + return + end if + + allocate( u%BladeMotion(p%NumBlds), STAT = ErrStat2 ) + if (ErrStat2 /= 0) then + call SetErrStat( ErrID_Fatal, 'Error allocating u%BladeMotion array.', ErrStat, ErrMsg, RoutineName ) + return + end if + + do k=1,p%NumBlds + + call MeshCreate ( BlankMesh = u%BladeRootMotion(k) & + ,IOS = COMPONENT_INPUT & + ,Nnodes = 1 & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Orientation = .true. & + ,TranslationDisp = .true. & + ,TranslationVel = .true. & + ,RotationVel = .true. & + ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + call MeshPositionNode(u%BladeRootMotion(k), 1, InitInp%BldRootPos(:,k), errStat2, errMsg2, InitInp%BldRootOrient(:,:,k)) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + call MeshConstructElement( u%BladeRootMotion(k), ELEMENT_POINT, errStat2, errMsg2, p1=1 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + call MeshCommit(u%BladeRootMotion(k), errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + u%BladeRootMotion(k)%Orientation = u%BladeRootMotion(k)%RefOrientation + u%BladeRootMotion(k)%TranslationDisp = 0.0_R8Ki + u%BladeRootMotion(k)%TranslationVel = 0.0_R8Ki + u%BladeRootMotion(k)%RotationVel = 0.0_R8Ki + + call MeshCreate ( BlankMesh = u%BladeMotion(k) & + ,IOS = COMPONENT_INPUT & + ,Nnodes = InitInp%NumBldNodes(k) & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Orientation = .true. & + ,TranslationDisp = .true. & + ,TranslationVel = .true. & + ,RotationVel = .true. & + ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + + do j=1,InitInp%NumBldNodes(k) + + ! reference position of the jth node in the kth blade: + position(:) = InitInp%BldPos(:,j,k) + + ! reference orientation of the jth node in the kth blade + orientation(:,:) = InitInp%BldOrient(:,:,j,k) + + + call MeshPositionNode(u%BladeMotion(k), j, position, errStat2, errMsg2, orientation) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + end do ! j=blade nodes + + ! create point elements + do j=1,InitInp%NumBldNodes(k) + call MeshConstructElement( u%BladeMotion(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + end do !j + + call MeshCommit(u%BladeMotion(k), errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + + if (errStat >= AbortErrLev) return + + u%BladeMotion(k)%Orientation = u%BladeMotion(k)%RefOrientation + u%BladeMotion(k)%TranslationDisp = 0.0_R8Ki + u%BladeMotion(k)%TranslationVel = 0.0_R8Ki + u%BladeMotion(k)%RotationVel = 0.0_R8Ki + + end do !k=numBlades + + ! Set the parameters first + CALL AllocPAry( u%DX_u%nTowerNodes, 1, 'nTowerNodes', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + u%DX_u%c_obj%nTowerNodes_Len = 1; u%DX_u%c_obj%nTowerNodes = C_LOC( u%DX_u%nTowerNodes(1) ) + u%DX_u%nTowerNodes(1) = p%NumTwrNds + CALL AllocPAry( u%DX_u%nBlades, 1, 'nBlades', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + u%DX_u%c_obj%nBlades_Len = 1; u%DX_u%c_obj%nBlades = C_LOC( u%DX_u%nBlades(1) ) + u%DX_u%nBlades(1) = p%NumBlds + CALL AllocPAry( u%DX_u%nBladeNodes, p%NumBlds, 'nBladeNodes', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + u%DX_u%c_obj%nBladeNodes_Len = p%NumBlds; u%DX_u%c_obj%nBladeNodes = C_LOC( u%DX_u%nBladeNodes(1) ) + u%DX_u%nBladeNodes(:) = p%NumBldNds(:) + + ! Set the reference positions next + CALL AllocPAry( u%DX_u%twrRefPos, p%NumTwrNds*6, 'twrRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%bldRefPos, p%nTotBldNds*6, 'bldRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%hubRefPos, 6, 'hubRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%nacRefPos, 6, 'nacRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry (u%DX_u%bldRootRefPos, p%NumBlds*6, 'bldRootRefPos', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! make sure the C versions are synced with these arrays + u%DX_u%c_obj%twrRefPos_Len = p%NumTwrNds*6; u%DX_u%c_obj%twrRefPos = C_LOC( u%DX_u%twrRefPos(1) ) + u%DX_u%c_obj%bldRefPos_Len = p%nTotBldNds*6; u%DX_u%c_obj%bldRefPos = C_LOC( u%DX_u%bldRefPos(1) ) + u%DX_u%c_obj%hubRefPos_Len = 6; u%DX_u%c_obj%hubRefPos = C_LOC( u%DX_u%hubRefPos(1) ) + u%DX_u%c_obj%nacRefPos_Len = 6; u%DX_u%c_obj%nacRefPos = C_LOC( u%DX_u%nacRefPos(1) ) + u%DX_u%c_obj%bldRootRefPos_Len = p%NumBlds*6; u%DX_u%c_obj%bldRootRefPos = C_LOC( u%DX_u%bldRootRefPos(1) ) + + if (p%TwrAero) then + do j=1,p%NumTwrNds + call BD_CrvExtractCrv(u%TowerMotion%RefOrientation(:,:,j), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + u%DX_u%twrRefPos((j-1)*6+1:(j-1)*6+3) = u%TowerMotion%Position(:,j) + u%DX_u%twrRefPos((j-1)*6+4:(j-1)*6+6) = wm_crv + end do + end if + + jTot = 1 + do k=1,p%NumBlds + do j=1,p%NumBldNds(k) + call BD_CrvExtractCrv(u%BladeMotion(k)%RefOrientation(:,:,j), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + u%DX_u%bldRefPos((jTot-1)*6+1:(jTot-1)*6+3) = u%BladeMotion(k)%Position(:,j) + u%DX_u%bldRefPos((jTot-1)*6+4:(jTot-1)*6+6) = wm_crv + jTot = jTot+1 + end do + end do + + call BD_CrvExtractCrv(u%HubMotion%RefOrientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + u%DX_u%hubRefPos(1:3) = u%HubMotion%Position(:,1) + u%DX_u%hubRefPos(4:6) = wm_crv + + call BD_CrvExtractCrv(u%NacelleMotion%RefOrientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + u%DX_u%nacRefPos(1:3) = u%NacelleMotion%Position(:,1) + u%DX_u%nacRefPos(4:6) = wm_crv + + do k=1,p%NumBlds + call BD_CrvExtractCrv(u%BladeRootMotion(k)%RefOrientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + u%DX_u%bldRootRefPos((k-1)*6+1:(k-1)*6+3) = u%BladeRootMotion(k)%Position(:,1) + u%DX_u%bldRootRefPos((k-1)*6+4:(k-1)*6+6) = wm_crv + end do + + + ! Now the displacements + CALL AllocPAry( u%DX_u%twrDef, p%NumTwrNds*12, 'twrDef', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%bldDef, p%nTotBldNds*12, 'bldDef', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%hubDef, 12, 'hubDef', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%nacDef, 12, 'nacDef', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%bldRootDef, p%NumBlds*12, 'bldRootDef', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! make sure the C versions are synced with these arrays + u%DX_u%c_obj%twrDef_Len = p%NumTwrNds*12; u%DX_u%c_obj%twrDef = C_LOC( u%DX_u%twrDef(1) ) + u%DX_u%c_obj%bldDef_Len = p%nTotBldNds*12; u%DX_u%c_obj%bldDef = C_LOC( u%DX_u%bldDef(1) ) + u%DX_u%c_obj%hubDef_Len = 12; u%DX_u%c_obj%hubDef = C_LOC( u%DX_u%hubDef(1) ) + u%DX_u%c_obj%nacDef_Len = 12; u%DX_u%c_obj%nacDef = C_LOC( u%DX_u%nacDef(1) ) + u%DX_u%c_obj%bldRootDef_Len = p%NumBlds*12; u%DX_u%c_obj%bldRootDef = C_LOC( u%DX_u%bldRootDef(1) ) + call ExtLd_ConvertInpDataForExtProg(u, p, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL AllocPAry( u%DX_u%bldChord, p%nTotBldNds, 'bldChord', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%bldRloc, p%nTotBldNds, 'bldRloc', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%twrdia, p%NumTwrNds, 'twrDia', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%twrHloc, p%NumTwrNds, 'twrHloc', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( u%DX_u%bldPitch, p%NumBlds, 'bldPitch', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! make sure the C versions are synced with these arrays + u%DX_u%c_obj%bldChord_Len = p%nTotBldNds; u%DX_u%c_obj%bldChord = C_LOC( u%DX_u%bldChord(1) ) + u%DX_u%c_obj%bldRloc_Len = p%nTotBldNds; u%DX_u%c_obj%bldRloc = C_LOC( u%DX_u%bldRloc(1) ) + u%DX_u%c_obj%twrDia_Len = p%NumTwrNds; u%DX_u%c_obj%twrDia = C_LOC( u%DX_u%twrDia(1) ) + u%DX_u%c_obj%twrHloc_Len = p%NumTwrNds; u%DX_u%c_obj%twrHloc = C_LOC( u%DX_u%twrHloc(1) ) + u%DX_u%c_obj%bldPitch_Len = p%NumBlds; u%DX_u%c_obj%bldPitch = C_LOC( u%DX_u%bldPitch(1) ) + + jTot = 1 + do k=1,p%NumBlds + do j=1,p%NumBldNds(k) + u%DX_u%bldChord(jTot) = InitInp%bldChord(j,k) + u%DX_u%bldRloc(jTot) = InitInp%bldRloc(j,k) + jTot = jTot+1 + end do + end do + + do j=1,p%NumTwrNds + u%DX_u%twrDia(j) = InitInp%twrDia(j) + u%DX_u%twrHloc(j) = InitInp%twrHloc(j) + end do + +end subroutine Init_u +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine converts the displacement data in the meshes in the input into a simple array format that can be accessed by external programs +subroutine ExtLd_ConvertInpDataForExtProg(u, p, errStat, errMsg ) +!.................................................................................................................................. + USE BeamDyn_IO, ONLY: BD_CrvExtractCrv + + type(ExtLd_InputType), intent(inout) :: u !< Input data + type(ExtLd_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(R8Ki) :: wm_crv(3) ! Wiener-Milenkovic parameters + integer(intKi) :: j ! counter for nodes + integer(intKi) :: jTot ! counter for nodes + integer(intKi) :: k ! counter for blades + real(reki) :: cref(3) + real(reki) :: xloc(3) + real(reki) :: yloc(3) + real(reki) :: zloc(3) + + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'ExtLd_ConvertInpDataForExtProg' + + ! Initialize variables for this routine + + ErrStat = ErrID_None + ErrMsg = "" + + if (p%TwrAero) then + do j=1,p%NumTwrNds + call BD_CrvExtractCrv(u%TowerMotion%Orientation(:,:,j), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + u%DX_u%twrDef((j-1)*12+1:(j-1)*12+3) = u%TowerMotion%TranslationDisp(:,j) + u%DX_u%twrDef((j-1)*12+4:(j-1)*12+6) = u%TowerMotion%TranslationVel(:,j) + u%DX_u%twrDef((j-1)*12+7:(j-1)*12+9) = wm_crv + u%DX_u%twrDef((j-1)*12+10:(j-1)*12+12) = u%TowerMotion%RotationVel(:,j) + end do + end if + + jTot = 1 + do k=1,p%NumBlds + do j=1,p%NumBldNds(k) + call BD_CrvExtractCrv(u%BladeMotion(k)%Orientation(:,:,j), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + u%DX_u%bldDef((jTot-1)*12+1:(jTot-1)*12+3) = u%BladeMotion(k)%TranslationDisp(:,j) + u%DX_u%bldDef((jTot-1)*12+4:(jTot-1)*12+6) = u%BladeMotion(k)%TranslationVel(:,j) + u%DX_u%bldDef((jTot-1)*12+7:(jTot-1)*12+9) = wm_crv + u%DX_u%bldDef((jTot-1)*12+10:(jTot-1)*12+12) = u%BladeMotion(k)%RotationVel(:,j) + jTot = jTot+1 + end do + end do + + call BD_CrvExtractCrv(u%HubMotion%Orientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + u%DX_u%hubDef(1:3) = u%HubMotion%TranslationDisp(:,1) + u%DX_u%hubDef(4:6) = u%HubMotion%TranslationVel(:,1) + u%DX_u%hubDef(7:9) = wm_crv + u%DX_u%hubDef(10:12) = u%HubMotion%RotationVel(:,1) + + call BD_CrvExtractCrv(u%NacelleMotion%Orientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + u%DX_u%nacDef(1:3) = u%NacelleMotion%TranslationDisp(:,1) + u%DX_u%nacDef(4:6) = u%NacelleMotion%TranslationVel(:,1) + u%DX_u%nacDef(7:9) = wm_crv + u%DX_u%nacDef(10:12) = u%NacelleMotion%RotationVel(:,1) + + do k=1,p%NumBlds + call BD_CrvExtractCrv(u%BladeRootMotion(k)%Orientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + u%DX_u%bldRootDef( (k-1)*12+1:(k-1)*12+3 ) = u%BladeRootMotion(k)%TranslationDisp(:,1) + u%DX_u%bldRootDef( (k-1)*12+4:(k-1)*12+6 ) = u%BladeRootMotion(k)%TranslationVel(:,1) + u%DX_u%bldRootDef( (k-1)*12+7:(k-1)*12+9 ) = wm_crv + u%DX_u%bldRootDef( (k-1)*12+10:(k-1)*12+12 ) = u%BladeRootMotion(k)%RotationVel(:,1) + end do + +end subroutine ExtLd_ConvertInpDataForExtProg +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine converts the data in the simple array format in the output data type into OpenFAST mesh format +subroutine ExtLd_ConvertOpDataForOpenFAST(y, u, m, p, errStat, errMsg ) +!.................................................................................................................................. + + type(ExtLd_OutputType), intent(inout) :: y !< Ouput data + type(ExtLd_InputType), intent(in ) :: u !< Input data + type(ExtLd_MiscVarType), intent(inout) :: m !< Misc var + type(ExtLd_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 + integer(intKi) :: j ! counter for nodes + integer(intKi) :: jTot ! counter for nodes + integer(intKi) :: k ! counter for blades + real(ReKi) :: tmp_az, delta_az ! temporary variable for azimuth + + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'ExtLd_ConvertInpDataForExtProg' + + ! Initialize variables for this routine + + ErrStat = ErrID_None + ErrMsg = "" + + tmp_az = m%az + call Zero2TwoPi(tmp_az) + delta_az = u%az - tmp_az + if ( delta_az .lt. -1.0 ) then + m%az = m%az + delta_az + PI + else + m%az = m%az + delta_az + end if + if (m%az > (p%az_blend_mean - 0.5 * p%az_blend_delta)) then + m%phi_cfd = 0.5 * ( tanh( (m%az - p%az_blend_mean)/p%az_blend_delta ) + 1.0 ) + else + m%phi_cfd = 0.0 + end if + + if (p%TwrAero) then + do j=1,p%NumTwrNds + y%TowerLoad%Force(:,j) = m%phi_cfd * y%DX_y%twrLd((j-1)*6+1:(j-1)*6+3) + (1.0 - m%phi_cfd) * y%TowerLoadAD%Force(:,j) + y%TowerLoad%Moment(:,j) = m%phi_cfd * y%DX_y%twrLd((j-1)*6+4:(j-1)*6+6) + (1.0 - m%phi_cfd) * y%TowerLoadAD%Moment(:,j) + end do + end if + + jTot = 1 + do k=1,p%NumBlds + do j=1,p%NumBldNds(k) + y%BladeLoad(k)%Force(:,j) = m%phi_cfd * y%DX_y%bldLd((jTot-1)*6+1:(jTot-1)*6+3) + (1.0 - m%phi_cfd) * y%BladeLoadAD(k)%Force(:,j) + y%BladeLoad(k)%Moment(:,j) = m%phi_cfd * y%DX_y%bldLd((jTot-1)*6+4:(jTot-1)*6+6) + (1.0 - m%phi_cfd) * y%BladeLoadAD(k)%Moment(:,j) + jTot = jTot+1 + end do + end do + + +end subroutine ExtLd_ConvertOpDataForOpenFAST +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine is called at the end of the simulation. +subroutine ExtLd_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) +!.................................................................................................................................. + + TYPE(ExtLd_InputType), INTENT(INOUT) :: u !< System inputs + TYPE(ExtLd_ParameterType), INTENT(INOUT) :: p !< Parameters + TYPE(ExtLd_ContinuousStateType), INTENT(INOUT) :: x !< Continuous states + TYPE(ExtLd_DiscreteStateType), INTENT(INOUT) :: xd !< Discrete states + TYPE(ExtLd_ConstraintStateType), INTENT(INOUT) :: z !< Constraint states + TYPE(ExtLd_OtherStateType), INTENT(INOUT) :: OtherState !< Other states + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y !< System outputs + TYPE(ExtLd_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + + + ! Initialize ErrStat + + ErrStat = ErrID_None + ErrMsg = "" + + + ! Place any last minute operations or calculations here: + + + ! Close files here: + + + ! Destroy the input data: + + +END SUBROUTINE ExtLd_End +!---------------------------------------------------------------------------------------------------------------------------------- +!> Loose coupling routine for solving for constraint states, integrating continuous states, and updating discrete and other states. +!! Continuous, constraint, discrete, and other states are updated for t + Interval +subroutine ExtLd_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, m, errStat, errMsg ) +!.................................................................................................................................. + + real(DbKi), intent(in ) :: t !< Current simulation time in seconds + integer(IntKi), intent(in ) :: n !< Current simulation time step n = 0,1,... + type(ExtLd_InputType), intent(inout) :: u(:) !< Inputs at utimes (out only for mesh record-keeping in ExtrapInterp routine) + real(DbKi), intent(in ) :: utimes(:) !< Times associated with u(:), in seconds + type(ExtLd_ParameterType), intent(in ) :: p !< Parameters + type(ExtLd_ContinuousStateType), intent(inout) :: x !< Input: Continuous states at t; + !! Output: Continuous states at t + Interval + type(ExtLd_DiscreteStateType), intent(inout) :: xd !< Input: Discrete states at t; + !! Output: Discrete states at t + Interval + type(ExtLd_ConstraintStateType), intent(inout) :: z !< Input: Constraint states at t; + !! Output: Constraint states at t+dt + type(ExtLd_OtherStateType), intent(inout) :: OtherState !< Input: Other states at t; + !! Output: Other states at t+dt + type(ExtLd_MiscVarType), intent(inout) :: m !< Misc/optimization variables + integer(IntKi), intent( out) :: errStat !< Error status of the operation + character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + type(ExtLd_InputType) :: uInterp ! Interpolated/Extrapolated input + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'ExtLd_UpdateStates' + + ErrStat = ErrID_None + ErrMsg = "" + + +end subroutine ExtLd_UpdateStates +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine for computing outputs, used in both loose and tight coupling. +!! This subroutine is used to compute the output channels (motions and loads) and place them in the WriteOutput() array. +!! The descriptions of the output channels are not given here. Please see the included OutListParameters.xlsx sheet for +!! for a complete description of each output parameter. +subroutine ExtLd_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) +! NOTE: no matter how many channels are selected for output, all of the outputs are calculated +! All of the calculated output channels are placed into the m%AllOuts(:), while the channels selected for outputs are +! placed in the y%WriteOutput(:) array. +!.................................................................................................................................. + + REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds + TYPE(ExtLd_InputType), INTENT(IN ) :: u !< Inputs at Time t + TYPE(ExtLd_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(ExtLd_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t + TYPE(ExtLd_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t + TYPE(ExtLd_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t + TYPE(ExtLd_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y !< Outputs computed at t (Input only so that mesh con- + !! nectivity information does not have to be recalculated) + type(ExtLd_MiscVarType), intent(inout) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + + integer, parameter :: indx = 1 ! m%BEMT_u(1) is at t; m%BEMT_u(2) is t+dt + integer(intKi) :: i + integer(intKi) :: j + + integer(intKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'ExtLd_CalcOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + end subroutine ExtLd_CalcOutput + + subroutine apply_wm(c, v, vrot, transpose) + + real(reki), intent(in) :: c(:) ! The Wiener-Milenkovic parameter + real(reki), intent(in) :: v(:) ! The vector to be rotated + real(reki), intent(inout) :: vrot(:) !Hold the rotated vector + real(reki), intent(in) :: transpose !Whether to transpose the rotation + + real(reki) :: magC, c0, nu, cosPhiO2 + real(reki) :: cCrossV(3) + real(reki) :: cCrosscCrossV(3) + + magC = c(1)*c(1) + c(2)*c(2) + c(3)*c(3) + c0 = 2.0-0.125*magC + nu = 2.0/(4.0-c0) + cosPhiO2 = 0.5*c0*nu + cCrossV(1) = c(2)*v(3) - c(3)*v(2) + cCrossV(2) = c(3)*v(1) - c(1)*v(3) + cCrossV(3) = c(1)*v(2) - c(2)*v(1) + + !write(*,*) ' c = ', c(1), ', ', c(2), ', ', c(3) + !write(*,*) ' cCrossV = ', cCrossV(1), ', ', cCrossV(2), ', ', cCrossV(3) + + cCrosscCrossV(1) = c(2)*cCrossV(3) - c(3)*cCrossV(2) + cCrosscCrossV(2) = c(3)*cCrossV(1) - c(1)*cCrossV(3) + cCrosscCrossV(3) = c(1)*cCrossV(2) - c(2)*cCrossV(1) + + vrot(1) = v(1) + transpose * nu * cosPhiO2 * cCrossV(1) + 0.5 * nu * nu * cCrosscCrossV(1) + vrot(2) = v(2) + transpose * nu * cosPhiO2 * cCrossV(2) + 0.5 * nu * nu * cCrosscCrossV(2) + vrot(3) = v(3) + transpose * nu * cosPhiO2 * cCrossV(3) + 0.5 * nu * nu * cCrosscCrossV(3) + + end subroutine apply_wm + +END MODULE ExtLoads diff --git a/modules/extloads/src/ExtLoadsDX_Registry.txt b/modules/extloads/src/ExtLoadsDX_Registry.txt new file mode 100644 index 0000000000..7f09fae1ca --- /dev/null +++ b/modules/extloads/src/ExtLoadsDX_Registry.txt @@ -0,0 +1,44 @@ +################################################################################################################################### +# Registry for ExternalLoadsDX in the FAST Modularization Framework +# This Registry file is used to create ExtLoadsDX_Types which contains data used in the ExtLoads module for data exchange with external drivers. +# It also contains copy, destroy, pack, and unpack routines associated with each defined data types. +# See the NWTC Programmer's Handbook for further information on the format/contents of this file. +# +# Entries are of the form +# +# +# Use ^ as a shortcut for the value in the same column from the previous line. +################################################################################################################################### +# File last committed $Date$ +# (File) Revision #: $Rev$ +# URL: $HeadURL$ +################################################################################################################################### +# ...... Include files (definitions from NWTC Library) ............................................................................ +include Registry_NWTC_Library.txt + +# ..... Inputs .................................................................................................................... +# Define inputs that are contained on the mesh here: +typedef ExtLoadsDX/ExtLdDX InputType R8Ki twrDef {:} - - "Deformations on the tower - to send to external driver" +typedef ^ InputType R8Ki bldDef {:} - - "Deformations on all blades - to send to external driver" +typedef ^ InputType R8Ki hubDef {:} - - "Deformations on the hub - to send to external driver" +typedef ^ InputType R8Ki nacDef {:} - - "Deformations the nacelle - to send to external driver" +typedef ^ InputType R8Ki bldRootDef {:} - - "Deformations of the blade root nodes - to send to external driver" +typedef ^ InputType R8Ki twrRefPos {:} - - "Reference position of the tower nodes - to send to external driver" +typedef ^ InputType R8Ki bldRefPos {:} - - "Reference position of the all blade nodes - to send to external driver" +typedef ^ InputType R8Ki hubRefPos {:} - - "Reference position of the tower nodes - to send to external driver" +typedef ^ InputType R8Ki nacRefPos {:} - - "Reference position of the all blade nodes - to send to external driver" +typedef ^ InputType R8Ki bldRootRefPos {:} - - "Reference position of the blade root nodes - to send to external driver" +typedef ^ InputType IntKi nBlades {:} - - "Number of blades" +typedef ^ InputType IntKi nBladeNodes {:} - - "Number of blade nodes for each blade" - +typedef ^ InputType IntKi nTowerNodes {:} - - "Number of tower nodes for each blade" - +typedef ^ InputType R8Ki bldChord {:} - - "Blade chord" m +typedef ^ InputType R8Ki bldRloc {:} - - "Radial location along the blade" m +typedef ^ InputType R8Ki twrDia {:} - - "Tower diameter" m +typedef ^ InputType R8Ki twrHloc {:} - - "Height location along the tower" m +typedef ^ InputType R8Ki bldPitch {:} - - "Pitch angle of blade" + + +# ..... Outputs ................................................................................................................... +# Define outputs that are contained on the mesh here: +typedef ^ OutputType R8Ki twrLd {:} - - "Loads on the tower - Externally supplied" +typedef ^ OutputType R8Ki bldLd {:} - - "Loads on all blades - Externally supplied" diff --git a/modules/extloads/src/ExtLoadsDX_Types.f90 b/modules/extloads/src/ExtLoadsDX_Types.f90 new file mode 100644 index 0000000000..6fd8494e49 --- /dev/null +++ b/modules/extloads/src/ExtLoadsDX_Types.f90 @@ -0,0 +1,2674 @@ +!STARTOFREGISTRYGENERATEDFILE 'ExtLoadsDX_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 +!********************************************************************************************************************************* +! ExtLoadsDX_Types +!................................................................................................................................. +! This file is part of ExtLoadsDX. +! +! 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 ExtLoadsDX. 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 ExtLoadsDX_Types +!--------------------------------------------------------------------------------------------------------------------------------- +!USE, INTRINSIC :: ISO_C_Binding +USE NWTC_Library +IMPLICIT NONE +! ========= ExtLdDX_InputType_C ======= + TYPE, BIND(C) :: ExtLdDX_InputType_C + TYPE(C_PTR) :: object = C_NULL_PTR + TYPE(C_ptr) :: twrDef = C_NULL_PTR + INTEGER(C_int) :: twrDef_Len = 0 + TYPE(C_ptr) :: bldDef = C_NULL_PTR + INTEGER(C_int) :: bldDef_Len = 0 + TYPE(C_ptr) :: hubDef = C_NULL_PTR + INTEGER(C_int) :: hubDef_Len = 0 + TYPE(C_ptr) :: nacDef = C_NULL_PTR + INTEGER(C_int) :: nacDef_Len = 0 + TYPE(C_ptr) :: bldRootDef = C_NULL_PTR + INTEGER(C_int) :: bldRootDef_Len = 0 + TYPE(C_ptr) :: twrRefPos = C_NULL_PTR + INTEGER(C_int) :: twrRefPos_Len = 0 + TYPE(C_ptr) :: bldRefPos = C_NULL_PTR + INTEGER(C_int) :: bldRefPos_Len = 0 + TYPE(C_ptr) :: hubRefPos = C_NULL_PTR + INTEGER(C_int) :: hubRefPos_Len = 0 + TYPE(C_ptr) :: nacRefPos = C_NULL_PTR + INTEGER(C_int) :: nacRefPos_Len = 0 + TYPE(C_ptr) :: bldRootRefPos = C_NULL_PTR + INTEGER(C_int) :: bldRootRefPos_Len = 0 + TYPE(C_ptr) :: nBlades = C_NULL_PTR + INTEGER(C_int) :: nBlades_Len = 0 + TYPE(C_ptr) :: nBladeNodes = C_NULL_PTR + INTEGER(C_int) :: nBladeNodes_Len = 0 + TYPE(C_ptr) :: nTowerNodes = C_NULL_PTR + INTEGER(C_int) :: nTowerNodes_Len = 0 + TYPE(C_ptr) :: bldChord = C_NULL_PTR + INTEGER(C_int) :: bldChord_Len = 0 + TYPE(C_ptr) :: bldRloc = C_NULL_PTR + INTEGER(C_int) :: bldRloc_Len = 0 + TYPE(C_ptr) :: twrDia = C_NULL_PTR + INTEGER(C_int) :: twrDia_Len = 0 + TYPE(C_ptr) :: twrHloc = C_NULL_PTR + INTEGER(C_int) :: twrHloc_Len = 0 + TYPE(C_ptr) :: bldPitch = C_NULL_PTR + INTEGER(C_int) :: bldPitch_Len = 0 + END TYPE ExtLdDX_InputType_C + TYPE, PUBLIC :: ExtLdDX_InputType + TYPE( ExtLdDX_InputType_C ) :: C_obj + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrDef => NULL() !< Deformations on the tower - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldDef => NULL() !< Deformations on all blades - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: hubDef => NULL() !< Deformations on the hub - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: nacDef => NULL() !< Deformations the nacelle - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRootDef => NULL() !< Deformations of the blade root nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrRefPos => NULL() !< Reference position of the tower nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRefPos => NULL() !< Reference position of the all blade nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: hubRefPos => NULL() !< Reference position of the tower nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: nacRefPos => NULL() !< Reference position of the all blade nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRootRefPos => NULL() !< Reference position of the blade root nodes - to send to external driver [-] + INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBlades => NULL() !< Number of blades [-] + INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBladeNodes => NULL() !< Number of blade nodes for each blade [-] + INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nTowerNodes => NULL() !< Number of tower nodes for each blade [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldChord => NULL() !< Blade chord [m] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRloc => NULL() !< Radial location along the blade [m] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrDia => NULL() !< Tower diameter [m] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrHloc => NULL() !< Height location along the tower [m] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldPitch => NULL() !< Pitch angle of blade [-] + END TYPE ExtLdDX_InputType +! ======================= +! ========= ExtLdDX_OutputType_C ======= + TYPE, BIND(C) :: ExtLdDX_OutputType_C + TYPE(C_PTR) :: object = C_NULL_PTR + TYPE(C_ptr) :: twrLd = C_NULL_PTR + INTEGER(C_int) :: twrLd_Len = 0 + TYPE(C_ptr) :: bldLd = C_NULL_PTR + INTEGER(C_int) :: bldLd_Len = 0 + END TYPE ExtLdDX_OutputType_C + TYPE, PUBLIC :: ExtLdDX_OutputType + TYPE( ExtLdDX_OutputType_C ) :: C_obj + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrLd => NULL() !< Loads on the tower - Externally supplied [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldLd => NULL() !< Loads on all blades - Externally supplied [-] + END TYPE ExtLdDX_OutputType +! ======================= +CONTAINS + SUBROUTINE ExtLdDX_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLdDX_InputType), INTENT(IN) :: SrcInputData + TYPE(ExtLdDX_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) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_CopyInput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ASSOCIATED(SrcInputData%twrDef)) THEN + i1_l = LBOUND(SrcInputData%twrDef,1) + i1_u = UBOUND(SrcInputData%twrDef,1) + IF (.NOT. ASSOCIATED(DstInputData%twrDef)) THEN + ALLOCATE(DstInputData%twrDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%twrDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%twrDef_Len = SIZE(DstInputData%twrDef) + IF (DstInputData%c_obj%twrDef_Len > 0) & + DstInputData%c_obj%twrDef = C_LOC( DstInputData%twrDef( i1_l ) ) + END IF + DstInputData%twrDef = SrcInputData%twrDef +ENDIF +IF (ASSOCIATED(SrcInputData%bldDef)) THEN + i1_l = LBOUND(SrcInputData%bldDef,1) + i1_u = UBOUND(SrcInputData%bldDef,1) + IF (.NOT. ASSOCIATED(DstInputData%bldDef)) THEN + ALLOCATE(DstInputData%bldDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%bldDef_Len = SIZE(DstInputData%bldDef) + IF (DstInputData%c_obj%bldDef_Len > 0) & + DstInputData%c_obj%bldDef = C_LOC( DstInputData%bldDef( i1_l ) ) + END IF + DstInputData%bldDef = SrcInputData%bldDef +ENDIF +IF (ASSOCIATED(SrcInputData%hubDef)) THEN + i1_l = LBOUND(SrcInputData%hubDef,1) + i1_u = UBOUND(SrcInputData%hubDef,1) + IF (.NOT. ASSOCIATED(DstInputData%hubDef)) THEN + ALLOCATE(DstInputData%hubDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%hubDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%hubDef_Len = SIZE(DstInputData%hubDef) + IF (DstInputData%c_obj%hubDef_Len > 0) & + DstInputData%c_obj%hubDef = C_LOC( DstInputData%hubDef( i1_l ) ) + END IF + DstInputData%hubDef = SrcInputData%hubDef +ENDIF +IF (ASSOCIATED(SrcInputData%nacDef)) THEN + i1_l = LBOUND(SrcInputData%nacDef,1) + i1_u = UBOUND(SrcInputData%nacDef,1) + IF (.NOT. ASSOCIATED(DstInputData%nacDef)) THEN + ALLOCATE(DstInputData%nacDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nacDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%nacDef_Len = SIZE(DstInputData%nacDef) + IF (DstInputData%c_obj%nacDef_Len > 0) & + DstInputData%c_obj%nacDef = C_LOC( DstInputData%nacDef( i1_l ) ) + END IF + DstInputData%nacDef = SrcInputData%nacDef +ENDIF +IF (ASSOCIATED(SrcInputData%bldRootDef)) THEN + i1_l = LBOUND(SrcInputData%bldRootDef,1) + i1_u = UBOUND(SrcInputData%bldRootDef,1) + IF (.NOT. ASSOCIATED(DstInputData%bldRootDef)) THEN + ALLOCATE(DstInputData%bldRootDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldRootDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%bldRootDef_Len = SIZE(DstInputData%bldRootDef) + IF (DstInputData%c_obj%bldRootDef_Len > 0) & + DstInputData%c_obj%bldRootDef = C_LOC( DstInputData%bldRootDef( i1_l ) ) + END IF + DstInputData%bldRootDef = SrcInputData%bldRootDef +ENDIF +IF (ASSOCIATED(SrcInputData%twrRefPos)) THEN + i1_l = LBOUND(SrcInputData%twrRefPos,1) + i1_u = UBOUND(SrcInputData%twrRefPos,1) + IF (.NOT. ASSOCIATED(DstInputData%twrRefPos)) THEN + ALLOCATE(DstInputData%twrRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%twrRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%twrRefPos_Len = SIZE(DstInputData%twrRefPos) + IF (DstInputData%c_obj%twrRefPos_Len > 0) & + DstInputData%c_obj%twrRefPos = C_LOC( DstInputData%twrRefPos( i1_l ) ) + END IF + DstInputData%twrRefPos = SrcInputData%twrRefPos +ENDIF +IF (ASSOCIATED(SrcInputData%bldRefPos)) THEN + i1_l = LBOUND(SrcInputData%bldRefPos,1) + i1_u = UBOUND(SrcInputData%bldRefPos,1) + IF (.NOT. ASSOCIATED(DstInputData%bldRefPos)) THEN + ALLOCATE(DstInputData%bldRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%bldRefPos_Len = SIZE(DstInputData%bldRefPos) + IF (DstInputData%c_obj%bldRefPos_Len > 0) & + DstInputData%c_obj%bldRefPos = C_LOC( DstInputData%bldRefPos( i1_l ) ) + END IF + DstInputData%bldRefPos = SrcInputData%bldRefPos +ENDIF +IF (ASSOCIATED(SrcInputData%hubRefPos)) THEN + i1_l = LBOUND(SrcInputData%hubRefPos,1) + i1_u = UBOUND(SrcInputData%hubRefPos,1) + IF (.NOT. ASSOCIATED(DstInputData%hubRefPos)) THEN + ALLOCATE(DstInputData%hubRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%hubRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%hubRefPos_Len = SIZE(DstInputData%hubRefPos) + IF (DstInputData%c_obj%hubRefPos_Len > 0) & + DstInputData%c_obj%hubRefPos = C_LOC( DstInputData%hubRefPos( i1_l ) ) + END IF + DstInputData%hubRefPos = SrcInputData%hubRefPos +ENDIF +IF (ASSOCIATED(SrcInputData%nacRefPos)) THEN + i1_l = LBOUND(SrcInputData%nacRefPos,1) + i1_u = UBOUND(SrcInputData%nacRefPos,1) + IF (.NOT. ASSOCIATED(DstInputData%nacRefPos)) THEN + ALLOCATE(DstInputData%nacRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nacRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%nacRefPos_Len = SIZE(DstInputData%nacRefPos) + IF (DstInputData%c_obj%nacRefPos_Len > 0) & + DstInputData%c_obj%nacRefPos = C_LOC( DstInputData%nacRefPos( i1_l ) ) + END IF + DstInputData%nacRefPos = SrcInputData%nacRefPos +ENDIF +IF (ASSOCIATED(SrcInputData%bldRootRefPos)) THEN + i1_l = LBOUND(SrcInputData%bldRootRefPos,1) + i1_u = UBOUND(SrcInputData%bldRootRefPos,1) + IF (.NOT. ASSOCIATED(DstInputData%bldRootRefPos)) THEN + ALLOCATE(DstInputData%bldRootRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldRootRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%bldRootRefPos_Len = SIZE(DstInputData%bldRootRefPos) + IF (DstInputData%c_obj%bldRootRefPos_Len > 0) & + DstInputData%c_obj%bldRootRefPos = C_LOC( DstInputData%bldRootRefPos( i1_l ) ) + END IF + DstInputData%bldRootRefPos = SrcInputData%bldRootRefPos +ENDIF +IF (ASSOCIATED(SrcInputData%nBlades)) THEN + i1_l = LBOUND(SrcInputData%nBlades,1) + i1_u = UBOUND(SrcInputData%nBlades,1) + IF (.NOT. ASSOCIATED(DstInputData%nBlades)) THEN + ALLOCATE(DstInputData%nBlades(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nBlades.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%nBlades_Len = SIZE(DstInputData%nBlades) + IF (DstInputData%c_obj%nBlades_Len > 0) & + DstInputData%c_obj%nBlades = C_LOC( DstInputData%nBlades( i1_l ) ) + END IF + DstInputData%nBlades = SrcInputData%nBlades +ENDIF +IF (ASSOCIATED(SrcInputData%nBladeNodes)) THEN + i1_l = LBOUND(SrcInputData%nBladeNodes,1) + i1_u = UBOUND(SrcInputData%nBladeNodes,1) + IF (.NOT. ASSOCIATED(DstInputData%nBladeNodes)) THEN + ALLOCATE(DstInputData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%nBladeNodes_Len = SIZE(DstInputData%nBladeNodes) + IF (DstInputData%c_obj%nBladeNodes_Len > 0) & + DstInputData%c_obj%nBladeNodes = C_LOC( DstInputData%nBladeNodes( i1_l ) ) + END IF + DstInputData%nBladeNodes = SrcInputData%nBladeNodes +ENDIF +IF (ASSOCIATED(SrcInputData%nTowerNodes)) THEN + i1_l = LBOUND(SrcInputData%nTowerNodes,1) + i1_u = UBOUND(SrcInputData%nTowerNodes,1) + IF (.NOT. ASSOCIATED(DstInputData%nTowerNodes)) THEN + ALLOCATE(DstInputData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%nTowerNodes_Len = SIZE(DstInputData%nTowerNodes) + IF (DstInputData%c_obj%nTowerNodes_Len > 0) & + DstInputData%c_obj%nTowerNodes = C_LOC( DstInputData%nTowerNodes( i1_l ) ) + END IF + DstInputData%nTowerNodes = SrcInputData%nTowerNodes +ENDIF +IF (ASSOCIATED(SrcInputData%bldChord)) THEN + i1_l = LBOUND(SrcInputData%bldChord,1) + i1_u = UBOUND(SrcInputData%bldChord,1) + IF (.NOT. ASSOCIATED(DstInputData%bldChord)) THEN + ALLOCATE(DstInputData%bldChord(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%bldChord_Len = SIZE(DstInputData%bldChord) + IF (DstInputData%c_obj%bldChord_Len > 0) & + DstInputData%c_obj%bldChord = C_LOC( DstInputData%bldChord( i1_l ) ) + END IF + DstInputData%bldChord = SrcInputData%bldChord +ENDIF +IF (ASSOCIATED(SrcInputData%bldRloc)) THEN + i1_l = LBOUND(SrcInputData%bldRloc,1) + i1_u = UBOUND(SrcInputData%bldRloc,1) + IF (.NOT. ASSOCIATED(DstInputData%bldRloc)) THEN + ALLOCATE(DstInputData%bldRloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldRloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%bldRloc_Len = SIZE(DstInputData%bldRloc) + IF (DstInputData%c_obj%bldRloc_Len > 0) & + DstInputData%c_obj%bldRloc = C_LOC( DstInputData%bldRloc( i1_l ) ) + END IF + DstInputData%bldRloc = SrcInputData%bldRloc +ENDIF +IF (ASSOCIATED(SrcInputData%twrDia)) THEN + i1_l = LBOUND(SrcInputData%twrDia,1) + i1_u = UBOUND(SrcInputData%twrDia,1) + IF (.NOT. ASSOCIATED(DstInputData%twrDia)) THEN + ALLOCATE(DstInputData%twrDia(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%twrDia.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%twrDia_Len = SIZE(DstInputData%twrDia) + IF (DstInputData%c_obj%twrDia_Len > 0) & + DstInputData%c_obj%twrDia = C_LOC( DstInputData%twrDia( i1_l ) ) + END IF + DstInputData%twrDia = SrcInputData%twrDia +ENDIF +IF (ASSOCIATED(SrcInputData%twrHloc)) THEN + i1_l = LBOUND(SrcInputData%twrHloc,1) + i1_u = UBOUND(SrcInputData%twrHloc,1) + IF (.NOT. ASSOCIATED(DstInputData%twrHloc)) THEN + ALLOCATE(DstInputData%twrHloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%twrHloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%twrHloc_Len = SIZE(DstInputData%twrHloc) + IF (DstInputData%c_obj%twrHloc_Len > 0) & + DstInputData%c_obj%twrHloc = C_LOC( DstInputData%twrHloc( i1_l ) ) + END IF + DstInputData%twrHloc = SrcInputData%twrHloc +ENDIF +IF (ASSOCIATED(SrcInputData%bldPitch)) THEN + i1_l = LBOUND(SrcInputData%bldPitch,1) + i1_u = UBOUND(SrcInputData%bldPitch,1) + IF (.NOT. ASSOCIATED(DstInputData%bldPitch)) THEN + ALLOCATE(DstInputData%bldPitch(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldPitch.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstInputData%c_obj%bldPitch_Len = SIZE(DstInputData%bldPitch) + IF (DstInputData%c_obj%bldPitch_Len > 0) & + DstInputData%c_obj%bldPitch = C_LOC( DstInputData%bldPitch( i1_l ) ) + END IF + DstInputData%bldPitch = SrcInputData%bldPitch +ENDIF + END SUBROUTINE ExtLdDX_CopyInput + + SUBROUTINE ExtLdDX_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLdDX_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 = 'ExtLdDX_DestroyInput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ASSOCIATED(InputData%twrDef)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%twrDef) + InputData%twrDef => NULL() + InputData%C_obj%twrDef = C_NULL_PTR + InputData%C_obj%twrDef_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%bldDef)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%bldDef) + InputData%bldDef => NULL() + InputData%C_obj%bldDef = C_NULL_PTR + InputData%C_obj%bldDef_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%hubDef)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%hubDef) + InputData%hubDef => NULL() + InputData%C_obj%hubDef = C_NULL_PTR + InputData%C_obj%hubDef_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%nacDef)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%nacDef) + InputData%nacDef => NULL() + InputData%C_obj%nacDef = C_NULL_PTR + InputData%C_obj%nacDef_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%bldRootDef)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%bldRootDef) + InputData%bldRootDef => NULL() + InputData%C_obj%bldRootDef = C_NULL_PTR + InputData%C_obj%bldRootDef_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%twrRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%twrRefPos) + InputData%twrRefPos => NULL() + InputData%C_obj%twrRefPos = C_NULL_PTR + InputData%C_obj%twrRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%bldRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%bldRefPos) + InputData%bldRefPos => NULL() + InputData%C_obj%bldRefPos = C_NULL_PTR + InputData%C_obj%bldRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%hubRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%hubRefPos) + InputData%hubRefPos => NULL() + InputData%C_obj%hubRefPos = C_NULL_PTR + InputData%C_obj%hubRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%nacRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%nacRefPos) + InputData%nacRefPos => NULL() + InputData%C_obj%nacRefPos = C_NULL_PTR + InputData%C_obj%nacRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%bldRootRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%bldRootRefPos) + InputData%bldRootRefPos => NULL() + InputData%C_obj%bldRootRefPos = C_NULL_PTR + InputData%C_obj%bldRootRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%nBlades)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%nBlades) + InputData%nBlades => NULL() + InputData%C_obj%nBlades = C_NULL_PTR + InputData%C_obj%nBlades_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%nBladeNodes)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%nBladeNodes) + InputData%nBladeNodes => NULL() + InputData%C_obj%nBladeNodes = C_NULL_PTR + InputData%C_obj%nBladeNodes_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%nTowerNodes)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%nTowerNodes) + InputData%nTowerNodes => NULL() + InputData%C_obj%nTowerNodes = C_NULL_PTR + InputData%C_obj%nTowerNodes_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%bldChord)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%bldChord) + InputData%bldChord => NULL() + InputData%C_obj%bldChord = C_NULL_PTR + InputData%C_obj%bldChord_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%bldRloc)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%bldRloc) + InputData%bldRloc => NULL() + InputData%C_obj%bldRloc = C_NULL_PTR + InputData%C_obj%bldRloc_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%twrDia)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%twrDia) + InputData%twrDia => NULL() + InputData%C_obj%twrDia = C_NULL_PTR + InputData%C_obj%twrDia_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%twrHloc)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%twrHloc) + InputData%twrHloc => NULL() + InputData%C_obj%twrHloc = C_NULL_PTR + InputData%C_obj%twrHloc_Len = 0 +ENDIF +IF (ASSOCIATED(InputData%bldPitch)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(InputData%bldPitch) + InputData%bldPitch => NULL() + InputData%C_obj%bldPitch = C_NULL_PTR + InputData%C_obj%bldPitch_Len = 0 +ENDIF + END SUBROUTINE ExtLdDX_DestroyInput + + SUBROUTINE ExtLdDX_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(ExtLdDX_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 = 'ExtLdDX_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 ! twrDef allocated yes/no + IF ( ASSOCIATED(InData%twrDef) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrDef upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrDef) ! twrDef + END IF + Int_BufSz = Int_BufSz + 1 ! bldDef allocated yes/no + IF ( ASSOCIATED(InData%bldDef) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldDef upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldDef) ! bldDef + END IF + Int_BufSz = Int_BufSz + 1 ! hubDef allocated yes/no + IF ( ASSOCIATED(InData%hubDef) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! hubDef upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%hubDef) ! hubDef + END IF + Int_BufSz = Int_BufSz + 1 ! nacDef allocated yes/no + IF ( ASSOCIATED(InData%nacDef) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nacDef upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%nacDef) ! nacDef + END IF + Int_BufSz = Int_BufSz + 1 ! bldRootDef allocated yes/no + IF ( ASSOCIATED(InData%bldRootDef) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldRootDef upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldRootDef) ! bldRootDef + END IF + Int_BufSz = Int_BufSz + 1 ! twrRefPos allocated yes/no + IF ( ASSOCIATED(InData%twrRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrRefPos) ! twrRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! bldRefPos allocated yes/no + IF ( ASSOCIATED(InData%bldRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldRefPos) ! bldRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! hubRefPos allocated yes/no + IF ( ASSOCIATED(InData%hubRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! hubRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%hubRefPos) ! hubRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! nacRefPos allocated yes/no + IF ( ASSOCIATED(InData%nacRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nacRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%nacRefPos) ! nacRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! bldRootRefPos allocated yes/no + IF ( ASSOCIATED(InData%bldRootRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldRootRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldRootRefPos) ! bldRootRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! nBlades allocated yes/no + IF ( ASSOCIATED(InData%nBlades) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nBlades upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nBlades) ! nBlades + END IF + Int_BufSz = Int_BufSz + 1 ! nBladeNodes allocated yes/no + IF ( ASSOCIATED(InData%nBladeNodes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nBladeNodes upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nBladeNodes) ! nBladeNodes + END IF + Int_BufSz = Int_BufSz + 1 ! nTowerNodes allocated yes/no + IF ( ASSOCIATED(InData%nTowerNodes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nTowerNodes upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nTowerNodes) ! nTowerNodes + END IF + Int_BufSz = Int_BufSz + 1 ! bldChord allocated yes/no + IF ( ASSOCIATED(InData%bldChord) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldChord upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldChord) ! bldChord + END IF + Int_BufSz = Int_BufSz + 1 ! bldRloc allocated yes/no + IF ( ASSOCIATED(InData%bldRloc) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldRloc upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldRloc) ! bldRloc + END IF + Int_BufSz = Int_BufSz + 1 ! twrDia allocated yes/no + IF ( ASSOCIATED(InData%twrDia) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrDia upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrDia) ! twrDia + END IF + Int_BufSz = Int_BufSz + 1 ! twrHloc allocated yes/no + IF ( ASSOCIATED(InData%twrHloc) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrHloc upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrHloc) ! twrHloc + END IF + Int_BufSz = Int_BufSz + 1 ! bldPitch allocated yes/no + IF ( ASSOCIATED(InData%bldPitch) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldPitch upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldPitch) ! bldPitch + 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) + + IF (C_ASSOCIATED(InData%C_obj%object)) CALL SetErrStat(ErrID_Severe,'C_obj%object cannot be packed.',ErrStat,ErrMsg,RoutineName) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ASSOCIATED(InData%twrDef) ) 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%twrDef,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrDef,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrDef,1), UBOUND(InData%twrDef,1) + DbKiBuf(Db_Xferred) = InData%twrDef(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldDef) ) 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%bldDef,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldDef,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldDef,1), UBOUND(InData%bldDef,1) + DbKiBuf(Db_Xferred) = InData%bldDef(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%hubDef) ) 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%hubDef,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%hubDef,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%hubDef,1), UBOUND(InData%hubDef,1) + DbKiBuf(Db_Xferred) = InData%hubDef(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nacDef) ) 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%nacDef,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nacDef,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nacDef,1), UBOUND(InData%nacDef,1) + DbKiBuf(Db_Xferred) = InData%nacDef(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldRootDef) ) 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%bldRootDef,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRootDef,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldRootDef,1), UBOUND(InData%bldRootDef,1) + DbKiBuf(Db_Xferred) = InData%bldRootDef(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%twrRefPos) ) 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%twrRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrRefPos,1), UBOUND(InData%twrRefPos,1) + DbKiBuf(Db_Xferred) = InData%twrRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldRefPos) ) 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%bldRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldRefPos,1), UBOUND(InData%bldRefPos,1) + DbKiBuf(Db_Xferred) = InData%bldRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%hubRefPos) ) 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%hubRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%hubRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%hubRefPos,1), UBOUND(InData%hubRefPos,1) + DbKiBuf(Db_Xferred) = InData%hubRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nacRefPos) ) 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%nacRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nacRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nacRefPos,1), UBOUND(InData%nacRefPos,1) + DbKiBuf(Db_Xferred) = InData%nacRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldRootRefPos) ) 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%bldRootRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRootRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldRootRefPos,1), UBOUND(InData%bldRootRefPos,1) + DbKiBuf(Db_Xferred) = InData%bldRootRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nBlades) ) 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%nBlades,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nBlades,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nBlades,1), UBOUND(InData%nBlades,1) + IntKiBuf(Int_Xferred) = InData%nBlades(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nBladeNodes) ) 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%nBladeNodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nBladeNodes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nBladeNodes,1), UBOUND(InData%nBladeNodes,1) + IntKiBuf(Int_Xferred) = InData%nBladeNodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nTowerNodes) ) 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%nTowerNodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nTowerNodes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nTowerNodes,1), UBOUND(InData%nTowerNodes,1) + IntKiBuf(Int_Xferred) = InData%nTowerNodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldChord) ) 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%bldChord,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldChord,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldChord,1), UBOUND(InData%bldChord,1) + DbKiBuf(Db_Xferred) = InData%bldChord(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldRloc) ) 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%bldRloc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRloc,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldRloc,1), UBOUND(InData%bldRloc,1) + DbKiBuf(Db_Xferred) = InData%bldRloc(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%twrDia) ) 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%twrDia,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrDia,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrDia,1), UBOUND(InData%twrDia,1) + DbKiBuf(Db_Xferred) = InData%twrDia(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%twrHloc) ) 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%twrHloc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrHloc,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrHloc,1), UBOUND(InData%twrHloc,1) + DbKiBuf(Db_Xferred) = InData%twrHloc(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldPitch) ) 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%bldPitch,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldPitch,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldPitch,1), UBOUND(InData%bldPitch,1) + DbKiBuf(Db_Xferred) = InData%bldPitch(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLdDX_PackInput + + SUBROUTINE ExtLdDX_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(ExtLdDX_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) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_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 ! twrDef 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 (ASSOCIATED(OutData%twrDef)) DEALLOCATE(OutData%twrDef) + ALLOCATE(OutData%twrDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%twrDef_Len = SIZE(OutData%twrDef) + IF (OutData%c_obj%twrDef_Len > 0) & + OutData%c_obj%twrDef = C_LOC( OutData%twrDef( i1_l ) ) + DO i1 = LBOUND(OutData%twrDef,1), UBOUND(OutData%twrDef,1) + OutData%twrDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldDef 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 (ASSOCIATED(OutData%bldDef)) DEALLOCATE(OutData%bldDef) + ALLOCATE(OutData%bldDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldDef_Len = SIZE(OutData%bldDef) + IF (OutData%c_obj%bldDef_Len > 0) & + OutData%c_obj%bldDef = C_LOC( OutData%bldDef( i1_l ) ) + DO i1 = LBOUND(OutData%bldDef,1), UBOUND(OutData%bldDef,1) + OutData%bldDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hubDef 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 (ASSOCIATED(OutData%hubDef)) DEALLOCATE(OutData%hubDef) + ALLOCATE(OutData%hubDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%hubDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%hubDef_Len = SIZE(OutData%hubDef) + IF (OutData%c_obj%hubDef_Len > 0) & + OutData%c_obj%hubDef = C_LOC( OutData%hubDef( i1_l ) ) + DO i1 = LBOUND(OutData%hubDef,1), UBOUND(OutData%hubDef,1) + OutData%hubDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nacDef 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 (ASSOCIATED(OutData%nacDef)) DEALLOCATE(OutData%nacDef) + ALLOCATE(OutData%nacDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nacDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nacDef_Len = SIZE(OutData%nacDef) + IF (OutData%c_obj%nacDef_Len > 0) & + OutData%c_obj%nacDef = C_LOC( OutData%nacDef( i1_l ) ) + DO i1 = LBOUND(OutData%nacDef,1), UBOUND(OutData%nacDef,1) + OutData%nacDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRootDef 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 (ASSOCIATED(OutData%bldRootDef)) DEALLOCATE(OutData%bldRootDef) + ALLOCATE(OutData%bldRootDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRootDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldRootDef_Len = SIZE(OutData%bldRootDef) + IF (OutData%c_obj%bldRootDef_Len > 0) & + OutData%c_obj%bldRootDef = C_LOC( OutData%bldRootDef( i1_l ) ) + DO i1 = LBOUND(OutData%bldRootDef,1), UBOUND(OutData%bldRootDef,1) + OutData%bldRootDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrRefPos 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 (ASSOCIATED(OutData%twrRefPos)) DEALLOCATE(OutData%twrRefPos) + ALLOCATE(OutData%twrRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%twrRefPos_Len = SIZE(OutData%twrRefPos) + IF (OutData%c_obj%twrRefPos_Len > 0) & + OutData%c_obj%twrRefPos = C_LOC( OutData%twrRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%twrRefPos,1), UBOUND(OutData%twrRefPos,1) + OutData%twrRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRefPos 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 (ASSOCIATED(OutData%bldRefPos)) DEALLOCATE(OutData%bldRefPos) + ALLOCATE(OutData%bldRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldRefPos_Len = SIZE(OutData%bldRefPos) + IF (OutData%c_obj%bldRefPos_Len > 0) & + OutData%c_obj%bldRefPos = C_LOC( OutData%bldRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%bldRefPos,1), UBOUND(OutData%bldRefPos,1) + OutData%bldRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hubRefPos 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 (ASSOCIATED(OutData%hubRefPos)) DEALLOCATE(OutData%hubRefPos) + ALLOCATE(OutData%hubRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%hubRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%hubRefPos_Len = SIZE(OutData%hubRefPos) + IF (OutData%c_obj%hubRefPos_Len > 0) & + OutData%c_obj%hubRefPos = C_LOC( OutData%hubRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%hubRefPos,1), UBOUND(OutData%hubRefPos,1) + OutData%hubRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nacRefPos 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 (ASSOCIATED(OutData%nacRefPos)) DEALLOCATE(OutData%nacRefPos) + ALLOCATE(OutData%nacRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nacRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nacRefPos_Len = SIZE(OutData%nacRefPos) + IF (OutData%c_obj%nacRefPos_Len > 0) & + OutData%c_obj%nacRefPos = C_LOC( OutData%nacRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%nacRefPos,1), UBOUND(OutData%nacRefPos,1) + OutData%nacRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRootRefPos 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 (ASSOCIATED(OutData%bldRootRefPos)) DEALLOCATE(OutData%bldRootRefPos) + ALLOCATE(OutData%bldRootRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRootRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldRootRefPos_Len = SIZE(OutData%bldRootRefPos) + IF (OutData%c_obj%bldRootRefPos_Len > 0) & + OutData%c_obj%bldRootRefPos = C_LOC( OutData%bldRootRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%bldRootRefPos,1), UBOUND(OutData%bldRootRefPos,1) + OutData%bldRootRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nBlades 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 (ASSOCIATED(OutData%nBlades)) DEALLOCATE(OutData%nBlades) + ALLOCATE(OutData%nBlades(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBlades.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nBlades_Len = SIZE(OutData%nBlades) + IF (OutData%c_obj%nBlades_Len > 0) & + OutData%c_obj%nBlades = C_LOC( OutData%nBlades( i1_l ) ) + DO i1 = LBOUND(OutData%nBlades,1), UBOUND(OutData%nBlades,1) + OutData%nBlades(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nBladeNodes 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 (ASSOCIATED(OutData%nBladeNodes)) DEALLOCATE(OutData%nBladeNodes) + ALLOCATE(OutData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nBladeNodes_Len = SIZE(OutData%nBladeNodes) + IF (OutData%c_obj%nBladeNodes_Len > 0) & + OutData%c_obj%nBladeNodes = C_LOC( OutData%nBladeNodes( i1_l ) ) + DO i1 = LBOUND(OutData%nBladeNodes,1), UBOUND(OutData%nBladeNodes,1) + OutData%nBladeNodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nTowerNodes 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 (ASSOCIATED(OutData%nTowerNodes)) DEALLOCATE(OutData%nTowerNodes) + ALLOCATE(OutData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nTowerNodes_Len = SIZE(OutData%nTowerNodes) + IF (OutData%c_obj%nTowerNodes_Len > 0) & + OutData%c_obj%nTowerNodes = C_LOC( OutData%nTowerNodes( i1_l ) ) + DO i1 = LBOUND(OutData%nTowerNodes,1), UBOUND(OutData%nTowerNodes,1) + OutData%nTowerNodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldChord 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 (ASSOCIATED(OutData%bldChord)) DEALLOCATE(OutData%bldChord) + ALLOCATE(OutData%bldChord(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldChord_Len = SIZE(OutData%bldChord) + IF (OutData%c_obj%bldChord_Len > 0) & + OutData%c_obj%bldChord = C_LOC( OutData%bldChord( i1_l ) ) + DO i1 = LBOUND(OutData%bldChord,1), UBOUND(OutData%bldChord,1) + OutData%bldChord(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRloc 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 (ASSOCIATED(OutData%bldRloc)) DEALLOCATE(OutData%bldRloc) + ALLOCATE(OutData%bldRloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldRloc_Len = SIZE(OutData%bldRloc) + IF (OutData%c_obj%bldRloc_Len > 0) & + OutData%c_obj%bldRloc = C_LOC( OutData%bldRloc( i1_l ) ) + DO i1 = LBOUND(OutData%bldRloc,1), UBOUND(OutData%bldRloc,1) + OutData%bldRloc(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrDia 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 (ASSOCIATED(OutData%twrDia)) DEALLOCATE(OutData%twrDia) + ALLOCATE(OutData%twrDia(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrDia.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%twrDia_Len = SIZE(OutData%twrDia) + IF (OutData%c_obj%twrDia_Len > 0) & + OutData%c_obj%twrDia = C_LOC( OutData%twrDia( i1_l ) ) + DO i1 = LBOUND(OutData%twrDia,1), UBOUND(OutData%twrDia,1) + OutData%twrDia(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrHloc 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 (ASSOCIATED(OutData%twrHloc)) DEALLOCATE(OutData%twrHloc) + ALLOCATE(OutData%twrHloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrHloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%twrHloc_Len = SIZE(OutData%twrHloc) + IF (OutData%c_obj%twrHloc_Len > 0) & + OutData%c_obj%twrHloc = C_LOC( OutData%twrHloc( i1_l ) ) + DO i1 = LBOUND(OutData%twrHloc,1), UBOUND(OutData%twrHloc,1) + OutData%twrHloc(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldPitch 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 (ASSOCIATED(OutData%bldPitch)) DEALLOCATE(OutData%bldPitch) + ALLOCATE(OutData%bldPitch(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldPitch.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldPitch_Len = SIZE(OutData%bldPitch) + IF (OutData%c_obj%bldPitch_Len > 0) & + OutData%c_obj%bldPitch = C_LOC( OutData%bldPitch( i1_l ) ) + DO i1 = LBOUND(OutData%bldPitch,1), UBOUND(OutData%bldPitch,1) + OutData%bldPitch(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLdDX_UnPackInput + + SUBROUTINE ExtLdDX_C2Fary_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) + TYPE(ExtLdDX_InputType), INTENT(INOUT) :: InputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers + ! + LOGICAL :: SkipPointers_local + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(SkipPointers)) THEN + SkipPointers_local = SkipPointers + ELSE + SkipPointers_local = .false. + END IF + + ! -- twrDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrDef ) ) THEN + NULLIFY( InputData%twrDef ) + ELSE + CALL C_F_POINTER(InputData%C_obj%twrDef, InputData%twrDef, (/InputData%C_obj%twrDef_Len/)) + END IF + END IF + + ! -- bldDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldDef ) ) THEN + NULLIFY( InputData%bldDef ) + ELSE + CALL C_F_POINTER(InputData%C_obj%bldDef, InputData%bldDef, (/InputData%C_obj%bldDef_Len/)) + END IF + END IF + + ! -- hubDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%hubDef ) ) THEN + NULLIFY( InputData%hubDef ) + ELSE + CALL C_F_POINTER(InputData%C_obj%hubDef, InputData%hubDef, (/InputData%C_obj%hubDef_Len/)) + END IF + END IF + + ! -- nacDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nacDef ) ) THEN + NULLIFY( InputData%nacDef ) + ELSE + CALL C_F_POINTER(InputData%C_obj%nacDef, InputData%nacDef, (/InputData%C_obj%nacDef_Len/)) + END IF + END IF + + ! -- bldRootDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldRootDef ) ) THEN + NULLIFY( InputData%bldRootDef ) + ELSE + CALL C_F_POINTER(InputData%C_obj%bldRootDef, InputData%bldRootDef, (/InputData%C_obj%bldRootDef_Len/)) + END IF + END IF + + ! -- twrRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrRefPos ) ) THEN + NULLIFY( InputData%twrRefPos ) + ELSE + CALL C_F_POINTER(InputData%C_obj%twrRefPos, InputData%twrRefPos, (/InputData%C_obj%twrRefPos_Len/)) + END IF + END IF + + ! -- bldRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldRefPos ) ) THEN + NULLIFY( InputData%bldRefPos ) + ELSE + CALL C_F_POINTER(InputData%C_obj%bldRefPos, InputData%bldRefPos, (/InputData%C_obj%bldRefPos_Len/)) + END IF + END IF + + ! -- hubRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%hubRefPos ) ) THEN + NULLIFY( InputData%hubRefPos ) + ELSE + CALL C_F_POINTER(InputData%C_obj%hubRefPos, InputData%hubRefPos, (/InputData%C_obj%hubRefPos_Len/)) + END IF + END IF + + ! -- nacRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nacRefPos ) ) THEN + NULLIFY( InputData%nacRefPos ) + ELSE + CALL C_F_POINTER(InputData%C_obj%nacRefPos, InputData%nacRefPos, (/InputData%C_obj%nacRefPos_Len/)) + END IF + END IF + + ! -- bldRootRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldRootRefPos ) ) THEN + NULLIFY( InputData%bldRootRefPos ) + ELSE + CALL C_F_POINTER(InputData%C_obj%bldRootRefPos, InputData%bldRootRefPos, (/InputData%C_obj%bldRootRefPos_Len/)) + END IF + END IF + + ! -- nBlades Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nBlades ) ) THEN + NULLIFY( InputData%nBlades ) + ELSE + CALL C_F_POINTER(InputData%C_obj%nBlades, InputData%nBlades, (/InputData%C_obj%nBlades_Len/)) + END IF + END IF + + ! -- nBladeNodes Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nBladeNodes ) ) THEN + NULLIFY( InputData%nBladeNodes ) + ELSE + CALL C_F_POINTER(InputData%C_obj%nBladeNodes, InputData%nBladeNodes, (/InputData%C_obj%nBladeNodes_Len/)) + END IF + END IF + + ! -- nTowerNodes Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nTowerNodes ) ) THEN + NULLIFY( InputData%nTowerNodes ) + ELSE + CALL C_F_POINTER(InputData%C_obj%nTowerNodes, InputData%nTowerNodes, (/InputData%C_obj%nTowerNodes_Len/)) + END IF + END IF + + ! -- bldChord Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldChord ) ) THEN + NULLIFY( InputData%bldChord ) + ELSE + CALL C_F_POINTER(InputData%C_obj%bldChord, InputData%bldChord, (/InputData%C_obj%bldChord_Len/)) + END IF + END IF + + ! -- bldRloc Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldRloc ) ) THEN + NULLIFY( InputData%bldRloc ) + ELSE + CALL C_F_POINTER(InputData%C_obj%bldRloc, InputData%bldRloc, (/InputData%C_obj%bldRloc_Len/)) + END IF + END IF + + ! -- twrDia Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrDia ) ) THEN + NULLIFY( InputData%twrDia ) + ELSE + CALL C_F_POINTER(InputData%C_obj%twrDia, InputData%twrDia, (/InputData%C_obj%twrDia_Len/)) + END IF + END IF + + ! -- twrHloc Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrHloc ) ) THEN + NULLIFY( InputData%twrHloc ) + ELSE + CALL C_F_POINTER(InputData%C_obj%twrHloc, InputData%twrHloc, (/InputData%C_obj%twrHloc_Len/)) + END IF + END IF + + ! -- bldPitch Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldPitch ) ) THEN + NULLIFY( InputData%bldPitch ) + ELSE + CALL C_F_POINTER(InputData%C_obj%bldPitch, InputData%bldPitch, (/InputData%C_obj%bldPitch_Len/)) + END IF + END IF + END SUBROUTINE ExtLdDX_C2Fary_CopyInput + + SUBROUTINE ExtLdDX_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) + TYPE(ExtLdDX_InputType), INTENT(INOUT) :: InputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers + ! + LOGICAL :: SkipPointers_local + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(SkipPointers)) THEN + SkipPointers_local = SkipPointers + ELSE + SkipPointers_local = .false. + END IF + + ! -- twrDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%twrDef)) THEN + InputData%c_obj%twrDef_Len = 0 + InputData%c_obj%twrDef = C_NULL_PTR + ELSE + InputData%c_obj%twrDef_Len = SIZE(InputData%twrDef) + IF (InputData%c_obj%twrDef_Len > 0) & + InputData%c_obj%twrDef = C_LOC( InputData%twrDef( LBOUND(InputData%twrDef,1) ) ) + END IF + END IF + + ! -- bldDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%bldDef)) THEN + InputData%c_obj%bldDef_Len = 0 + InputData%c_obj%bldDef = C_NULL_PTR + ELSE + InputData%c_obj%bldDef_Len = SIZE(InputData%bldDef) + IF (InputData%c_obj%bldDef_Len > 0) & + InputData%c_obj%bldDef = C_LOC( InputData%bldDef( LBOUND(InputData%bldDef,1) ) ) + END IF + END IF + + ! -- hubDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%hubDef)) THEN + InputData%c_obj%hubDef_Len = 0 + InputData%c_obj%hubDef = C_NULL_PTR + ELSE + InputData%c_obj%hubDef_Len = SIZE(InputData%hubDef) + IF (InputData%c_obj%hubDef_Len > 0) & + InputData%c_obj%hubDef = C_LOC( InputData%hubDef( LBOUND(InputData%hubDef,1) ) ) + END IF + END IF + + ! -- nacDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%nacDef)) THEN + InputData%c_obj%nacDef_Len = 0 + InputData%c_obj%nacDef = C_NULL_PTR + ELSE + InputData%c_obj%nacDef_Len = SIZE(InputData%nacDef) + IF (InputData%c_obj%nacDef_Len > 0) & + InputData%c_obj%nacDef = C_LOC( InputData%nacDef( LBOUND(InputData%nacDef,1) ) ) + END IF + END IF + + ! -- bldRootDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%bldRootDef)) THEN + InputData%c_obj%bldRootDef_Len = 0 + InputData%c_obj%bldRootDef = C_NULL_PTR + ELSE + InputData%c_obj%bldRootDef_Len = SIZE(InputData%bldRootDef) + IF (InputData%c_obj%bldRootDef_Len > 0) & + InputData%c_obj%bldRootDef = C_LOC( InputData%bldRootDef( LBOUND(InputData%bldRootDef,1) ) ) + END IF + END IF + + ! -- twrRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%twrRefPos)) THEN + InputData%c_obj%twrRefPos_Len = 0 + InputData%c_obj%twrRefPos = C_NULL_PTR + ELSE + InputData%c_obj%twrRefPos_Len = SIZE(InputData%twrRefPos) + IF (InputData%c_obj%twrRefPos_Len > 0) & + InputData%c_obj%twrRefPos = C_LOC( InputData%twrRefPos( LBOUND(InputData%twrRefPos,1) ) ) + END IF + END IF + + ! -- bldRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%bldRefPos)) THEN + InputData%c_obj%bldRefPos_Len = 0 + InputData%c_obj%bldRefPos = C_NULL_PTR + ELSE + InputData%c_obj%bldRefPos_Len = SIZE(InputData%bldRefPos) + IF (InputData%c_obj%bldRefPos_Len > 0) & + InputData%c_obj%bldRefPos = C_LOC( InputData%bldRefPos( LBOUND(InputData%bldRefPos,1) ) ) + END IF + END IF + + ! -- hubRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%hubRefPos)) THEN + InputData%c_obj%hubRefPos_Len = 0 + InputData%c_obj%hubRefPos = C_NULL_PTR + ELSE + InputData%c_obj%hubRefPos_Len = SIZE(InputData%hubRefPos) + IF (InputData%c_obj%hubRefPos_Len > 0) & + InputData%c_obj%hubRefPos = C_LOC( InputData%hubRefPos( LBOUND(InputData%hubRefPos,1) ) ) + END IF + END IF + + ! -- nacRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%nacRefPos)) THEN + InputData%c_obj%nacRefPos_Len = 0 + InputData%c_obj%nacRefPos = C_NULL_PTR + ELSE + InputData%c_obj%nacRefPos_Len = SIZE(InputData%nacRefPos) + IF (InputData%c_obj%nacRefPos_Len > 0) & + InputData%c_obj%nacRefPos = C_LOC( InputData%nacRefPos( LBOUND(InputData%nacRefPos,1) ) ) + END IF + END IF + + ! -- bldRootRefPos Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%bldRootRefPos)) THEN + InputData%c_obj%bldRootRefPos_Len = 0 + InputData%c_obj%bldRootRefPos = C_NULL_PTR + ELSE + InputData%c_obj%bldRootRefPos_Len = SIZE(InputData%bldRootRefPos) + IF (InputData%c_obj%bldRootRefPos_Len > 0) & + InputData%c_obj%bldRootRefPos = C_LOC( InputData%bldRootRefPos( LBOUND(InputData%bldRootRefPos,1) ) ) + END IF + END IF + + ! -- nBlades Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%nBlades)) THEN + InputData%c_obj%nBlades_Len = 0 + InputData%c_obj%nBlades = C_NULL_PTR + ELSE + InputData%c_obj%nBlades_Len = SIZE(InputData%nBlades) + IF (InputData%c_obj%nBlades_Len > 0) & + InputData%c_obj%nBlades = C_LOC( InputData%nBlades( LBOUND(InputData%nBlades,1) ) ) + END IF + END IF + + ! -- nBladeNodes Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%nBladeNodes)) THEN + InputData%c_obj%nBladeNodes_Len = 0 + InputData%c_obj%nBladeNodes = C_NULL_PTR + ELSE + InputData%c_obj%nBladeNodes_Len = SIZE(InputData%nBladeNodes) + IF (InputData%c_obj%nBladeNodes_Len > 0) & + InputData%c_obj%nBladeNodes = C_LOC( InputData%nBladeNodes( LBOUND(InputData%nBladeNodes,1) ) ) + END IF + END IF + + ! -- nTowerNodes Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%nTowerNodes)) THEN + InputData%c_obj%nTowerNodes_Len = 0 + InputData%c_obj%nTowerNodes = C_NULL_PTR + ELSE + InputData%c_obj%nTowerNodes_Len = SIZE(InputData%nTowerNodes) + IF (InputData%c_obj%nTowerNodes_Len > 0) & + InputData%c_obj%nTowerNodes = C_LOC( InputData%nTowerNodes( LBOUND(InputData%nTowerNodes,1) ) ) + END IF + END IF + + ! -- bldChord Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%bldChord)) THEN + InputData%c_obj%bldChord_Len = 0 + InputData%c_obj%bldChord = C_NULL_PTR + ELSE + InputData%c_obj%bldChord_Len = SIZE(InputData%bldChord) + IF (InputData%c_obj%bldChord_Len > 0) & + InputData%c_obj%bldChord = C_LOC( InputData%bldChord( LBOUND(InputData%bldChord,1) ) ) + END IF + END IF + + ! -- bldRloc Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%bldRloc)) THEN + InputData%c_obj%bldRloc_Len = 0 + InputData%c_obj%bldRloc = C_NULL_PTR + ELSE + InputData%c_obj%bldRloc_Len = SIZE(InputData%bldRloc) + IF (InputData%c_obj%bldRloc_Len > 0) & + InputData%c_obj%bldRloc = C_LOC( InputData%bldRloc( LBOUND(InputData%bldRloc,1) ) ) + END IF + END IF + + ! -- twrDia Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%twrDia)) THEN + InputData%c_obj%twrDia_Len = 0 + InputData%c_obj%twrDia = C_NULL_PTR + ELSE + InputData%c_obj%twrDia_Len = SIZE(InputData%twrDia) + IF (InputData%c_obj%twrDia_Len > 0) & + InputData%c_obj%twrDia = C_LOC( InputData%twrDia( LBOUND(InputData%twrDia,1) ) ) + END IF + END IF + + ! -- twrHloc Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%twrHloc)) THEN + InputData%c_obj%twrHloc_Len = 0 + InputData%c_obj%twrHloc = C_NULL_PTR + ELSE + InputData%c_obj%twrHloc_Len = SIZE(InputData%twrHloc) + IF (InputData%c_obj%twrHloc_Len > 0) & + InputData%c_obj%twrHloc = C_LOC( InputData%twrHloc( LBOUND(InputData%twrHloc,1) ) ) + END IF + END IF + + ! -- bldPitch Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(InputData%bldPitch)) THEN + InputData%c_obj%bldPitch_Len = 0 + InputData%c_obj%bldPitch = C_NULL_PTR + ELSE + InputData%c_obj%bldPitch_Len = SIZE(InputData%bldPitch) + IF (InputData%c_obj%bldPitch_Len > 0) & + InputData%c_obj%bldPitch = C_LOC( InputData%bldPitch( LBOUND(InputData%bldPitch,1) ) ) + END IF + END IF + END SUBROUTINE ExtLdDX_F2C_CopyInput + + SUBROUTINE ExtLdDX_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLdDX_OutputType), INTENT(IN) :: SrcOutputData + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: DstOutputData + 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 = 'ExtLdDX_CopyOutput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ASSOCIATED(SrcOutputData%twrLd)) THEN + i1_l = LBOUND(SrcOutputData%twrLd,1) + i1_u = UBOUND(SrcOutputData%twrLd,1) + IF (.NOT. ASSOCIATED(DstOutputData%twrLd)) THEN + ALLOCATE(DstOutputData%twrLd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%twrLd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstOutputData%c_obj%twrLd_Len = SIZE(DstOutputData%twrLd) + IF (DstOutputData%c_obj%twrLd_Len > 0) & + DstOutputData%c_obj%twrLd = C_LOC( DstOutputData%twrLd( i1_l ) ) + END IF + DstOutputData%twrLd = SrcOutputData%twrLd +ENDIF +IF (ASSOCIATED(SrcOutputData%bldLd)) THEN + i1_l = LBOUND(SrcOutputData%bldLd,1) + i1_u = UBOUND(SrcOutputData%bldLd,1) + IF (.NOT. ASSOCIATED(DstOutputData%bldLd)) THEN + ALLOCATE(DstOutputData%bldLd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%bldLd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstOutputData%c_obj%bldLd_Len = SIZE(DstOutputData%bldLd) + IF (DstOutputData%c_obj%bldLd_Len > 0) & + DstOutputData%c_obj%bldLd = C_LOC( DstOutputData%bldLd( i1_l ) ) + END IF + DstOutputData%bldLd = SrcOutputData%bldLd +ENDIF + END SUBROUTINE ExtLdDX_CopyOutput + + SUBROUTINE ExtLdDX_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: OutputData + 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 = 'ExtLdDX_DestroyOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ASSOCIATED(OutputData%twrLd)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(OutputData%twrLd) + OutputData%twrLd => NULL() + OutputData%C_obj%twrLd = C_NULL_PTR + OutputData%C_obj%twrLd_Len = 0 +ENDIF +IF (ASSOCIATED(OutputData%bldLd)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(OutputData%bldLd) + OutputData%bldLd => NULL() + OutputData%C_obj%bldLd = C_NULL_PTR + OutputData%C_obj%bldLd_Len = 0 +ENDIF + END SUBROUTINE ExtLdDX_DestroyOutput + + SUBROUTINE ExtLdDX_PackOutput( 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(ExtLdDX_OutputType), 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 = 'ExtLdDX_PackOutput' + ! 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 ! twrLd allocated yes/no + IF ( ASSOCIATED(InData%twrLd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrLd upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrLd) ! twrLd + END IF + Int_BufSz = Int_BufSz + 1 ! bldLd allocated yes/no + IF ( ASSOCIATED(InData%bldLd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldLd upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldLd) ! bldLd + 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) + + IF (C_ASSOCIATED(InData%C_obj%object)) CALL SetErrStat(ErrID_Severe,'C_obj%object cannot be packed.',ErrStat,ErrMsg,RoutineName) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ASSOCIATED(InData%twrLd) ) 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%twrLd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrLd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrLd,1), UBOUND(InData%twrLd,1) + DbKiBuf(Db_Xferred) = InData%twrLd(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldLd) ) 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%bldLd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldLd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldLd,1), UBOUND(InData%bldLd,1) + DbKiBuf(Db_Xferred) = InData%bldLd(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLdDX_PackOutput + + SUBROUTINE ExtLdDX_UnPackOutput( 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(ExtLdDX_OutputType), 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 = 'ExtLdDX_UnPackOutput' + ! 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 ! twrLd 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 (ASSOCIATED(OutData%twrLd)) DEALLOCATE(OutData%twrLd) + ALLOCATE(OutData%twrLd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrLd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%twrLd_Len = SIZE(OutData%twrLd) + IF (OutData%c_obj%twrLd_Len > 0) & + OutData%c_obj%twrLd = C_LOC( OutData%twrLd( i1_l ) ) + DO i1 = LBOUND(OutData%twrLd,1), UBOUND(OutData%twrLd,1) + OutData%twrLd(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldLd 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 (ASSOCIATED(OutData%bldLd)) DEALLOCATE(OutData%bldLd) + ALLOCATE(OutData%bldLd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldLd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldLd_Len = SIZE(OutData%bldLd) + IF (OutData%c_obj%bldLd_Len > 0) & + OutData%c_obj%bldLd = C_LOC( OutData%bldLd( i1_l ) ) + DO i1 = LBOUND(OutData%bldLd,1), UBOUND(OutData%bldLd,1) + OutData%bldLd(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLdDX_UnPackOutput + + SUBROUTINE ExtLdDX_C2Fary_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: OutputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers + ! + LOGICAL :: SkipPointers_local + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(SkipPointers)) THEN + SkipPointers_local = SkipPointers + ELSE + SkipPointers_local = .false. + END IF + + ! -- twrLd Output Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( OutputData%C_obj%twrLd ) ) THEN + NULLIFY( OutputData%twrLd ) + ELSE + CALL C_F_POINTER(OutputData%C_obj%twrLd, OutputData%twrLd, (/OutputData%C_obj%twrLd_Len/)) + END IF + END IF + + ! -- bldLd Output Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( OutputData%C_obj%bldLd ) ) THEN + NULLIFY( OutputData%bldLd ) + ELSE + CALL C_F_POINTER(OutputData%C_obj%bldLd, OutputData%bldLd, (/OutputData%C_obj%bldLd_Len/)) + END IF + END IF + END SUBROUTINE ExtLdDX_C2Fary_CopyOutput + + SUBROUTINE ExtLdDX_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: OutputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers + ! + LOGICAL :: SkipPointers_local + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(SkipPointers)) THEN + SkipPointers_local = SkipPointers + ELSE + SkipPointers_local = .false. + END IF + + ! -- twrLd Output Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(OutputData%twrLd)) THEN + OutputData%c_obj%twrLd_Len = 0 + OutputData%c_obj%twrLd = C_NULL_PTR + ELSE + OutputData%c_obj%twrLd_Len = SIZE(OutputData%twrLd) + IF (OutputData%c_obj%twrLd_Len > 0) & + OutputData%c_obj%twrLd = C_LOC( OutputData%twrLd( LBOUND(OutputData%twrLd,1) ) ) + END IF + END IF + + ! -- bldLd Output Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(OutputData%bldLd)) THEN + OutputData%c_obj%bldLd_Len = 0 + OutputData%c_obj%bldLd = C_NULL_PTR + ELSE + OutputData%c_obj%bldLd_Len = SIZE(OutputData%bldLd) + IF (OutputData%c_obj%bldLd_Len > 0) & + OutputData%c_obj%bldLd = C_LOC( OutputData%bldLd( LBOUND(OutputData%bldLd,1) ) ) + END IF + END IF + END SUBROUTINE ExtLdDX_F2C_CopyOutput + + + SUBROUTINE ExtLdDX_Input_ExtrapInterp(u, t, u_out, t_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time +! values of u (which has values associated with times in t). Order of the interpolation is given by the size of u +! +! expressions below based on either +! +! f(t) = a +! f(t) = a + b * t, or +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = u1, f(t2) = u2, f(t3) = u3 (as appropriate) +! +!.................................................................................................................................. + + TYPE(ExtLdDX_InputType), INTENT(IN) :: u(:) ! Input at t1 > t2 > t3 + REAL(DbKi), INTENT(IN ) :: t(:) ! Times associated with the Inputs + TYPE(ExtLdDX_InputType), INTENT(INOUT) :: u_out ! Input at tin_out + REAL(DbKi), INTENT(IN ) :: t_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_Input_ExtrapInterp' + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + if ( size(t) .ne. size(u)) then + CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(u)',ErrStat,ErrMsg,RoutineName) + RETURN + endif + order = SIZE(u) - 1 + IF ( order .eq. 0 ) THEN + CALL ExtLdDX_CopyInput(u(1), u_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 1 ) THEN + CALL ExtLdDX_Input_ExtrapInterp1(u(1), u(2), t, u_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 2 ) THEN + CALL ExtLdDX_Input_ExtrapInterp2(u(1), u(2), u(3), t, u_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE + CALL SetErrStat(ErrID_Fatal,'size(u) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName) + RETURN + ENDIF + END SUBROUTINE ExtLdDX_Input_ExtrapInterp + + + SUBROUTINE ExtLdDX_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time +! values of u (which has values associated with times in t). Order of the interpolation is 1. +! +! f(t) = a + b * t, or +! +! where a and b are determined as the solution to +! f(t1) = u1, f(t2) = u2 +! +!.................................................................................................................................. + + TYPE(ExtLdDX_InputType), INTENT(IN) :: u1 ! Input at t1 > t2 + TYPE(ExtLdDX_InputType), INTENT(IN) :: u2 ! Input at t2 + REAL(DbKi), INTENT(IN ) :: tin(2) ! Times associated with the Inputs + TYPE(ExtLdDX_InputType), INTENT(INOUT) :: u_out ! Input at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(2) ! Times associated with the Inputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_Input_ExtrapInterp1' + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / t(2) +IF (ASSOCIATED(u_out%twrDef) .AND. ASSOCIATED(u1%twrDef)) THEN + DO i1 = LBOUND(u_out%twrDef,1),UBOUND(u_out%twrDef,1) + b = -(u1%twrDef(i1) - u2%twrDef(i1)) + u_out%twrDef(i1) = u1%twrDef(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldDef) .AND. ASSOCIATED(u1%bldDef)) THEN + DO i1 = LBOUND(u_out%bldDef,1),UBOUND(u_out%bldDef,1) + b = -(u1%bldDef(i1) - u2%bldDef(i1)) + u_out%bldDef(i1) = u1%bldDef(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%hubDef) .AND. ASSOCIATED(u1%hubDef)) THEN + DO i1 = LBOUND(u_out%hubDef,1),UBOUND(u_out%hubDef,1) + b = -(u1%hubDef(i1) - u2%hubDef(i1)) + u_out%hubDef(i1) = u1%hubDef(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%nacDef) .AND. ASSOCIATED(u1%nacDef)) THEN + DO i1 = LBOUND(u_out%nacDef,1),UBOUND(u_out%nacDef,1) + b = -(u1%nacDef(i1) - u2%nacDef(i1)) + u_out%nacDef(i1) = u1%nacDef(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRootDef) .AND. ASSOCIATED(u1%bldRootDef)) THEN + DO i1 = LBOUND(u_out%bldRootDef,1),UBOUND(u_out%bldRootDef,1) + b = -(u1%bldRootDef(i1) - u2%bldRootDef(i1)) + u_out%bldRootDef(i1) = u1%bldRootDef(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%twrRefPos) .AND. ASSOCIATED(u1%twrRefPos)) THEN + DO i1 = LBOUND(u_out%twrRefPos,1),UBOUND(u_out%twrRefPos,1) + b = -(u1%twrRefPos(i1) - u2%twrRefPos(i1)) + u_out%twrRefPos(i1) = u1%twrRefPos(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRefPos) .AND. ASSOCIATED(u1%bldRefPos)) THEN + DO i1 = LBOUND(u_out%bldRefPos,1),UBOUND(u_out%bldRefPos,1) + b = -(u1%bldRefPos(i1) - u2%bldRefPos(i1)) + u_out%bldRefPos(i1) = u1%bldRefPos(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%hubRefPos) .AND. ASSOCIATED(u1%hubRefPos)) THEN + DO i1 = LBOUND(u_out%hubRefPos,1),UBOUND(u_out%hubRefPos,1) + b = -(u1%hubRefPos(i1) - u2%hubRefPos(i1)) + u_out%hubRefPos(i1) = u1%hubRefPos(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%nacRefPos) .AND. ASSOCIATED(u1%nacRefPos)) THEN + DO i1 = LBOUND(u_out%nacRefPos,1),UBOUND(u_out%nacRefPos,1) + b = -(u1%nacRefPos(i1) - u2%nacRefPos(i1)) + u_out%nacRefPos(i1) = u1%nacRefPos(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRootRefPos) .AND. ASSOCIATED(u1%bldRootRefPos)) THEN + DO i1 = LBOUND(u_out%bldRootRefPos,1),UBOUND(u_out%bldRootRefPos,1) + b = -(u1%bldRootRefPos(i1) - u2%bldRootRefPos(i1)) + u_out%bldRootRefPos(i1) = u1%bldRootRefPos(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%nBlades) .AND. ASSOCIATED(u1%nBlades)) THEN +END IF ! check if allocated +IF (ASSOCIATED(u_out%nBladeNodes) .AND. ASSOCIATED(u1%nBladeNodes)) THEN +END IF ! check if allocated +IF (ASSOCIATED(u_out%nTowerNodes) .AND. ASSOCIATED(u1%nTowerNodes)) THEN +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldChord) .AND. ASSOCIATED(u1%bldChord)) THEN + DO i1 = LBOUND(u_out%bldChord,1),UBOUND(u_out%bldChord,1) + b = -(u1%bldChord(i1) - u2%bldChord(i1)) + u_out%bldChord(i1) = u1%bldChord(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRloc) .AND. ASSOCIATED(u1%bldRloc)) THEN + DO i1 = LBOUND(u_out%bldRloc,1),UBOUND(u_out%bldRloc,1) + b = -(u1%bldRloc(i1) - u2%bldRloc(i1)) + u_out%bldRloc(i1) = u1%bldRloc(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%twrDia) .AND. ASSOCIATED(u1%twrDia)) THEN + DO i1 = LBOUND(u_out%twrDia,1),UBOUND(u_out%twrDia,1) + b = -(u1%twrDia(i1) - u2%twrDia(i1)) + u_out%twrDia(i1) = u1%twrDia(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%twrHloc) .AND. ASSOCIATED(u1%twrHloc)) THEN + DO i1 = LBOUND(u_out%twrHloc,1),UBOUND(u_out%twrHloc,1) + b = -(u1%twrHloc(i1) - u2%twrHloc(i1)) + u_out%twrHloc(i1) = u1%twrHloc(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldPitch) .AND. ASSOCIATED(u1%bldPitch)) THEN + DO i1 = LBOUND(u_out%bldPitch,1),UBOUND(u_out%bldPitch,1) + b = -(u1%bldPitch(i1) - u2%bldPitch(i1)) + u_out%bldPitch(i1) = u1%bldPitch(i1) + b * ScaleFactor + END DO +END IF ! check if allocated + END SUBROUTINE ExtLdDX_Input_ExtrapInterp1 + + + SUBROUTINE ExtLdDX_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time +! values of u (which has values associated with times in t). Order of the interpolation is 2. +! +! expressions below based on either +! +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = u1, f(t2) = u2, f(t3) = u3 +! +!.................................................................................................................................. + + TYPE(ExtLdDX_InputType), INTENT(IN) :: u1 ! Input at t1 > t2 > t3 + TYPE(ExtLdDX_InputType), INTENT(IN) :: u2 ! Input at t2 > t3 + TYPE(ExtLdDX_InputType), INTENT(IN) :: u3 ! Input at t3 + REAL(DbKi), INTENT(IN ) :: tin(3) ! Times associated with the Inputs + TYPE(ExtLdDX_InputType), INTENT(INOUT) :: u_out ! Input at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(3) ! Times associated with the Inputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: c ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_Input_ExtrapInterp2' + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) +IF (ASSOCIATED(u_out%twrDef) .AND. ASSOCIATED(u1%twrDef)) THEN + DO i1 = LBOUND(u_out%twrDef,1),UBOUND(u_out%twrDef,1) + b = (t(3)**2*(u1%twrDef(i1) - u2%twrDef(i1)) + t(2)**2*(-u1%twrDef(i1) + u3%twrDef(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%twrDef(i1) + t(3)*u2%twrDef(i1) - t(2)*u3%twrDef(i1) ) * scaleFactor + u_out%twrDef(i1) = u1%twrDef(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldDef) .AND. ASSOCIATED(u1%bldDef)) THEN + DO i1 = LBOUND(u_out%bldDef,1),UBOUND(u_out%bldDef,1) + b = (t(3)**2*(u1%bldDef(i1) - u2%bldDef(i1)) + t(2)**2*(-u1%bldDef(i1) + u3%bldDef(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%bldDef(i1) + t(3)*u2%bldDef(i1) - t(2)*u3%bldDef(i1) ) * scaleFactor + u_out%bldDef(i1) = u1%bldDef(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%hubDef) .AND. ASSOCIATED(u1%hubDef)) THEN + DO i1 = LBOUND(u_out%hubDef,1),UBOUND(u_out%hubDef,1) + b = (t(3)**2*(u1%hubDef(i1) - u2%hubDef(i1)) + t(2)**2*(-u1%hubDef(i1) + u3%hubDef(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%hubDef(i1) + t(3)*u2%hubDef(i1) - t(2)*u3%hubDef(i1) ) * scaleFactor + u_out%hubDef(i1) = u1%hubDef(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%nacDef) .AND. ASSOCIATED(u1%nacDef)) THEN + DO i1 = LBOUND(u_out%nacDef,1),UBOUND(u_out%nacDef,1) + b = (t(3)**2*(u1%nacDef(i1) - u2%nacDef(i1)) + t(2)**2*(-u1%nacDef(i1) + u3%nacDef(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%nacDef(i1) + t(3)*u2%nacDef(i1) - t(2)*u3%nacDef(i1) ) * scaleFactor + u_out%nacDef(i1) = u1%nacDef(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRootDef) .AND. ASSOCIATED(u1%bldRootDef)) THEN + DO i1 = LBOUND(u_out%bldRootDef,1),UBOUND(u_out%bldRootDef,1) + b = (t(3)**2*(u1%bldRootDef(i1) - u2%bldRootDef(i1)) + t(2)**2*(-u1%bldRootDef(i1) + u3%bldRootDef(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%bldRootDef(i1) + t(3)*u2%bldRootDef(i1) - t(2)*u3%bldRootDef(i1) ) * scaleFactor + u_out%bldRootDef(i1) = u1%bldRootDef(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%twrRefPos) .AND. ASSOCIATED(u1%twrRefPos)) THEN + DO i1 = LBOUND(u_out%twrRefPos,1),UBOUND(u_out%twrRefPos,1) + b = (t(3)**2*(u1%twrRefPos(i1) - u2%twrRefPos(i1)) + t(2)**2*(-u1%twrRefPos(i1) + u3%twrRefPos(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%twrRefPos(i1) + t(3)*u2%twrRefPos(i1) - t(2)*u3%twrRefPos(i1) ) * scaleFactor + u_out%twrRefPos(i1) = u1%twrRefPos(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRefPos) .AND. ASSOCIATED(u1%bldRefPos)) THEN + DO i1 = LBOUND(u_out%bldRefPos,1),UBOUND(u_out%bldRefPos,1) + b = (t(3)**2*(u1%bldRefPos(i1) - u2%bldRefPos(i1)) + t(2)**2*(-u1%bldRefPos(i1) + u3%bldRefPos(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%bldRefPos(i1) + t(3)*u2%bldRefPos(i1) - t(2)*u3%bldRefPos(i1) ) * scaleFactor + u_out%bldRefPos(i1) = u1%bldRefPos(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%hubRefPos) .AND. ASSOCIATED(u1%hubRefPos)) THEN + DO i1 = LBOUND(u_out%hubRefPos,1),UBOUND(u_out%hubRefPos,1) + b = (t(3)**2*(u1%hubRefPos(i1) - u2%hubRefPos(i1)) + t(2)**2*(-u1%hubRefPos(i1) + u3%hubRefPos(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%hubRefPos(i1) + t(3)*u2%hubRefPos(i1) - t(2)*u3%hubRefPos(i1) ) * scaleFactor + u_out%hubRefPos(i1) = u1%hubRefPos(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%nacRefPos) .AND. ASSOCIATED(u1%nacRefPos)) THEN + DO i1 = LBOUND(u_out%nacRefPos,1),UBOUND(u_out%nacRefPos,1) + b = (t(3)**2*(u1%nacRefPos(i1) - u2%nacRefPos(i1)) + t(2)**2*(-u1%nacRefPos(i1) + u3%nacRefPos(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%nacRefPos(i1) + t(3)*u2%nacRefPos(i1) - t(2)*u3%nacRefPos(i1) ) * scaleFactor + u_out%nacRefPos(i1) = u1%nacRefPos(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRootRefPos) .AND. ASSOCIATED(u1%bldRootRefPos)) THEN + DO i1 = LBOUND(u_out%bldRootRefPos,1),UBOUND(u_out%bldRootRefPos,1) + b = (t(3)**2*(u1%bldRootRefPos(i1) - u2%bldRootRefPos(i1)) + t(2)**2*(-u1%bldRootRefPos(i1) + u3%bldRootRefPos(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%bldRootRefPos(i1) + t(3)*u2%bldRootRefPos(i1) - t(2)*u3%bldRootRefPos(i1) ) * scaleFactor + u_out%bldRootRefPos(i1) = u1%bldRootRefPos(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%nBlades) .AND. ASSOCIATED(u1%nBlades)) THEN +END IF ! check if allocated +IF (ASSOCIATED(u_out%nBladeNodes) .AND. ASSOCIATED(u1%nBladeNodes)) THEN +END IF ! check if allocated +IF (ASSOCIATED(u_out%nTowerNodes) .AND. ASSOCIATED(u1%nTowerNodes)) THEN +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldChord) .AND. ASSOCIATED(u1%bldChord)) THEN + DO i1 = LBOUND(u_out%bldChord,1),UBOUND(u_out%bldChord,1) + b = (t(3)**2*(u1%bldChord(i1) - u2%bldChord(i1)) + t(2)**2*(-u1%bldChord(i1) + u3%bldChord(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%bldChord(i1) + t(3)*u2%bldChord(i1) - t(2)*u3%bldChord(i1) ) * scaleFactor + u_out%bldChord(i1) = u1%bldChord(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldRloc) .AND. ASSOCIATED(u1%bldRloc)) THEN + DO i1 = LBOUND(u_out%bldRloc,1),UBOUND(u_out%bldRloc,1) + b = (t(3)**2*(u1%bldRloc(i1) - u2%bldRloc(i1)) + t(2)**2*(-u1%bldRloc(i1) + u3%bldRloc(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%bldRloc(i1) + t(3)*u2%bldRloc(i1) - t(2)*u3%bldRloc(i1) ) * scaleFactor + u_out%bldRloc(i1) = u1%bldRloc(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%twrDia) .AND. ASSOCIATED(u1%twrDia)) THEN + DO i1 = LBOUND(u_out%twrDia,1),UBOUND(u_out%twrDia,1) + b = (t(3)**2*(u1%twrDia(i1) - u2%twrDia(i1)) + t(2)**2*(-u1%twrDia(i1) + u3%twrDia(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%twrDia(i1) + t(3)*u2%twrDia(i1) - t(2)*u3%twrDia(i1) ) * scaleFactor + u_out%twrDia(i1) = u1%twrDia(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%twrHloc) .AND. ASSOCIATED(u1%twrHloc)) THEN + DO i1 = LBOUND(u_out%twrHloc,1),UBOUND(u_out%twrHloc,1) + b = (t(3)**2*(u1%twrHloc(i1) - u2%twrHloc(i1)) + t(2)**2*(-u1%twrHloc(i1) + u3%twrHloc(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%twrHloc(i1) + t(3)*u2%twrHloc(i1) - t(2)*u3%twrHloc(i1) ) * scaleFactor + u_out%twrHloc(i1) = u1%twrHloc(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(u_out%bldPitch) .AND. ASSOCIATED(u1%bldPitch)) THEN + DO i1 = LBOUND(u_out%bldPitch,1),UBOUND(u_out%bldPitch,1) + b = (t(3)**2*(u1%bldPitch(i1) - u2%bldPitch(i1)) + t(2)**2*(-u1%bldPitch(i1) + u3%bldPitch(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%bldPitch(i1) + t(3)*u2%bldPitch(i1) - t(2)*u3%bldPitch(i1) ) * scaleFactor + u_out%bldPitch(i1) = u1%bldPitch(i1) + b + c * t_out + END DO +END IF ! check if allocated + END SUBROUTINE ExtLdDX_Input_ExtrapInterp2 + + + SUBROUTINE ExtLdDX_Output_ExtrapInterp(y, t, y_out, t_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time +! values of y (which has values associated with times in t). Order of the interpolation is given by the size of y +! +! expressions below based on either +! +! f(t) = a +! f(t) = a + b * t, or +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = y1, f(t2) = y2, f(t3) = y3 (as appropriate) +! +!.................................................................................................................................. + + TYPE(ExtLdDX_OutputType), INTENT(IN) :: y(:) ! Output at t1 > t2 > t3 + REAL(DbKi), INTENT(IN ) :: t(:) ! Times associated with the Outputs + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out + REAL(DbKi), INTENT(IN ) :: t_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_Output_ExtrapInterp' + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + if ( size(t) .ne. size(y)) then + CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(y)',ErrStat,ErrMsg,RoutineName) + RETURN + endif + order = SIZE(y) - 1 + IF ( order .eq. 0 ) THEN + CALL ExtLdDX_CopyOutput(y(1), y_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 1 ) THEN + CALL ExtLdDX_Output_ExtrapInterp1(y(1), y(2), t, y_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 2 ) THEN + CALL ExtLdDX_Output_ExtrapInterp2(y(1), y(2), y(3), t, y_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE + CALL SetErrStat(ErrID_Fatal,'size(y) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName) + RETURN + ENDIF + END SUBROUTINE ExtLdDX_Output_ExtrapInterp + + + SUBROUTINE ExtLdDX_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time +! values of y (which has values associated with times in t). Order of the interpolation is 1. +! +! f(t) = a + b * t, or +! +! where a and b are determined as the solution to +! f(t1) = y1, f(t2) = y2 +! +!.................................................................................................................................. + + TYPE(ExtLdDX_OutputType), INTENT(IN) :: y1 ! Output at t1 > t2 + TYPE(ExtLdDX_OutputType), INTENT(IN) :: y2 ! Output at t2 + REAL(DbKi), INTENT(IN ) :: tin(2) ! Times associated with the Outputs + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(2) ! Times associated with the Outputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_Output_ExtrapInterp1' + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / t(2) +IF (ASSOCIATED(y_out%twrLd) .AND. ASSOCIATED(y1%twrLd)) THEN + DO i1 = LBOUND(y_out%twrLd,1),UBOUND(y_out%twrLd,1) + b = -(y1%twrLd(i1) - y2%twrLd(i1)) + y_out%twrLd(i1) = y1%twrLd(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ASSOCIATED(y_out%bldLd) .AND. ASSOCIATED(y1%bldLd)) THEN + DO i1 = LBOUND(y_out%bldLd,1),UBOUND(y_out%bldLd,1) + b = -(y1%bldLd(i1) - y2%bldLd(i1)) + y_out%bldLd(i1) = y1%bldLd(i1) + b * ScaleFactor + END DO +END IF ! check if allocated + END SUBROUTINE ExtLdDX_Output_ExtrapInterp1 + + + SUBROUTINE ExtLdDX_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time +! values of y (which has values associated with times in t). Order of the interpolation is 2. +! +! expressions below based on either +! +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = y1, f(t2) = y2, f(t3) = y3 +! +!.................................................................................................................................. + + TYPE(ExtLdDX_OutputType), INTENT(IN) :: y1 ! Output at t1 > t2 > t3 + TYPE(ExtLdDX_OutputType), INTENT(IN) :: y2 ! Output at t2 > t3 + TYPE(ExtLdDX_OutputType), INTENT(IN) :: y3 ! Output at t3 + REAL(DbKi), INTENT(IN ) :: tin(3) ! Times associated with the Outputs + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(3) ! Times associated with the Outputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: c ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_Output_ExtrapInterp2' + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) +IF (ASSOCIATED(y_out%twrLd) .AND. ASSOCIATED(y1%twrLd)) THEN + DO i1 = LBOUND(y_out%twrLd,1),UBOUND(y_out%twrLd,1) + b = (t(3)**2*(y1%twrLd(i1) - y2%twrLd(i1)) + t(2)**2*(-y1%twrLd(i1) + y3%twrLd(i1)))* scaleFactor + c = ( (t(2)-t(3))*y1%twrLd(i1) + t(3)*y2%twrLd(i1) - t(2)*y3%twrLd(i1) ) * scaleFactor + y_out%twrLd(i1) = y1%twrLd(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ASSOCIATED(y_out%bldLd) .AND. ASSOCIATED(y1%bldLd)) THEN + DO i1 = LBOUND(y_out%bldLd,1),UBOUND(y_out%bldLd,1) + b = (t(3)**2*(y1%bldLd(i1) - y2%bldLd(i1)) + t(2)**2*(-y1%bldLd(i1) + y3%bldLd(i1)))* scaleFactor + c = ( (t(2)-t(3))*y1%bldLd(i1) + t(3)*y2%bldLd(i1) - t(2)*y3%bldLd(i1) ) * scaleFactor + y_out%bldLd(i1) = y1%bldLd(i1) + b + c * t_out + END DO +END IF ! check if allocated + END SUBROUTINE ExtLdDX_Output_ExtrapInterp2 + +END MODULE ExtLoadsDX_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/extloads/src/ExtLoadsDX_Types.h b/modules/extloads/src/ExtLoadsDX_Types.h new file mode 100644 index 0000000000..23d47a3a35 --- /dev/null +++ b/modules/extloads/src/ExtLoadsDX_Types.h @@ -0,0 +1,57 @@ +//!STARTOFREGISTRYGENERATEDFILE 'ExtLoadsDX_Types.h' +//! +//! WARNING This file is generated automatically by the FAST registry. +//! Do not edit. Your changes to this file will be lost. +//! + +#ifndef _ExtLoadsDX_TYPES_H +#define _ExtLoadsDX_TYPES_H + + +#ifdef _WIN32 //define something for Windows (32-bit) +# include "stdbool.h" +# define CALL __declspec( dllexport ) +#elif _WIN64 //define something for Windows (64-bit) +# include "stdbool.h" +# define CALL __declspec( dllexport ) +#else +# include +# define CALL +#endif + + + typedef struct ExtLdDX_InputType { + void * object ; + double * twrDef ; int twrDef_Len ; + double * bldDef ; int bldDef_Len ; + double * hubDef ; int hubDef_Len ; + double * nacDef ; int nacDef_Len ; + double * bldRootDef ; int bldRootDef_Len ; + double * twrRefPos ; int twrRefPos_Len ; + double * bldRefPos ; int bldRefPos_Len ; + double * hubRefPos ; int hubRefPos_Len ; + double * nacRefPos ; int nacRefPos_Len ; + double * bldRootRefPos ; int bldRootRefPos_Len ; + int * nBlades ; int nBlades_Len ; + int * nBladeNodes ; int nBladeNodes_Len ; + int * nTowerNodes ; int nTowerNodes_Len ; + double * bldChord ; int bldChord_Len ; + double * bldRloc ; int bldRloc_Len ; + double * twrDia ; int twrDia_Len ; + double * twrHloc ; int twrHloc_Len ; + double * bldPitch ; int bldPitch_Len ; + } ExtLdDX_InputType_t ; + typedef struct ExtLdDX_OutputType { + void * object ; + double * twrLd ; int twrLd_Len ; + double * bldLd ; int bldLd_Len ; + } ExtLdDX_OutputType_t ; + typedef struct ExtLdDX_UserData { + ExtLdDX_InputType_t ExtLdDX_Input ; + ExtLdDX_OutputType_t ExtLdDX_Output ; + } ExtLdDX_t ; + +#endif // _ExtLoadsDX_TYPES_H + + +//!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/extloads/src/ExtLoads_Registry.txt b/modules/extloads/src/ExtLoads_Registry.txt new file mode 100644 index 0000000000..66f457ee8a --- /dev/null +++ b/modules/extloads/src/ExtLoads_Registry.txt @@ -0,0 +1,103 @@ +################################################################################################################################### +# Registry for ExternalLoads in the FAST Modularization Framework +# This Registry file is used to create ExtLoads_Types which contains data used in the ExtLoads module. +# It also contains copy, destroy, pack, and unpack routines associated with each defined data types. +# See the NWTC Programmer's Handbook for further information on the format/contents of this file. +# +# Entries are of the form +# +# +# Use ^ as a shortcut for the value in the same column from the previous line. +################################################################################################################################### +# File last committed $Date$ +# (File) Revision #: $Rev$ +# URL: $HeadURL$ +################################################################################################################################### +# ...... Include files (definitions from NWTC Library) ............................................................................ +include Registry_NWTC_Library.txt +usefrom ExtLoadsDX_Registry.txt + +# ..... Initialization data ....................................................................................................... +# Define inputs that the initialization routine may need here: +typedef ExtLoads/ExtLd InitInputType IntKi NumBlades - - - "Number of blades on the turbine" - +typedef ^ InitInputType IntKi NumBldNodes {:} - - "Number of blade nodes for each blade" - +typedef ^ InitInputType Logical TwrAero - .false. - "Flag that tells this module if the tower aero is on." - +typedef ^ InitInputType IntKi NumTwrNds - - - "Number of tower nodes for each blade" - +typedef ^ InitInputType ReKi HubPos {3} - - "X-Y-Z reference position of hub" m +typedef ^ InitInputType R8Ki HubOrient {3}{3} - - "DCM reference orientation of hub" - +typedef ^ InitInputType ReKi NacellePos {3} - - "X-Y-Z reference position of Nacelle" m +typedef ^ InitInputType R8Ki NacelleOrient {3}{3} - - "DCM reference orientation of Nacelle" - +typedef ^ InitInputType ReKi BldRootPos {:}{:} - - "X-Y-Z reference position of each blade root (3 x NumBlades)" m +typedef ^ InitInputType R8Ki BldRootOrient {:}{:}{:} - - "DCM reference orientation of blade root (3x3 x NumBlades )" - +typedef ^ InitInputType ReKi BldPos {:}{:}{:} - - "X-Y-Z reference position of each blade (3 x NumBladeNodesMax x NumBlades)" m +typedef ^ InitInputType R8Ki BldOrient {:}{:}{:}{:} - - "DCM reference orientation of blade (3x3 x NumBladeNodesMax x NumBlades )" - +typedef ^ InitInputType ReKi TwrPos {:}{:} - - "X-Y-Z reference position of tower (3 x NumTowerNodes)" m +typedef ^ InitInputType R8Ki TwrOrient {:}{:}{:} - - "DCM reference orientation of tower (3x3 x NumTowerNodes)" - +typedef ^ InitInputType ReKi az_blend_mean - - - "Mean azimuth at which to blend the external and aerodyn loads" - +typedef ^ InitInputType ReKi az_blend_delta - - - "The width of the tanh function over which to blend the external and aerodyn loads" - +typedef ^ InitInputType ReKi vel_mean - - - "Mean velocity at reference height" m/s +typedef ^ InitInputType ReKi wind_dir - - - "Wind direction" degrees +typedef ^ InitInputType ReKi z_ref - - - "Reference height for velocity profile" m +typedef ^ InitInputType ReKi shear_exp - - - "Shear exponent" - +typedef ^ InitInputType ReKi BldChord {:}{:} - - "Blade chord (NumBladeNodesMax x NumBlades)" m +typedef ^ InitInputType ReKi BldRloc {:}{:} - - "Radial location of each node along the blade" m +typedef ^ InitInputType ReKi TwrDia {:} - - "Tower diameter (NumTwrNodes)" m +typedef ^ InitInputType ReKi TwrHloc {:} - - "Height location of each node along the tower" m + +# Define outputs from the initialization routine here: +typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - +typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output-to-file channels" - +typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - +typedef ^ InitOutputType ReKi AirDens - - - "Air density" kg/m^3 + +# ..... States .................................................................................................................... +# Define continuous (differentiable) states here: +typedef ^ ContinuousStateType ReKi blah - - - "Something" - + +# Define discrete (nondifferentiable) states here: +typedef ^ DiscreteStateType ReKi blah - - - "Something" - + +#Defin misc variables here +typedef ^ MiscVarType ReKi az - - - "Current azimuth" - +typedef ^ MiscVarType ReKi phi_cfd - - - "Blending ratio of load from external driver [0-1]" - + +# Define constraint states here: +typedef ^ ConstraintStateType ReKi blah - - - "Something" - + +# Define "other" states here: +typedef ^ OtherStateType ReKi blah - - - "Something" - + +# Define misc/optimization variables (any data that are not considered actual states) here: + + +# ..... Parameters ................................................................................................................ +# Define parameters here: +typedef ^ ParameterType IntKi NumBlds - - - "Number of blades on the turbine" - +typedef ^ ParameterType IntKi NumBldNds {:} - - "Number of blade nodes for each blade" - +typedef ^ ParameterType IntKi nTotBldNds - - - "Total number of blade nodes" - +typedef ^ ParameterType Logical TwrAero - .FALSE. - "Flag that tells this module if the tower aero is on." - +typedef ^ ParameterType IntKi NumTwrNds - - - "Number of tower nodes" - +typedef ^ ParameterType ReKi az_blend_mean - - - "Mean azimuth at which to blend the external and aerodyn loads" - +typedef ^ ParameterType ReKi az_blend_delta - - - "The width of the tanh function over which to blend the external and aerodyn loads" - +typedef ^ ParameterType ReKi vel_mean - - - "Mean velocity at reference height" m/s +typedef ^ ParameterType ReKi wind_dir - - - "Wind direction" m +typedef ^ ParameterType ReKi z_ref - - - "Reference height for velocity profile" degrees +typedef ^ ParameterType ReKi shear_exp - - - "Shear exponent" - + +# ..... Inputs .................................................................................................................... +# Define inputs that are contained on the mesh here: +typedef ^ InputType ExtLdDX_InputType DX_u - - - "Data to send to external driver" +typedef ^ InputType ReKi az - - - "Azimuth of rotor" +typedef ^ InputType MeshType TowerMotion - - - "motion on the tower" - +typedef ^ InputType MeshType HubMotion - - - "motion on the hub" - +typedef ^ InputType MeshType NacelleMotion - - - "motion on the nacelle" - +typedef ^ InputType MeshType BladeRootMotion {:} - - "motion on each blade root" - +typedef ^ InputType MeshType BladeMotion {:} - - "motion on each blade" - + +# ..... Outputs ................................................................................................................... +# Define outputs that are contained on the mesh here: +typedef ^ OutputType ExtLdDX_OutputType DX_y - - - "Data to get from external driver" +typedef ^ OutputType MeshType TowerLoad - - - "loads on the tower" - +typedef ^ OutputType MeshType BladeLoad {:} - - "loads on each blade" - +typedef ^ OutputType MeshType TowerLoadAD - - - "loads on the tower from aerodyn" - +typedef ^ OutputType MeshType BladeLoadAD {:} - - "loads on each blade from aerodyn" - diff --git a/modules/extloads/src/ExtLoads_Types.f90 b/modules/extloads/src/ExtLoads_Types.f90 new file mode 100644 index 0000000000..8b6debb03f --- /dev/null +++ b/modules/extloads/src/ExtLoads_Types.f90 @@ -0,0 +1,4274 @@ +!STARTOFREGISTRYGENERATEDFILE 'ExtLoads_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 +!********************************************************************************************************************************* +! ExtLoads_Types +!................................................................................................................................. +! This file is part of ExtLoads. +! +! 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 ExtLoads. 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 ExtLoads_Types +!--------------------------------------------------------------------------------------------------------------------------------- +USE ExtLoadsDX_Types +USE NWTC_Library +IMPLICIT NONE +! ========= ExtLd_InitInputType ======= + TYPE, PUBLIC :: ExtLd_InitInputType + INTEGER(IntKi) :: NumBlades !< Number of blades on the turbine [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: NumBldNodes !< Number of blade nodes for each blade [-] + LOGICAL :: TwrAero = .false. !< Flag that tells this module if the tower aero is on. [-] + INTEGER(IntKi) :: NumTwrNds !< Number of tower nodes for each blade [-] + REAL(ReKi) , DIMENSION(1:3) :: HubPos !< X-Y-Z reference position of hub [m] + REAL(R8Ki) , DIMENSION(1:3,1:3) :: HubOrient !< DCM reference orientation of hub [-] + REAL(ReKi) , DIMENSION(1:3) :: NacellePos !< X-Y-Z reference position of Nacelle [m] + REAL(R8Ki) , DIMENSION(1:3,1:3) :: NacelleOrient !< DCM reference orientation of Nacelle [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BldRootPos !< X-Y-Z reference position of each blade root (3 x NumBlades) [m] + REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: BldRootOrient !< DCM reference orientation of blade root (3x3 x NumBlades ) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: BldPos !< X-Y-Z reference position of each blade (3 x NumBladeNodesMax x NumBlades) [m] + REAL(R8Ki) , DIMENSION(:,:,:,:), ALLOCATABLE :: BldOrient !< DCM reference orientation of blade (3x3 x NumBladeNodesMax x NumBlades ) [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TwrPos !< X-Y-Z reference position of tower (3 x NumTowerNodes) [m] + REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: TwrOrient !< DCM reference orientation of tower (3x3 x NumTowerNodes) [-] + REAL(ReKi) :: az_blend_mean !< Mean azimuth at which to blend the external and aerodyn loads [-] + REAL(ReKi) :: az_blend_delta !< The width of the tanh function over which to blend the external and aerodyn loads [-] + REAL(ReKi) :: vel_mean !< Mean velocity at reference height [m/s] + REAL(ReKi) :: wind_dir !< Wind direction [degrees] + REAL(ReKi) :: z_ref !< Reference height for velocity profile [m] + REAL(ReKi) :: shear_exp !< Shear exponent [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BldChord !< Blade chord (NumBladeNodesMax x NumBlades) [m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BldRloc !< Radial location of each node along the blade [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrDia !< Tower diameter (NumTwrNodes) [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrHloc !< Height location of each node along the tower [m] + END TYPE ExtLd_InitInputType +! ======================= +! ========= ExtLd_InitOutputType ======= + TYPE, PUBLIC :: ExtLd_InitOutputType + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Names of the output-to-file channels [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of the output-to-file channels [-] + TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] + REAL(ReKi) :: AirDens !< Air density [kg/m^3] + END TYPE ExtLd_InitOutputType +! ======================= +! ========= ExtLd_ContinuousStateType ======= + TYPE, PUBLIC :: ExtLd_ContinuousStateType + REAL(ReKi) :: blah !< Something [-] + END TYPE ExtLd_ContinuousStateType +! ======================= +! ========= ExtLd_DiscreteStateType ======= + TYPE, PUBLIC :: ExtLd_DiscreteStateType + REAL(ReKi) :: blah !< Something [-] + END TYPE ExtLd_DiscreteStateType +! ======================= +! ========= ExtLd_MiscVarType ======= + TYPE, PUBLIC :: ExtLd_MiscVarType + REAL(ReKi) :: az !< Current azimuth [-] + REAL(ReKi) :: phi_cfd !< Blending ratio of load from external driver [0-1] [-] + END TYPE ExtLd_MiscVarType +! ======================= +! ========= ExtLd_ConstraintStateType ======= + TYPE, PUBLIC :: ExtLd_ConstraintStateType + REAL(ReKi) :: blah !< Something [-] + END TYPE ExtLd_ConstraintStateType +! ======================= +! ========= ExtLd_OtherStateType ======= + TYPE, PUBLIC :: ExtLd_OtherStateType + REAL(ReKi) :: blah !< Something [-] + END TYPE ExtLd_OtherStateType +! ======================= +! ========= ExtLd_ParameterType ======= + TYPE, PUBLIC :: ExtLd_ParameterType + INTEGER(IntKi) :: NumBlds !< Number of blades on the turbine [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: NumBldNds !< Number of blade nodes for each blade [-] + INTEGER(IntKi) :: nTotBldNds !< Total number of blade nodes [-] + LOGICAL :: TwrAero = .FALSE. !< Flag that tells this module if the tower aero is on. [-] + INTEGER(IntKi) :: NumTwrNds !< Number of tower nodes [-] + REAL(ReKi) :: az_blend_mean !< Mean azimuth at which to blend the external and aerodyn loads [-] + REAL(ReKi) :: az_blend_delta !< The width of the tanh function over which to blend the external and aerodyn loads [-] + REAL(ReKi) :: vel_mean !< Mean velocity at reference height [m/s] + REAL(ReKi) :: wind_dir !< Wind direction [m] + REAL(ReKi) :: z_ref !< Reference height for velocity profile [degrees] + REAL(ReKi) :: shear_exp !< Shear exponent [-] + END TYPE ExtLd_ParameterType +! ======================= +! ========= ExtLd_InputType ======= + TYPE, PUBLIC :: ExtLd_InputType + TYPE(ExtLdDX_InputType) :: DX_u !< Data to send to external driver [-] + REAL(ReKi) :: az !< Azimuth of rotor [-] + TYPE(MeshType) :: TowerMotion !< motion on the tower [-] + TYPE(MeshType) :: HubMotion !< motion on the hub [-] + TYPE(MeshType) :: NacelleMotion !< motion on the nacelle [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeRootMotion !< motion on each blade root [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeMotion !< motion on each blade [-] + END TYPE ExtLd_InputType +! ======================= +! ========= ExtLd_OutputType ======= + TYPE, PUBLIC :: ExtLd_OutputType + TYPE(ExtLdDX_OutputType) :: DX_y !< Data to get from external driver [-] + TYPE(MeshType) :: TowerLoad !< loads on the tower [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeLoad !< loads on each blade [-] + TYPE(MeshType) :: TowerLoadAD !< loads on the tower from aerodyn [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeLoadAD !< loads on each blade from aerodyn [-] + END TYPE ExtLd_OutputType +! ======================= +CONTAINS + SUBROUTINE ExtLd_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_InitInputType), INTENT(IN) :: SrcInitInputData + TYPE(ExtLd_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 = 'ExtLd_CopyInitInput' +! + ErrStat = ErrID_None + ErrMsg = "" + DstInitInputData%NumBlades = SrcInitInputData%NumBlades +IF (ALLOCATED(SrcInitInputData%NumBldNodes)) THEN + i1_l = LBOUND(SrcInitInputData%NumBldNodes,1) + i1_u = UBOUND(SrcInitInputData%NumBldNodes,1) + IF (.NOT. ALLOCATED(DstInitInputData%NumBldNodes)) THEN + ALLOCATE(DstInitInputData%NumBldNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%NumBldNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%NumBldNodes = SrcInitInputData%NumBldNodes +ENDIF + DstInitInputData%TwrAero = SrcInitInputData%TwrAero + DstInitInputData%NumTwrNds = SrcInitInputData%NumTwrNds + DstInitInputData%HubPos = SrcInitInputData%HubPos + DstInitInputData%HubOrient = SrcInitInputData%HubOrient + DstInitInputData%NacellePos = SrcInitInputData%NacellePos + DstInitInputData%NacelleOrient = SrcInitInputData%NacelleOrient +IF (ALLOCATED(SrcInitInputData%BldRootPos)) THEN + i1_l = LBOUND(SrcInitInputData%BldRootPos,1) + i1_u = UBOUND(SrcInitInputData%BldRootPos,1) + i2_l = LBOUND(SrcInitInputData%BldRootPos,2) + i2_u = UBOUND(SrcInitInputData%BldRootPos,2) + IF (.NOT. ALLOCATED(DstInitInputData%BldRootPos)) THEN + ALLOCATE(DstInitInputData%BldRootPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%BldRootPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%BldRootPos = SrcInitInputData%BldRootPos +ENDIF +IF (ALLOCATED(SrcInitInputData%BldRootOrient)) THEN + i1_l = LBOUND(SrcInitInputData%BldRootOrient,1) + i1_u = UBOUND(SrcInitInputData%BldRootOrient,1) + i2_l = LBOUND(SrcInitInputData%BldRootOrient,2) + i2_u = UBOUND(SrcInitInputData%BldRootOrient,2) + i3_l = LBOUND(SrcInitInputData%BldRootOrient,3) + i3_u = UBOUND(SrcInitInputData%BldRootOrient,3) + IF (.NOT. ALLOCATED(DstInitInputData%BldRootOrient)) THEN + ALLOCATE(DstInitInputData%BldRootOrient(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%BldRootOrient.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%BldRootOrient = SrcInitInputData%BldRootOrient +ENDIF +IF (ALLOCATED(SrcInitInputData%BldPos)) THEN + i1_l = LBOUND(SrcInitInputData%BldPos,1) + i1_u = UBOUND(SrcInitInputData%BldPos,1) + i2_l = LBOUND(SrcInitInputData%BldPos,2) + i2_u = UBOUND(SrcInitInputData%BldPos,2) + i3_l = LBOUND(SrcInitInputData%BldPos,3) + i3_u = UBOUND(SrcInitInputData%BldPos,3) + IF (.NOT. ALLOCATED(DstInitInputData%BldPos)) THEN + ALLOCATE(DstInitInputData%BldPos(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%BldPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%BldPos = SrcInitInputData%BldPos +ENDIF +IF (ALLOCATED(SrcInitInputData%BldOrient)) THEN + i1_l = LBOUND(SrcInitInputData%BldOrient,1) + i1_u = UBOUND(SrcInitInputData%BldOrient,1) + i2_l = LBOUND(SrcInitInputData%BldOrient,2) + i2_u = UBOUND(SrcInitInputData%BldOrient,2) + i3_l = LBOUND(SrcInitInputData%BldOrient,3) + i3_u = UBOUND(SrcInitInputData%BldOrient,3) + i4_l = LBOUND(SrcInitInputData%BldOrient,4) + i4_u = UBOUND(SrcInitInputData%BldOrient,4) + IF (.NOT. ALLOCATED(DstInitInputData%BldOrient)) THEN + ALLOCATE(DstInitInputData%BldOrient(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 DstInitInputData%BldOrient.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%BldOrient = SrcInitInputData%BldOrient +ENDIF +IF (ALLOCATED(SrcInitInputData%TwrPos)) THEN + i1_l = LBOUND(SrcInitInputData%TwrPos,1) + i1_u = UBOUND(SrcInitInputData%TwrPos,1) + i2_l = LBOUND(SrcInitInputData%TwrPos,2) + i2_u = UBOUND(SrcInitInputData%TwrPos,2) + IF (.NOT. ALLOCATED(DstInitInputData%TwrPos)) THEN + ALLOCATE(DstInitInputData%TwrPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%TwrPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%TwrPos = SrcInitInputData%TwrPos +ENDIF +IF (ALLOCATED(SrcInitInputData%TwrOrient)) THEN + i1_l = LBOUND(SrcInitInputData%TwrOrient,1) + i1_u = UBOUND(SrcInitInputData%TwrOrient,1) + i2_l = LBOUND(SrcInitInputData%TwrOrient,2) + i2_u = UBOUND(SrcInitInputData%TwrOrient,2) + i3_l = LBOUND(SrcInitInputData%TwrOrient,3) + i3_u = UBOUND(SrcInitInputData%TwrOrient,3) + IF (.NOT. ALLOCATED(DstInitInputData%TwrOrient)) THEN + ALLOCATE(DstInitInputData%TwrOrient(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%TwrOrient.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%TwrOrient = SrcInitInputData%TwrOrient +ENDIF + DstInitInputData%az_blend_mean = SrcInitInputData%az_blend_mean + DstInitInputData%az_blend_delta = SrcInitInputData%az_blend_delta + DstInitInputData%vel_mean = SrcInitInputData%vel_mean + DstInitInputData%wind_dir = SrcInitInputData%wind_dir + DstInitInputData%z_ref = SrcInitInputData%z_ref + DstInitInputData%shear_exp = SrcInitInputData%shear_exp +IF (ALLOCATED(SrcInitInputData%BldChord)) THEN + i1_l = LBOUND(SrcInitInputData%BldChord,1) + i1_u = UBOUND(SrcInitInputData%BldChord,1) + i2_l = LBOUND(SrcInitInputData%BldChord,2) + i2_u = UBOUND(SrcInitInputData%BldChord,2) + IF (.NOT. ALLOCATED(DstInitInputData%BldChord)) THEN + ALLOCATE(DstInitInputData%BldChord(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%BldChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%BldChord = SrcInitInputData%BldChord +ENDIF +IF (ALLOCATED(SrcInitInputData%BldRloc)) THEN + i1_l = LBOUND(SrcInitInputData%BldRloc,1) + i1_u = UBOUND(SrcInitInputData%BldRloc,1) + i2_l = LBOUND(SrcInitInputData%BldRloc,2) + i2_u = UBOUND(SrcInitInputData%BldRloc,2) + IF (.NOT. ALLOCATED(DstInitInputData%BldRloc)) THEN + ALLOCATE(DstInitInputData%BldRloc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%BldRloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%BldRloc = SrcInitInputData%BldRloc +ENDIF +IF (ALLOCATED(SrcInitInputData%TwrDia)) THEN + i1_l = LBOUND(SrcInitInputData%TwrDia,1) + i1_u = UBOUND(SrcInitInputData%TwrDia,1) + IF (.NOT. ALLOCATED(DstInitInputData%TwrDia)) THEN + ALLOCATE(DstInitInputData%TwrDia(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%TwrDia.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%TwrDia = SrcInitInputData%TwrDia +ENDIF +IF (ALLOCATED(SrcInitInputData%TwrHloc)) THEN + i1_l = LBOUND(SrcInitInputData%TwrHloc,1) + i1_u = UBOUND(SrcInitInputData%TwrHloc,1) + IF (.NOT. ALLOCATED(DstInitInputData%TwrHloc)) THEN + ALLOCATE(DstInitInputData%TwrHloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%TwrHloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%TwrHloc = SrcInitInputData%TwrHloc +ENDIF + END SUBROUTINE ExtLd_CopyInitInput + + SUBROUTINE ExtLd_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyInitInput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InitInputData%NumBldNodes)) THEN + DEALLOCATE(InitInputData%NumBldNodes) +ENDIF +IF (ALLOCATED(InitInputData%BldRootPos)) THEN + DEALLOCATE(InitInputData%BldRootPos) +ENDIF +IF (ALLOCATED(InitInputData%BldRootOrient)) THEN + DEALLOCATE(InitInputData%BldRootOrient) +ENDIF +IF (ALLOCATED(InitInputData%BldPos)) THEN + DEALLOCATE(InitInputData%BldPos) +ENDIF +IF (ALLOCATED(InitInputData%BldOrient)) THEN + DEALLOCATE(InitInputData%BldOrient) +ENDIF +IF (ALLOCATED(InitInputData%TwrPos)) THEN + DEALLOCATE(InitInputData%TwrPos) +ENDIF +IF (ALLOCATED(InitInputData%TwrOrient)) THEN + DEALLOCATE(InitInputData%TwrOrient) +ENDIF +IF (ALLOCATED(InitInputData%BldChord)) THEN + DEALLOCATE(InitInputData%BldChord) +ENDIF +IF (ALLOCATED(InitInputData%BldRloc)) THEN + DEALLOCATE(InitInputData%BldRloc) +ENDIF +IF (ALLOCATED(InitInputData%TwrDia)) THEN + DEALLOCATE(InitInputData%TwrDia) +ENDIF +IF (ALLOCATED(InitInputData%TwrHloc)) THEN + DEALLOCATE(InitInputData%TwrHloc) +ENDIF + END SUBROUTINE ExtLd_DestroyInitInput + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 ! NumBlades + Int_BufSz = Int_BufSz + 1 ! NumBldNodes allocated yes/no + IF ( ALLOCATED(InData%NumBldNodes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NumBldNodes upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%NumBldNodes) ! NumBldNodes + END IF + Int_BufSz = Int_BufSz + 1 ! TwrAero + Int_BufSz = Int_BufSz + 1 ! NumTwrNds + Re_BufSz = Re_BufSz + SIZE(InData%HubPos) ! HubPos + Db_BufSz = Db_BufSz + SIZE(InData%HubOrient) ! HubOrient + Re_BufSz = Re_BufSz + SIZE(InData%NacellePos) ! NacellePos + Db_BufSz = Db_BufSz + SIZE(InData%NacelleOrient) ! NacelleOrient + Int_BufSz = Int_BufSz + 1 ! BldRootPos allocated yes/no + IF ( ALLOCATED(InData%BldRootPos) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BldRootPos upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BldRootPos) ! BldRootPos + END IF + Int_BufSz = Int_BufSz + 1 ! BldRootOrient allocated yes/no + IF ( ALLOCATED(InData%BldRootOrient) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! BldRootOrient upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%BldRootOrient) ! BldRootOrient + END IF + Int_BufSz = Int_BufSz + 1 ! BldPos allocated yes/no + IF ( ALLOCATED(InData%BldPos) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! BldPos upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BldPos) ! BldPos + END IF + Int_BufSz = Int_BufSz + 1 ! BldOrient allocated yes/no + IF ( ALLOCATED(InData%BldOrient) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! BldOrient upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%BldOrient) ! BldOrient + END IF + Int_BufSz = Int_BufSz + 1 ! TwrPos allocated yes/no + IF ( ALLOCATED(InData%TwrPos) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! TwrPos upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrPos) ! TwrPos + END IF + Int_BufSz = Int_BufSz + 1 ! TwrOrient allocated yes/no + IF ( ALLOCATED(InData%TwrOrient) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! TwrOrient upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%TwrOrient) ! TwrOrient + END IF + Re_BufSz = Re_BufSz + 1 ! az_blend_mean + Re_BufSz = Re_BufSz + 1 ! az_blend_delta + Re_BufSz = Re_BufSz + 1 ! vel_mean + Re_BufSz = Re_BufSz + 1 ! wind_dir + Re_BufSz = Re_BufSz + 1 ! z_ref + Re_BufSz = Re_BufSz + 1 ! shear_exp + Int_BufSz = Int_BufSz + 1 ! BldChord allocated yes/no + IF ( ALLOCATED(InData%BldChord) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BldChord upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BldChord) ! BldChord + END IF + Int_BufSz = Int_BufSz + 1 ! BldRloc allocated yes/no + IF ( ALLOCATED(InData%BldRloc) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BldRloc upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BldRloc) ! BldRloc + END IF + Int_BufSz = Int_BufSz + 1 ! TwrDia allocated yes/no + IF ( ALLOCATED(InData%TwrDia) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrDia upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrDia) ! TwrDia + END IF + Int_BufSz = Int_BufSz + 1 ! TwrHloc allocated yes/no + IF ( ALLOCATED(InData%TwrHloc) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrHloc upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrHloc) ! TwrHloc + 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%NumBlades + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%NumBldNodes) ) 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%NumBldNodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NumBldNodes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NumBldNodes,1), UBOUND(InData%NumBldNodes,1) + IntKiBuf(Int_Xferred) = InData%NumBldNodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrAero, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumTwrNds + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%HubPos,1), UBOUND(InData%HubPos,1) + ReKiBuf(Re_Xferred) = InData%HubPos(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i2 = LBOUND(InData%HubOrient,2), UBOUND(InData%HubOrient,2) + DO i1 = LBOUND(InData%HubOrient,1), UBOUND(InData%HubOrient,1) + DbKiBuf(Db_Xferred) = InData%HubOrient(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + DO i1 = LBOUND(InData%NacellePos,1), UBOUND(InData%NacellePos,1) + ReKiBuf(Re_Xferred) = InData%NacellePos(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i2 = LBOUND(InData%NacelleOrient,2), UBOUND(InData%NacelleOrient,2) + DO i1 = LBOUND(InData%NacelleOrient,1), UBOUND(InData%NacelleOrient,1) + DbKiBuf(Db_Xferred) = InData%NacelleOrient(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + IF ( .NOT. ALLOCATED(InData%BldRootPos) ) 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%BldRootPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldRootPos,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldRootPos,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldRootPos,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BldRootPos,2), UBOUND(InData%BldRootPos,2) + DO i1 = LBOUND(InData%BldRootPos,1), UBOUND(InData%BldRootPos,1) + ReKiBuf(Re_Xferred) = InData%BldRootPos(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BldRootOrient) ) 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%BldRootOrient,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldRootOrient,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldRootOrient,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldRootOrient,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldRootOrient,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldRootOrient,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%BldRootOrient,3), UBOUND(InData%BldRootOrient,3) + DO i2 = LBOUND(InData%BldRootOrient,2), UBOUND(InData%BldRootOrient,2) + DO i1 = LBOUND(InData%BldRootOrient,1), UBOUND(InData%BldRootOrient,1) + DbKiBuf(Db_Xferred) = InData%BldRootOrient(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BldPos) ) 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%BldPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldPos,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldPos,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldPos,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldPos,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldPos,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%BldPos,3), UBOUND(InData%BldPos,3) + DO i2 = LBOUND(InData%BldPos,2), UBOUND(InData%BldPos,2) + DO i1 = LBOUND(InData%BldPos,1), UBOUND(InData%BldPos,1) + ReKiBuf(Re_Xferred) = InData%BldPos(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BldOrient) ) 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%BldOrient,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldOrient,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldOrient,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldOrient,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldOrient,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldOrient,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldOrient,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldOrient,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%BldOrient,4), UBOUND(InData%BldOrient,4) + DO i3 = LBOUND(InData%BldOrient,3), UBOUND(InData%BldOrient,3) + DO i2 = LBOUND(InData%BldOrient,2), UBOUND(InData%BldOrient,2) + DO i1 = LBOUND(InData%BldOrient,1), UBOUND(InData%BldOrient,1) + DbKiBuf(Db_Xferred) = InData%BldOrient(i1,i2,i3,i4) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrPos) ) 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%TwrPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrPos,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrPos,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrPos,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%TwrPos,2), UBOUND(InData%TwrPos,2) + DO i1 = LBOUND(InData%TwrPos,1), UBOUND(InData%TwrPos,1) + ReKiBuf(Re_Xferred) = InData%TwrPos(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrOrient) ) 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%TwrOrient,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrOrient,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrOrient,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrOrient,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrOrient,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrOrient,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%TwrOrient,3), UBOUND(InData%TwrOrient,3) + DO i2 = LBOUND(InData%TwrOrient,2), UBOUND(InData%TwrOrient,2) + DO i1 = LBOUND(InData%TwrOrient,1), UBOUND(InData%TwrOrient,1) + DbKiBuf(Db_Xferred) = InData%TwrOrient(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%az_blend_mean + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%az_blend_delta + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%vel_mean + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%wind_dir + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%z_ref + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%shear_exp + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%BldChord) ) 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%BldChord,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldChord,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldChord,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldChord,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BldChord,2), UBOUND(InData%BldChord,2) + DO i1 = LBOUND(InData%BldChord,1), UBOUND(InData%BldChord,1) + ReKiBuf(Re_Xferred) = InData%BldChord(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BldRloc) ) 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%BldRloc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldRloc,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldRloc,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldRloc,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BldRloc,2), UBOUND(InData%BldRloc,2) + DO i1 = LBOUND(InData%BldRloc,1), UBOUND(InData%BldRloc,1) + ReKiBuf(Re_Xferred) = InData%BldRloc(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrDia) ) 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%TwrDia,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDia,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrDia,1), UBOUND(InData%TwrDia,1) + ReKiBuf(Re_Xferred) = InData%TwrDia(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrHloc) ) 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%TwrHloc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrHloc,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrHloc,1), UBOUND(InData%TwrHloc,1) + ReKiBuf(Re_Xferred) = InData%TwrHloc(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLd_PackInitInput + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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%NumBlades = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NumBldNodes 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%NumBldNodes)) DEALLOCATE(OutData%NumBldNodes) + ALLOCATE(OutData%NumBldNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NumBldNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%NumBldNodes,1), UBOUND(OutData%NumBldNodes,1) + OutData%NumBldNodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + OutData%TwrAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrAero) + Int_Xferred = Int_Xferred + 1 + OutData%NumTwrNds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%HubPos,1) + i1_u = UBOUND(OutData%HubPos,1) + DO i1 = LBOUND(OutData%HubPos,1), UBOUND(OutData%HubPos,1) + OutData%HubPos(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%HubOrient,1) + i1_u = UBOUND(OutData%HubOrient,1) + i2_l = LBOUND(OutData%HubOrient,2) + i2_u = UBOUND(OutData%HubOrient,2) + DO i2 = LBOUND(OutData%HubOrient,2), UBOUND(OutData%HubOrient,2) + DO i1 = LBOUND(OutData%HubOrient,1), UBOUND(OutData%HubOrient,1) + OutData%HubOrient(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + i1_l = LBOUND(OutData%NacellePos,1) + i1_u = UBOUND(OutData%NacellePos,1) + DO i1 = LBOUND(OutData%NacellePos,1), UBOUND(OutData%NacellePos,1) + OutData%NacellePos(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%NacelleOrient,1) + i1_u = UBOUND(OutData%NacelleOrient,1) + i2_l = LBOUND(OutData%NacelleOrient,2) + i2_u = UBOUND(OutData%NacelleOrient,2) + DO i2 = LBOUND(OutData%NacelleOrient,2), UBOUND(OutData%NacelleOrient,2) + DO i1 = LBOUND(OutData%NacelleOrient,1), UBOUND(OutData%NacelleOrient,1) + OutData%NacelleOrient(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldRootPos 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%BldRootPos)) DEALLOCATE(OutData%BldRootPos) + ALLOCATE(OutData%BldRootPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldRootPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BldRootPos,2), UBOUND(OutData%BldRootPos,2) + DO i1 = LBOUND(OutData%BldRootPos,1), UBOUND(OutData%BldRootPos,1) + OutData%BldRootPos(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldRootOrient 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%BldRootOrient)) DEALLOCATE(OutData%BldRootOrient) + ALLOCATE(OutData%BldRootOrient(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%BldRootOrient.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%BldRootOrient,3), UBOUND(OutData%BldRootOrient,3) + DO i2 = LBOUND(OutData%BldRootOrient,2), UBOUND(OutData%BldRootOrient,2) + DO i1 = LBOUND(OutData%BldRootOrient,1), UBOUND(OutData%BldRootOrient,1) + OutData%BldRootOrient(i1,i2,i3) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldPos 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%BldPos)) DEALLOCATE(OutData%BldPos) + ALLOCATE(OutData%BldPos(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%BldPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%BldPos,3), UBOUND(OutData%BldPos,3) + DO i2 = LBOUND(OutData%BldPos,2), UBOUND(OutData%BldPos,2) + DO i1 = LBOUND(OutData%BldPos,1), UBOUND(OutData%BldPos,1) + OutData%BldPos(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldOrient 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%BldOrient)) DEALLOCATE(OutData%BldOrient) + ALLOCATE(OutData%BldOrient(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%BldOrient.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%BldOrient,4), UBOUND(OutData%BldOrient,4) + DO i3 = LBOUND(OutData%BldOrient,3), UBOUND(OutData%BldOrient,3) + DO i2 = LBOUND(OutData%BldOrient,2), UBOUND(OutData%BldOrient,2) + DO i1 = LBOUND(OutData%BldOrient,1), UBOUND(OutData%BldOrient,1) + OutData%BldOrient(i1,i2,i3,i4) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrPos 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%TwrPos)) DEALLOCATE(OutData%TwrPos) + ALLOCATE(OutData%TwrPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%TwrPos,2), UBOUND(OutData%TwrPos,2) + DO i1 = LBOUND(OutData%TwrPos,1), UBOUND(OutData%TwrPos,1) + OutData%TwrPos(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrOrient 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%TwrOrient)) DEALLOCATE(OutData%TwrOrient) + ALLOCATE(OutData%TwrOrient(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%TwrOrient.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%TwrOrient,3), UBOUND(OutData%TwrOrient,3) + DO i2 = LBOUND(OutData%TwrOrient,2), UBOUND(OutData%TwrOrient,2) + DO i1 = LBOUND(OutData%TwrOrient,1), UBOUND(OutData%TwrOrient,1) + OutData%TwrOrient(i1,i2,i3) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + OutData%az_blend_mean = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%az_blend_delta = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%vel_mean = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%wind_dir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%z_ref = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%shear_exp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldChord 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%BldChord)) DEALLOCATE(OutData%BldChord) + ALLOCATE(OutData%BldChord(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BldChord,2), UBOUND(OutData%BldChord,2) + DO i1 = LBOUND(OutData%BldChord,1), UBOUND(OutData%BldChord,1) + OutData%BldChord(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldRloc 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%BldRloc)) DEALLOCATE(OutData%BldRloc) + ALLOCATE(OutData%BldRloc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldRloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BldRloc,2), UBOUND(OutData%BldRloc,2) + DO i1 = LBOUND(OutData%BldRloc,1), UBOUND(OutData%BldRloc,1) + OutData%BldRloc(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDia 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%TwrDia)) DEALLOCATE(OutData%TwrDia) + ALLOCATE(OutData%TwrDia(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDia.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrDia,1), UBOUND(OutData%TwrDia,1) + OutData%TwrDia(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrHloc 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%TwrHloc)) DEALLOCATE(OutData%TwrHloc) + ALLOCATE(OutData%TwrHloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrHloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrHloc,1), UBOUND(OutData%TwrHloc,1) + OutData%TwrHloc(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLd_UnPackInitInput + + SUBROUTINE ExtLd_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_InitOutputType), INTENT(IN) :: SrcInitOutputData + TYPE(ExtLd_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 = 'ExtLd_CopyInitOutput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN + ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr +ENDIF +IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN + ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt +ENDIF + CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInitOutputData%AirDens = SrcInitOutputData%AirDens + END SUBROUTINE ExtLd_CopyInitOutput + + SUBROUTINE ExtLd_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyInitOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN + DEALLOCATE(InitOutputData%WriteOutputHdr) +ENDIF +IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN + DEALLOCATE(InitOutputData%WriteOutputUnt) +ENDIF + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ExtLd_DestroyInitOutput + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 + Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no + IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr + END IF + Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no + IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt + END IF + ! 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 + 1 ! AirDens + 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%WriteOutputHdr) ) 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%WriteOutputHdr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) + DO I = 1, LEN(InData%WriteOutputHdr) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) 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%WriteOutputUnt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) + DO I = 1, LEN(InData%WriteOutputUnt) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + 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 + ReKiBuf(Re_Xferred) = InData%AirDens + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_PackInitOutput + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr 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%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr) + ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) + DO I = 1, LEN(OutData%WriteOutputHdr) + OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt 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%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt) + ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) + DO I = 1, LEN(OutData%WriteOutputUnt) + OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + 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 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%AirDens = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_UnPackInitOutput + + SUBROUTINE ExtLd_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_ContinuousStateType), INTENT(IN) :: SrcContStateData + TYPE(ExtLd_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 = 'ExtLd_CopyContState' +! + ErrStat = ErrID_None + ErrMsg = "" + DstContStateData%blah = SrcContStateData%blah + END SUBROUTINE ExtLd_CopyContState + + SUBROUTINE ExtLd_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyContState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE ExtLd_DestroyContState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 ! blah + 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%blah + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_PackContState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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%blah = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_UnPackContState + + SUBROUTINE ExtLd_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_DiscreteStateType), INTENT(IN) :: SrcDiscStateData + TYPE(ExtLd_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 = 'ExtLd_CopyDiscState' +! + ErrStat = ErrID_None + ErrMsg = "" + DstDiscStateData%blah = SrcDiscStateData%blah + END SUBROUTINE ExtLd_CopyDiscState + + SUBROUTINE ExtLd_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyDiscState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE ExtLd_DestroyDiscState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 ! blah + 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%blah + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_PackDiscState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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%blah = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_UnPackDiscState + + SUBROUTINE ExtLd_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_MiscVarType), INTENT(IN) :: SrcMiscData + TYPE(ExtLd_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 = 'ExtLd_CopyMisc' +! + ErrStat = ErrID_None + ErrMsg = "" + DstMiscData%az = SrcMiscData%az + DstMiscData%phi_cfd = SrcMiscData%phi_cfd + END SUBROUTINE ExtLd_CopyMisc + + SUBROUTINE ExtLd_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyMisc' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE ExtLd_DestroyMisc + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 ! az + Re_BufSz = Re_BufSz + 1 ! phi_cfd + 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%az + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%phi_cfd + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_PackMisc + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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%az = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%phi_cfd = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_UnPackMisc + + SUBROUTINE ExtLd_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_ConstraintStateType), INTENT(IN) :: SrcConstrStateData + TYPE(ExtLd_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 = 'ExtLd_CopyConstrState' +! + ErrStat = ErrID_None + ErrMsg = "" + DstConstrStateData%blah = SrcConstrStateData%blah + END SUBROUTINE ExtLd_CopyConstrState + + SUBROUTINE ExtLd_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyConstrState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE ExtLd_DestroyConstrState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 ! blah + 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%blah + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_PackConstrState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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%blah = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_UnPackConstrState + + SUBROUTINE ExtLd_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_OtherStateType), INTENT(IN) :: SrcOtherStateData + TYPE(ExtLd_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 = 'ExtLd_CopyOtherState' +! + ErrStat = ErrID_None + ErrMsg = "" + DstOtherStateData%blah = SrcOtherStateData%blah + END SUBROUTINE ExtLd_CopyOtherState + + SUBROUTINE ExtLd_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyOtherState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE ExtLd_DestroyOtherState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 ! blah + 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%blah + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_PackOtherState + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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%blah = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_UnPackOtherState + + SUBROUTINE ExtLd_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_ParameterType), INTENT(IN) :: SrcParamData + TYPE(ExtLd_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 = 'ExtLd_CopyParam' +! + ErrStat = ErrID_None + ErrMsg = "" + DstParamData%NumBlds = SrcParamData%NumBlds +IF (ALLOCATED(SrcParamData%NumBldNds)) THEN + i1_l = LBOUND(SrcParamData%NumBldNds,1) + i1_u = UBOUND(SrcParamData%NumBldNds,1) + IF (.NOT. ALLOCATED(DstParamData%NumBldNds)) THEN + ALLOCATE(DstParamData%NumBldNds(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%NumBldNds.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%NumBldNds = SrcParamData%NumBldNds +ENDIF + DstParamData%nTotBldNds = SrcParamData%nTotBldNds + DstParamData%TwrAero = SrcParamData%TwrAero + DstParamData%NumTwrNds = SrcParamData%NumTwrNds + DstParamData%az_blend_mean = SrcParamData%az_blend_mean + DstParamData%az_blend_delta = SrcParamData%az_blend_delta + DstParamData%vel_mean = SrcParamData%vel_mean + DstParamData%wind_dir = SrcParamData%wind_dir + DstParamData%z_ref = SrcParamData%z_ref + DstParamData%shear_exp = SrcParamData%shear_exp + END SUBROUTINE ExtLd_CopyParam + + SUBROUTINE ExtLd_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyParam' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ParamData%NumBldNds)) THEN + DEALLOCATE(ParamData%NumBldNds) +ENDIF + END SUBROUTINE ExtLd_DestroyParam + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 ! NumBlds + Int_BufSz = Int_BufSz + 1 ! NumBldNds allocated yes/no + IF ( ALLOCATED(InData%NumBldNds) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NumBldNds upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%NumBldNds) ! NumBldNds + END IF + Int_BufSz = Int_BufSz + 1 ! nTotBldNds + Int_BufSz = Int_BufSz + 1 ! TwrAero + Int_BufSz = Int_BufSz + 1 ! NumTwrNds + Re_BufSz = Re_BufSz + 1 ! az_blend_mean + Re_BufSz = Re_BufSz + 1 ! az_blend_delta + Re_BufSz = Re_BufSz + 1 ! vel_mean + Re_BufSz = Re_BufSz + 1 ! wind_dir + Re_BufSz = Re_BufSz + 1 ! z_ref + Re_BufSz = Re_BufSz + 1 ! shear_exp + 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%NumBlds + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%NumBldNds) ) 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%NumBldNds,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NumBldNds,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NumBldNds,1), UBOUND(InData%NumBldNds,1) + IntKiBuf(Int_Xferred) = InData%NumBldNds(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%nTotBldNds + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrAero, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumTwrNds + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%az_blend_mean + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%az_blend_delta + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%vel_mean + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%wind_dir + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%z_ref + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%shear_exp + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_PackParam + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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%NumBlds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NumBldNds 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%NumBldNds)) DEALLOCATE(OutData%NumBldNds) + ALLOCATE(OutData%NumBldNds(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NumBldNds.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%NumBldNds,1), UBOUND(OutData%NumBldNds,1) + OutData%NumBldNds(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + OutData%nTotBldNds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%TwrAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrAero) + Int_Xferred = Int_Xferred + 1 + OutData%NumTwrNds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%az_blend_mean = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%az_blend_delta = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%vel_mean = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%wind_dir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%z_ref = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%shear_exp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ExtLd_UnPackParam + + SUBROUTINE ExtLd_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_InputType), INTENT(INOUT) :: SrcInputData + TYPE(ExtLd_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) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_CopyInput' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL ExtLdDX_CopyInput( SrcInputData%DX_u, DstInputData%DX_u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInputData%az = SrcInputData%az + CALL MeshCopy( SrcInputData%TowerMotion, DstInputData%TowerMotion, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcInputData%HubMotion, DstInputData%HubMotion, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcInputData%NacelleMotion, DstInputData%NacelleMotion, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcInputData%BladeRootMotion)) THEN + i1_l = LBOUND(SrcInputData%BladeRootMotion,1) + i1_u = UBOUND(SrcInputData%BladeRootMotion,1) + IF (.NOT. ALLOCATED(DstInputData%BladeRootMotion)) THEN + ALLOCATE(DstInputData%BladeRootMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%BladeRootMotion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInputData%BladeRootMotion,1), UBOUND(SrcInputData%BladeRootMotion,1) + CALL MeshCopy( SrcInputData%BladeRootMotion(i1), DstInputData%BladeRootMotion(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcInputData%BladeMotion)) THEN + i1_l = LBOUND(SrcInputData%BladeMotion,1) + i1_u = UBOUND(SrcInputData%BladeMotion,1) + IF (.NOT. ALLOCATED(DstInputData%BladeMotion)) THEN + ALLOCATE(DstInputData%BladeMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%BladeMotion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInputData%BladeMotion,1), UBOUND(SrcInputData%BladeMotion,1) + CALL MeshCopy( SrcInputData%BladeMotion(i1), DstInputData%BladeMotion(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + END SUBROUTINE ExtLd_CopyInput + + SUBROUTINE ExtLd_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_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 = 'ExtLd_DestroyInput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL ExtLdDX_DestroyInput( InputData%DX_u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%TowerMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%HubMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%NacelleMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(InputData%BladeRootMotion)) THEN +DO i1 = LBOUND(InputData%BladeRootMotion,1), UBOUND(InputData%BladeRootMotion,1) + CALL MeshDestroy( InputData%BladeRootMotion(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(InputData%BladeRootMotion) +ENDIF +IF (ALLOCATED(InputData%BladeMotion)) THEN +DO i1 = LBOUND(InputData%BladeMotion,1), UBOUND(InputData%BladeMotion,1) + CALL MeshDestroy( InputData%BladeMotion(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(InputData%BladeMotion) +ENDIF + END SUBROUTINE ExtLd_DestroyInput + + SUBROUTINE ExtLd_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(ExtLd_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 = 'ExtLd_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 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! DX_u: size of buffers for each call to pack subtype + CALL ExtLdDX_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%DX_u, ErrStat2, ErrMsg2, .TRUE. ) ! DX_u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! DX_u + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! DX_u + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! DX_u + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Re_BufSz = Re_BufSz + 1 ! az + Int_BufSz = Int_BufSz + 3 ! TowerMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%TowerMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TowerMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TowerMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TowerMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TowerMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! HubMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%HubMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! HubMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! HubMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! HubMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! HubMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! NacelleMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%NacelleMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! NacelleMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! NacelleMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! NacelleMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! NacelleMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! BladeRootMotion allocated yes/no + IF ( ALLOCATED(InData%BladeRootMotion) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeRootMotion upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeRootMotion,1), UBOUND(InData%BladeRootMotion,1) + Int_BufSz = Int_BufSz + 3 ! BladeRootMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeRootMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeRootMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeRootMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeRootMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! BladeMotion allocated yes/no + IF ( ALLOCATED(InData%BladeMotion) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeMotion upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeMotion,1), UBOUND(InData%BladeMotion,1) + Int_BufSz = Int_BufSz + 3 ! BladeMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + 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 ExtLdDX_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%DX_u, ErrStat2, ErrMsg2, OnlySize ) ! DX_u + 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 + ReKiBuf(Re_Xferred) = InData%az + Re_Xferred = Re_Xferred + 1 + CALL MeshPack( InData%TowerMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TowerMotion + 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 MeshPack( InData%HubMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! HubMotion + 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 MeshPack( InData%NacelleMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! NacelleMotion + 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%BladeRootMotion) ) 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%BladeRootMotion,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootMotion,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeRootMotion,1), UBOUND(InData%BladeRootMotion,1) + CALL MeshPack( InData%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeRootMotion + 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 DO + END IF + IF ( .NOT. ALLOCATED(InData%BladeMotion) ) 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%BladeMotion,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeMotion,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeMotion,1), UBOUND(InData%BladeMotion,1) + CALL MeshPack( InData%BladeMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeMotion + 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 DO + END IF + END SUBROUTINE ExtLd_PackInput + + SUBROUTINE ExtLd_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(ExtLd_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) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_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 + 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 ExtLdDX_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%DX_u, ErrStat2, ErrMsg2 ) ! DX_u + 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%az = 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 MeshUnpack( OutData%TowerMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TowerMotion + 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 MeshUnpack( OutData%HubMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! HubMotion + 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 MeshUnpack( OutData%NacelleMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! NacelleMotion + 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 ! BladeRootMotion 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%BladeRootMotion)) DEALLOCATE(OutData%BladeRootMotion) + ALLOCATE(OutData%BladeRootMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootMotion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeRootMotion,1), UBOUND(OutData%BladeRootMotion,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 MeshUnpack( OutData%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeRootMotion + 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 ! BladeMotion 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%BladeMotion)) DEALLOCATE(OutData%BladeMotion) + ALLOCATE(OutData%BladeMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeMotion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeMotion,1), UBOUND(OutData%BladeMotion,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 MeshUnpack( OutData%BladeMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeMotion + 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 + END SUBROUTINE ExtLd_UnPackInput + + SUBROUTINE ExtLd_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLd_OutputType), INTENT(INOUT) :: SrcOutputData + TYPE(ExtLd_OutputType), INTENT(INOUT) :: DstOutputData + 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 = 'ExtLd_CopyOutput' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL ExtLdDX_CopyOutput( SrcOutputData%DX_y, DstOutputData%DX_y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcOutputData%TowerLoad, DstOutputData%TowerLoad, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcOutputData%BladeLoad)) THEN + i1_l = LBOUND(SrcOutputData%BladeLoad,1) + i1_u = UBOUND(SrcOutputData%BladeLoad,1) + IF (.NOT. ALLOCATED(DstOutputData%BladeLoad)) THEN + ALLOCATE(DstOutputData%BladeLoad(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%BladeLoad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOutputData%BladeLoad,1), UBOUND(SrcOutputData%BladeLoad,1) + CALL MeshCopy( SrcOutputData%BladeLoad(i1), DstOutputData%BladeLoad(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL MeshCopy( SrcOutputData%TowerLoadAD, DstOutputData%TowerLoadAD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcOutputData%BladeLoadAD)) THEN + i1_l = LBOUND(SrcOutputData%BladeLoadAD,1) + i1_u = UBOUND(SrcOutputData%BladeLoadAD,1) + IF (.NOT. ALLOCATED(DstOutputData%BladeLoadAD)) THEN + ALLOCATE(DstOutputData%BladeLoadAD(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%BladeLoadAD.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOutputData%BladeLoadAD,1), UBOUND(SrcOutputData%BladeLoadAD,1) + CALL MeshCopy( SrcOutputData%BladeLoadAD(i1), DstOutputData%BladeLoadAD(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + END SUBROUTINE ExtLd_CopyOutput + + SUBROUTINE ExtLd_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLd_OutputType), INTENT(INOUT) :: OutputData + 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 = 'ExtLd_DestroyOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL ExtLdDX_DestroyOutput( OutputData%DX_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%TowerLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(OutputData%BladeLoad)) THEN +DO i1 = LBOUND(OutputData%BladeLoad,1), UBOUND(OutputData%BladeLoad,1) + CALL MeshDestroy( OutputData%BladeLoad(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(OutputData%BladeLoad) +ENDIF + CALL MeshDestroy( OutputData%TowerLoadAD, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(OutputData%BladeLoadAD)) THEN +DO i1 = LBOUND(OutputData%BladeLoadAD,1), UBOUND(OutputData%BladeLoadAD,1) + CALL MeshDestroy( OutputData%BladeLoadAD(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(OutputData%BladeLoadAD) +ENDIF + END SUBROUTINE ExtLd_DestroyOutput + + SUBROUTINE ExtLd_PackOutput( 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(ExtLd_OutputType), 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 = 'ExtLd_PackOutput' + ! 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 ! DX_y: size of buffers for each call to pack subtype + CALL ExtLdDX_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%DX_y, ErrStat2, ErrMsg2, .TRUE. ) ! DX_y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! DX_y + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! DX_y + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! DX_y + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! TowerLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%TowerLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TowerLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TowerLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TowerLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TowerLoad + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! BladeLoad allocated yes/no + IF ( ALLOCATED(InData%BladeLoad) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeLoad upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeLoad,1), UBOUND(InData%BladeLoad,1) + Int_BufSz = Int_BufSz + 3 ! BladeLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeLoad + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! TowerLoadAD: size of buffers for each call to pack subtype + CALL MeshPack( InData%TowerLoadAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TowerLoadAD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TowerLoadAD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TowerLoadAD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TowerLoadAD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! BladeLoadAD allocated yes/no + IF ( ALLOCATED(InData%BladeLoadAD) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeLoadAD upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeLoadAD,1), UBOUND(InData%BladeLoadAD,1) + Int_BufSz = Int_BufSz + 3 ! BladeLoadAD: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeLoadAD(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeLoadAD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeLoadAD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeLoadAD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeLoadAD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + 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 ExtLdDX_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%DX_y, ErrStat2, ErrMsg2, OnlySize ) ! DX_y + 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 MeshPack( InData%TowerLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TowerLoad + 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%BladeLoad) ) 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%BladeLoad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeLoad,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeLoad,1), UBOUND(InData%BladeLoad,1) + CALL MeshPack( InData%BladeLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeLoad + 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 DO + END IF + CALL MeshPack( InData%TowerLoadAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TowerLoadAD + 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%BladeLoadAD) ) 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%BladeLoadAD,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeLoadAD,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeLoadAD,1), UBOUND(InData%BladeLoadAD,1) + CALL MeshPack( InData%BladeLoadAD(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeLoadAD + 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 DO + END IF + END SUBROUTINE ExtLd_PackOutput + + SUBROUTINE ExtLd_UnPackOutput( 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(ExtLd_OutputType), 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 = 'ExtLd_UnPackOutput' + ! 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 ExtLdDX_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%DX_y, ErrStat2, ErrMsg2 ) ! DX_y + 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 MeshUnpack( OutData%TowerLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TowerLoad + 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 ! BladeLoad 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%BladeLoad)) DEALLOCATE(OutData%BladeLoad) + ALLOCATE(OutData%BladeLoad(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeLoad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeLoad,1), UBOUND(OutData%BladeLoad,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 MeshUnpack( OutData%BladeLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeLoad + 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 + 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 MeshUnpack( OutData%TowerLoadAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TowerLoadAD + 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 ! BladeLoadAD 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%BladeLoadAD)) DEALLOCATE(OutData%BladeLoadAD) + ALLOCATE(OutData%BladeLoadAD(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeLoadAD.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeLoadAD,1), UBOUND(OutData%BladeLoadAD,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 MeshUnpack( OutData%BladeLoadAD(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeLoadAD + 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 + END SUBROUTINE ExtLd_UnPackOutput + + + SUBROUTINE ExtLd_Input_ExtrapInterp(u, t, u_out, t_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time +! values of u (which has values associated with times in t). Order of the interpolation is given by the size of u +! +! expressions below based on either +! +! f(t) = a +! f(t) = a + b * t, or +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = u1, f(t2) = u2, f(t3) = u3 (as appropriate) +! +!.................................................................................................................................. + + TYPE(ExtLd_InputType), INTENT(INOUT) :: u(:) ! Input at t1 > t2 > t3 + REAL(DbKi), INTENT(IN ) :: t(:) ! Times associated with the Inputs + TYPE(ExtLd_InputType), INTENT(INOUT) :: u_out ! Input at tin_out + REAL(DbKi), INTENT(IN ) :: t_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_Input_ExtrapInterp' + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + if ( size(t) .ne. size(u)) then + CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(u)',ErrStat,ErrMsg,RoutineName) + RETURN + endif + order = SIZE(u) - 1 + IF ( order .eq. 0 ) THEN + CALL ExtLd_CopyInput(u(1), u_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 1 ) THEN + CALL ExtLd_Input_ExtrapInterp1(u(1), u(2), t, u_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 2 ) THEN + CALL ExtLd_Input_ExtrapInterp2(u(1), u(2), u(3), t, u_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE + CALL SetErrStat(ErrID_Fatal,'size(u) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName) + RETURN + ENDIF + END SUBROUTINE ExtLd_Input_ExtrapInterp + + + SUBROUTINE ExtLd_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time +! values of u (which has values associated with times in t). Order of the interpolation is 1. +! +! f(t) = a + b * t, or +! +! where a and b are determined as the solution to +! f(t1) = u1, f(t2) = u2 +! +!.................................................................................................................................. + + TYPE(ExtLd_InputType), INTENT(INOUT) :: u1 ! Input at t1 > t2 + TYPE(ExtLd_InputType), INTENT(INOUT) :: u2 ! Input at t2 + REAL(DbKi), INTENT(IN ) :: tin(2) ! Times associated with the Inputs + TYPE(ExtLd_InputType), INTENT(INOUT) :: u_out ! Input at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(2) ! Times associated with the Inputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_Input_ExtrapInterp1' + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / t(2) + CALL ExtLdDX_Input_ExtrapInterp1( u1%DX_u, u2%DX_u, tin, u_out%DX_u, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + b = -(u1%az - u2%az) + u_out%az = u1%az + b * ScaleFactor + CALL MeshExtrapInterp1(u1%TowerMotion, u2%TowerMotion, tin, u_out%TowerMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp1(u1%HubMotion, u2%HubMotion, tin, u_out%HubMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp1(u1%NacelleMotion, u2%NacelleMotion, tin, u_out%NacelleMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(u_out%BladeRootMotion) .AND. ALLOCATED(u1%BladeRootMotion)) THEN + DO i1 = LBOUND(u_out%BladeRootMotion,1),UBOUND(u_out%BladeRootMotion,1) + CALL MeshExtrapInterp1(u1%BladeRootMotion(i1), u2%BladeRootMotion(i1), tin, u_out%BladeRootMotion(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated +IF (ALLOCATED(u_out%BladeMotion) .AND. ALLOCATED(u1%BladeMotion)) THEN + DO i1 = LBOUND(u_out%BladeMotion,1),UBOUND(u_out%BladeMotion,1) + CALL MeshExtrapInterp1(u1%BladeMotion(i1), u2%BladeMotion(i1), tin, u_out%BladeMotion(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated + END SUBROUTINE ExtLd_Input_ExtrapInterp1 + + + SUBROUTINE ExtLd_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time +! values of u (which has values associated with times in t). Order of the interpolation is 2. +! +! expressions below based on either +! +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = u1, f(t2) = u2, f(t3) = u3 +! +!.................................................................................................................................. + + TYPE(ExtLd_InputType), INTENT(INOUT) :: u1 ! Input at t1 > t2 > t3 + TYPE(ExtLd_InputType), INTENT(INOUT) :: u2 ! Input at t2 > t3 + TYPE(ExtLd_InputType), INTENT(INOUT) :: u3 ! Input at t3 + REAL(DbKi), INTENT(IN ) :: tin(3) ! Times associated with the Inputs + TYPE(ExtLd_InputType), INTENT(INOUT) :: u_out ! Input at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(3) ! Times associated with the Inputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: c ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_Input_ExtrapInterp2' + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) + CALL ExtLdDX_Input_ExtrapInterp2( u1%DX_u, u2%DX_u, u3%DX_u, tin, u_out%DX_u, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + b = (t(3)**2*(u1%az - u2%az) + t(2)**2*(-u1%az + u3%az))* scaleFactor + c = ( (t(2)-t(3))*u1%az + t(3)*u2%az - t(2)*u3%az ) * scaleFactor + u_out%az = u1%az + b + c * t_out + CALL MeshExtrapInterp2(u1%TowerMotion, u2%TowerMotion, u3%TowerMotion, tin, u_out%TowerMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp2(u1%HubMotion, u2%HubMotion, u3%HubMotion, tin, u_out%HubMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp2(u1%NacelleMotion, u2%NacelleMotion, u3%NacelleMotion, tin, u_out%NacelleMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(u_out%BladeRootMotion) .AND. ALLOCATED(u1%BladeRootMotion)) THEN + DO i1 = LBOUND(u_out%BladeRootMotion,1),UBOUND(u_out%BladeRootMotion,1) + CALL MeshExtrapInterp2(u1%BladeRootMotion(i1), u2%BladeRootMotion(i1), u3%BladeRootMotion(i1), tin, u_out%BladeRootMotion(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated +IF (ALLOCATED(u_out%BladeMotion) .AND. ALLOCATED(u1%BladeMotion)) THEN + DO i1 = LBOUND(u_out%BladeMotion,1),UBOUND(u_out%BladeMotion,1) + CALL MeshExtrapInterp2(u1%BladeMotion(i1), u2%BladeMotion(i1), u3%BladeMotion(i1), tin, u_out%BladeMotion(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated + END SUBROUTINE ExtLd_Input_ExtrapInterp2 + + + SUBROUTINE ExtLd_Output_ExtrapInterp(y, t, y_out, t_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time +! values of y (which has values associated with times in t). Order of the interpolation is given by the size of y +! +! expressions below based on either +! +! f(t) = a +! f(t) = a + b * t, or +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = y1, f(t2) = y2, f(t3) = y3 (as appropriate) +! +!.................................................................................................................................. + + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y(:) ! Output at t1 > t2 > t3 + REAL(DbKi), INTENT(IN ) :: t(:) ! Times associated with the Outputs + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out + REAL(DbKi), INTENT(IN ) :: t_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_Output_ExtrapInterp' + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + if ( size(t) .ne. size(y)) then + CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(y)',ErrStat,ErrMsg,RoutineName) + RETURN + endif + order = SIZE(y) - 1 + IF ( order .eq. 0 ) THEN + CALL ExtLd_CopyOutput(y(1), y_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 1 ) THEN + CALL ExtLd_Output_ExtrapInterp1(y(1), y(2), t, y_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE IF ( order .eq. 2 ) THEN + CALL ExtLd_Output_ExtrapInterp2(y(1), y(2), y(3), t, y_out, t_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ELSE + CALL SetErrStat(ErrID_Fatal,'size(y) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName) + RETURN + ENDIF + END SUBROUTINE ExtLd_Output_ExtrapInterp + + + SUBROUTINE ExtLd_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time +! values of y (which has values associated with times in t). Order of the interpolation is 1. +! +! f(t) = a + b * t, or +! +! where a and b are determined as the solution to +! f(t1) = y1, f(t2) = y2 +! +!.................................................................................................................................. + + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y1 ! Output at t1 > t2 + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y2 ! Output at t2 + REAL(DbKi), INTENT(IN ) :: tin(2) ! Times associated with the Outputs + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(2) ! Times associated with the Outputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_Output_ExtrapInterp1' + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / t(2) + CALL ExtLdDX_Output_ExtrapInterp1( y1%DX_y, y2%DX_y, tin, y_out%DX_y, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp1(y1%TowerLoad, y2%TowerLoad, tin, y_out%TowerLoad, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(y_out%BladeLoad) .AND. ALLOCATED(y1%BladeLoad)) THEN + DO i1 = LBOUND(y_out%BladeLoad,1),UBOUND(y_out%BladeLoad,1) + CALL MeshExtrapInterp1(y1%BladeLoad(i1), y2%BladeLoad(i1), tin, y_out%BladeLoad(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated + CALL MeshExtrapInterp1(y1%TowerLoadAD, y2%TowerLoadAD, tin, y_out%TowerLoadAD, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(y_out%BladeLoadAD) .AND. ALLOCATED(y1%BladeLoadAD)) THEN + DO i1 = LBOUND(y_out%BladeLoadAD,1),UBOUND(y_out%BladeLoadAD,1) + CALL MeshExtrapInterp1(y1%BladeLoadAD(i1), y2%BladeLoadAD(i1), tin, y_out%BladeLoadAD(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated + END SUBROUTINE ExtLd_Output_ExtrapInterp1 + + + SUBROUTINE ExtLd_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, ErrMsg ) +! +! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time +! values of y (which has values associated with times in t). Order of the interpolation is 2. +! +! expressions below based on either +! +! f(t) = a + b * t + c * t**2 +! +! where a, b and c are determined as the solution to +! f(t1) = y1, f(t2) = y2, f(t3) = y3 +! +!.................................................................................................................................. + + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y1 ! Output at t1 > t2 > t3 + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y2 ! Output at t2 > t3 + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y3 ! Output at t3 + REAL(DbKi), INTENT(IN ) :: tin(3) ! Times associated with the Outputs + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out + REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + REAL(DbKi) :: t(3) ! Times associated with the Outputs + REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + INTEGER(IntKi) :: order ! order of polynomial fit (max 2) + REAL(DbKi) :: b ! temporary for extrapolation/interpolation + REAL(DbKi) :: c ! temporary for extrapolation/interpolation + REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation + INTEGER(IntKi) :: ErrStat2 ! local errors + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLd_Output_ExtrapInterp2' + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + ! we'll subtract a constant from the times to resolve some + ! numerical issues when t gets large (and to simplify the equations) + t = tin - tin(1) + t_out = tin_out - tin(1) + + IF ( EqualRealNos( t(1), t(2) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN + CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + + ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) + CALL ExtLdDX_Output_ExtrapInterp2( y1%DX_y, y2%DX_y, y3%DX_y, tin, y_out%DX_y, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp2(y1%TowerLoad, y2%TowerLoad, y3%TowerLoad, tin, y_out%TowerLoad, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(y_out%BladeLoad) .AND. ALLOCATED(y1%BladeLoad)) THEN + DO i1 = LBOUND(y_out%BladeLoad,1),UBOUND(y_out%BladeLoad,1) + CALL MeshExtrapInterp2(y1%BladeLoad(i1), y2%BladeLoad(i1), y3%BladeLoad(i1), tin, y_out%BladeLoad(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated + CALL MeshExtrapInterp2(y1%TowerLoadAD, y2%TowerLoadAD, y3%TowerLoadAD, tin, y_out%TowerLoadAD, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(y_out%BladeLoadAD) .AND. ALLOCATED(y1%BladeLoadAD)) THEN + DO i1 = LBOUND(y_out%BladeLoadAD,1),UBOUND(y_out%BladeLoadAD,1) + CALL MeshExtrapInterp2(y1%BladeLoadAD(i1), y2%BladeLoadAD(i1), y3%BladeLoadAD(i1), tin, y_out%BladeLoadAD(i1), tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated + END SUBROUTINE ExtLd_Output_ExtrapInterp2 + +END MODULE ExtLoads_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index a1d2570ca3..4a3fb947ad 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -120,6 +120,7 @@ MODULE NWTC_IO MODULE PROCEDURE AllIPAry1 MODULE PROCEDURE AllIPAry2 MODULE PROCEDURE AllFPAry1 + MODULE PROCEDURE AllDPAry1 MODULE PROCEDURE AllRPAry2 MODULE PROCEDURE AllR4PAry3 MODULE PROCEDURE AllR8PAry3 @@ -666,6 +667,39 @@ SUBROUTINE AllFPAry1 ( Ary, AryDim1, Descr, ErrStat, ErrMsg ) RETURN END SUBROUTINE AllFPAry1 !======================================================================= +!> \copydoc nwtc_io::allipary1 + SUBROUTINE AllDPAry1 ( Ary, AryDim1, Descr, ErrStat, ErrMsg ) + + ! This routine allocates a 1-D REAL array. + ! Argument declarations. + + REAL(C_DOUBLE), POINTER :: Ary (:) ! Array to be allocated + INTEGER, INTENT(IN) :: AryDim1 ! The size of the first dimension of the array. + INTEGER, INTENT(OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message corresponding to ErrStat + CHARACTER(*), INTENT(IN) :: Descr ! Brief array description. + + + IF ( ASSOCIATED(Ary) ) THEN + DEALLOCATE(Ary) + !ErrStat = ErrID_Warn + !ErrMsg = " AllRPAry2: Ary already allocated." + END IF + + ALLOCATE ( Ary(AryDim1) , STAT=ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = 'Error allocating '//TRIM(Num2LStr(AryDim1*BYTES_IN_REAL))//& + ' bytes of memory for the '//TRIM( Descr )//' array.' + ELSE + ErrStat = ErrID_None + ErrMsg = '' + END IF + + Ary = 0 + RETURN + END SUBROUTINE AllDPAry1 +!======================================================================= !> \copydoc nwtc_io::allipary1 SUBROUTINE AllRPAry2 ( Ary, AryDim1, AryDim2, Descr, ErrStat, ErrMsg ) diff --git a/modules/openfast-library/CMakeLists.txt b/modules/openfast-library/CMakeLists.txt index 86d77b47ea..7b7144cb5b 100644 --- a/modules/openfast-library/CMakeLists.txt +++ b/modules/openfast-library/CMakeLists.txt @@ -45,6 +45,7 @@ target_link_libraries(openfast_prelib versioninfolib aerodyn14lib aerodynlib + extloadslib beamdynlib elastodynlib extptfm_mckflib diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index e253a1a44d..9977338aa0 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -506,63 +506,170 @@ subroutine FAST_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, NumOuts_c, d #endif end subroutine FAST_Restart + !================================================================================================================================== -subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, NumSC2CtrlGlob, NumSC2Ctrl, NumCtrl2SC, InitSCOutputsGlob, InitSCOutputsTurbine, NumActForcePtsBlade, NumActForcePtsTower, TurbPosn, AbortErrLev_c, dt_c, NumBl_c, NumBlElem_c, NodeClusterType_c, & - ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtInfw_Init') +subroutine FAST_BR_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, NumBl_c, & + az_blend_mean_c, az_blend_delta_c, vel_mean_c, wind_dir_c, z_ref_c, shear_exp_c, & + ExtLd_Input_from_FAST, ExtLd_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_BR_CFD_Init') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_BR_CFD_Init IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Init -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Init +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Init +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Init #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - REAL(C_DOUBLE), INTENT(IN ) :: TMax - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) - INTEGER(C_INT), INTENT(IN ) :: TurbID ! Need not be same as iTurb - INTEGER(C_INT), INTENT(IN ) :: NumSC2CtrlGlob ! Supercontroller global outputs = controller global inputs - INTEGER(C_INT), INTENT(IN ) :: NumSC2Ctrl ! Supercontroller outputs = controller inputs - INTEGER(C_INT), INTENT(IN ) :: NumCtrl2SC ! controller outputs = Supercontroller inputs - REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsGlob (*) ! Initial Supercontroller global outputs = controller inputs - REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsTurbine (*) ! Initial Supercontroller turbine specific outputs = controller inputs - INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsBlade ! number of actuator line force points in blade - INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsTower ! number of actuator line force points in tower - INTEGER(C_INT), INTENT(IN ):: NodeClusterType_c - REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) - INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_c - INTEGER(C_INT), INTENT( OUT) :: NumBl_c - INTEGER(C_INT), INTENT( OUT) :: NumBlElem_c - TYPE(ExtInfw_InputType_C), INTENT(INOUT) :: ExtInfw_Input_from_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes - TYPE(ExtInfw_OutputType_C),INTENT(INOUT) :: ExtInfw_Output_to_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + REAL(C_DOUBLE), INTENT(IN ) :: TMax + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) + INTEGER(C_INT), INTENT(IN ) :: TurbID ! Need not be same as iTurb + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: OutFileRoot_c(IntfStrLen) + REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) + REAL(C_DOUBLE), INTENT(IN ) :: dtDriver_c + REAL(C_DOUBLE), INTENT(IN ) :: az_blend_mean_c + REAL(C_DOUBLE), INTENT(IN ) :: az_blend_delta_c + REAL(C_DOUBLE), INTENT(IN ) :: vel_mean_c + REAL(C_DOUBLE), INTENT(IN ) :: wind_dir_c + REAL(C_DOUBLE), INTENT(IN ) :: z_ref_c + REAL(C_DOUBLE), INTENT(IN ) :: shear_exp_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT( OUT) :: NumBl_c + TYPE(ExtLdDX_InputType_C), INTENT( OUT) :: ExtLd_Input_from_FAST + TYPE(ExtLdDX_OutputType_C),INTENT( OUT) :: ExtLd_Output_to_FAST TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local - CHARACTER(IntfStrLen) :: InputFileName - INTEGER(C_INT) :: i + CHARACTER(IntfStrLen) :: InputFileName + INTEGER(C_INT) :: i TYPE(FAST_ExternInitType) :: ExternInitData - - ! transfer the character array from C to a Fortran string: + INTEGER(IntKi) :: CompLoadsType + + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_BR_CFD_Init' + + ! transfer the character array from C to a Fortran string: InputFileName = TRANSFER( InputFileName_c, InputFileName ) I = INDEX(InputFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) InputFileName = InputFileName(1:I) ! remove it - - ! initialize variables: - n_t_global = 0 + + ! initialize variables: + n_t_global = 0 ErrStat = ErrID_None ErrMsg = "" - + + ExternInitData%TMax = TMax + ExternInitData%TurbineID = TurbID + ExternInitData%TurbinePos = TurbPosn + ExternInitData%SensorType = SensorType_None + ExternInitData%NumSC2CtrlGlob = 0 + ExternInitData%NumCtrl2SC = 0 + ExternInitData%NumSC2Ctrl = 0 + ExternInitData%DTdriver = dtDriver_c + ExternInitData%az_blend_mean = az_blend_mean_c + ExternInitData%az_blend_delta = az_blend_delta_c + ExternInitData%vel_mean = vel_mean_c + ExternInitData%wind_dir = wind_dir_c + ExternInitData%z_ref = z_ref_c + ExternInitData%shear_exp = shear_exp_c + + CALL FAST_InitializeAll_T( t_initial, 1_IntKi, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) + + write(*,*) 'ErrMsg = ', ErrMsg + ! set values for return to ExternalInflow + if (ErrStat .ne. ErrID_None) then + AbortErrLev_c = AbortErrLev + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( TRIM(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if + + dt_c = DBLE(Turbine(iTurb)%p_FAST%DT) + + NumBl_c = Turbine(iTurb)%ED%p%NumBl + + CompLoadsType = Turbine(iTurb)%p_FAST%CompAero + + if ( (CompLoadsType .ne. Module_ExtLd) ) then + CALL SetErrStat(ErrID_Fatal, "CompAero is not set to 3 for use of the External Loads module. Use a different C++ initialization call for this turbine.", ErrStat, ErrMsg, RoutineName ) + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if + + call SetExtLoads_pointers(iTurb, ExtLd_Input_from_FAST, ExtLd_Output_to_FAST) + + OutFileRoot_c = TRANSFER( trim(Turbine(iTurb)%p_FAST%OutFileRoot)//C_NULL_CHAR, OutFileRoot_c ) + + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + +end subroutine FAST_BR_CFD_Init + +!================================================================================================================================== +subroutine FAST_AL_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, NumSC2CtrlGlob, NumSC2Ctrl, NumCtrl2SC, InitSCOutputsGlob, InitSCOutputsTurbine, & + NumActForcePtsBlade, NumActForcePtsTower, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, InflowType, NumBl_c, NumBlElem_c, NumTwrElem_c, & + ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_AL_CFD_Init') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_Init + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Init +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Init +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + REAL(C_DOUBLE), INTENT(IN ) :: TMax + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) + INTEGER(C_INT), INTENT(IN ) :: TurbID ! Need not be same as iTurb + INTEGER(C_INT), INTENT(IN ) :: NumSC2CtrlGlob ! Supercontroller global outputs = controller global inputs + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: OutFileRoot_c(IntfStrLen) ! Root of output and restart file name + INTEGER(C_INT), INTENT(IN ) :: NumSC2Ctrl ! Supercontroller outputs = controller inputs + INTEGER(C_INT), INTENT(IN ) :: NumCtrl2SC ! controller outputs = Supercontroller inputs + REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsGlob (*) ! Initial Supercontroller global outputs = controller inputs + REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsTurbine (*) ! Initial Supercontroller turbine specific outputs = controller inputs + INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsBlade ! number of actuator line force points in blade + INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsTower ! number of actuator line force points in tower + REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) + REAL(C_DOUBLE), INTENT(IN ) :: dtDriver_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT( OUT) :: InflowType ! inflow type - 1 = From Inflow module, 2 = External + INTEGER(C_INT), INTENT( OUT) :: NumBl_c + INTEGER(C_INT), INTENT( OUT) :: NumBlElem_c + INTEGER(C_INT), INTENT( OUT) :: NumTwrElem_c + TYPE(ExtInfw_InputType_C), INTENT( OUT) :: ExtInfw_Input_from_FAST + TYPE(ExtInfw_OutputType_C),INTENT( OUT) :: ExtInfw_Output_to_FAST + TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST + TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + ! local + CHARACTER(IntfStrLen) :: InputFileName + INTEGER(C_INT) :: i + TYPE(FAST_ExternInitType) :: ExternInitData + + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_CFD_Init' + + ! transfer the character array from C to a Fortran string: + InputFileName = TRANSFER( InputFileName_c, InputFileName ) + I = INDEX(InputFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + IF ( I > 0 ) InputFileName = InputFileName(1:I) ! remove it + + ! initialize variables: + n_t_global = 0 + ErrStat = ErrID_None + ErrMsg = "" + NumBl_c = 0 ! initialize here in case of error NumBlElem_c = 0 ! initialize here in case of error - + ExternInitData%TMax = TMax ExternInitData%TurbineID = TurbID ExternInitData%TurbinePos = TurbPosn ExternInitData%SensorType = SensorType_None ExternInitData%NumCtrl2SC = NumCtrl2SC ExternInitData%NumSC2CtrlGlob = NumSC2CtrlGlob - + if ( NumSC2CtrlGlob > 0 ) then CALL AllocAry( ExternInitData%fromSCGlob, NumSC2CtrlGlob, 'ExternInitData%fromSCGlob', ErrStat, ErrMsg) IF (FAILED()) RETURN @@ -571,7 +678,7 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, NumSC2CtrlGlo ExternInitData%fromSCGlob(i) = InitScOutputsGlob(i) end do end if - + ExternInitData%NumSC2Ctrl = NumSC2Ctrl if ( NumSC2Ctrl > 0 ) then CALL AllocAry( ExternInitData%fromSC, NumSC2Ctrl, 'ExternInitData%fromSC', ErrStat, ErrMsg) @@ -581,167 +688,340 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, NumSC2CtrlGlo ExternInitData%fromSC(i) = InitScOutputsTurbine(i) end do end if - + ExternInitData%NumActForcePtsBlade = NumActForcePtsBlade ExternInitData%NumActForcePtsTower = NumActForcePtsTower + ExternInitData%DTdriver = dtDriver_c - ExternInitData%NodeClusterType = NodeClusterType_c - - CALL FAST_InitializeAll_T( t_initial, iTurb, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) + CALL FAST_InitializeAll_T( t_initial, 1_IntKi, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) ! set values for return to ExternalInflow - AbortErrLev_c = AbortErrLev - dt_c = Turbine(iTurb)%p_FAST%dt - ErrStat_c = ErrStat - ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR - ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - - IF ( ErrStat >= AbortErrLev ) THEN - CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) - RETURN - END IF - + if (ErrStat .ne. ErrID_None) then + AbortErrLev_c = AbortErrLev + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( TRIM(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if + + dt_c = Turbine(iTurb)%p_FAST%dt + + InflowType = Turbine(iTurb)%p_FAST%CompInflow + + if ( (InflowType == 3) .and. (NumActForcePtsBlade .eq. 0) .and. (NumActForcePtsTower .eq. 0) ) then + CALL SetErrStat(ErrID_Warn, "Number of actuator points is zero when inflow type is 2. Mapping of loads may not work. ", ErrStat, ErrMsg, RoutineName ) + end if + + if ( (InflowType .ne. 3) .and. ((NumActForcePtsBlade .ne. 0) .or. (NumActForcePtsTower .ne. 0)) ) then + !!FAST reassigns CompInflow after reading it to a module number based on an internal list in the FAST_Registry. So 2 in input file becomes 3 inside the code. + CALL SetErrStat(ErrID_Fatal, "Number of requested actuator points is non-zero when inflow type is not 2. Please set number of actuator points to zero when induction is turned on.", ErrStat, ErrMsg, RoutineName ) + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if + call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) - - ! 7-Sep-2015: Sang wants these integers for the ExternalInflow mapping, which is tied to the AeroDyn nodes. FAST doesn't restrict the number of nodes on each - ! blade mesh to be the same, so if this DOES ever change, we'll need to make ExternalInflow less tied to the AeroDyn mapping. - IF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD14) THEN + + ! 7-Sep-2015: OpenFAST doesn't restrict the number of nodes on each blade mesh to be the same, so if this DOES ever change, + ! we'll need to make ExternalInflow less tied to the AeroDyn mapping. + IF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD14) THEN NumBl_c = SIZE(Turbine(iTurb)%AD14%Input(1)%InputMarkers) NumBlElem_c = Turbine(iTurb)%AD14%Input(1)%InputMarkers(1)%Nnodes + NumTwrElem_c = 0 ! Don't care about Aerodyn14 anymore ELSEIF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD) THEN - IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors)) THEN - IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion)) THEN - NumBl_c = SIZE(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion) - END IF - END IF - IF (NumBl_c > 0) THEN - NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes - END IF + NumBl_c = SIZE(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion) + NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes + NumTwrElem_c = Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Nnodes + ELSE + NumBl_c = 0 + NumBlElem_c = 0 + NumTwrElem_c = 0 END IF - -contains + + OutFileRoot_c = TRANSFER( trim(Turbine(iTurb)%p_FAST%OutFileRoot)//C_NULL_CHAR, OutFileRoot_c ) + + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + + contains LOGICAL FUNCTION FAILED() - - FAILED = ErrStat >= AbortErrLev - - IF (ErrStat > 0) THEN - CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) - - IF ( FAILED ) THEN - - AbortErrLev_c = AbortErrLev - ErrStat_c = ErrStat - ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR - ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - - !IF (ALLOCATED(Turbine)) DEALLOCATE(Turbine) - ! bjj: if there is an error, the driver should call FAST_DeallocateTurbines() instead of putting this deallocate statement here - END IF - END IF - - + + FAILED = ErrStat >= AbortErrLev + + IF (ErrStat > 0) THEN + CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) + + IF ( FAILED ) THEN + + AbortErrLev_c = AbortErrLev + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + + !IF (ALLOCATED(Turbine)) DEALLOCATE(Turbine) + ! bjj: if there is an error, the driver should call FAST_DeallocateTurbines() instead of putting this deallocate statement here + END IF + END IF + + END FUNCTION FAILED -end subroutine + +end subroutine FAST_AL_CFD_Init !================================================================================================================================== -subroutine FAST_ExtInfw_Solution0(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtInfw_Solution0') +subroutine FAST_CFD_Solution0(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Solution0') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Solution0 -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Solution0 +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Solution0 +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Solution0 #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - call FAST_Solution0_T(Turbine(iTurb), ErrStat, ErrMsg ) + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_CFD_Solution0' + + call FAST_Solution0_T(Turbine(iTurb), ErrStat, ErrMsg ) ! if(Turbine(iTurb)%SC_DX%p%useSC) then ! CALL SC_SetInputs(Turbine(iTurb)%p_FAST, Turbine(iTurb)%SrvD%y, Turbine(iTurb)%SC_DX, ErrStat, ErrMsg) ! end if - + + ! set values for return to ExternalInflow + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg, ErrMsg_c ) + +end subroutine FAST_CFD_Solution0 +!================================================================================================================================== +subroutine FAST_CFD_InitIOarrays_SS(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_InitIOarrays_SS') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_InitIOarrays_SS + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_InitIOarrays_SS +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + call FAST_InitIOarrays_SS_T(t_initial, Turbine(iTurb), ErrStat, ErrMsg ) + ! set values for return to ExternalInflow ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - - -end subroutine FAST_ExtInfw_Solution0 + +end subroutine FAST_CFD_InitIOarrays_SS !================================================================================================================================== -subroutine FAST_ExtInfw_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, numblades_c, numElementsPerBlade_c, n_t_global_c, & - ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtInfw_Restart') +subroutine FAST_AL_CFD_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, InflowType, numblades_c, & + numElementsPerBlade_c, numElementsTower_c, n_t_global_c, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, & + SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_AL_CFD_Restart') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_AL_CFD_Restart IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Restart -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Restart +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_AL_CFD_Restart +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_AL_CFD_Restart #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) - INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c - INTEGER(C_INT), INTENT( OUT) :: numblades_c - INTEGER(C_INT), INTENT( OUT) :: numElementsPerBlade_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_c - INTEGER(C_INT), INTENT( OUT) :: n_t_global_c - TYPE(ExtInfw_InputType_C), INTENT(INOUT) :: ExtInfw_Input_from_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes - TYPE(ExtInfw_OutputType_C),INTENT(INOUT) :: ExtInfw_Output_to_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT( OUT) :: numblades_c + INTEGER(C_INT), INTENT( OUT) :: numElementsPerBlade_c + INTEGER(C_INT), INTENT( OUT) :: numElementsTower_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: InflowType + INTEGER(C_INT), INTENT( OUT) :: n_t_global_c + TYPE(ExtInfw_InputType_C), INTENT( OUT) :: ExtInfw_Input_from_FAST + TYPE(ExtInfw_OutputType_C),INTENT( OUT) :: ExtInfw_Output_to_FAST TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local variables - INTEGER(C_INT) :: NumOuts_c - CHARACTER(IntfStrLen) :: CheckpointRootName + INTEGER(C_INT) :: NumOuts_c + CHARACTER(IntfStrLen) :: CheckpointRootName INTEGER(IntKi) :: I INTEGER(IntKi) :: Unit REAL(DbKi) :: t_initial_out INTEGER(IntKi) :: NumTurbines_out - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' - + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' + CALL NWTC_Init() - ! transfer the character array from C to a Fortran string: + ! transfer the character array from C to a Fortran string: CheckpointRootName = TRANSFER( CheckpointRootName_c, CheckpointRootName ) I = INDEX(CheckpointRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) CheckpointRootName = CheckpointRootName(1:I) ! remove it - + Unit = -1 CALL FAST_RestoreFromCheckpoint_T(t_initial_out, n_t_global, NumTurbines_out, Turbine(iTurb), CheckpointRootName, ErrStat, ErrMsg, Unit ) - + ! check that these are valid: IF (t_initial_out /= t_initial) CALL SetErrStat(ErrID_Fatal, "invalid value of t_initial.", ErrStat, ErrMsg, RoutineName ) IF (NumTurbines_out /= 1) CALL SetErrStat(ErrID_Fatal, "invalid value of NumTurbines.", ErrStat, ErrMsg, RoutineName ) - - ! transfer Fortran variables to C: + + ! transfer Fortran variables to C: n_t_global_c = n_t_global - AbortErrLev_c = AbortErrLev - NumOuts_c = min(MAXOUTPUTS, SUM( Turbine(iTurb)%y_FAST%numOuts )) ! includes time + AbortErrLev_c = AbortErrLev + NumOuts_c = min(MAXOUTPUTS, 1 + SUM( Turbine(iTurb)%y_FAST%numOuts )) ! includes time + if (allocated(Turbine(iTurb)%ad%p%rotors)) then ! this might not be allocated if we had an error earlier numBlades_c = Turbine(iTurb)%ad%p%rotors(1)%numblades numElementsPerBlade_c = Turbine(iTurb)%ad%p%rotors(1)%numblnds ! I'm not sure if FASTv8 can handle different number of blade nodes for each blade. + numElementsTower_c = Turbine(iTurb)%ad%y%rotors(1)%TowerLoad%Nnodes else numBlades_c = 0 numElementsPerBlade_c = 0 + numElementsTower_c = 0 end if - - dt_c = Turbine(iTurb)%p_FAST%dt - + + dt_c = Turbine(iTurb)%p_FAST%dt + ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -#ifdef CONSOLE_FILE - if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) -#endif +#ifdef CONSOLE_FILE + if (ErrStat .ne. ErrID_None) call wrscr1(trim(ErrMsg)) +#endif if (ErrStat >= AbortErrLev) return - + + call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) + + InflowType = Turbine(iTurb)%p_FAST%CompInflow + + if (ErrStat .ne. ErrID_None) then + call wrscr1(trim(ErrMsg)) + return + end if + + if (dt_c == Turbine(iTurb)%p_FAST%dt) then + CALL SetErrStat(ErrID_Fatal, "Time step specified in C++ API does not match with time step specified in OpenFAST input file.", ErrStat, ErrMsg, RoutineName ) + return + end if + call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) -end subroutine FAST_ExtInfw_Restart +end subroutine FAST_AL_CFD_Restart + +!================================================================================================================================== +subroutine FAST_BR_CFD_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, numblades_c, & + n_t_global_c, ExtLd_Input_from_FAST, ExtLd_Output_to_FAST, & + SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_BR_CFD_Restart') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_BR_CFD_Restart + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Restart +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Restart +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT( OUT) :: numblades_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: n_t_global_c + TYPE(ExtLdDX_InputType_C), INTENT( OUT) :: ExtLd_Input_from_FAST + TYPE(ExtLdDX_OutputType_C),INTENT( OUT) :: ExtLd_Output_to_FAST + TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST + TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + ! local variables + INTEGER(C_INT) :: NumOuts_c + CHARACTER(IntfStrLen) :: CheckpointRootName + INTEGER(IntKi) :: I + INTEGER(IntKi) :: Unit + REAL(DbKi) :: t_initial_out + INTEGER(IntKi) :: NumTurbines_out + INTEGER(IntKi) :: CompLoadsType + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' + + CALL NWTC_Init() + ! transfer the character array from C to a Fortran string: + CheckpointRootName = TRANSFER( CheckpointRootName_c, CheckpointRootName ) + I = INDEX(CheckpointRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + IF ( I > 0 ) CheckpointRootName = CheckpointRootName(1:I) ! remove it + + Unit = -1 + CALL FAST_RestoreFromCheckpoint_T(t_initial_out, n_t_global, NumTurbines_out, Turbine(iTurb), CheckpointRootName, ErrStat, ErrMsg, Unit ) + + if (ErrStat .ne. ErrID_None) then + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if + + ! check that these are valid: + IF (t_initial_out /= t_initial) CALL SetErrStat(ErrID_Fatal, "invalid value of t_initial.", ErrStat, ErrMsg, RoutineName ) + IF (NumTurbines_out /= 1) CALL SetErrStat(ErrID_Fatal, "invalid value of NumTurbines.", ErrStat, ErrMsg, RoutineName ) + + ! transfer Fortran variables to C: + n_t_global_c = n_t_global + AbortErrLev_c = AbortErrLev + NumOuts_c = min(MAXOUTPUTS, 1 + SUM( Turbine(iTurb)%y_FAST%numOuts )) ! includes time + numblades_c = Turbine(iTurb)%ED%p%NumBl + dt_c = Turbine(iTurb)%p_FAST%dt + +#ifdef CONSOLE_FILE + if (ErrStat .ne. ErrID_None) call wrscr1(trim(ErrMsg)) +#endif + + CompLoadsType = Turbine(iTurb)%p_FAST%CompAero + + if ( (CompLoadsType .ne. Module_ExtLd) ) then + CALL SetErrStat(ErrID_Fatal, "CompAero is not set to 3 for use of the External Loads module. Use a different initialization call for this turbine.", ErrStat, ErrMsg, RoutineName ) + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if + + write(*,*) 'Finished restoring OpenFAST from checkpoint' + call SetExtLoads_pointers(iTurb, ExtLd_Input_from_FAST, ExtLd_Output_to_FAST) + + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + +end subroutine FAST_BR_CFD_Restart +!================================================================================================================================== +subroutine SetExtLoads_pointers(iTurb, ExtLd_iFromOF, ExtLd_oToOF) + + IMPLICIT NONE + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + TYPE(ExtLdDX_InputType_C), INTENT(INOUT) :: ExtLd_iFromOF + TYPE(ExtLdDX_OutputType_C),INTENT(INOUT) :: ExtLd_oToOF + + ExtLd_iFromOF%bldPitch_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch_Len; ExtLd_iFromOF%bldPitch = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch + ExtLd_iFromOF%twrHloc_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrHloc_Len; ExtLd_iFromOF%twrHloc = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrHloc + ExtLd_iFromOF%twrDia_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDia_Len; ExtLd_iFromOF%twrDia = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDia + ExtLd_iFromOF%twrRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrRefPos_Len; ExtLd_iFromOF%twrRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrRefPos + ExtLd_iFromOF%twrDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDef_Len; ExtLd_iFromOF%twrDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDef + ExtLd_iFromOF%bldRloc_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRloc_Len; ExtLd_iFromOF%bldRloc = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRloc + ExtLd_iFromOF%bldChord_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldChord_Len; ExtLd_iFromOF%bldChord = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldChord + ExtLd_iFromOF%bldRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRefPos_Len; ExtLd_iFromOF%bldRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRefPos + ExtLd_iFromOF%bldRootRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootRefPos_Len; ExtLd_iFromOF%bldRootRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootRefPos + ExtLd_iFromOF%bldDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef_Len; ExtLd_iFromOF%bldDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef + ExtLd_iFromOF%nBlades_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBlades_Len; ExtLd_iFromOF%nBlades = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBlades + ExtLd_iFromOF%nBladeNodes_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBladeNodes_Len; ExtLd_iFromOF%nBladeNodes = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBladeNodes + ExtLd_iFromOF%nTowerNodes_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nTowerNodes_Len; ExtLd_iFromOF%nTowerNodes = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nTowerNodes + + ExtLd_iFromOF%bldRootDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef_Len; ExtLd_iFromOF%bldRootDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef + + ExtLd_iFromOF%hubRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubRefPos_Len; ExtLd_iFromOF%hubRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubRefPos + ExtLd_iFromOF%hubDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubDef_Len; ExtLd_iFromOF%hubDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubDef + + ExtLd_iFromOF%nacRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacRefPos_Len; ExtLd_iFromOF%nacRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacRefPos + ExtLd_iFromOF%nacDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef_Len; ExtLd_iFromOF%nacDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef + + ExtLd_oToOF%twrLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd_Len; ExtLd_oToOF%twrLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd + ExtLd_oToOF%bldLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd_Len; ExtLd_oToOF%bldLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd + + end subroutine SetExtLoads_pointers + !================================================================================================================================== subroutine SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) IMPLICIT NONE - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number TYPE(ExtInfw_InputType_C), INTENT(INOUT) :: ExtInfw_Input_from_FAST TYPE(ExtInfw_OutputType_C),INTENT(INOUT) :: ExtInfw_Output_to_FAST TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST @@ -750,12 +1030,15 @@ subroutine SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Ou ExtInfw_Input_from_FAST%pxVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxVel_Len; ExtInfw_Input_from_FAST%pxVel = Turbine(iTurb)%ExtInfw%u%c_obj%pxVel ExtInfw_Input_from_FAST%pyVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyVel_Len; ExtInfw_Input_from_FAST%pyVel = Turbine(iTurb)%ExtInfw%u%c_obj%pyVel ExtInfw_Input_from_FAST%pzVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzVel_Len; ExtInfw_Input_from_FAST%pzVel = Turbine(iTurb)%ExtInfw%u%c_obj%pzVel + ExtInfw_Input_from_FAST%pxDotVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotVel_Len; ExtInfw_Input_from_FAST%pxDotVel = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotVel + ExtInfw_Input_from_FAST%pyDotVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotVel_Len; ExtInfw_Input_from_FAST%pyDotVel = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotVel + ExtInfw_Input_from_FAST%pzDotVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotVel_Len; ExtInfw_Input_from_FAST%pzDotVel = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotVel ExtInfw_Input_from_FAST%pxForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxForce_Len; ExtInfw_Input_from_FAST%pxForce = Turbine(iTurb)%ExtInfw%u%c_obj%pxForce ExtInfw_Input_from_FAST%pyForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyForce_Len; ExtInfw_Input_from_FAST%pyForce = Turbine(iTurb)%ExtInfw%u%c_obj%pyForce ExtInfw_Input_from_FAST%pzForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzForce_Len; ExtInfw_Input_from_FAST%pzForce = Turbine(iTurb)%ExtInfw%u%c_obj%pzForce - ExtInfw_Input_from_FAST%xdotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%xdotForce_Len; ExtInfw_Input_from_FAST%xdotForce = Turbine(iTurb)%ExtInfw%u%c_obj%xdotForce - ExtInfw_Input_from_FAST%ydotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%ydotForce_Len; ExtInfw_Input_from_FAST%ydotForce = Turbine(iTurb)%ExtInfw%u%c_obj%ydotForce - ExtInfw_Input_from_FAST%zdotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%zdotForce_Len; ExtInfw_Input_from_FAST%zdotForce = Turbine(iTurb)%ExtInfw%u%c_obj%zdotForce + ExtInfw_Input_from_FAST%pxDotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotForce_Len; ExtInfw_Input_from_FAST%pxDotForce = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotForce + ExtInfw_Input_from_FAST%pyDotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotForce_Len; ExtInfw_Input_from_FAST%pyDotForce = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotForce + ExtInfw_Input_from_FAST%pzDotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotForce_Len; ExtInfw_Input_from_FAST%pzDotForce = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotForce ExtInfw_Input_from_FAST%pOrientation_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pOrientation_Len; ExtInfw_Input_from_FAST%pOrientation = Turbine(iTurb)%ExtInfw%u%c_obj%pOrientation ExtInfw_Input_from_FAST%fx_Len = Turbine(iTurb)%ExtInfw%u%c_obj%fx_Len; ExtInfw_Input_from_FAST%fx = Turbine(iTurb)%ExtInfw%u%c_obj%fx ExtInfw_Input_from_FAST%fy_Len = Turbine(iTurb)%ExtInfw%u%c_obj%fy_Len; ExtInfw_Input_from_FAST%fy = Turbine(iTurb)%ExtInfw%u%c_obj%fy @@ -764,6 +1047,7 @@ subroutine SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Ou ExtInfw_Input_from_FAST%momenty_Len = Turbine(iTurb)%ExtInfw%u%c_obj%momenty_Len; ExtInfw_Input_from_FAST%momenty = Turbine(iTurb)%ExtInfw%u%c_obj%momenty ExtInfw_Input_from_FAST%momentz_Len = Turbine(iTurb)%ExtInfw%u%c_obj%momentz_Len; ExtInfw_Input_from_FAST%momentz = Turbine(iTurb)%ExtInfw%u%c_obj%momentz ExtInfw_Input_from_FAST%forceNodesChord_Len = Turbine(iTurb)%ExtInfw%u%c_obj%forceNodesChord_Len; ExtInfw_Input_from_FAST%forceNodesChord = Turbine(iTurb)%ExtInfw%u%c_obj%forceNodesChord + ExtInfw_Input_from_FAST%forceRHloc_Len = Turbine(iTurb)%ExtInfw%u%c_obj%forceRHloc_Len; ExtInfw_Input_from_FAST%forceRHloc = Turbine(iTurb)%ExtInfw%u%c_obj%forceRHloc if (Turbine(iTurb)%p_FAST%UseSC) then SC_DX_Input_from_FAST%toSC_Len = Turbine(iTurb)%SC_DX%u%c_obj%toSC_Len @@ -781,47 +1065,236 @@ subroutine SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Ou end subroutine SetExternalInflow_pointers !================================================================================================================================== -subroutine FAST_ExtInfw_Step(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtInfw_Step') +subroutine FAST_CFD_Prework(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Prework') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_Prework IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Step -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Step +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Prework #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - - - IF ( n_t_global > Turbine(iTurb)%p_FAST%n_TMax_m1 ) THEN !finish - + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + + IF ( n_t_global > Turbine(iTurb)%p_FAST%n_TMax_m1 ) THEN !finish + ! we can't continue because we might over-step some arrays that are allocated to the size of the simulation - + if (iTurb .eq. (NumTurbines-1) ) then IF (n_t_global == Turbine(iTurb)%p_FAST%n_TMax_m1 + 1) THEN ! we call update an extra time in Simulink, which we can ignore until the time shift with outputs is solved n_t_global = n_t_global + 1 ErrStat_c = ErrID_None ErrMsg = C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - ELSE + ELSE ErrStat_c = ErrID_Info ErrMsg = "Simulation completed."//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) END IF end if - + ELSE - CALL FAST_Solution_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + ! if(Turbine(iTurb)%SC%p%scOn) then + ! CALL SC_SetOutputs(Turbine(iTurb)%p_FAST, Turbine(iTurb)%SrvD%Input(1), Turbine(iTurb)%SC, ErrStat, ErrMsg) + ! end if + + CALL FAST_Prework_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + END IF + +end subroutine FAST_CFD_Prework +!================================================================================================================================== +subroutine FAST_CFD_UpdateStates(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_UpdateStates') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_UpdateStates + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_UpdateStates +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + + IF ( n_t_global > Turbine(iTurb)%p_FAST%n_TMax_m1 ) THEN !finish + + ! we can't continue because we might over-step some arrays that are allocated to the size of the simulation + + if (iTurb .eq. (NumTurbines-1) ) then + IF (n_t_global == Turbine(iTurb)%p_FAST%n_TMax_m1 + 1) THEN ! we call update an extra time in Simulink, which we can ignore until the time shift with outputs is solved + n_t_global = n_t_global + 1 + ErrStat_c = ErrID_None + ErrMsg = C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + ELSE + ErrStat_c = ErrID_Info + ErrMsg = "Simulation completed."//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + END IF + end if + + ELSE + + CALL FAST_UpdateStates_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + END IF + +end subroutine FAST_CFD_UpdateStates +!================================================================================================================================== +subroutine FAST_CFD_AdvanceToNextTimeStep(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_AdvanceToNextTimeStep') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_AdvanceToNextTimeStep + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_AdvanceToNextTimeStep +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + + IF ( n_t_global > Turbine(iTurb)%p_FAST%n_TMax_m1 ) THEN !finish + + ! we can't continue because we might over-step some arrays that are allocated to the size of the simulation + + if (iTurb .eq. (NumTurbines-1) ) then + IF (n_t_global == Turbine(iTurb)%p_FAST%n_TMax_m1 + 1) THEN ! we call update an extra time in Simulink, which we can ignore until the time shift with outputs is solved + n_t_global = n_t_global + 1 + ErrStat_c = ErrID_None + ErrMsg = C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + ELSE + ErrStat_c = ErrID_Info + ErrMsg = "Simulation completed."//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + END IF + end if + + ELSE + + CALL FAST_AdvanceToNextTimeStep_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + + ! if(Turbine(iTurb)%SC%p%scOn) then + ! CALL SC_SetInputs(Turbine(iTurb)%p_FAST, Turbine(iTurb)%SrvD%y, Turbine(iTurb)%SC, ErrStat, ErrMsg) + ! end if + if (iTurb .eq. (NumTurbines-1) ) then n_t_global = n_t_global + 1 end if - + ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) END IF - - -end subroutine FAST_ExtInfw_Step -!================================================================================================================================== + + +end subroutine FAST_CFD_AdvanceToNextTimeStep +!================================================================================================================================== +subroutine FAST_CFD_WriteOutput(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_WriteOutput') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_WriteOutput + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_WriteOutput +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + CALL FAST_WriteOutput_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + +end subroutine FAST_CFD_WriteOutput +!================================================================================================================================== +subroutine FAST_CFD_Step(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Step') + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Step +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Step +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + + IF ( n_t_global > Turbine(iTurb)%p_FAST%n_TMax_m1 ) THEN !finish + + ! we can't continue because we might over-step some arrays that are allocated to the size of the simulation + + if (iTurb .eq. (NumTurbines-1) ) then + IF (n_t_global == Turbine(iTurb)%p_FAST%n_TMax_m1 + 1) THEN ! we call update an extra time in Simulink, which we can ignore until the time shift with outputs is solved + n_t_global = n_t_global + 1 + ErrStat_c = ErrID_None + ErrMsg = C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + ELSE + ErrStat_c = ErrID_Info + ErrMsg = "Simulation completed."//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + END IF + end if + + ELSE + + CALL FAST_Solution_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + + if (iTurb .eq. (NumTurbines-1) ) then + n_t_global = n_t_global + 1 + end if + + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + END IF + + +end subroutine FAST_CFD_Step +!================================================================================================================================== +subroutine FAST_CFD_Reset_SS(iTurb, n_timesteps, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Reset_SS') + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT + !DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Reset_SS + !GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Reset_SS +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT(IN ) :: n_timesteps ! Number of time steps to go back + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + CALL FAST_Reset_SS_T(t_initial, n_t_global-n_timesteps, n_timesteps, Turbine(iTurb), ErrStat, ErrMsg ) + + if (iTurb .eq. (NumTurbines-1) ) then + n_t_global = n_t_global - n_timesteps + end if + + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + + +end subroutine FAST_CFD_Reset_SS +!================================================================================================================================== +subroutine FAST_CFD_Store_SS(iTurb, n_t_global, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Store_SS') + IMPLICIT NONE +#ifndef IMPLICIT_DLLEXPORT + !DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Store_SS + !GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Store_SS +#endif + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT(IN ) :: n_t_global !< loop counter + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + + CALL FAST_Store_SS_T(t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + + +end subroutine FAST_CFD_Store_SS +!================================================================================================================================== END MODULE FAST_Data diff --git a/modules/openfast-library/src/FAST_Library.h b/modules/openfast-library/src/FAST_Library.h index 779aba9456..aa8ccb6005 100644 --- a/modules/openfast-library/src/FAST_Library.h +++ b/modules/openfast-library/src/FAST_Library.h @@ -3,6 +3,7 @@ // routines in FAST_Library_$(PlatformName).dll #include "ExternalInflow_Types.h" +#include "ExtLoadsDX_Types.h" #include "SCDataEx_Types.h" #include "stdio.h" @@ -15,13 +16,33 @@ EXTERNAL_ROUTINE void FAST_AllocateTurbines(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_DeallocateTurbines(int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_ExtInfw_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * NumBlElem, int * n_t_global, - ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_ExtInfw_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, int * NumSC2CtrlGlob, int * NumSC2Ctrl, int * NumCtrl2SC, float * initSCInputsGlob, float * initSCInputsTurbine, int * NumActForcePtsBlade, int * NumActForcePtsTower, float * TurbinePosition, - int *AbortErrLev, double * dt, int * NumBl, int * NumBlElem, int * NodeClusterType, ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, - int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_ExtInfw_Solution0(int * iTurb, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_ExtInfw_Step(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_AL_CFD_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, + double * dt, int * InflowType, int * NumBl, int * NumBlElem, int * NumTwrElem, int * n_t_global, + ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, + SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, + int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_AL_CFD_Init(int * iTurb, double *TMax, const char *InputFileName, + int * TurbineID, char *OutFileRoot, + int * NumSC2CtrlGlob, int * NumSC2Ctrl, int * NumCtrl2SC, + float * initSCInputsGlob, float * initSCInputsTurbine, + int * NumActForcePtsBlade, int * NumActForcePtsTower, float * TurbinePosition, + int *AbortErrLev, double * dtDriver, double * dt, int * InflowType, + int * NumBl, int * NumBlElem, int * NumTwrElem, + ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, + SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, + int *ErrStat, char *ErrMsg); + +EXTERNAL_ROUTINE void FAST_BR_CFD_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * n_t_global, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_BR_CFD_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, char *OutFileRoot, float * TurbinePosition, int *AbortErrLev, double * dtDriver, double * dt, int * NumBl, double * az_blend_mean, double * az_blend_delta, double * vel_mean, double * wind_dir, double * z_ref, double * shear_exp, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_Solution0(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_InitIOarrays_SS(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_Prework(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_UpdateStates(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_AdvanceToNextTimeStep(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_WriteOutput(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_Step(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_Reset_SS(int * iTurb, int * n_timesteps, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_Store_SS(int * iTurb, int * n_t_global, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_HubPosition(int * iTurb, float * absolute_position, float * rotation_veocity, double * orientation_dcm, int *ErrStat, char *ErrMsg); diff --git a/modules/openfast-library/src/FAST_Mods.f90 b/modules/openfast-library/src/FAST_Mods.f90 index e223e39268..fd0fadb776 100644 --- a/modules/openfast-library/src/FAST_Mods.f90 +++ b/modules/openfast-library/src/FAST_Mods.f90 @@ -38,6 +38,8 @@ MODULE FAST_ModTypes ! state array indexes INTEGER(IntKi), PARAMETER :: STATE_CURR = 1 !< index for "current" (t_global) states INTEGER(IntKi), PARAMETER :: STATE_PRED = 2 !< index for "predicted" (t_global_next) states + INTEGER(IntKi), PARAMETER :: STATE_SS_CURR = 3 + INTEGER(IntKi), PARAMETER :: STATE_SS_PRED = 4 ! VTK visualization INTEGER(IntKi), PARAMETER :: VTK_Unknown = -1 !< unknown option (will produce error) diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index c172b99d88..c83136a7e4 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -16,6 +16,7 @@ usefrom Registry_BeamDyn.txt usefrom ServoDyn_Registry.txt usefrom Registry-AD14.txt usefrom AeroDyn_Registry.txt +usefrom ExtLoads_Registry.txt usefrom SubDyn_Registry.txt usefrom SeaState.txt usefrom HydroDyn.txt @@ -39,23 +40,24 @@ param FAST - INTEGER Module_Unknown - -1 - "Unknown" - param ^ - INTEGER Module_None - 0 - "No module selected" - param ^ - INTEGER Module_Glue - 1 - "Glue code" - param ^ - INTEGER Module_IfW - 2 - "InflowWind" - -param ^ - INTEGER Module_ExtInfw - 3 "ExternalInflow" - +param ^ - INTEGER Module_ExtInfw - 3 - "ExternalInflow" - param ^ - INTEGER Module_ED - 4 - "ElastoDyn" - param ^ - INTEGER Module_BD - 5 - "BeamDyn" - param ^ - INTEGER Module_AD14 - 6 - "AeroDyn14" - param ^ - INTEGER Module_AD - 7 - "AeroDyn" - -param ^ - INTEGER Module_SrvD - 8 - "ServoDyn" - -param ^ - INTEGER Module_SeaSt - 9 - "SeaState" - -param ^ - INTEGER Module_HD - 10 - "HydroDyn" - -param ^ - INTEGER Module_SD - 11 - "SubDyn" - -param ^ - INTEGER Module_ExtPtfm - 12 - "External Platform Loading MCKF" - -param ^ - INTEGER Module_MAP - 13 - "MAP (Mooring Analysis Program)" - -param ^ - INTEGER Module_FEAM - 14 - "FEAMooring" - -param ^ - INTEGER Module_MD - 15 - "MoorDyn" - -param ^ - INTEGER Module_Orca - 16 - "OrcaFlex integration (HD/Mooring)" - -param ^ - INTEGER Module_IceF - 17 - "IceFloe" - -param ^ - INTEGER Module_IceD - 18 - "IceDyn" - -param ^ - INTEGER NumModules - 18 - "The number of modules available in FAST" - +param ^ - INTEGER Module_ExtLd - 8 - "AeroDyn" - +param ^ - INTEGER Module_SrvD - 9 - "ServoDyn" - +param ^ - INTEGER Module_SeaSt - 10 - "SeaState" - +param ^ - INTEGER Module_HD - 11 - "HydroDyn" - +param ^ - INTEGER Module_SD - 12 - "SubDyn" - +param ^ - INTEGER Module_ExtPtfm - 13 - "External Platform Loading MCKF" - +param ^ - INTEGER Module_MAP - 14 - "MAP (Mooring Analysis Program)" - +param ^ - INTEGER Module_FEAM - 15 - "FEAMooring" - +param ^ - INTEGER Module_MD - 16 - "MoorDyn" - +param ^ - INTEGER Module_Orca - 17 - "OrcaFlex integration (HD/Mooring)" - +param ^ - INTEGER Module_IceF - 18 - "IceFloe" - +param ^ - INTEGER Module_IceD - 19 - "IceDyn" - +param ^ - INTEGER NumModules - 20 - "The number of modules available in FAST" - # Other Constants param ^ - INTEGER MaxNBlades - 3 - "Maximum number of blades allowed on a turbine" - param ^ - INTEGER IceD_MaxLegs - 4 - "because I don't know how many legs there are before calling IceD_Init and I don't want to copy the data because of sibling mesh issues, I'm going to allocate IceD based on this number" - @@ -377,7 +379,9 @@ typedef ^ ^ IceD_InputType u {:} - - "System inputs" typedef ^ ^ IceD_OutputType y {:} - - "System outputs" typedef ^ ^ IceD_MiscVarType m {:} - - "Misc/optimization variables" typedef ^ ^ IceD_InputType Input {:}{:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ IceD_InputType Input_bak {:}{:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:}{:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:}{:} - - "Backup Array of times associated with Input Array" # ..... BeamDyn data ....................................................................................................... # [ the last dimension of each allocatable array is for the instance of BeamDyn being used ] @@ -393,54 +397,64 @@ typedef ^ ^ BD_MiscVarType m {:} - - "Misc/optimization variables" typedef ^ ^ BD_OutputType Output {:}{:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ BD_OutputType y_interp {:} - - "interpolated system outputs for CalcSteady" typedef ^ ^ BD_InputType Input {:}{:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ BD_InputType Input_bak {:}{:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:}{:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:}{:} - - "Backup Array of times associated with Input Array" # ..... ElastoDyn data ....................................................................................................... -typedef FAST ElastoDyn_Data ED_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ ED_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ ED_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ ED_OtherStateType OtherSt {2} - - "Other states" +typedef FAST ElastoDyn_Data ED_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ ED_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ ED_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ ED_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ ED_ParameterType p - - - "Parameters" typedef ^ ^ ED_InputType u - - - "System inputs" typedef ^ ^ ED_OutputType y - - - "System outputs" typedef ^ ^ ED_MiscVarType m - - - "Misc (optimization) variables not associated with time" typedef ^ ^ ED_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" +typedef ^ ^ ED_OutputType Output_bak {:} - - "Backup Array of outputs associated with InputTimes" typedef ^ ^ ED_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ ED_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ ED_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... ServoDyn data ....................................................................................................... -typedef FAST ServoDyn_Data SrvD_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ SrvD_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ SrvD_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ SrvD_OtherStateType OtherSt {2} - - "Other states" +typedef FAST ServoDyn_Data SrvD_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ SrvD_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ SrvD_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ SrvD_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ SrvD_ParameterType p - - - "Parameters" typedef ^ ^ SrvD_InputType u - - - "System inputs" typedef ^ ^ SrvD_OutputType y - - - "System outputs" typedef ^ ^ SrvD_MiscVarType m - - - "Misc (optimization) variables not associated with time" +typedef ^ ^ SrvD_MiscVarType m_bak - - - "Backup Misc (optimization) variables not associated with time" typedef ^ ^ SrvD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ SrvD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ SrvD_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ SrvD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... AeroDyn14 data ....................................................................................................... -typedef FAST AeroDyn14_Data AD14_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ AD14_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ AD14_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ AD14_OtherStateType OtherSt {2} - - "Other states" +typedef FAST AeroDyn14_Data AD14_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ AD14_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ AD14_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ AD14_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ AD14_ParameterType p - - - "Parameters" typedef ^ ^ AD14_InputType u - - - "System inputs" typedef ^ ^ AD14_OutputType y - - - "System outputs" typedef ^ ^ AD14_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ AD14_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ AD14_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... AeroDyn data ....................................................................................................... -typedef FAST AeroDyn_Data AD_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ AD_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ AD_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ AD_OtherStateType OtherSt {2} - - "Other states" +typedef FAST AeroDyn_Data AD_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ AD_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ AD_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ AD_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ AD_ParameterType p - - - "Parameters" typedef ^ ^ AD_InputType u - - - "System inputs" typedef ^ ^ AD_OutputType y - - - "System outputs" @@ -448,13 +462,26 @@ typedef ^ ^ AD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ AD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ AD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ AD_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ AD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" + +# ..... ExtLoads data ....................................................................................................... +typedef FAST ExtLoads_Data ExtLd_ContinuousStateType x {2} - - "Continuous states" +typedef ^ ^ ExtLd_DiscreteStateType xd {2} - - "Discrete states" +typedef ^ ^ ExtLd_ConstraintStateType z {2} - - "Constraint states" +typedef ^ ^ ExtLd_OtherStateType OtherSt {2} - - "Other states" +typedef ^ ^ ExtLd_ParameterType p - - - "Parameters" +typedef ^ ^ ExtLd_InputType u - - - "System inputs" +typedef ^ ^ ExtLd_OutputType y - - - "System outputs" +typedef ^ ^ ExtLd_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" # ..... InflowWind data ....................................................................................................... -typedef FAST InflowWind_Data InflowWind_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ InflowWind_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ InflowWind_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ InflowWind_OtherStateType OtherSt {2} - - "Other states" +typedef FAST InflowWind_Data InflowWind_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ InflowWind_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ InflowWind_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ InflowWind_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ InflowWind_ParameterType p - - - "Parameters" typedef ^ ^ InflowWind_InputType u - - - "System inputs" typedef ^ ^ InflowWind_OutputType y - - - "System outputs" @@ -462,7 +489,9 @@ typedef ^ ^ InflowWind_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ InflowWind_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ InflowWind_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ InflowWind_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ InflowWind_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... ExternalInflow integration data ....................................................................................................... typedef FAST ExternalInflow_Data ExtInfw_InputType u - - - "System inputs" @@ -476,50 +505,56 @@ typedef ^ ^ SC_DX_OutputType y - - - "System outputs" typedef ^ ^ SC_DX_ParameterType p - - - "System parameters" # ..... SubDyn data ....................................................................................................... -typedef FAST SubDyn_Data SD_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ SD_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ SD_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ SD_OtherStateType OtherSt {2} - - "Other states" +typedef FAST SubDyn_Data SD_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ SD_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ SD_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ SD_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ SD_ParameterType p - - - "Parameters" typedef ^ ^ SD_InputType u - - - "System inputs" typedef ^ ^ SD_OutputType y - - - "System outputs" typedef ^ ^ SD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ SD_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ SD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ SD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ SD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... ExtPtfm data ....................................................................................................... -typedef FAST ExtPtfm_Data ExtPtfm_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ ExtPtfm_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ ExtPtfm_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ ExtPtfm_OtherStateType OtherSt {2} - - "Other states" +typedef FAST ExtPtfm_Data ExtPtfm_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ ExtPtfm_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ ExtPtfm_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ ExtPtfm_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ ExtPtfm_ParameterType p - - - "Parameters" typedef ^ ^ ExtPtfm_InputType u - - - "System inputs" typedef ^ ^ ExtPtfm_OutputType y - - - "System outputs" typedef ^ ^ ExtPtfm_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ ExtPtfm_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ ExtPtfm_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... SeaState data ....................................................................................................... -typedef FAST SeaState_Data SeaSt_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ SeaSt_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ SeaSt_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ SeaSt_OtherStateType OtherSt {2} - - "Other states" +typedef FAST SeaState_Data SeaSt_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ SeaSt_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ SeaSt_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ SeaSt_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ SeaSt_ParameterType p - - - "Parameters" typedef ^ ^ SeaSt_InputType u - - - "System inputs" typedef ^ ^ SeaSt_OutputType y - - - "System outputs" typedef ^ ^ SeaSt_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ SeaSt_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ SeaSt_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ SeaSt_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ SeaSt_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... HydroDyn data ....................................................................................................... -typedef FAST HydroDyn_Data HydroDyn_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ HydroDyn_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ HydroDyn_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ HydroDyn_OtherStateType OtherSt {2} - - "Other states" +typedef FAST HydroDyn_Data HydroDyn_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ HydroDyn_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ HydroDyn_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ HydroDyn_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ HydroDyn_ParameterType p - - - "Parameters" typedef ^ ^ HydroDyn_InputType u - - - "System inputs" typedef ^ ^ HydroDyn_OutputType y - - - "System outputs" @@ -527,24 +562,28 @@ typedef ^ ^ HydroDyn_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ HydroDyn_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ HydroDyn_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ HydroDyn_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ HydroDyn_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... IceFloe data ....................................................................................................... -typedef FAST IceFloe_Data IceFloe_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ IceFloe_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ IceFloe_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ IceFloe_OtherStateType OtherSt {2} - - "Other states" +typedef FAST IceFloe_Data IceFloe_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ IceFloe_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ IceFloe_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ IceFloe_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ IceFloe_ParameterType p - - - "Parameters" typedef ^ ^ IceFloe_InputType u - - - "System inputs" typedef ^ ^ IceFloe_OutputType y - - - "System outputs" typedef ^ ^ IceFloe_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ IceFloe_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ IceFloe_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... MAP data ....................................................................................................... -typedef FAST MAP_Data MAP_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ MAP_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ MAP_ConstraintStateType z {2} - - "Constraint states" +typedef FAST MAP_Data MAP_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ MAP_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ MAP_ConstraintStateType z {4} - - "Constraint states" typedef ^ ^ MAP_OtherStateType OtherSt - - - "Other/optimization states" typedef ^ ^ MAP_ParameterType p - - - "Parameters" typedef ^ ^ MAP_InputType u - - - "System inputs" @@ -553,25 +592,29 @@ typedef ^ ^ MAP_OtherStateType OtherSt_old - - - "Other/optimization states (cop typedef ^ ^ MAP_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ MAP_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ MAP_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ MAP_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... FEAMooring data ....................................................................................................... -typedef FAST FEAMooring_Data FEAM_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ FEAM_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ FEAM_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ FEAM_OtherStateType OtherSt {2} - - "Other states" +typedef FAST FEAMooring_Data FEAM_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ FEAM_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ FEAM_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ FEAM_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ FEAM_ParameterType p - - - "Parameters" typedef ^ ^ FEAM_InputType u - - - "System inputs" typedef ^ ^ FEAM_OutputType y - - - "System outputs" typedef ^ ^ FEAM_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ FEAM_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ FEAM_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... MoorDyn data ....................................................................................................... -typedef FAST MoorDyn_Data MD_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ MD_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ MD_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ MD_OtherStateType OtherSt {2} - - "Other states" +typedef FAST MoorDyn_Data MD_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ MD_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ MD_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ MD_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ MD_ParameterType p - - - "Parameters" typedef ^ ^ MD_InputType u - - - "System inputs" typedef ^ ^ MD_OutputType y - - - "System outputs" @@ -579,19 +622,23 @@ typedef ^ ^ MD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ MD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ MD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ MD_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ MD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... OrcaFlex data ....................................................................................................... -typedef FAST OrcaFlex_Data Orca_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ Orca_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ Orca_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ Orca_OtherStateType OtherSt {2} - - "Other states" +typedef FAST OrcaFlex_Data Orca_ContinuousStateType x {4} - - "Continuous states" +typedef ^ ^ Orca_DiscreteStateType xd {4} - - "Discrete states" +typedef ^ ^ Orca_ConstraintStateType z {4} - - "Constraint states" +typedef ^ ^ Orca_OtherStateType OtherSt {4} - - "Other states" typedef ^ ^ Orca_ParameterType p - - - "Parameters" typedef ^ ^ Orca_InputType u - - - "System inputs" typedef ^ ^ Orca_OutputType y - - - "System outputs" typedef ^ ^ Orca_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ Orca_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ Orca_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" # ..... FAST_ModuleMapType data ....................................................................................................... # ! Data structures for mapping and coupling the various modules together @@ -626,7 +673,7 @@ typedef ^ FAST_ModuleMapType MeshMapType SubStructure_2_SStC_P_P {:} - - "Map Su # ED --> SrvD -- PlatformPtMesh motion to SrvD%PtfmMotionMesh for passing to DLL typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_SrvD_P_P - - - "Map ElastoDyn platform point mesh motion to ServoDyn point mesh -- for passing to controller" # ED/BD <-> AD (blades) -typedef ^ FAST_ModuleMapType MeshMapType BDED_L_2_AD_L_B {:} - - "Map ElastoDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes" +typedef ^ FAST_ModuleMapType MeshMapType BDED_L_2_AD_L_B {:} - - "Map ElastoDyn/BeamDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes" typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_BDED_B {:} - - "Map AeroDyn14 InputMarkers or AeroDyn BladeLoad line2 meshes to ElastoDyn BladePtLoad point meshes or BeamDyn BldMotion line2 meshes" typedef ^ FAST_ModuleMapType MeshMapType BD_L_2_BD_L {:} - - "Map BeamDyn BldMotion output meshes to locations on the BD input DistrLoad mesh stored in MeshMapType%y_BD_BldMotion_4Loads (BD input and output meshes are not siblings and in fact have nodes at different locations" # ED <-> AD (nacelle, tower, hub, blade root, tailfin) @@ -639,6 +686,16 @@ typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_ED_P_T - - - "Map AeroDyn14 Twr_ typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_R {:} - - "Map ElastoDyn BladeRootMotion point meshes to AeroDyn BladeRootMotion point meshes" typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_H - - - "Map ElastoDyn HubPtMotion point mesh to AeroDyn HubMotion point mesh" typedef ^ FAST_ModuleMapType MeshMapType AD_P_2_ED_P_H - - - "Map AeroDyn HubLoad point mesh to ElastoDyn HubPtLoad point mesh" +# ED/BD <-> ExtLd (blades) +typedef ^ FAST_ModuleMapType MeshMapType BDED_L_2_ExtLd_P_B {:} - - "Map ElastoDyn/BeamDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to ExtLoads point meshes" +typedef ^ FAST_ModuleMapType MeshMapType ExtLd_P_2_BDED_B {:} - - "Map ExtLoads at points to ElastoDyn BladePtLoad point meshes or BeamDyn BldMotion line2 meshes" +# ED <-> ExtLd (tower, hub, blade root) +typedef ^ FAST_ModuleMapType MeshMapType ED_L_2_ExtLd_P_T - - - "Map ElastoDyn TowerLn2Mesh line2 mesh to ExtLoads point mesh" +typedef ^ FAST_ModuleMapType MeshMapType ExtLd_P_2_ED_P_T - - - "Map ExtLoads TowerLoad point mesh to ElastoDyn TowerPtLoads point mesh" +typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_ExtLd_P_R {:} - - "Map ElastoDyn BladeRootMotion point meshes to ExtLoads BladeRootMotion point meshes" +typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_ExtLd_P_H - - - "Map ElastoDyn HubPtMotion point mesh to ExtLoads HubMotion point mesh" +typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_ExtLd_B {:} - - "Map AeroDyn line loads on blades to ExtLoads point loads" +typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_ExtLd_T - - - "Map AeroDyn line loads on tower to ExtKoads point loads" # IceF <-> SD typedef ^ FAST_ModuleMapType MeshMapType IceF_P_2_SD_P - - - "Map IceFloe point mesh to SubDyn LMesh point mesh" typedef ^ FAST_ModuleMapType MeshMapType SDy3_P_2_IceF_P - - - "Map SubDyn y3Mesh point mesh to IceFloe point mesh" @@ -709,6 +766,8 @@ typedef ^ FAST_InitData AD14_InitInputType InData_AD14 - - typedef ^ FAST_InitData AD14_InitOutputType OutData_AD14 - - - "AD14 Initialization output data" typedef ^ FAST_InitData AD_InitInputType InData_AD - - - "AD Initialization input data" typedef ^ FAST_InitData AD_InitOutputType OutData_AD - - - "AD Initialization output data" +typedef ^ FAST_InitData ExtLd_InitInputType InData_ExtLd - - - "ExtLd Initialization input data" +typedef ^ FAST_InitData ExtLd_InitOutputType OutData_ExtLd - - - "ExtLd Initialization output data" typedef ^ FAST_InitData InflowWind_InitInputType InData_IfW - - - "IfW Initialization input data" typedef ^ FAST_InitData InflowWind_InitOutputType OutData_IfW - - - "IfW Initialization output data" typedef ^ FAST_InitData ExtInfw_InitInputType InData_ExtInfw - - - "ExtInfw Initialization input data" @@ -754,7 +813,15 @@ typedef ^ FAST_ExternInitType ReKi windGrid_pZero 3 - - "fixed position of the X typedef ^ FAST_ExternInitType CHARACTER(1024) RootName - - - "Root name of FAST output files (overrides normal operation)" - typedef ^ FAST_ExternInitType IntKi NumActForcePtsBlade - - - "number of actuator line force points in blade" - typedef ^ FAST_ExternInitType IntKi NumActForcePtsTower - - - "number of actuator line force points in tower" - -typedef ^ FAST_ExternInitType IntKi NodeClusterType - - - "Node clustering for actuator line (0 - Uniform, 1 - Non-uniform clustered towards tip)" - +typedef ^ FAST_ExternInitType IntKi NodeClusterType - - - "Node clustering for actuator line (0 - Uniform, 1 - Non-uniform clustered towards tip)" - +typedef ^ FAST_ExternInitType DbKi DTdriver - -1 - "External driver time step" s +typedef ^ FAST_ExternInitType Logical TwrAero - .false. - "Is Tower aerodynamics enabled for ExtLoads module?" +typedef ^ FAST_ExternInitType ReKi az_blend_mean - - - "Mean azimuth at which to blend the external and aerodyn loads" - +typedef ^ FAST_ExternInitType ReKi az_blend_delta - - - "Mean azimuth at which to blend the external and aerodyn loads" - +typedef ^ FAST_ExternInitType ReKi vel_mean - - - "Mean velocity at reference height" m/s +typedef ^ FAST_ExternInitType ReKi wind_dir - - - "Wind direction in compass angle" degrees +typedef ^ FAST_ExternInitType ReKi z_ref - - - "Reference height for velocity profile" m +typedef ^ FAST_ExternInitType ReKi shear_exp - - - "Shear exponent" - # ..... FAST Turbine Data (one realization) ....................................................................................................... typedef ^ FAST_TurbineType IntKi TurbID - 1 - "Turbine ID Number" - @@ -767,6 +834,7 @@ typedef ^ FAST_TurbineType BeamDyn_Data BD - - - "Data for the BeamDyn module" - typedef ^ FAST_TurbineType ServoDyn_Data SrvD - - - "Data for the ServoDyn module" - typedef ^ FAST_TurbineType AeroDyn_Data AD - - - "Data for the AeroDyn module" - typedef ^ FAST_TurbineType AeroDyn14_Data AD14 - - - "Data for the AeroDyn14 module" - +typedef ^ FAST_TurbineType ExtLoads_Data ExtLd - - - "Data for the External loads module" - typedef ^ FAST_TurbineType InflowWind_Data IfW - - - "Data for InflowWind module" - typedef ^ FAST_TurbineType ExternalInflow_Data ExtInfw - - - "Data for ExternalInflow integration module" - typedef ^ FAST_TurbineType SCDataEx_Data SC_DX - - - "Data for SuperController integration module" - diff --git a/modules/openfast-library/src/FAST_Solver.f90 b/modules/openfast-library/src/FAST_Solver.f90 index c72e340a72..b12715f653 100644 --- a/modules/openfast-library/src/FAST_Solver.f90 +++ b/modules/openfast-library/src/FAST_Solver.f90 @@ -29,6 +29,7 @@ MODULE FAST_Solver USE AeroDyn USE AeroDyn14 + USE ExtLoads USE InflowWind USE ElastoDyn USE BeamDyn @@ -52,13 +53,17 @@ MODULE FAST_Solver !---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets the inputs required for BD--using the Option 2 solve method; currently the only inputs solved in this routine !! are the blade distributed loads from AD15; other inputs are solved in option 1. -SUBROUTINE BD_InputSolve( p_FAST, BD, y_AD, u_AD, y_ED, y_SrvD, u_SrvD, MeshMapData, ErrStat, ErrMsg ) +SUBROUTINE BD_InputSolve( p_FAST, BD, y_AD, u_AD, m_ExtLd, y_ExtLd, u_ExtLd, p_ExtLd, y_ED, y_SrvD, u_SrvD, MeshMapData, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Glue-code simulation parameters TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BD Inputs at t TYPE(AD_OutputType), INTENT(IN ) :: y_AD !< AeroDyn outputs TYPE(AD_InputType), INTENT(IN ) :: u_AD !< AD inputs (for AD-BD load transfer) + TYPE(ExtLd_MiscVarType), INTENT(INOUT) :: m_ExtLd !< External Misc Var + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y_ExtLd !< External Load outputs + TYPE(ExtLd_InputType), INTENT(IN ) :: u_ExtLd !< External Load inputs (for ExtL-BD load transfer) + TYPE(ExtLd_ParameterType), INTENT(IN ) :: p_ExtLd !< External Load parameters TYPE(ED_OutputType), INTENT(IN ) :: y_ED !< ElastoDyn outputs TYPE(SrvD_OutputType), INTENT(IN ) :: y_SrvD !< ServoDyn outputs TYPE(SrvD_InputType), INTENT(IN ) :: u_SrvD !< ServoDyn Inputs (for SrvD-BD load transfer) @@ -112,7 +117,41 @@ SUBROUTINE BD_InputSolve( p_FAST, BD, y_AD, u_AD, y_ED, y_SrvD, u_SrvD, MeshMapD END DO end if - + + ELSE IF (p_FAST%CompAero == Module_ExtLd ) THEN + + !Get the aerodyn loads first + do K = 1,p_FAST%nBeams ! Loop through all blades + call Transfer_Line2_to_Point( y_AD%rotors(1)%BladeLoad(k), y_ExtLd%BladeLoadAD(k), MeshMapData%AD_L_2_ExtLd_B(k), ErrStat2, ErrMsg2, u_AD%rotors(1)%BladeMotion(k), u_ExtLd%BladeMotion(k) ) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end do + + !Blend the aerodyn loads with the external loads + call ExtLd_ConvertOpDataForOpenFAST(y_ExtLd, u_ExtLd, m_ExtLd, p_ExtLd, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (p_FAST%BD_OutputSibling) then + + DO K = 1,p_FAST%nBeams ! Loop through all blades + + CALL Transfer_Point_to_Line2( y_ExtLd%BladeLoad(k), BD%Input(1,k)%DistrLoad, MeshMapData%ExtLd_P_2_BDED_B(k), ErrStat2, ErrMsg2, u_ExtLd%BladeMotion(k), BD%y(k)%BldMotion ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + END DO + + else + DO K = 1,p_FAST%nBeams ! Loop through all blades + + ! need to transfer the BD output blade motions to nodes on a sibling of the BD blade motion mesh: + CALL Transfer_Line2_to_Line2( BD%y(k)%BldMotion, MeshMapData%y_BD_BldMotion_4Loads(k), MeshMapData%BD_L_2_BD_L(k), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + CALL Transfer_Point_to_Line2( y_ExtLd%BladeLoad(k), BD%Input(1,k)%DistrLoad, MeshMapData%ExtLd_P_2_BDED_B(k), ErrStat2, ErrMsg2, u_ExtLd%BladeMotion(k), MeshMapData%y_BD_BldMotion_4Loads(k) ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + END DO + end if + ELSE DO K = 1,p_FAST%nBeams ! Loop through all blades @@ -178,7 +217,7 @@ END SUBROUTINE BD_InputSolve !---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets the inputs required for ED--using the Option 2 solve method. Currently the only inputs not solved in this routine !! are the fields on PlatformPtMesh, which are solved in Option 1. The fields on HubPtLoad are solved in both Option 2 and Option 1. -SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD, u_SrvD, MeshMapData, ErrStat, ErrMsg ) +SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD, y_ExtLd, m_ExtLd, u_ExtLd, p_ExtLd, u_SrvD, MeshMapData, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Glue-code simulation parameters @@ -188,6 +227,10 @@ SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD TYPE(AD14_OutputType), INTENT(IN ) :: y_AD14 !< AeroDyn14 outputs TYPE(AD_OutputType), INTENT(IN ) :: y_AD !< AeroDyn outputs TYPE(AD_InputType), INTENT(IN ) :: u_AD !< AD inputs (for AD-ED load transfer) + TYPE(ExtLd_OutputType), INTENT(INOUT) :: y_ExtLd !< ExtLoads outputs + TYPE(ExtLd_MiscVarType), INTENT(INOUT) :: m_ExtLd !< ExtLoads misc var + TYPE(ExtLd_InputType), INTENT(IN ) :: u_ExtLd !< ExtLoads inputs (for ExtLoads-ED load transfer) + TYPE(ExtLd_ParameterType), INTENT(IN ) :: p_ExtLd !< ExtLoads parameters (for ExtLoads-ED load transfer) TYPE(SrvD_OutputType), INTENT(IN ) :: y_SrvD !< ServoDyn outputs TYPE(SrvD_InputType), INTENT(IN ) :: u_SrvD !< ServoDyn inputs @@ -235,7 +278,23 @@ SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD CALL Transfer_Line2_to_Point( y_AD%rotors(1)%BladeLoad(k), u_ED%BladePtLoads(k), MeshMapData%AD_L_2_BDED_B(k), ErrStat2, ErrMsg2, u_AD%rotors(1)%BladeMotion(k), y_ED%BladeLn2Mesh(k) ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END DO - + + ELSE IF (p_FAST%CompAero == Module_ExtLd ) THEN + + DO K = 1,SIZE(u_ED%BladePtLoads,1) ! Loop through all blades (p_ED%NumBl) + CALL Transfer_Line2_to_Point( y_AD%rotors(1)%BladeLoad(k), y_ExtLd%BladeLoadAD(k), MeshMapData%AD_L_2_ExtLd_B(k), ErrStat2, ErrMsg2, u_AD%rotors(1)%BladeMotion(k), u_ExtLd%BladeMotion(k) ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END DO + + call ExtLd_ConvertOpDataForOpenFAST(y_ExtLd, u_ExtLd, m_ExtLd, p_ExtLd, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + DO K = 1,SIZE(u_ED%BladePtLoads,1) ! Loop through all blades (p_ED%NumBl) + ! NOTE - not only is BladeLn2Mesh not a Sbiling of BladePtLoads, it is a line 2 mesh with different number of nodes + CALL Transfer_Point_to_Point( y_ExtLd%BladeLoad(k), u_ED%BladePtLoads(k), MeshMapData%ExtLd_P_2_BDED_B(k), ErrStat2, ErrMsg2, u_ExtLd%BladeMotion(k), y_ED%BladeLn2Mesh(k) ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END DO + ELSE !p_FAST%CompAero = Module_None DO K = 1,SIZE(u_ED%BladePtLoads,1) ! Loop through all blades (p_ED%NumBl) @@ -275,7 +334,20 @@ SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD CALL Transfer_Line2_to_Point( y_AD%rotors(1)%TowerLoad, u_ED%TowerPtLoads, MeshMapData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2, u_AD%rotors(1)%TowerMotion, y_ED%TowerLn2Mesh ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END IF - + + ELSE IF (p_FAST%CompAero == Module_ExtLd ) THEN + + IF ( y_ExtLd%TowerLoad%Committed ) THEN ! NOTE - not only is TowerLn2Mesh not a Sbiling of TowerPtLoads, it is a line 2 mesh with different number of nodes + call Transfer_Line2_to_point( y_AD%rotors(1)%TowerLoad, y_ExtLd%TowerLoadAD, MeshMapData%AD_L_2_ExtLd_T, ErrStat2, ErrMsg2, u_AD%rotors(1)%TowerMotion, u_ExtLd%TowerMotion ) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ExtLd_ConvertOpDataForOpenFAST(y_ExtLd, u_ExtLd, m_ExtLd, p_ExtLd, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + CALL Transfer_Point_to_Point( y_ExtLd%TowerLoad, u_ED%TowerPtLoads, MeshMapData%ExtLd_P_2_ED_P_T, ErrStat2, ErrMsg2, u_ExtLd%TowerMotion, y_ED%TowerLn2Mesh ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + ELSE u_ED%TowerPtLoads%Force = 0.0_ReKi u_ED%TowerPtLoads%Moment = 0.0_ReKi @@ -582,6 +654,55 @@ SUBROUTINE AD_InputSolve_IfW( p_FAST, u_AD, y_IfW, y_ExtInfw, ErrStat, ErrMsg ) END SUBROUTINE AD_InputSolve_IfW !---------------------------------------------------------------------------------------------------------------------------------- + +SUBROUTINE AD_InputSolve_IfW_ExtLoads( p_FAST, u_AD, p_ExtLd, ErrStat, ErrMsg ) + + type(FAST_ParameterType), intent(in) :: p_FAST !< FAST parameter data + type(AD_InputType), intent(inout) :: u_AD !< The inputs to AeroDyn + type(ExtLd_ParameterType), intent(in) :: p_ExtLd !< Parameters of ExtLoads + integer(IntKi) :: ErrStat !< Error status of the operation + character(*) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + !local variables + real(ReKi) :: z !< Local 'z' coordinate + real(ReKi) :: mean_vel !< Local mean velocity + real(ReKi) :: pi !< Our favorite number + integer(IntKi) :: j,k !< Local counter variables + integer(IntKi) :: NumBl !< Number of blades + integer(IntKi) :: Nnodes !< Number of nodes + + ErrStat = ErrID_None + ErrMsg = '' + + pi = acos(-1.0) + NumBl = size(u_AD%rotors(1)%InflowOnBlade,3) + Nnodes = size(u_AD%rotors(1)%InflowOnBlade,2) + + do k=1,NumBl + do j=1,Nnodes + !Get position first + z = u_AD%rotors(1)%BladeMotion(k)%Position(3,j) + u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(3,j) + mean_vel = p_ExtLd%vel_mean * ( (z/p_ExtLd%z_ref) ** p_ExtLd%shear_exp) + u_AD%rotors(1)%InflowOnBlade(1,j,k) = -mean_vel * sin(p_ExtLd%wind_dir * pi / 180.0) + u_AD%rotors(1)%InflowOnBlade(2,j,k) = -mean_vel * cos(p_ExtLd%wind_dir * pi / 180.0) + u_AD%rotors(1)%InflowOnBlade(3,j,k) = 0.0 + end do + end do + + if ( allocated(u_AD%rotors(1)%InflowOnTower) ) then + Nnodes = size(u_AD%rotors(1)%InflowOnTower,2) + do j=1,Nnodes + !Get position first + z = u_AD%rotors(1)%TowerMotion%Position(3,j) + u_AD%rotors(1)%TowerMotion%TranslationDisp(3,j) + mean_vel = p_ExtLd%vel_mean * ( (z/p_ExtLd%z_ref) ** p_ExtLd%shear_exp) + u_AD%rotors(1)%InflowOnTower(1,j) = -mean_vel * sin(p_ExtLd%wind_dir * pi / 180.0) + u_AD%rotors(1)%InflowOnTower(2,j) = -mean_vel * cos(p_ExtLd%wind_dir * pi / 180.0) + u_AD%rotors(1)%InflowOnTower(3,j) = 0.0 + end do + end if + +END SUBROUTINE AD_InputSolve_IfW_ExtLoads +!---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets all the AeroDyn inputs, except for the wind inflow values. SUBROUTINE AD_InputSolve_NoIfW( p_FAST, u_AD, y_SrvD, y_ED, BD, MeshMapData, ErrStat, ErrMsg ) @@ -866,10 +987,75 @@ SUBROUTINE AD14_InputSolve_NoIfW( p_FAST, u_AD14, y_ED, MeshMapData, ErrStat, Er ! u_AD14%MulTabLoc(IElements,IBlades) = ??? END SUBROUTINE AD14_InputSolve_NoIfW +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine sets all the ExtLoads inputs, except for the wind inflow values. +SUBROUTINE ExtLd_InputSolve_NoIfW( p_FAST, u_ExtLd, p_ExtLd, y_ED, BD, MeshMapData, ErrStat, ErrMsg ) + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< FAST parameter data + TYPE(ExtLd_InputType), INTENT(INOUT) :: u_ExtLd !< The inputs to ExtLoads + TYPE(ExtLd_ParameterType), INTENT(IN) :: p_ExtLd !< The parameters of ExtLoads + TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the structural dynamics module + TYPE(BeamDyn_Data), INTENT(IN) :: BD !< The data from BeamDyn (want the outputs only, but it's in an array) + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + INTEGER(IntKi) :: ErrStat !< Error status of the operation + CHARACTER(*) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + INTEGER(IntKi) :: K ! Loops through blades + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_InputSolve_NoIfW' + + ErrStat = ErrID_None + ErrMsg = "" + + !------------------------------------------------------------------------------------------------- + ! Set the inputs from ElastoDyn and/or BeamDyn: + !------------------------------------------------------------------------------------------------- + + ! tower + IF (u_ExtLd%TowerMotion%Committed) THEN + CALL Transfer_Line2_to_Point( y_ED%TowerLn2Mesh, u_ExtLd%TowerMotion, MeshMapData%ED_L_2_ExtLd_P_T, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//':u_ExtLd%TowerMotion' ) + END IF + + ! hub + CALL Transfer_Point_to_Point( y_ED%HubPtMotion, u_ExtLd%HubMotion, MeshMapData%ED_P_2_ExtLd_P_H, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//':u_ExtLd%HubMotion' ) + + ! blade root + DO k=1,size(y_ED%BladeRootMotion) + CALL Transfer_Point_to_Point( y_ED%BladeRootMotion(k), u_ExtLd%BladeRootMotion(k), MeshMapData%ED_P_2_ExtLd_P_R(k), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//':u_ExtLd%BladeRootMotion('//trim(num2lstr(k))//')' ) + END DO + + ! blades + IF (p_FAST%CompElast == Module_ED ) THEN + + DO k=1,size(y_ED%BladeLn2Mesh) + CALL Transfer_Line2_to_Point( y_ED%BladeLn2Mesh(k), u_ExtLd%BladeMotion(k), MeshMapData%BDED_L_2_ExtLd_P_B(k), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//':u_ExtLd%BladeMotion('//trim(num2lstr(k))//')' ) + END DO + ELSEIF (p_FAST%CompElast == Module_BD ) THEN ! get them from BeamDyn + + DO k=1,size(u_ExtLd%BladeMotion) + CALL Transfer_Line2_to_Point( BD%y(k)%BldMotion, u_ExtLd%BladeMotion(k), MeshMapData%BDED_L_2_ExtLd_P_B(k), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//':u_ExtLd%BladeMotion('//trim(num2lstr(k))//')' ) + END DO + + END IF + + u_ExtLd%az = y_ED%LSSTipPxa + u_ExtLd%DX_u%bldPitch(:) = y_ED%BlPitch + + call ExtLd_ConvertInpDataForExtProg(u_ExtLd, p_ExtLd, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + +END SUBROUTINE ExtLd_InputSolve_NoIfW !---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets the inputs required for ServoDyn -SUBROUTINE SrvD_InputSolve( p_FAST, m_FAST, u_SrvD, y_ED, y_IfW, y_ExtInfw, y_BD, y_SD, MeshMapData, ErrStat, ErrMsg ) +SUBROUTINE SrvD_InputSolve( p_FAST, m_FAST, u_SrvD, y_ED, y_IfW, y_ExtInfw, p_ExtLd, y_BD, y_SD, MeshMapData, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(FAST_ParameterType), INTENT(IN) :: p_FAST !< Glue-code simulation parameters @@ -878,6 +1064,7 @@ SUBROUTINE SrvD_InputSolve( p_FAST, m_FAST, u_SrvD, y_ED, y_IfW, y_ExtInfw, y_BD TYPE(ED_OutputType),TARGET, INTENT(IN) :: y_ED !< ElastoDyn outputs TYPE(InflowWind_OutputType), INTENT(IN) :: y_IfW !< InflowWind outputs TYPE(ExtInfw_OutputType), INTENT(IN) :: y_ExtInfw !< ExternalInflow outputs + TYPE(ExtLd_ParameterType), INTENT(in) :: p_ExtLd !< Parameters of ExtLoads TYPE(BD_OutputType), INTENT(IN) :: y_BD(:) !< BD Outputs TYPE(SD_OutputType),TARGET, INTENT(IN) :: y_SD !< SD Outputs TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules @@ -888,6 +1075,11 @@ SUBROUTINE SrvD_InputSolve( p_FAST, m_FAST, u_SrvD, y_ED, y_IfW, y_ExtInfw, y_BD INTEGER(IntKi) :: k ! blade loop counter INTEGER(IntKi) :: j ! StC instance counter TYPE(MeshType), POINTER :: SubStructureMotion + real(ReKi) :: z !< Local 'z' coordinate + real(ReKi) :: u !< Local u velocity + real(ReKi) :: v !< Local v velocity + real(ReKi) :: mean_vel !< Local mean velocity + real(ReKi) :: pi !< Our favorite number INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None @@ -923,6 +1115,20 @@ SUBROUTINE SrvD_InputSolve( p_FAST, m_FAST, u_SrvD, y_ED, y_IfW, y_ExtInfw, y_BD if (allocated(u_SrvD%MsrPositionsY)) u_SrvD%MsrPositionsY = 0.0 if (allocated(u_SrvD%MsrPositionsz)) u_SrvD%MsrPositionsz = 0.0 + ELSE IF (p_FAST%CompAero == Module_ExtLd ) THEN + + pi = acos(-1.0) + z = y_ED%HubPtMotion%Position(3,1) + mean_vel = p_ExtLd%vel_mean * ( (z/p_ExtLd%z_ref) ** p_ExtLd%shear_exp) + u = -mean_vel * sin(p_ExtLd%wind_dir * pi / 180.0) + v = -mean_vel * cos(p_ExtLd%wind_dir * pi / 180.0) + u_SrvD%HorWindV = mean_vel + u_SrvD%WindDir = atan2( v, u) + if (allocated(u_SrvD%LidSpeed )) u_SrvD%LidSpeed = 0.0 + if (allocated(u_SrvD%MsrPositionsX)) u_SrvD%MsrPositionsX = 0.0 + if (allocated(u_SrvD%MsrPositionsY)) u_SrvD%MsrPositionsY = 0.0 + if (allocated(u_SrvD%MsrPositionsz)) u_SrvD%MsrPositionsz = 0.0 + ELSE ! No wind inflow u_SrvD%WindDir = 0.0 @@ -3851,7 +4057,7 @@ SUBROUTINE Perturb_u_FullOpt1( p_FAST, Jac_u_indx, n, u_perturb, u_ED_perturb, u END SUBROUTINE Perturb_u_FullOpt1 !---------------------------------------------------------------------------------------------------------------------------------- !> This routine resets the remap flags on all of the meshes -SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD ) +SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, ExtLd, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD ) !............................................................................................................................... TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code @@ -3861,6 +4067,7 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm data @@ -3928,7 +4135,8 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp AD14%Input(1)%Twr_InputMarkers%RemapFlag = .FALSE. AD14%y%Twr_OutputLoads%RemapFlag = .FALSE. END IF - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN + + ELSEIF ( (p_FAST%CompAero == Module_AD) .OR. (p_FAST%CompAero == Module_ExtLd ) ) THEN IF (AD%Input(1)%rotors(1)%HubMotion%Committed) THEN AD%Input(1)%rotors(1)%HubMotion%RemapFlag = .FALSE. @@ -3960,7 +4168,26 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp END DO END IF - + + IF (p_FAST%CompAero == Module_ExtLd ) THEN + + ExtLd%u%HubMotion%RemapFlag = .FALSE. + + IF ( ExtLd%u%TowerMotion%Committed ) THEN + ExtLd%u%TowerMotion%RemapFlag = .FALSE. + + IF ( ExtLd%y%TowerLoad%Committed ) THEN + ExtLd%y%TowerLoad%RemapFlag = .FALSE. + END IF + END IF + + DO k=1,SIZE( ExtLd%u%BladeMotion ) + ExtLd%u%BladeRootMotion(k)%RemapFlag = .FALSE. + ExtLd%u%BladeMotion( k)%RemapFlag = .FALSE. + ExtLd%y%BladeLoad( k)%RemapFlag = .FALSE. + END DO + + END IF ! ServoDyn -- StrucCtrl meshes IF ( p_FAST%CompServo == Module_SrvD ) THEN @@ -4070,16 +4297,16 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp END SUBROUTINE ResetRemapFlags !---------------------------------------------------------------------------------------------------------------------------------- !> This routine initializes all of the mapping data structures needed between the various modules. -SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg) +SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, ExtLd, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg) !............................................................................................................................... TYPE(FAST_ParameterType), INTENT(INOUT) :: p_FAST !< Parameters for the glue code - TYPE(ElastoDyn_Data),TARGET,INTENT(INOUT) :: ED !< ElastoDyn data TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data TYPE(SubDyn_Data), TARGET, INTENT(INOUT) :: SD !< SubDyn data TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm data @@ -4345,7 +4572,7 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M IF (ErrStat >= AbortErrLev ) RETURN - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN ! ED-AD and/or BD-AD + ELSEIF ( (p_FAST%CompAero == Module_AD) .OR. (p_FAST%CompAero == Module_ExtLd) ) THEN ! ED-AD and/or BD-AD ! allocate per-blade space for mapping to structural module @@ -4485,7 +4712,119 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M END IF ! AeroDyn/AeroDyn14 to structural code - + IF ( p_FAST%CompAero == Module_ExtLd ) THEN ! ED-ExtLd and/or BD-ExtLd + + NumBl = SIZE(ExtLd%u%BladeRootMotion) ! Get number of blades + + ! Allocate memory for mapping between ED and ExtLoad blade root meshes + ALLOCATE( MeshMapData%ED_P_2_ExtLd_P_R(NumBl), STAT=ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error allocating MeshMapData%ED_P_2_ExtLd_P_R.', ErrStat, ErrMsg, RoutineName ) + RETURN + END IF + + ! Create the the mesh mapping for mapping between ED and ExtLoad blade root meshes + DO K=1,NumBl + CALL MeshMapCreate( ED%y%BladeRootMotion(K), ExtLd%u%BladeRootMotion(K), MeshMapData%ED_P_2_ExtLd_P_R(K), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_ExtLd_P_R('//TRIM(Num2LStr(K))//')' ) + END DO + + ! Hub point mesh + CALL MeshMapCreate( ED%y%HubPtMotion, ExtLd%u%HubMotion, MeshMapData%ED_P_2_ExtLd_P_H, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_ExtLd_P_H' ) + + ! Blade meshes: (allocate two mapping data structures to number of blades, then allocate data inside the structures) + ALLOCATE( MeshMapData%BDED_L_2_ExtLd_P_B(NumBl), MeshMapData%ExtLd_P_2_BDED_B(NumBl), MeshMapData%AD_L_2_ExtLd_B(NumBl), STAT=ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error allocating MeshMapData%BDED_L_2_ExtLd_P_B and MeshMapData%ExtLd_P_2_BDED_B.', & + ErrStat, ErrMsg, RoutineName ) + RETURN + END IF + + ! Create mapping for AD line mesh to ExtLoads point mesh + do k=1,NumBl + call MeshMapCreate( AD%y%rotors(1)%BladeLoad(k), ExtLd%y%BladeLoadAD(k), MeshMapData%AD_L_2_ExtLd_B(k), ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':AD_L_2_ExtLd_B('//TRIM(Num2LStr(K))//')' ) + end do + + IF ( p_FAST%CompElast == Module_ED ) then + + DO K=1,NumBl + ! Create mapping for ElastoDyn BldMotion line2 meshes to ExtLoads point mesh + CALL MeshMapCreate( ED%y%BladeLn2Mesh(K), ExtLd%u%BladeMotion(K), MeshMapData%BDED_L_2_ExtLd_P_B(K), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':BDED_L_2_ExtLd_P_B('//TRIM(Num2LStr(K))//')' ) + ! Create mapping for ExtLoads point mesh to ElastoDyn BldMotion line2 mesh + CALL MeshMapCreate( ExtLd%y%BladeLoad(K), ED%Input(1)%BladePtLoads(K), MeshMapData%ExtLd_P_2_BDED_B(K), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ExtLd_P_2_BDED_B('//TRIM(Num2LStr(K))//')' ) + END DO + + ELSEIF ( p_FAST%CompElast == Module_BD ) then + + ! connect ExtLoads mesh with BeamDyn + DO K=1,NumBl + ! Create mapping for BeamDyn BldMotion line2 meshes to ExtLoads point mesh + CALL MeshMapCreate( BD%y(k)%BldMotion, ExtLd%u%BladeMotion(K), MeshMapData%BDED_L_2_ExtLd_P_B(K), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':BDED_L_2_ExtLd_P_B('//TRIM(Num2LStr(K))//')' ) + ! Create mapping for ExtLoads point mesh to BeamDyn BldMotion line2 mesh + CALL MeshMapCreate( ExtLd%y%BladeLoad(K), BD%Input(1,k)%DistrLoad, MeshMapData%ExtLd_P_2_BDED_B(K), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ExtLd_P_2_BDED_B('//TRIM(Num2LStr(K))//')' ) + END DO + + IF (.not. p_FAST%BD_OutputSibling) then + + ! Blade meshes for load transfer: (allocate meshes at BD input locations for motions transferred from BD output locations) + ALLOCATE( MeshMapData%BD_L_2_BD_L(NumBl), MeshMapData%y_BD_BldMotion_4Loads(NumBl), STAT=ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error allocating MeshMapData%BD_L_2_BD_L and MeshMapData%y_BD_BldMotion_4Loads.', & + ErrStat, ErrMsg, RoutineName ) + RETURN + END IF ! ( ErrStat2 /= 0 ) + + DO K=1,NumBl + ! create the new mesh: + CALL MeshCopy ( SrcMesh = BD%Input(1,k)%DistrLoad & + , DestMesh = MeshMapData%y_BD_BldMotion_4Loads(k) & + , CtrlCode = MESH_SIBLING & + , IOS = COMPONENT_OUTPUT & + , TranslationDisp = .TRUE. & + , Orientation = .TRUE. & + , RotationVel = .TRUE. & + , TranslationVel = .TRUE. & + , RotationAcc = .TRUE. & + , TranslationAcc = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN + + ! create the mapping: + CALL MeshMapCreate( BD%y(k)%BldMotion, MeshMapData%y_BD_BldMotion_4Loads(k), MeshMapData%BD_L_2_BD_L(K), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':BD_L_2_BD_L('//TRIM(Num2LStr(K))//')' ) + END DO + + END IF !.not. p_FAST%BD_OutputSibling + + ENDIF ! ( p_FAST%CompElast == Module_BD ) + + ! Tower mesh: + IF ( ExtLd%u%TowerMotion%Committed ) THEN + CALL MeshMapCreate( ED%y%TowerLn2Mesh, ExtLd%u%TowerMotion, MeshMapData%ED_L_2_ExtLd_P_T, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_L_2_ExtLd_P_T' ) + + IF ( ExtLd%y%TowerLoad%Committed ) THEN + CALL MeshMapCreate( ExtLd%y%TowerLoad, ED%Input(1)%TowerPtLoads, MeshMapData%ExtLd_P_2_ED_P_T, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ExtLd_P_2_ED_P_T' ) + + IF ( ( AD%Input(1)%rotors(1)%TowerMotion%Committed ) .and. ( AD%y%rotors(1)%TowerLoad%Committed ) ) THEN + !Aerodyn to External loads + CALL MeshMapCreate( AD%y%rotors(1)%TowerLoad, ExtLd%y%TowerLoadAD, MeshMapData%AD_L_2_ExtLd_T, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':AD_L_2_ExLd_T' ) + END IF + + END IF ! ( ExtLd%y%TowerLoad%Committed ) + END IF ! ( ExtLd%u%TowerMotion%Committed ) + + END IF ! ( p_FAST%CompAero == Module_ExtLd ) IF ( p_FAST%CompHydro == Module_HD ) THEN ! HydroDyn-{ElastoDyn or SubDyn} @@ -4659,7 +4998,7 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M !............................................................................................................................ ! reset the remap flags (do this before making the copies else the copies will always have remap = true) !............................................................................................................................ - CALL ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD ) + CALL ResetRemapFlags(p_FAST, ED, BD, AD14, AD, ExtLd, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD ) !............................................................................................................................ ! initialize the temporary input meshes (for input-output solves in Solve Option 1): @@ -4768,7 +5107,7 @@ END SUBROUTINE InitModuleMappings !! *** Note that modules that do not have direct feedthrough should be called first. *** SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, calcJacobian, NextJacCalcTime, & p_FAST, m_FAST, WriteThisStep, ED, BD, & - SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) REAL(DbKi) , intent(in ) :: this_time !< The current simulation time (actual or time of prediction) INTEGER(IntKi) , intent(in ) :: this_state !< Index into the state array (current or predicted states) INTEGER(IntKi) , intent(in ) :: n_t_global !< current time step (used only for SrvD hack) @@ -4784,6 +5123,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data @@ -4845,7 +5185,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca !> Solve option 2 (modules without direct feedthrough): - CALL SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat2, ErrMsg2, n_t_global < 0, WriteThisStep) + CALL SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, ExtLd, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat2, ErrMsg2, n_t_global < 0, WriteThisStep) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) #ifdef OUTPUT_MASS_MATRIX @@ -4900,6 +5240,20 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca CALL AD_InputSolve_IfW( p_FAST, AD%Input(1), IfW%y, ExtInfw%y, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSE IF (p_FAST%CompAero == Module_ExtLd ) THEN + + CALL AD_InputSolve_NoIfW( p_FAST, AD%Input(1), SrvD%y, ED%y, BD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL AD_InputSolve_IfW_ExtLoads( p_FAST, AD%Input(1), ExtLd%p, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ExtLd_InputSolve_NoIfW( p_FAST, ExtLd%u, ExtLd%p, ED%y, BD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + IF ( p_FAST%CompInflow == MODULE_IfW .OR. p_FAST%CompInflow == MODULE_ExtInfw ) THEN + CALL SetErrStat(ErrID_Fatal,'p_FAST%CompInflow option not setup to work with ExtLoads module.',ErrStat,ErrMsg,RoutineName) + ENDIF END IF IF ( p_FAST%CompInflow == Module_IfW ) THEN @@ -4915,7 +5269,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca IF ( p_FAST%CompServo == Module_SrvD ) THEN - CALL SrvD_InputSolve( p_FAST, m_FAST, SrvD%Input(1), ED%y, IfW%y, ExtInfw%y, BD%y, SD%y, MeshmapData, ErrStat2, ErrMsg2 ) + CALL SrvD_InputSolve( p_FAST, m_FAST, SrvD%Input(1), ED%y, IfW%y, ExtInfw%y, ExtLd%p, BD%y, SD%y, MeshmapData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF @@ -4929,7 +5283,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca ! Reset each mesh's RemapFlag (after calling all InputSolve routines): !..................................................................... - CALL ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD) + CALL ResetRemapFlags(p_FAST, ED, BD, AD14, AD, ExtLd, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD) END SUBROUTINE CalcOutputs_And_SolveForInputs @@ -5228,7 +5582,7 @@ SUBROUTINE SolveOption2b_Inp2IfW(this_time, this_state, p_FAST, m_FAST, ED, BD, CALL AD14_InputSolve_NoIfW( p_FAST, AD14%Input(1), ED%y, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSE IF ( p_FAST%CompAero == Module_AD ) THEN + ELSE IF ( ( p_FAST%CompAero == Module_AD ) .OR. (p_FAST%CompAero == Module_ExtLd) ) THEN ! note that this uses BD outputs, which are from the previous step (and need to be initialized) CALL AD_InputSolve_NoIfW( p_FAST, AD%Input(1), SrvD%y, ED%y, BD, MeshMapData, ErrStat2, ErrMsg2 ) @@ -5252,7 +5606,7 @@ SUBROUTINE SolveOption2b_Inp2IfW(this_time, this_state, p_FAST, m_FAST, ED, BD, END SUBROUTINE SolveOption2b_Inp2IfW !---------------------------------------------------------------------------------------------------------------------------------- !> This routine implements the first part of the "option 2" solve for inputs that apply to AeroDyn and ServoDyn. -SUBROUTINE SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat, ErrMsg, WriteThisStep) +SUBROUTINE SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, ExtLd, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat, ErrMsg, WriteThisStep) REAL(DbKi) , intent(in ) :: this_time !< The current simulation time (actual or time of prediction) INTEGER(IntKi) , intent(in ) :: this_state !< Index into the state array (current or predicted states) @@ -5265,6 +5619,7 @@ SUBROUTINE SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLD !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules @@ -5316,13 +5671,18 @@ SUBROUTINE SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, CALL AD_InputSolve_IfW( p_FAST, AD%Input(1), IfW%y, ExtInfw%y, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + + ELSE IF (p_FAST%CompAero == Module_ExtLd ) THEN + + CALL AD_InputSolve_IfW_ExtLoads( p_FAST, AD%Input(1), ExtLd%p, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF IF ( p_FAST%CompServo == Module_SrvD ) THEN - CALL SrvD_InputSolve( p_FAST, m_FAST, SrvD%Input(1), ED%y, IfW%y, ExtInfw%y, BD%y, SD%y, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SrvD_InputSolve( p_FAST, m_FAST, SrvD%Input(1), ED%y, IfW%y, ExtInfw%y, ExtLd%p, BD%y, SD%y, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF @@ -5331,7 +5691,7 @@ END SUBROUTINE SolveOption2c_Inp2AD_SrvD !---------------------------------------------------------------------------------------------------------------------------------- !> This routine implements the "option 2" solve for all inputs without direct links to HD, SD, MAP, or the ED platform reference !! point. -SUBROUTINE SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat, ErrMsg, firstCall, WriteThisStep) +SUBROUTINE SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, ExtLd, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat, ErrMsg, firstCall, WriteThisStep) !............................................................................................................................... LOGICAL , intent(in ) :: firstCall !< flag to determine how to call ServoDyn (a hack) REAL(DbKi) , intent(in ) :: this_time !< The current simulation time (actual or time of prediction) @@ -5346,6 +5706,7 @@ SUBROUTINE SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLD !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data @@ -5379,7 +5740,7 @@ SUBROUTINE SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, CALL SolveOption2b_Inp2IfW(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! call IfW's CalcOutput; transfer wind-inflow inputs to AD; compute all of SrvD inputs: - CALL SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) + CALL SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, ExtLd, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! ELSE ! these subroutines are called in the AdvanceStates routine before BD, IfW, AD, and SrvD states are updated. This gives a more accurate solution that would otherwise require a correction step. END IF @@ -5392,9 +5753,30 @@ SUBROUTINE SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, ELSE IF ( p_FAST%CompAero == Module_AD ) THEN + CALL AD_InputSolve_IfW( p_FAST, AD%Input(1), IfW%y, ExtInfw%y, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CalcOutput( this_time, AD%Input(1), AD%p, AD%x(this_state), AD%xd(this_state), AD%z(this_state), & AD%OtherSt(this_state), AD%y, AD%m, ErrStat2, ErrMsg2, WriteThisStep ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSE IF (p_FAST%CompAero == Module_ExtLd ) THEN + + IF ( p_FAST%CompInflow == MODULE_IfW .OR. p_FAST%CompInflow == MODULE_ExtInfw ) THEN + CALL SetErrStat(ErrID_Fatal,'p_FAST%CompInflow option not setup to work with ExtLoads module.',ErrStat,ErrMsg,RoutineName) + ENDIF + + CALL AD_InputSolve_IfW_ExtLoads( p_FAST, AD%Input(1), ExtLd%p, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL AD_CalcOutput( this_time, AD%Input(1), AD%p, AD%x(this_state), AD%xd(this_state), AD%z(this_state), & + AD%OtherSt(this_state), AD%y, AD%m, ErrStat2, ErrMsg2, WriteThisStep ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ExtLd_CalcOutput( this_time, ExtLd%u, ExtLd%p, ExtLd%x(this_state), ExtLd%xd(this_state), ExtLd%z(this_state), & + ExtLd%OtherSt(this_state), ExtLd%y, ExtLd%m, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF @@ -5420,16 +5802,16 @@ SUBROUTINE SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, !bjj: note ED%Input(1) may be a sibling mesh of output, but ED%u is not (routine may update something that needs to be shared between siblings) - CALL ED_InputSolve( p_FAST, ED%Input(1), ED%y, AD14%p, AD14%y, AD%y, SrvD%y, AD%Input(1), SrvD%Input(1), MeshMapData, ErrStat2, ErrMsg2 ) + CALL ED_InputSolve( p_FAST, ED%Input(1), ED%y, AD14%p, AD14%y, AD%y, SrvD%y, AD%Input(1), ExtLd%y, ExtLd%m, ExtLd%u, ExtLd%p, SrvD%Input(1), MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_InputSolve( p_FAST, BD, AD%y, AD%Input(1), ED%y, SrvD%y, SrvD%Input(1), MeshMapData, ErrStat2, ErrMsg2 ) + CALL BD_InputSolve( p_FAST, BD, AD%y, AD%Input(1), ExtLd%m, ExtLd%y, ExtLd%u, ExtLd%p, ED%y, SrvD%y, SrvD%Input(1), MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END SUBROUTINE SolveOption2 !---------------------------------------------------------------------------------------------------------------------------------- !> This routines advances the states of each module -SUBROUTINE FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & +SUBROUTINE FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg, WriteThisStep ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial simulation time (almost always 0) @@ -5442,6 +5824,7 @@ SUBROUTINE FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, Sr TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn v14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data @@ -5565,7 +5948,7 @@ SUBROUTINE FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, Sr ! because AeroDyn DBEMT states depend heavily on getting inputs correct, we are overwriting its inputs with updated inflow outputs here - CALL SolveOption2c_Inp2AD_SrvD(t_global_next, STATE_PRED, p_FAST, m_FAST, ED, BD, AD14, AD, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) + CALL SolveOption2c_Inp2AD_SrvD(t_global_next, STATE_PRED, p_FAST, m_FAST, ED, BD, AD14, AD, ExtLd, SD, SrvD, IfW, ExtInfw, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! AeroDyn: get predicted states @@ -5587,7 +5970,7 @@ SUBROUTINE FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, Sr AD14%xd(STATE_PRED), AD14%z(STATE_PRED), AD14%OtherSt(STATE_PRED), AD14%m, ErrStat2, ErrMsg2 ) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO !j_ss - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN CALL AD_CopyContState (AD%x( STATE_CURR), AD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AD_CopyDiscState (AD%xd(STATE_CURR), AD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) @@ -5607,6 +5990,9 @@ SUBROUTINE FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, Sr END DO !j_ss END IF + IF (p_FAST%CompAero == Module_ExtLd ) THEN + ! DO WE HAVE TO DO SOMETHING HERE? + END IF ! ServoDyn: get predicted states IF ( p_FAST%CompServo == Module_SrvD ) THEN @@ -5823,7 +6209,7 @@ SUBROUTINE FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, Sr END SUBROUTINE FAST_AdvanceStates !---------------------------------------------------------------------------------------------------------------------------------- !> This routine extrapolates inputs to modules to give predicted values at t+dt. -SUBROUTINE FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, & +SUBROUTINE FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, & IceF, IceD, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_global_next !< next global time step (t + dt), at which we're extrapolating inputs (and ED outputs) @@ -5835,6 +6221,7 @@ SUBROUTINE FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, A TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data @@ -5926,7 +6313,7 @@ SUBROUTINE FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, A CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) AD14%InputTimes(1) = t_global_next - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN + ELSEIF ( (p_FAST%CompAero == Module_AD ) .or. (p_FAST%CompAero == Module_ExtLd ) ) THEN CALL AD_Input_ExtrapInterp(AD%Input, AD%InputTimes, AD%u, t_global_next, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) @@ -5945,7 +6332,10 @@ SUBROUTINE FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, A END IF ! CompAero - + IF (p_FAST%CompAero == Module_ExtLd ) THEN + ! Don't need to do anything here. ExtLoads does not have inputs at different times + END IF + ! InflowWind IF ( p_FAST%CompInflow == Module_IfW ) THEN diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 945a5926de..f2a0dc864d 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -49,18 +49,18 @@ SUBROUTINE FAST_InitializeAll_T( t_initial, TurbID, Turbine, ErrStat, ErrMsg, In IF (PRESENT(InFile)) THEN IF (PRESENT(ExternInitData)) THEN CALL FAST_InitializeAll( t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX,& + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX,& Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg, InFile, ExternInitData ) ELSE CALL FAST_InitializeAll( t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg, InFile ) END IF ELSE CALL FAST_InitializeAll( t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) END IF @@ -69,7 +69,7 @@ SUBROUTINE FAST_InitializeAll_T( t_initial, TurbID, Turbine, ErrStat, ErrMsg, In END SUBROUTINE FAST_InitializeAll_T !---------------------------------------------------------------------------------------------------------------------------------- !> Routine to call Init routine for each module. This routine sets all of the init input data for each module. -SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & +SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg, InFile, ExternInitData ) use ElastoDyn_Parameters, only: Method_RK4 @@ -84,6 +84,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< SuperController exchange data @@ -205,7 +206,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (ExternInitData%FarmIntegration) then ! we're integrating with FAST.Farm CALL FAST_Init( p_FAST, m_FAST, y_FAST, t_initial, InputFile, ErrStat2, ErrMsg2, ExternInitData%TMax, OverrideAbortLev=.false., RootName=ExternInitData%RootName ) else - CALL FAST_Init( p_FAST, m_FAST, y_FAST, t_initial, InputFile, ErrStat2, ErrMsg2, ExternInitData%TMax, ExternInitData%TurbineID ) ! We have the name of the input file and the simulation length from somewhere else (e.g. Simulink) + CALL FAST_Init( p_FAST, m_FAST, y_FAST, t_initial, InputFile, ErrStat2, ErrMsg2, ExternInitData%TMax, ExternInitData%TurbineID, DTdriver=ExternInitData%DTdriver ) ! We have the name of the input file and the simulation length from somewhere else (e.g. Simulink) end if else @@ -236,6 +237,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( ED%Input_bak( p_FAST%InterpOrder+1 ), ED%InputTimes_bak( p_FAST%InterpOrder+1 ), ED%Output_bak( p_FAST%InterpOrder+1 ),STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating ED%Input_bak, ED%Output_bak, and ED%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + Init%InData_ED%Linearize = p_FAST%Linearize Init%InData_ED%CompAeroMaps = .FALSE. Init%InData_ED%RotSpeed = 0.0 ! will set this in a future commit that includes the OpenFAST AeroMap/Steady-State solver @@ -314,10 +322,17 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( BD%x( p_FAST%nBeams,2), & - BD%xd( p_FAST%nBeams,2), & - BD%z( p_FAST%nBeams,2), & - BD%OtherSt( p_FAST%nBeams,2), & + ALLOCATE( BD%Input_bak( p_FAST%InterpOrder+1, p_FAST%nBeams ), BD%InputTimes_bak( p_FAST%InterpOrder+1, p_FAST%nBeams ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating BD%Input_bak and BD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + + ALLOCATE( BD%x( p_FAST%nBeams,4), & + BD%xd( p_FAST%nBeams,4), & + BD%z( p_FAST%nBeams,4), & + BD%OtherSt( p_FAST%nBeams,4), & BD%p( p_FAST%nBeams ), & BD%u( p_FAST%nBeams ), & BD%y( p_FAST%nBeams ), & @@ -421,6 +436,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( AD14%Input_bak( p_FAST%InterpOrder+1 ), AD14%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating AD14%Input_bak and AD14%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + ALLOCATE( AD%Input( p_FAST%InterpOrder+1 ), AD%InputTimes( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating AD%Input and AD%InputTimes.",ErrStat,ErrMsg,RoutineName) @@ -428,6 +450,12 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( AD%Input_bak( p_FAST%InterpOrder+1 ), AD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating AD%Input and AD%InputTimes.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF IF ( p_FAST%CompAero == Module_AD14 ) THEN @@ -449,7 +477,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN + ELSEIF ( (p_FAST%CompAero == Module_AD) .OR. (p_FAST%CompAero == Module_ExtLd) ) THEN allocate(Init%InData_AD%rotors(1), stat=ErrStat2) if (ErrStat2 /= 0 ) then @@ -535,6 +563,29 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AirDens = 0.0_ReKi END IF ! CompAero + IF ( p_FAST%CompAero == Module_ExtLd ) THEN + + IF ( PRESENT(ExternInitData) ) THEN + + ! set initialization data for ExtLoads + CALL ExtLd_SetInitInput(Init%InData_ExtLd, Init%OutData_ED, ED%y, Init%OutData_BD, BD%y(:), Init%OutData_AD, p_FAST, ExternInitData, ErrStat2, ErrMsg2) + CALL ExtLd_Init( Init%InData_ExtLd, ExtLd%u, ExtLd%xd(1), ExtLd%p, ExtLd%y, ExtLd%m, p_FAST%dt_module( MODULE_ExtLd ), Init%OutData_ExtLd, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + p_FAST%ModuleInitialized(Module_ExtLd) = .TRUE. + CALL SetModuleSubstepTime(Module_ExtLd, p_FAST, y_FAST, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + IF (ErrStat >= AbortErrLev) THEN + CALL Cleanup() + RETURN + END IF + + AirDens = Init%OutData_ExtLd%AirDens + + END IF + + END IF ! ........................ ! initialize InflowWind @@ -546,6 +597,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( IfW%Input_bak( p_FAST%InterpOrder+1 ), IfW%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating IfW%Input_bak and IfW%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + IF ( p_FAST%CompInflow == Module_IfW ) THEN Init%InData_IfW%Linearize = p_FAST%Linearize @@ -760,6 +818,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( SeaSt%Input_bak( p_FAST%InterpOrder+1 ), SeaSt%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating SeaSt%Input_bak and SeaSt%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + if ( p_FAST%CompSeaSt == Module_SeaSt ) then Init%InData_SeaSt%Gravity = p_FAST%Gravity @@ -849,6 +914,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( HD%Input_bak( p_FAST%InterpOrder+1 ), HD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating HD%Input_bak and HD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + IF ( p_FAST%CompHydro == Module_HD ) THEN Init%InData_HD%Gravity = p_FAST%Gravity @@ -903,6 +975,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( SD%Input_bak( p_FAST%InterpOrder+1 ), SD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating SD%Input_bak and SD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + ALLOCATE( ExtPtfm%Input( p_FAST%InterpOrder+1 ), ExtPtfm%InputTimes( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating ExtPtfm%Input and ExtPtfm%InputTimes.",ErrStat,ErrMsg,RoutineName) @@ -910,6 +989,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( ExtPtfm%Input_bak( p_FAST%InterpOrder+1 ), ExtPtfm%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating ExtPtfm%Input_bak and ExtPtfm%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + IF ( p_FAST%CompSub == Module_SD ) THEN IF ( p_FAST%CompHydro == Module_HD ) THEN @@ -1001,24 +1087,48 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF + ALLOCATE( MAPp%Input_bak( p_FAST%InterpOrder+1 ), MAPp%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating MAPp%Input_bak and MAPp%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF ALLOCATE( MD%Input( p_FAST%InterpOrder+1 ), MD%InputTimes( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating MD%Input and MD%InputTimes.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF + ALLOCATE( MD%Input_bak( p_FAST%InterpOrder+1 ), MD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating MD%Input_bak and MD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF ALLOCATE( FEAM%Input( p_FAST%InterpOrder+1 ), FEAM%InputTimes( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating FEAM%Input and FEAM%InputTimes.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF + ALLOCATE( FEAM%Input_bak( p_FAST%InterpOrder+1 ), FEAM%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating FEAM%Input_bak and FEAM%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF ALLOCATE( Orca%Input( p_FAST%InterpOrder+1 ), Orca%InputTimes( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating Orca%Input and Orca%InputTimes.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF + ALLOCATE( Orca%Input_bak( p_FAST%InterpOrder+1 ), Orca%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating Orca%Input_bak and Orca%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF ! ........................ ! initialize MAP @@ -1176,6 +1286,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( IceF%Input_bak( p_FAST%InterpOrder+1 ), IceF%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating IceF%Input_bak and IceF%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + ! We need this to be allocated (else we have issues passing nonallocated arrays and using the first index of Input(), ! but we don't need the space of IceD_MaxLegs if we're not using it. IF ( p_FAST%CompIce /= Module_IceD ) THEN @@ -1193,10 +1310,17 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( IceD%x( IceDim,2), & - IceD%xd( IceDim,2), & - IceD%z( IceDim,2), & - IceD%OtherSt( IceDim,2), & + ALLOCATE( IceD%Input_bak( p_FAST%InterpOrder+1, IceDim ), IceD%InputTimes_bak( p_FAST%InterpOrder+1, IceDim ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating IceD%Input_bak and IceD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + + ALLOCATE( IceD%x( IceDim,4), & + IceD%xd( IceDim,4), & + IceD%z( IceDim,4), & + IceD%OtherSt( IceDim,4), & IceD%p( IceDim ), & IceD%u( IceDim ), & IceD%y( IceDim ), & @@ -1295,6 +1419,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF + ALLOCATE( SrvD%Input_bak( p_FAST%InterpOrder+1 ), SrvD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating SrvD%Input_bak and SrvD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + IF ( p_FAST%CompServo == Module_SrvD ) THEN Init%InData_SrvD%InputFile = p_FAST%ServoFile Init%InData_SrvD%RootName = TRIM(p_FAST%OutFileRoot)//'.'//TRIM(y_FAST%Module_Abrev(Module_SrvD)) @@ -1459,7 +1590,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! Initialize mesh-mapping data ! ------------------------------------------------------------------------- - CALL InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2) + CALL InitModuleMappings(p_FAST, ED, BD, AD14, AD, ExtLd, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) THEN @@ -1716,7 +1847,7 @@ END SUBROUTINE GetInputFileName !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine checks for command-line arguments, gets the root name of the input files !! (including full path name), and creates the names of the output files. -SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, TMax, TurbID, OverrideAbortLev, RootName ) +SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, TMax, TurbID, OverrideAbortLev, RootName, DTdriver ) IMPLICIT NONE @@ -1733,6 +1864,8 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, INTEGER(IntKi), INTENT(IN), OPTIONAL :: TurbID !< an ID for naming the tubine output file LOGICAL, INTENT(IN), OPTIONAL :: OverrideAbortLev !< whether or not we should override the abort error level (e.g., FAST.Farm) CHARACTER(*), INTENT(IN), OPTIONAL :: RootName !< A CHARACTER string containing the root name of FAST output files, overriding normal naming convention + REAL(DbKi), INTENT(IN), OPTIONAL :: DTdriver !< Driver program time step + ! Local variables INTEGER :: i ! loop counter @@ -1793,6 +1926,7 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, y_FAST%Module_Ver( Module_BD )%Name = 'BeamDyn' y_FAST%Module_Ver( Module_AD14 )%Name = 'AeroDyn14' y_FAST%Module_Ver( Module_AD )%Name = 'AeroDyn' + y_FAST%Module_Ver( Module_ExtLd )%Name = 'ExtLoads' y_FAST%Module_Ver( Module_SrvD )%Name = 'ServoDyn' y_FAST%Module_Ver( Module_SeaSt )%Name = 'SeaState' y_FAST%Module_Ver( Module_HD )%Name = 'HydroDyn' @@ -1812,6 +1946,7 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, y_FAST%Module_Abrev( Module_BD ) = 'BD' y_FAST%Module_Abrev( Module_AD14 ) = 'AD' y_FAST%Module_Abrev( Module_AD ) = 'AD' + y_FAST%Module_Abrev( Module_ExtLd ) = 'ExtLd' y_FAST%Module_Abrev( Module_SrvD ) = 'SrvD' y_FAST%Module_Abrev( Module_SeaSt ) = 'SEA' y_FAST%Module_Abrev( Module_HD ) = 'HD' @@ -1845,6 +1980,15 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, !p%TMax = MAX( TMax, p%TMax ) END IF + IF (PRESENT(DTdriver)) THEN + IF ( ABS( NINT(DTdriver/p%DT) * p%DT - DTdriver ) .lt. 0.001 ) THEN + p%DT_Out = NINT(DTdriver/p%DT) * p%DT + p%n_DT_Out = NINT(DTdriver/p%DT) + ELSE + CALL SetErrStat( ErrID_Fatal, 'DTdriver specified '//TRIM ( Num2LStr( DTdriver ) )//' is not an integral multiple of FAST time step '//TRIM ( Num2LStr( p%DT ) ), ErrStat, ErrMsg, RoutineName ) + END IF + END IF + IF ( ErrStat >= AbortErrLev ) RETURN @@ -1937,7 +2081,7 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) IF ( p%KMax < 1_IntKi ) CALL SetErrStat( ErrID_Fatal, 'KMax must be greater than 0.', ErrStat, ErrMsg, RoutineName ) IF (p%CompElast == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompElast must be 1 (ElastoDyn) or 2 (BeamDyn).', ErrStat, ErrMsg, RoutineName ) - IF (p%CompAero == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompAero must be 0 (None), 1 (AeroDyn14), or 2 (AeroDyn).', ErrStat, ErrMsg, RoutineName ) + IF (p%CompAero == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompAero must be 0 (None), 1 (AeroDyn14), 2 (AeroDyn), or 3 (ExtLoads).', ErrStat, ErrMsg, RoutineName ) IF (p%CompServo == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompServo must be 0 (None) or 1 (ServoDyn).', ErrStat, ErrMsg, RoutineName ) IF (p%CompSeaSt == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompSeaSt must be 0 (None) or 1 (SeaState).', ErrStat, ErrMsg, RoutineName ) IF (p%CompHydro == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompHydro must be 0 (None) or 1 (HydroDyn).', ErrStat, ErrMsg, RoutineName ) @@ -1976,6 +2120,7 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) IF (p%CompElast == Module_BD .and. p%CompAero == Module_AD14 ) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used when BeamDyn is used. Change CompAero or CompElast in the FAST input file.', ErrStat, ErrMsg, RoutineName ) if (p%CompInflow == MODULE_ExtInfw .and. p%CompAero == Module_AD14 ) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used when ExternalInflow is used. Change CompAero or CompInflow in the FAST input file.', ErrStat, ErrMsg, RoutineName ) + if ((p%CompAero == Module_ExtLd) .and. (p%CompInflow /= Module_NONE) ) call SetErrStat(ErrID_Fatal, 'Inflow module cannot be used when ExtLoads is used. Change CompAero or CompInflow in the OpenFAST input file.', ErrStat, ErrMsg, RoutineName) IF (p%MHK /= MHK_None .and. p%MHK /= MHK_FixedBottom .and. p%MHK /= MHK_Floating) CALL SetErrStat( ErrID_Fatal, 'MHK switch is invalid. Set MHK to 0, 1, or 2 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) @@ -2129,7 +2274,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) IF ( p_FAST%CompAero == Module_AD14 ) THEN y_FAST%Module_Ver( Module_AD14 ) = Init%OutData_AD14%Ver y_FAST%FileDescLines(2) = TRIM(y_FAST%FileDescLines(2) ) //'; '//TRIM(GetNVD(y_FAST%Module_Ver( Module_AD14 ) )) - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN y_FAST%Module_Ver( Module_AD ) = Init%OutData_AD%Ver y_FAST%FileDescLines(2) = TRIM(y_FAST%FileDescLines(2) ) //'; '//TRIM(GetNVD(y_FAST%Module_Ver( Module_AD ) )) END IF @@ -2227,12 +2372,6 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) indxNext = y_FAST%numOuts(Module_Glue) + 1 - - DO i=1,y_FAST%numOuts(Module_IfW) !InflowWind - y_FAST%ChannelNames(indxNext) = Init%OutData_IfW%WriteOutputHdr(i) - y_FAST%ChannelUnits(indxNext) = Init%OutData_IfW%WriteOutputUnt(i) - indxNext = indxNext + 1 - END DO DO i=1,y_FAST%numOuts(Module_ExtInfw) !ExternalInflow y_FAST%ChannelNames(indxNext) = Init%OutData_ExtInfw%WriteOutputHdr(i) @@ -2240,6 +2379,12 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) indxNext = indxNext + 1 END DO + DO i=1,y_FAST%numOuts(Module_IfW) !InflowWind + y_FAST%ChannelNames(indxNext) = Init%OutData_IfW%WriteOutputHdr(i) + y_FAST%ChannelUnits(indxNext) = Init%OutData_IfW%WriteOutputUnt(i) + indxNext = indxNext + 1 + END DO + DO i=1,y_FAST%numOuts(Module_ED) !ElastoDyn y_FAST%ChannelNames(indxNext) = Init%OutData_ED%WriteOutputHdr(i) y_FAST%ChannelUnits(indxNext) = Init%OutData_ED%WriteOutputUnt(i) @@ -2700,7 +2845,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS END IF ! CompAero - Compute aerodynamic loads (switch) {0=None; 1=AeroDyn}: - CALL ReadVar( UnIn, InputFile, p%CompAero, "CompAero", "Compute aerodynamic loads (switch) {0=None; 1=AeroDyn14; 2=AeroDyn}", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, p%CompAero, "CompAero", "Compute aerodynamic loads (switch) {0=None; 1=AeroDyn14; 2=AeroDyn; 3=ExtLoads}", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -2714,6 +2859,8 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS p%CompAero = Module_AD14 ELSEIF ( p%CompAero == 2 ) THEN p%CompAero = Module_AD + ELSEIF ( p%CompAero == 3 ) THEN + p%CompAero = Module_ExtLd ELSE p%CompAero = Module_Unknown END IF @@ -3865,6 +4012,284 @@ SUBROUTINE WrVTK_Ground ( RefPoint, HalfLengths, FileRootName, ErrStat, ErrMsg ) END SUBROUTINE WrVTK_Ground !---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine sets up the information needed to initialize ExtLoads +SUBROUTINE ExtLd_SetInitInput(InitInData_ExtLd, InitOutData_ED, y_ED, InitOutData_BD, y_BD, InitOutData_AD, p_FAST, ExternInitData, ErrStat, ErrMsg) + ! Passed variables: + TYPE(ExtLd_InitInputType), INTENT(INOUT) :: InitInData_ExtLd !< The initialization input to ExtLoads + TYPE(ED_InitOutputType), INTENT(IN) :: InitOutData_ED !< The initialization output from structural dynamics module + TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs of the structural dynamics module (meshes with position/RefOrientation set) + TYPE(BD_InitOutputType), INTENT(IN) :: InitOutData_BD(:) !< The initialization output from structural dynamics module + TYPE(BD_OutputType), INTENT(IN) :: y_BD(:) !< The outputs of the structural dynamics module (meshes with position/RefOrientation set) + TYPE(AD_InitOutputType), INTENT(IN) :: InitOutData_AD !< The initialization output from AeroDyn + TYPE(FAST_ParameterType), INTENT(IN) :: p_FAST !< The parameters of the glue code + TYPE(FAST_ExternInitType), INTENT(IN) :: ExternInitData !< Initialization input data from an external source + + INTEGER(IntKi) :: ErrStat !< Error status of the operation + CHARACTER(*) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! Local variables + INTEGER :: i,j,k,jLower,tmp + integer :: nNodesBladeProps, nNodesTowerProps + real(ReKi) :: rInterp + INTEGER :: nTotBldNds + INTEGER :: nMaxBldNds + REAL(ReKi) :: tmp_eta + + REAL(ReKi), ALLOCATABLE :: AD_etaNodes(:) ! Non-dimensional co-ordinates eta at which the blade and tower chord are defined + + ErrStat = ErrID_None + ErrMsg = "" + + InitInData_ExtLd%NumBlades = InitOutData_ED%NumBl + IF (.NOT. ALLOCATED( InitInData_ExtLd%NumBldNodes) ) THEN + ALLOCATE( InitInData_ExtLd%NumBldNodes(InitInData_ExtLd%NumBlades), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_ExtLd%NumBldNodes.' + RETURN + ELSE + ErrStat = ErrID_None !reset to ErrID_None, just in case ErrID_None /= 0 + END IF + END IF + + ! Blade node positions and orientations + nTotBldNds = 0 + nMaxBldNds = 0 + IF (p_FAST%CompElast == Module_ED ) THEN + nMaxBldNds = SIZE(y_ED%BladeLn2Mesh(1)%position(1,:)) + nTotBldNds = nMaxBldNds * InitInData_ExtLd%NumBlades + InitInData_ExtLd%NumBldNodes(:) = nMaxBldNds + ELSE IF (p_FAST%CompElast == Module_BD ) THEN + do k=1,InitInData_ExtLd%NumBlades + tmp = SIZE(y_BD(k)%BldMotion%position(1,:)) + nMaxBldNds = max(nMaxBldNds, tmp) + nTotBldNds = nTotBldNds + tmp + InitInData_ExtLd%NumBldNodes(k) = tmp + end do + END IF + + IF (.NOT. ALLOCATED( InitInData_ExtLd%BldRootPos) ) THEN + ALLOCATE( InitInData_ExtLd%BldRootPos( 3, InitInData_ExtLd%NumBlades), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_ExtLd%BldRootPos.' + RETURN + ELSE + ErrStat = ErrID_None !reset to ErrID_None, just in case ErrID_None /= 0 + END IF + END IF + + IF (.NOT. ALLOCATED( InitInData_ExtLd%BldRootOrient) ) THEN + ALLOCATE( InitInData_ExtLd%BldRootOrient( 3, 3, InitInData_ExtLd%NumBlades), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_ExtLd%BldRootOrient.' + RETURN + ELSE + ErrStat = ErrID_None !reset to ErrID_None, just in case ErrID_None /= 0 + END IF + END IF + + IF (.NOT. ALLOCATED( InitInData_ExtLd%BldPos) ) THEN + ALLOCATE( InitInData_ExtLd%BldPos( 3, nMaxBldNds, InitInData_ExtLd%NumBlades), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_ExtLd%BldPos.' + RETURN + ELSE + ErrStat = ErrID_None !reset to ErrID_None, just in case ErrID_None /= 0 + END IF + END IF + + IF (.NOT. ALLOCATED( InitInData_ExtLd%BldOrient) ) THEN + ALLOCATE( InitInData_ExtLd%BldOrient( 3, 3, nMaxBldNds, InitInData_ExtLd%NumBlades), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_ExtLd%BldOrient.' + RETURN + ELSE + ErrStat = ErrID_None !reset to ErrID_None, just in case ErrID_None /= 0 + END IF + END IF + + IF (p_FAST%CompElast == Module_ED ) THEN + DO k=1,InitInData_ExtLd%NumBlades + InitInData_ExtLd%BldRootPos(:,k) = y_ED%BladeRootMotion(k)%position(:,1) + InitInData_ExtLd%BldRootOrient(:,:,k) = y_ED%BladeRootMotion(k)%RefOrientation(:,:,1) + !Deal with the weird node ordering in ElastoDyn where the blade root is the last node + InitInData_ExtLd%BldPos(:,1,k) = y_ED%BladeLn2Mesh(k)%position(:,nMaxBldNds) + InitInData_ExtLd%BldOrient(:,:,1,k) = y_ED%BladeLn2Mesh(k)%RefOrientation(:,:,nMaxBldNds) + !Now fill in the rest of the nodes + InitInData_ExtLd%BldPos(:,2:nMaxBldNds,k) = y_ED%BladeLn2Mesh(k)%position(:,1:nMaxBldNds-1) + InitInData_ExtLd%BldOrient(:,:,2:nMaxBldNds,k) = y_ED%BladeLn2Mesh(k)%RefOrientation(:,:,1:nMaxBldNds-1) + END DO + ELSE IF (p_FAST%CompElast == Module_BD ) THEN + DO k=1,InitInData_ExtLd%NumBlades + InitInData_ExtLd%BldRootPos(:,k) = y_ED%BladeRootMotion(k)%position(:,1) + InitInData_ExtLd%BldRootOrient(:,:,k) = y_ED%BladeRootMotion(k)%RefOrientation(:,:,1) + InitInData_ExtLd%BldPos(:,:,k) = y_BD(k)%BldMotion%position(:,:) + InitInData_ExtLd%BldOrient(:,:,:,k) = y_BD(k)%BldMotion%RefOrientation(:,:,:) + END DO + END IF + + IF (.NOT. ALLOCATED( InitInData_ExtLd%BldRloc) ) THEN + ALLOCATE( InitInData_ExtLd%BldRloc( nMaxBldNds, InitInData_ExtLd%NumBlades), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_ExtLd%BldRloc.' + RETURN + ELSE + ErrStat = ErrID_None !reset to ErrID_None, just in case ErrID_None /= 0 + END IF + END IF + + do k=1,InitInData_ExtLd%NumBlades + InitInData_ExtLd%BldRloc(1,k) = 0.0 + do j = 2, InitInData_ExtLd%NumBldNodes(k) + InitInData_ExtLd%BldRloc(j,k) = InitInData_ExtLd%BldRloc(j-1,k) + norm2(InitInData_ExtLd%BldPos(:,j,k) - InitInData_ExtLd%BldPos(:,j-1,k)) + end do + end do + + ! Tower mesh + InitInData_ExtLd%TwrAero = .true. + if (InitInData_ExtLd%TwrAero) then + InitInData_ExtLd%NumTwrNds = y_ED%TowerLn2Mesh%NNodes + IF ( InitInData_ExtLd%NumTwrNds > 0 ) THEN + + IF (.NOT. ALLOCATED( InitInData_ExtLd%TwrPos ) ) THEN + ALLOCATE( InitInData_ExtLd%TwrPos( 3, InitInData_ExtLd%NumTwrNds ), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_AD%TwrNodeLocs.' + RETURN + ELSE + ErrStat = ErrID_None + END IF + END IF + IF (.NOT. ALLOCATED( InitInData_ExtLd%TwrOrient ) ) THEN + ALLOCATE( InitInData_ExtLd%TwrOrient( 3, 3, InitInData_ExtLd%NumTwrNds ), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_AD%TwrOrient.' + RETURN + ELSE + ErrStat = ErrID_None + END IF + END IF + + ! For some reason, ElastoDyn keeps the last point as the blade/tower root + InitInData_ExtLd%TwrPos(:,1) = y_ED%TowerLn2Mesh%Position(:,InitInData_ExtLd%NumTwrNds) + InitInData_ExtLd%TwrOrient(:,:,1) = y_ED%TowerLn2Mesh%RefOrientation(:,:,InitInData_ExtLd%NumTwrNds) + ! Now fill in rest of the nodes + InitInData_ExtLd%TwrPos(:,2:InitInData_ExtLd%NumTwrNds) = y_ED%TowerLn2Mesh%Position(:,1:InitInData_ExtLd%NumTwrNds-1) + InitInData_ExtLd%TwrOrient(:,:,2:InitInData_ExtLd%NumTwrNds) = y_ED%TowerLn2Mesh%RefOrientation(:,:,1:InitInData_ExtLd%NumTwrNds-1) + + IF (.NOT. ALLOCATED( InitInData_ExtLd%TwrDia ) ) THEN + ALLOCATE( InitInData_ExtLd%TwrDia( InitInData_ExtLd%NumTwrNds ), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_AD%TwrDia.' + RETURN + ELSE + ErrStat = ErrID_None + END IF + END IF + + IF (.NOT. ALLOCATED( InitInData_ExtLd%TwrHloc ) ) THEN + ALLOCATE( InitInData_ExtLd%TwrHloc( InitInData_ExtLd%NumTwrNds ), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_AD%TwrHloc.' + RETURN + ELSE + ErrStat = ErrID_None + END IF + END IF + + InitInData_ExtLd%TwrHloc(1) = 0.0 + do j = 2, InitInData_ExtLd%NumTwrNds + InitInData_ExtLd%TwrHloc(j) = InitInData_ExtLd%TwrHloc(j-1) + norm2(InitInData_ExtLd%TwrPos(:,j) - InitInData_ExtLd%TwrPos(:,j-1)) + end do + END IF + + else + + InitInData_ExtLd%NumTwrNds = 0 + + end if + + InitInData_ExtLd%HubPos = y_ED%HubPtMotion%Position(:,1) + InitInData_ExtLd%HubOrient = y_ED%HubPtMotion%RefOrientation(:,:,1) + + InitInData_ExtLd%NacellePos = y_ED%NacelleMotion%Position(:,1) + InitInData_ExtLd%NacelleOrient = y_ED%NacelleMotion%RefOrientation(:,:,1) + + InitInData_ExtLd%az_blend_mean = ExternInitData%az_blend_mean + InitInData_ExtLd%az_blend_delta = ExternInitData%az_blend_delta + InitInData_ExtLd%vel_mean = ExternInitData%vel_mean + InitInData_ExtLd%wind_dir = ExternInitData%wind_dir + InitInData_ExtLd%z_ref = ExternInitData%z_ref + InitInData_ExtLd%shear_exp = ExternInitData%shear_exp + + !Interpolate chord from AeroDyn to nodes of the ExtLoads module + IF (.NOT. ALLOCATED( InitInData_ExtLd%BldChord) ) THEN + ALLOCATE( InitInData_ExtLd%BldChord(nMaxBldNds, InitInData_ExtLd%NumBlades), STAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' Error allocating space for InitInData_ExtLd%BldRootPos.' + RETURN + ELSE + ErrStat = ErrID_None !reset to ErrID_None, just in case ErrID_None /= 0 + END IF + END IF + + ! The blades first + do k = 1, InitInData_ExtLd%NumBlades + ! Calculate the chord at the force nodes based on interpolation + nNodesBladeProps = SIZE(InitOutData_AD%rotors(1)%BladeProps(k)%BlChord) + allocate(AD_etaNodes(nNodesBladeProps)) + AD_etaNodes = InitOutData_AD%rotors(1)%BladeProps(k)%BlSpn(:)/InitOutData_AD%rotors(1)%BladeProps(k)%BlSpn(nNodesBladeProps) + do i=1,InitInData_ExtLd%NumBldNodes(k) + jLower=1 + tmp_eta = InitInData_ExtLd%BldRloc(i,k)/InitInData_ExtLd%BldRloc(InitInData_ExtLd%NumBldNodes(k),k) + do while ( ( (AD_etaNodes(jLower) - tmp_eta)*(AD_etaNodes(jLower+1) - tmp_eta) .gt. 0 ) .and. (jLower .lt. nNodesBladeProps) )!Determine the closest two nodes at which the blade properties are specified + jLower = jLower + 1 + end do + if (jLower .lt. nNodesBladeProps) then + rInterp = (tmp_eta - AD_etaNodes(jLower))/(AD_etaNodes(jLower+1)-AD_etaNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes + InitInData_ExtLd%BldChord(i,k) = InitOutData_AD%rotors(1)%BladeProps(k)%BlChord(jLower) + rInterp * (InitOutData_AD%rotors(1)%BladeProps(k)%BlChord(jLower+1) - InitOutData_AD%rotors(1)%BladeProps(k)%BlChord(jLower)) + else + InitInData_ExtLd%BldChord(i,k) = InitOutData_AD%rotors(1)%BladeProps(k)%BlChord(nNodesBladeProps) !Work around for when the last node of the actuator mesh is slightly outside of the Aerodyn blade properties. Surprisingly this is not an issue with the tower. + end if + end do + deallocate(AD_etaNodes) + end do + + ! The tower now + if ( InitInData_ExtLd%NumTwrNds > 0 ) then + nNodesTowerProps = SIZE(InitOutData_AD%rotors(1)%TwrElev) + allocate(AD_etaNodes(nNodesTowerProps)) + ! Calculate the chord at the force nodes based on interpolation + AD_etaNodes = InitOutData_AD%rotors(1)%TwrElev(:)/InitOutData_AD%rotors(1)%TwrElev(nNodesTowerProps) ! Non-dimensionalize the tower elevation array + do i=1,InitInData_ExtLd%NumTwrNds + tmp_eta = InitInData_ExtLd%TwrHloc(i)/InitInData_ExtLd%TwrHloc(InitInData_ExtLd%NumTwrNds) + do jLower = 1, nNodesTowerProps - 1 + if ((AD_etaNodes(jLower) - tmp_eta)*(AD_etaNodes(jLower+1) - tmp_eta) <= 0) exit + end do + if (jLower .lt. nNodesTowerProps) then + rInterp = (tmp_eta - AD_etaNodes(jLower))/(AD_etaNodes(jLower+1)-AD_etaNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes + InitInData_ExtLd%TwrDia(i) = InitOutData_AD%rotors(1)%TwrDiam(jLower) + rInterp * (InitOutData_AD%rotors(1)%TwrDiam(jLower+1) - InitOutData_AD%rotors(1)%TwrDiam(jLower)) + else + InitInData_ExtLd%TwrDia(i) = InitOutData_AD%rotors(1)%TwrDiam(nNodesTowerProps) !Work around for when the last node of the actuator mesh is slightly outside of the Aerodyn tower properties. + end if + end do + deallocate(AD_etaNodes) + end if + + RETURN + +END SUBROUTINE ExtLd_SetInitInput +!---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets up the information needed to initialize AeroDyn, then initializes AeroDyn SUBROUTINE AD_SetInitInput(InitInData_AD14, InitOutData_ED, y_ED, p_FAST, ErrStat, ErrMsg) @@ -4176,14 +4601,14 @@ SUBROUTINE FAST_Solution0_T(Turbine, ErrStat, ErrMsg) CALL FAST_Solution0(Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX,& + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX,& Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) END SUBROUTINE FAST_Solution0_T !---------------------------------------------------------------------------------------------------------------------------------- !> Routine that calls CalcOutput for the first time of the simulation (at t=0). After the initial solve, data arrays are initialized. -SUBROUTINE FAST_Solution0(p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & +SUBROUTINE FAST_Solution0(p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code @@ -4195,6 +4620,7 @@ SUBROUTINE FAST_Solution0(p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, E TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< Supercontroller exchange data @@ -4250,7 +4676,7 @@ SUBROUTINE FAST_Solution0(p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, E end if CALL CalcOutputs_And_SolveForInputs( n_t_global, t_initial, STATE_CURR, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & - p_FAST, m_FAST, y_FAST%WriteThisStep, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & + p_FAST, m_FAST, y_FAST%WriteThisStep, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -4442,7 +4868,7 @@ SUBROUTINE FAST_InitIOarrays( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, A CALL AD14_CopyOtherState( AD14%OtherSt(STATE_CURR), AD14%OtherSt(STATE_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 @@ -4745,6 +5171,2334 @@ SUBROUTINE FAST_InitIOarrays( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, A END SUBROUTINE FAST_InitIOarrays !---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_InitIOarrays_SS for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_InitIOarrays_SS_T(t_initial, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< start time of the simulation + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_InitIOarrays_SS_T' + + CALL FAST_InitIOarrays_SS(t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, & + Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, ErrStat2, ErrMsg2 ) + + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + +END SUBROUTINE FAST_InitIOarrays_SS_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine initializes the input and output arrays stored for extrapolation when used in a sub-timestepping mode with an external driver program. They are initialized after the first input-output solve so that the first +!! extrapolations are used with values from the solution, not just initial guesses. It also creates new copies of the state variables, which need to +!! be stored for the predictor-corrector loop. +SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< start time of the simulation + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(IN ) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(IN ) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn v14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< MoorDyn data + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + 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, j, k ! loop counters + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_InitIOarrays_SS' + + + ErrStat = ErrID_None + ErrMsg = "" + + ! We fill ED%InputTimes with negative times, but the ED%Input values are identical for each of those times; this allows + ! us to use, e.g., quadratic interpolation that effectively acts as a zeroth-order extrapolation and first-order extrapolation + ! for the first and second time steps. (The interpolation order in the ExtrapInput routines are determined as + ! order = SIZE(ED%Input) + + DO j = 1, p_FAST%InterpOrder + 1 + ED%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !ED_OutputTimes(p_FAST%InterpOrder + 1 + j) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL ED_CopyInput (ED%Input(1), ED%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ED_CopyOutput (ED%y, ED%Output_bak(1), MESH_NEWCOPY, Errstat2, ErrMsg2) !BJJ: THIS IS REALLY ONLY NECESSARY FOR ED-HD COUPLING AT THE MOMENT + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL ED_CopyContState (ED%x( STATE_CURR), ED%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyDiscState (ED%xd(STATE_CURR), ED%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyConstrState (ED%z( STATE_CURR), ED%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyOtherState (ED%OtherSt( STATE_CURR), ED%OtherSt( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + IF (p_FAST%CompElast == Module_BD ) THEN + + DO k = 1,p_FAST%nBeams + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + BD%InputTimes_bak(j,k) = t_initial - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL BD_CopyInput (BD%Input(1,k), BD%Input_bak(j,k), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL BD_CopyContState (BD%x( k,STATE_CURR), BD%x( k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyDiscState (BD%xd(k,STATE_CURR), BD%xd(k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyConstrState (BD%z( k,STATE_CURR), BD%z( k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_CURR), BD%OtherSt( k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END DO ! nBeams + + END IF ! CompElast + + + IF ( p_FAST%CompServo == Module_SrvD ) THEN + ! Initialize Input-Output arrays for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + SrvD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !SrvD_OutputTimes(j) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL SrvD_CopyInput (SrvD%Input(1), SrvD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL SrvD_CopyContState (SrvD%x( STATE_CURR), SrvD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_CURR), SrvD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyConstrState (SrvD%z( STATE_CURR), SrvD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyOtherState( SrvD%OtherSt(STATE_CURR), SrvD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyOtherState( SrvD%OtherSt(STATE_PRED), SrvD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL SrvD_CopyMisc( SrvD%m, SrvD%m_bak, MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompServo + + + IF ( p_FAST%CompAero == Module_AD14 ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + AD14%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL AD14_CopyInput (AD14%Input(1), AD14%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL AD14_CopyContState (AD14%x( STATE_CURR), AD14%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyDiscState (AD14%xd(STATE_CURR), AD14%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyConstrState (AD14%z( STATE_CURR), AD14%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyOtherState( AD14%OtherSt(STATE_CURR), AD14%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyOtherState( AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + AD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL AD_CopyInput (AD%Input(1), AD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL AD_CopyContState(AD%x(STATE_CURR), AD%x(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyDiscState(AD%xd(STATE_CURR), AD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyConstrState(AD%z(STATE_CURR), AD%z(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyOtherState(AD%OtherSt(STATE_CURR), AD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL AD_CopyContState(AD%x(STATE_PRED), AD%x(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyDiscState(AD%xd(STATE_PRED), AD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyConstrState(AD%z(STATE_PRED), AD%z(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyOtherState(AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompAero == Module_AD + + + + IF ( p_FAST%CompInflow == Module_IfW ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + IfW%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !IfW%OutputTimes(i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL InflowWind_CopyInput (IfW%Input(1), IfW%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL InflowWind_CopyContState (IfW%x( STATE_CURR), IfW%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_CURR), IfW%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyConstrState (IfW%z( STATE_CURR), IfW%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyOtherState( IfW%OtherSt(STATE_CURR), IfW%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyOtherState( IfW%OtherSt(STATE_PRED), IfW%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompInflow == Module_IfW + + + IF ( p_FAST%CompHydro == Module_HD ) THEN + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + HD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !HD_OutputTimes(i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL HydroDyn_CopyInput (HD%Input(1), HD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL HydroDyn_CopyContState (HD%x( STATE_CURR), HD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_CURR), HD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyConstrState (HD%z( STATE_CURR), HD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyOtherState( HD%OtherSt(STATE_CURR), HD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyOtherState( HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF !CompHydro + + + IF (p_FAST%CompSub == Module_SD ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + SD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !SD_OutputTimes(i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL SD_CopyInput (SD%Input(1), SD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL SD_CopyContState (SD%x( STATE_CURR), SD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyDiscState (SD%xd(STATE_CURR), SD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyConstrState (SD%z( STATE_CURR), SD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyOtherState( SD%OtherSt(STATE_CURR), SD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyOtherState( SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSE IF (p_FAST%CompSub == Module_ExtPtfm ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + ExtPtfm%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL ExtPtfm_CopyInput (ExtPtfm%Input(1), ExtPtfm%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_CURR), ExtPtfm%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_CURR), ExtPtfm%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_CURR), ExtPtfm%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyOtherState( ExtPtfm%OtherSt(STATE_CURR), ExtPtfm%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyOtherState( ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompSub + + + IF (p_FAST%CompMooring == Module_MAP) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + MAPp%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !MAP_OutputTimes(i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL MAP_CopyInput (MAPp%Input(1), MAPp%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL MAP_CopyContState (MAPp%x( STATE_CURR), MAPp%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyDiscState (MAPp%xd(STATE_CURR), MAPp%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyConstrState (MAPp%z( STATE_CURR), MAPp%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( p_FAST%n_substeps( MODULE_MAP ) > 1 ) THEN + CALL MAP_CopyOtherState( MAPp%OtherSt, MAPp%OtherSt_old, MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + ! Initialize predicted states for j_pc loop: + CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( p_FAST%n_substeps( MODULE_MAP ) > 1 ) THEN + CALL MAP_CopyOtherState( MAPp%OtherSt, MAPp%OtherSt_old, MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + ELSEIF (p_FAST%CompMooring == Module_MD) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + MD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !MD_OutputTimes(i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL MD_CopyInput (MD%Input(1), MD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL MD_CopyContState (MD%x( STATE_CURR), MD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyDiscState (MD%xd(STATE_CURR), MD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyConstrState (MD%z( STATE_CURR), MD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyOtherState( MD%OtherSt(STATE_CURR), MD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyOtherState( MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + + ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + FEAM%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !FEAM_OutputTimes(i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL FEAM_CopyInput (FEAM%Input(1), FEAM%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL FEAM_CopyContState (FEAM%x( STATE_CURR), FEAM%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_CURR), FEAM%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyConstrState (FEAM%z( STATE_CURR), FEAM%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyOtherState( FEAM%OtherSt(STATE_CURR), FEAM%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyOtherState( FEAM%OtherSt(STATE_PRED), FEAM%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompMooring == Module_Orca) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + Orca%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL Orca_CopyInput (Orca%Input(1), Orca%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL Orca_CopyContState (Orca%x( STATE_CURR), Orca%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyDiscState (Orca%xd(STATE_CURR), Orca%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyConstrState (Orca%z( STATE_CURR), Orca%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyOtherState( Orca%OtherSt(STATE_CURR), Orca%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyOtherState( Orca%OtherSt(STATE_PRED), Orca%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompMooring + + + IF (p_FAST%CompIce == Module_IceF ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + IceF%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + !IceF_OutputTimes(i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL IceFloe_CopyInput (IceF%Input(1), IceF%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL IceFloe_CopyContState (IceF%x( STATE_CURR), IceF%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_CURR), IceF%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyConstrState (IceF%z( STATE_CURR), IceF%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyOtherState( IceF%OtherSt(STATE_CURR), IceF%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyOtherState( IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompIce == Module_IceD ) THEN + + DO i = 1,p_FAST%numIceLegs + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + IceD%InputTimes_bak(j,i) = t_initial - (j - 1) * p_FAST%dt + !IceD%OutputTimes(j,i) = t_initial - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL IceD_CopyInput (IceD%Input(1,i), IceD%Input_bak(j,i), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + ! Initialize predicted states for j_pc loop: + CALL IceD_CopyContState (IceD%x( i,STATE_CURR), IceD%x( i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_CURR), IceD%xd(i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyConstrState (IceD%z( i,STATE_CURR), IceD%z( i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyOtherState( IceD%OtherSt(i,STATE_CURR), IceD%OtherSt(i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Initialize predicted states for j_pc loop: + CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyOtherState( IceD%OtherSt(i,STATE_PRED), IceD%OtherSt(i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END DO ! numIceLegs + + END IF ! CompIce + + +END SUBROUTINE FAST_InitIOarrays_SS +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_Reset_SS for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_Reset_SS_T(t_initial, n_t_global, n_timesteps, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + INTEGER(IntKi), INTENT(IN ) :: n_timesteps !< number of time steps to go back + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CALL FAST_Reset_SS(t_initial, n_t_global, n_timesteps, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & + Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + +END SUBROUTINE FAST_Reset_SS_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine resets the states, inputs and output data from n_t_global to n_t_global - 1 +SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + + USE BladedInterface, ONLY: CallBladedDLL ! Hack for Bladed-style DLL + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + INTEGER(IntKi), INTENT(IN ) :: n_timesteps !< number of time steps to go back + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data), INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + INTEGER(IntKi) :: j_pc ! predictor-corrector loop counter + INTEGER(IntKi) :: NumCorrections ! number of corrections for this time step + + INTEGER(IntKi) :: i, j, k ! generic loop counters + REAL(DbKi) :: t_global ! the time to which states, inputs and outputs are reset + INTEGER(IntKi) :: old_avrSwap1 ! previous value of avrSwap(1) !hack for Bladed DLL checkpoint/restore + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Solution' + + + ErrStat = ErrID_None + ErrMsg = "" + + + t_global = t_initial + n_t_global * p_FAST%DT + + !---------------------------------------------------------------------------------------- + !! copy the stored states and inputs from n_t_global the current states and inputs + !---------------------------------------------------------------------------------------- + + DO j = 1, p_FAST%InterpOrder + 1 + ED%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !ED_OutputTimes(j) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL ED_CopyInput (ED%Input_bak(j), ED%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + CALL ED_CopyOutput (ED%Output_bak(1), ED%y, MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! ElastoDyn: copy final predictions to actual states + CALL ED_CopyContState (ED%x( STATE_SS_PRED), ED%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyDiscState (ED%xd(STATE_SS_PRED), ED%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyConstrState (ED%z( STATE_SS_PRED), ED%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyOtherState (ED%OtherSt( STATE_SS_PRED), ED%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ED_CopyContState (ED%x( STATE_SS_CURR), ED%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyDiscState (ED%xd(STATE_SS_CURR), ED%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyConstrState (ED%z( STATE_SS_CURR), ED%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyOtherState (ED%OtherSt( STATE_SS_CURR), ED%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + IF (p_FAST%CompElast == Module_BD ) THEN + + DO k = 1,p_FAST%nBeams + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + BD%InputTimes(j,k) = t_global - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL BD_CopyInput (BD%Input_bak(j,k), BD%Input(j,k), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL BD_CopyContState (BD%x( k,STATE_SS_PRED), BD%x( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyDiscState (BD%xd(k,STATE_SS_PRED), BD%xd(k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyConstrState (BD%z( k,STATE_SS_PRED), BD%z( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_SS_PRED), BD%OtherSt( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL BD_CopyContState (BD%x( k,STATE_SS_CURR), BD%x( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyDiscState (BD%xd(k,STATE_SS_CURR), BD%xd(k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyConstrState (BD%z( k,STATE_SS_CURR), BD%z( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_SS_CURR), BD%OtherSt( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + END IF + + IF ( p_FAST%CompServo == Module_SrvD ) THEN + + ! A hack to restore Bladed-style DLL data + if (SrvD%p%UseBladedInterface) then + if (SrvD%m%dll_data%avrSWAP( 1) > 0 ) then ! this isn't allocated if UseBladedInterface is FALSE + ! store value to be overwritten + old_avrSwap1 = SrvD%m%dll_data%avrSWAP( 1) + SrvD%m%dll_data%avrSWAP( 1) = -10 + CALL CallBladedDLL(SrvD%Input(1), SrvD%p, SrvD%m%dll_data, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! put values back: + SrvD%m%dll_data%avrSWAP( 1) = old_avrSwap1 + end if + end if + + ! Initialize Input-Output arrays for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + SrvD%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL SrvD_CopyInput (SrvD%Input_bak(j), SrvD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL SrvD_CopyContState (SrvD%x( STATE_SS_PRED), SrvD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_SS_PRED), SrvD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyConstrState (SrvD%z( STATE_SS_PRED), SrvD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_SS_PRED), SrvD%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL SrvD_CopyContState (SrvD%x( STATE_SS_CURR), SrvD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_SS_CURR), SrvD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyConstrState (SrvD%z( STATE_SS_CURR), SrvD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_SS_CURR), SrvD%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL SrvD_CopyMisc( SrvD%m_bak, SrvD%m, MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF + + IF ( p_FAST%CompAero == Module_AD14 ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + AD14%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL AD14_CopyInput (AD14%Input_bak(j), AD14%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL AD14_CopyContState (AD14%x( STATE_SS_PRED), AD14%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyDiscState (AD14%xd(STATE_SS_PRED), AD14%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyConstrState (AD14%z( STATE_SS_PRED), AD14%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_SS_PRED), AD14%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL AD14_CopyContState (AD14%x( STATE_SS_CURR), AD14%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyDiscState (AD14%xd(STATE_SS_CURR), AD14%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyConstrState (AD14%z( STATE_SS_CURR), AD14%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_SS_CURR), AD14%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + AD%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL AD_CopyInput (AD%Input_bak(j), AD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL AD_CopyContState (AD%x( STATE_SS_PRED), AD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyDiscState (AD%xd(STATE_SS_PRED), AD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyConstrState (AD%z( STATE_SS_PRED), AD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyOtherState (AD%OtherSt(STATE_SS_PRED), AD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL AD_CopyContState (AD%x( STATE_SS_CURR), AD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyDiscState (AD%xd(STATE_SS_CURR), AD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyConstrState (AD%z( STATE_SS_CURR), AD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyOtherState (AD%OtherSt(STATE_SS_CURR), AD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompAero == Module_AD + + IF ( p_FAST%CompInflow == Module_IfW ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + IfW%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !IfW%OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL InflowWind_CopyInput (IfW%Input_bak(j), IfW%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL InflowWind_CopyContState (IfW%x( STATE_SS_PRED), IfW%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_SS_PRED), IfW%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyConstrState (IfW%z( STATE_SS_PRED), IfW%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_SS_PRED), IfW%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL InflowWind_CopyContState (IfW%x( STATE_SS_CURR), IfW%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_SS_CURR), IfW%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyConstrState (IfW%z( STATE_SS_CURR), IfW%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_SS_CURR), IfW%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompInflow == Module_IfW + + + IF ( p_FAST%CompHydro == Module_HD ) THEN + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + HD%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !HD_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL HydroDyn_CopyInput (HD%Input_bak(j), HD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL HydroDyn_CopyContState (HD%x( STATE_SS_PRED), HD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_SS_PRED), HD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyConstrState (HD%z( STATE_SS_PRED), HD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_SS_PRED), HD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL HydroDyn_CopyContState (HD%x( STATE_SS_CURR), HD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_SS_CURR), HD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyConstrState (HD%z( STATE_SS_CURR), HD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_SS_CURR), HD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF !CompHydro + + + IF (p_FAST%CompSub == Module_SD ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + SD%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !SD_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL SD_CopyInput (SD%Input_bak(j), SD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL SD_CopyContState (SD%x( STATE_SS_PRED), SD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyDiscState (SD%xd(STATE_SS_PRED), SD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyConstrState (SD%z( STATE_SS_PRED), SD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyOtherState (SD%OtherSt(STATE_SS_PRED), SD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL SD_CopyContState (SD%x( STATE_SS_CURR), SD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyDiscState (SD%xd(STATE_SS_CURR), SD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyConstrState (SD%z( STATE_SS_CURR), SD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyOtherState (SD%OtherSt(STATE_SS_CURR), SD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSE IF (p_FAST%CompSub == Module_ExtPtfm ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + ExtPtfm%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL ExtPtfm_CopyInput (ExtPtfm%Input_bak(j), ExtPtfm%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_SS_PRED), ExtPtfm%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_SS_PRED), ExtPtfm%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_SS_PRED), ExtPtfm%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_SS_PRED), ExtPtfm%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_SS_CURR), ExtPtfm%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_SS_CURR), ExtPtfm%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_SS_CURR), ExtPtfm%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_SS_CURR), ExtPtfm%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompSub + + + IF (p_FAST%CompMooring == Module_MAP) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + MAPp%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !MAP_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL MAP_CopyInput (MAPp%Input_bak(j), MAPp%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL MAP_CopyContState (MAPp%x( STATE_SS_PRED), MAPp%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyDiscState (MAPp%xd(STATE_SS_PRED), MAPp%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyConstrState (MAPp%z( STATE_SS_PRED), MAPp%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_SS_PRED), MAPp%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL MAP_CopyContState (MAPp%x( STATE_SS_CURR), MAPp%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyDiscState (MAPp%xd(STATE_SS_CURR), MAPp%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyConstrState (MAPp%z( STATE_SS_CURR), MAPp%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_SS_CURR), MAPp%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompMooring == Module_MD) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + MD%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !MD_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL MD_CopyInput (MD%Input_bak(j), MD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL MD_CopyContState (MD%x( STATE_SS_PRED), MD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyDiscState (MD%xd(STATE_SS_PRED), MD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyConstrState (MD%z( STATE_SS_PRED), MD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyOtherState (MD%OtherSt(STATE_SS_PRED), MD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL MD_CopyContState (MD%x( STATE_SS_CURR), MD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyDiscState (MD%xd(STATE_SS_CURR), MD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyConstrState (MD%z( STATE_SS_CURR), MD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyOtherState (MD%OtherSt(STATE_SS_CURR), MD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + FEAM%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !FEAM_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL FEAM_CopyInput (FEAM%Input_bak(j), FEAM%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL FEAM_CopyContState (FEAM%x( STATE_SS_PRED), FEAM%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_SS_PRED), FEAM%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyConstrState (FEAM%z( STATE_SS_PRED), FEAM%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_SS_PRED), FEAM%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL FEAM_CopyContState (FEAM%x( STATE_SS_CURR), FEAM%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_SS_CURR), FEAM%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyConstrState (FEAM%z( STATE_SS_CURR), FEAM%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_SS_CURR), FEAM%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompMooring == Module_Orca) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + Orca%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL Orca_CopyInput (Orca%Input_bak(j), Orca%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL Orca_CopyContState (Orca%x( STATE_SS_PRED), Orca%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyDiscState (Orca%xd(STATE_SS_PRED), Orca%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyConstrState (Orca%z( STATE_SS_PRED), Orca%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_SS_PRED), Orca%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL Orca_CopyContState (Orca%x( STATE_SS_CURR), Orca%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyDiscState (Orca%xd(STATE_SS_CURR), Orca%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyConstrState (Orca%z( STATE_SS_CURR), Orca%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_SS_CURR), Orca%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompMooring + + + IF (p_FAST%CompIce == Module_IceF ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + IceF%InputTimes(j) = t_global - (j - 1) * p_FAST%dt + !IceF_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL IceFloe_CopyInput (IceF%Input_bak(j), IceF%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL IceFloe_CopyContState (IceF%x( STATE_SS_PRED), IceF%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_SS_PRED), IceF%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyConstrState (IceF%z( STATE_SS_PRED), IceF%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_SS_PRED), IceF%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL IceFloe_CopyContState (IceF%x( STATE_SS_CURR), IceF%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_SS_CURR), IceF%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyConstrState (IceF%z( STATE_SS_CURR), IceF%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_SS_CURR), IceF%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompIce == Module_IceD ) THEN + + DO i = 1,p_FAST%numIceLegs + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + IceD%InputTimes(j,i) = t_global - (j - 1) * p_FAST%dt + !IceD%OutputTimes(j,i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL IceD_CopyInput (IceD%Input_bak(j,i), IceD%Input(j,i), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL IceD_CopyContState (IceD%x( i,STATE_SS_PRED), IceD%x( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_SS_PRED), IceD%xd(i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyConstrState (IceD%z( i,STATE_SS_PRED), IceD%z( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_SS_PRED), IceD%OtherSt( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL IceD_CopyContState (IceD%x( i,STATE_SS_CURR), IceD%x( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_SS_CURR), IceD%xd(i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyConstrState (IceD%z( i,STATE_SS_CURR), IceD%z( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_SS_CURR), IceD%OtherSt( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END DO ! numIceLegs + + END IF ! CompIce + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! We've moved everything back to the initial time step: + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! update the global time + + m_FAST%t_global = t_global +! y_FAST%n_Out = y_FAST%n_Out - n_timesteps + +END SUBROUTINE FAST_Reset_SS +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_Store_SS for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_Store_SS_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CALL FAST_Store_SS(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & + Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + +END SUBROUTINE FAST_Store_SS_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine resets the states, inputs and output data from n_t_global to n_t_global - 1 +SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + + USE BladedInterface, ONLY: CallBladedDLL ! Hack for Bladed-style DLL + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data), INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + INTEGER(IntKi) :: j_pc ! predictor-corrector loop counter + INTEGER(IntKi) :: NumCorrections ! number of corrections for this time step + + INTEGER(IntKi) :: i, j, k ! generic loop counters + REAL(DbKi) :: t_global ! the time to which states, inputs and outputs are reset + INTEGER(IntKi) :: old_avrSwap1 ! previous value of avrSwap(1) !hack for Bladed DLL checkpoint/restore + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Solution' + + + ErrStat = ErrID_None + ErrMsg = "" + + + t_global = t_initial + n_t_global * p_FAST%DT + + !---------------------------------------------------------------------------------------- + !! copy the stored states and inputs from n_t_global the current states and inputs + !---------------------------------------------------------------------------------------- + + DO j = 1, p_FAST%InterpOrder + 1 + ED%InputTimes_bak(j) = ED%InputTimes(j) + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL ED_CopyInput (ED%Input(j), ED%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + CALL ED_CopyOutput (ED%y, ED%Output_bak(1), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + ! ElastoDyn: copy final predictions to actual states + CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ED_CopyContState (ED%x( STATE_CURR), ED%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyDiscState (ED%xd(STATE_CURR), ED%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyConstrState (ED%z( STATE_CURR), ED%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyOtherState (ED%OtherSt( STATE_CURR), ED%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + IF (p_FAST%CompElast == Module_BD ) THEN + + DO k = 1,p_FAST%nBeams + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + BD%InputTimes_bak(j,k) = BD%InputTimes(j,k) + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL BD_CopyInput (BD%Input(j,k), BD%Input_bak(j,k), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL BD_CopyContState (BD%x( k,STATE_CURR), BD%x( k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyDiscState (BD%xd(k,STATE_CURR), BD%xd(k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyConstrState (BD%z( k,STATE_CURR), BD%z( k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_CURR), BD%OtherSt( k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + END IF + + IF ( p_FAST%CompServo == Module_SrvD ) THEN + ! Initialize Input-Output arrays for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + SrvD%InputTimes_bak(j) = SrvD%InputTimes(j) + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL SrvD_CopyInput (SrvD%Input(j), SrvD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_PRED), SrvD%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL SrvD_CopyContState (SrvD%x( STATE_CURR), SrvD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_CURR), SrvD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyConstrState (SrvD%z( STATE_CURR), SrvD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_CURR), SrvD%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL SrvD_CopyMisc( SrvD%m, SrvD%m_bak, MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF + + IF ( p_FAST%CompAero == Module_AD14 ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + AD14%InputTimes_bak(j) = AD14%InputTimes(j) + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL AD14_CopyInput (AD14%Input(j), AD14%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL AD14_CopyContState (AD14%x( STATE_CURR), AD14%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyDiscState (AD14%xd(STATE_CURR), AD14%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyConstrState (AD14%z( STATE_CURR), AD14%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_CURR), AD14%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + AD%InputTimes_bak(j) = AD%InputTimes(j) + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL AD_CopyInput (AD%Input(j), AD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL AD_CopyContState (AD%x( STATE_PRED), AD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyDiscState (AD%xd(STATE_PRED), AD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyConstrState (AD%z( STATE_PRED), AD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyOtherState (AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL AD_CopyContState (AD%x( STATE_CURR), AD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyDiscState (AD%xd(STATE_CURR), AD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyConstrState (AD%z( STATE_CURR), AD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyOtherState (AD%OtherSt(STATE_CURR), AD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompAero == Module_AD + + IF ( p_FAST%CompInflow == Module_IfW ) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + IfW%InputTimes_bak(j) = IfW%InputTimes(j) + !IfW%OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL InflowWind_CopyInput (IfW%Input(j), IfW%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_PRED), IfW%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL InflowWind_CopyContState (IfW%x( STATE_CURR), IfW%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_CURR), IfW%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyConstrState (IfW%z( STATE_CURR), IfW%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_CURR), IfW%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompInflow == Module_IfW + + + IF ( p_FAST%CompHydro == Module_HD ) THEN + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + HD%InputTimes_bak(j) = HD%InputTimes(j) + !HD_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL HydroDyn_CopyInput (HD%Input(j), HD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL HydroDyn_CopyContState (HD%x( STATE_CURR), HD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_CURR), HD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyConstrState (HD%z( STATE_CURR), HD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_CURR), HD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF !CompHydro + + + IF (p_FAST%CompSub == Module_SD ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + SD%InputTimes_bak(j) = SD%InputTimes(j) + !SD_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL SD_CopyInput (SD%Input(j), SD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyOtherState (SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL SD_CopyContState (SD%x( STATE_CURR), SD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyDiscState (SD%xd(STATE_CURR), SD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyConstrState (SD%z( STATE_CURR), SD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyOtherState (SD%OtherSt(STATE_CURR), SD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSE IF (p_FAST%CompSub == Module_ExtPtfm ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + ExtPtfm%InputTimes_bak(j) = ExtPtfm%InputTimes(j) + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL ExtPtfm_CopyInput (ExtPtfm%Input(j), ExtPtfm%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_CURR), ExtPtfm%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_CURR), ExtPtfm%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_CURR), ExtPtfm%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_CURR), ExtPtfm%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompSub + + + IF (p_FAST%CompMooring == Module_MAP) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + MAPp%InputTimes_bak(j) = MAPp%InputTimes(j) + !MAP_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL MAP_CopyInput (MAPp%Input(j), MAPp%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_PRED), MAPp%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL MAP_CopyContState (MAPp%x( STATE_CURR), MAPp%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyDiscState (MAPp%xd(STATE_CURR), MAPp%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyConstrState (MAPp%z( STATE_CURR), MAPp%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_CURR), MAPp%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompMooring == Module_MD) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + MD%InputTimes_bak(j) = MD%InputTimes(j) + !MD_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL MD_CopyInput (MD%Input(j), MD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyOtherState (MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL MD_CopyContState (MD%x( STATE_CURR), MD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyDiscState (MD%xd(STATE_CURR), MD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyConstrState (MD%z( STATE_CURR), MD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyOtherState (MD%OtherSt(STATE_CURR), MD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + FEAM%InputTimes_bak(j) = FEAM%InputTimes(j) + !FEAM_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL FEAM_CopyInput (FEAM%Input(j), FEAM%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_PRED), FEAM%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL FEAM_CopyContState (FEAM%x( STATE_CURR), FEAM%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_CURR), FEAM%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyConstrState (FEAM%z( STATE_CURR), FEAM%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_CURR), FEAM%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompMooring == Module_Orca) THEN + ! Copy values for interpolation/extrapolation: + + DO j = 1, p_FAST%InterpOrder + 1 + Orca%InputTimes_bak(j) = Orca%InputTimes(j) + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL Orca_CopyInput (Orca%Input(j), Orca%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_PRED), Orca%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL Orca_CopyContState (Orca%x( STATE_CURR), Orca%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyDiscState (Orca%xd(STATE_CURR), Orca%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyConstrState (Orca%z( STATE_CURR), Orca%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_CURR), Orca%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END IF ! CompMooring + + + IF (p_FAST%CompIce == Module_IceF ) THEN + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + IceF%InputTimes_bak(j) = IceF%InputTimes(j) + !IceF_OutputTimes(i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL IceFloe_CopyInput (IceF%Input(j), IceF%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL IceFloe_CopyContState (IceF%x( STATE_CURR), IceF%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_CURR), IceF%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyConstrState (IceF%z( STATE_CURR), IceF%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_CURR), IceF%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ELSEIF (p_FAST%CompIce == Module_IceD ) THEN + + DO i = 1,p_FAST%numIceLegs + + ! Copy values for interpolation/extrapolation: + DO j = 1, p_FAST%InterpOrder + 1 + IceD%InputTimes_bak(j,i) = IceD%InputTimes(j,i) + !IceD%OutputTimes(j,i) = t_global - (j - 1) * dt + END DO + + DO j = 1, p_FAST%InterpOrder + 1 + CALL IceD_CopyInput (IceD%Input(j,i), IceD%Input_bak(j,i), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + + CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_PRED), IceD%OtherSt( i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL IceD_CopyContState (IceD%x( i,STATE_CURR), IceD%x( i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_CURR), IceD%xd(i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyConstrState (IceD%z( i,STATE_CURR), IceD%z( i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_CURR), IceD%OtherSt( i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + END DO ! numIceLegs + + END IF ! CompIce + + ! A hack to store Bladed-style DLL data + if (SrvD%p%UseBladedInterface) then + if (SrvD%m%dll_data%avrSWAP( 1) > 0 ) then ! this isn't allocated if UseBladedInterface is FALSE + ! store value to be overwritten + old_avrSwap1 = SrvD%m%dll_data%avrSWAP( 1) + SrvD%m%dll_data%avrSWAP( 1) = -11 + CALL CallBladedDLL(SrvD%Input(1), SrvD%p, SrvD%m%dll_data, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! put values back: + SrvD%m%dll_data%avrSWAP( 1) = old_avrSwap1 + end if + end if + +END SUBROUTINE FAST_Store_SS +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_Prework for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_Prework_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CALL FAST_Prework(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, & + Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + +END SUBROUTINE FAST_Prework_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine does the prep work to advance the time step from n_t_global to n_t_global + 1 +SUBROUTINE FAST_Prework(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, & + ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + REAL(DbKi) :: t_global_next ! next simulation time (m_FAST%t_global + p_FAST%dt) + INTEGER(IntKi) :: j_pc ! predictor-corrector loop counter + INTEGER(IntKi) :: NumCorrections ! number of corrections for this time step + + INTEGER(IntKi) :: I, k ! generic loop counters + + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Prework' + + + ErrStat = ErrID_None + ErrMsg = "" + + t_global_next = t_initial + (n_t_global+1)*p_FAST%DT ! = m_FAST%t_global + p_FAST%dt + + !! determine if the Jacobian should be calculated this time + IF ( m_FAST%calcJacobian ) THEN ! this was true (possibly at initialization), so we'll advance the time for the next calculation of the Jacobian + + if (p_FAST%CompMooring == Module_Orca .and. n_t_global < 5) then + m_FAST%NextJacCalcTime = m_FAST%t_global + p_FAST%DT ! the jacobian calculated with OrcaFlex at t=0 is incorrect, but is okay on the 2nd step (it's not okay for OrcaFlex version 10, so I increased this to 5) + else + m_FAST%NextJacCalcTime = m_FAST%t_global + p_FAST%DT_UJac + end if + + END IF + + ! the ServoDyn inputs from Simulink are for t, not t+dt, so we're going to overwrite the inputs from + ! the previous step before we extrapolate these inputs: + IF ( p_FAST%CompServo == Module_SrvD ) CALL SrvD_SetExternalInputs( p_FAST, m_FAST, SrvD%Input(1) ) + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 1.a: Extrapolate Inputs + !! + !! gives predicted values at t+dt + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + CALL FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + +END SUBROUTINE FAST_Prework +!---------------------------------------------------------------------------------------------------------------------------------- +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_PredictStates for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_UpdateStates_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CALL FAST_UpdateStates(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, & + Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + +END SUBROUTINE FAST_UpdateStates_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine takes data from n_t_global and predicts the states and output at n_t_global+1 +SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, & + ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + REAL(DbKi) :: t_global_next ! next simulation time (m_FAST%t_global + p_FAST%dt) + INTEGER(IntKi) :: n_t_global_next ! n_t_global + 1 + INTEGER(IntKi) :: j_pc ! predictor-corrector loop counter + INTEGER(IntKi) :: NumCorrections ! number of corrections for this time step + INTEGER(IntKi), parameter :: MaxCorrections = 20 ! maximum number of corrections allowed + LOGICAL :: WriteThisStep ! Whether WriteOutput values will be printed + + INTEGER(IntKi) :: I, k ! generic loop counters + + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_UpdateStates' + + + ErrStat = ErrID_None + ErrMsg = "" + + t_global_next = t_initial + (n_t_global+1)*p_FAST%DT ! = m_FAST%t_global + p_FAST%dt + n_t_global_next = n_t_global+1 + + y_FAST%WriteThisStep = NeedWriteOutput(n_t_global_next, t_global_next, p_FAST) + + ! set number of corrections to be used for this time step: + IF ( p_FAST%CompElast == Module_BD ) THEN ! BD accelerations have fewer spikes with these corrections on the first several time steps + if (n_t_global > 2) then ! this 2 should probably be related to p_FAST%InterpOrder + NumCorrections = p_FAST%NumCrctn + elseif (n_t_global == 0) then + NumCorrections = max(p_FAST%NumCrctn,16) + else + NumCorrections = max(p_FAST%NumCrctn,1) + end if + ELSE + NumCorrections = p_FAST%NumCrctn + END IF + + !! predictor-corrector loop: + DO j_pc = 0, NumCorrections + WriteThisStep = y_FAST%WriteThisStep .AND. j_pc==NumCorrections + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 1.b: Advance states (yield state and constraint values at t_global_next) + !! + !! STATE_CURR values of x, xd, z, and OtherSt contain values at m_FAST%t_global; + !! STATE_PRED values contain values at t_global_next. + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + CALL FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 1.c: Input-Output Solve + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + CALL CalcOutputs_And_SolveForInputs( n_t_global, t_global_next, STATE_PRED, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & + p_FAST, m_FAST, y_FAST%WriteThisStep, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 2: Correct (continue in loop) + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + enddo ! j_pc + +END SUBROUTINE FAST_UpdateStates + +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_AdvanceToNextTimeStep for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_AdvanceToNextTimeStep_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CALL FAST_AdvanceToNextTimeStep(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & + Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + +END SUBROUTINE FAST_AdvanceToNextTimeStep_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine advances the time step from n_t_global to n_t_global + 1 and does all the relvant copying of data +SUBROUTINE FAST_AdvanceToNextTimeStep(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + REAL(DbKi) :: t_global_next ! next simulation time (m_FAST%t_global + p_FAST%dt) + INTEGER(IntKi) :: j_pc ! predictor-corrector loop counter + INTEGER(IntKi) :: NumCorrections ! number of corrections for this time step + + INTEGER(IntKi) :: I, k ! generic loop counters + + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_AdvanceToNextTimeStep' + + + ErrStat = ErrID_None + ErrMsg = "" + + t_global_next = t_initial + (n_t_global+1)*p_FAST%DT ! = m_FAST%t_global + p_FAST%dt + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 3: Save all final variables (advance to next time) + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + !---------------------------------------------------------------------------------------- + !! copy the final predicted states from step t_global_next to actual states for that step + !---------------------------------------------------------------------------------------- + + ! ElastoDyn: copy final predictions to actual states + CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + ! BeamDyn: copy final predictions to actual states + IF ( p_FAST%CompElast == Module_BD ) THEN + DO k=1,p_FAST%nBeams + CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + END IF + + + ! AeroDyn: copy final predictions to actual states; copy current outputs to next + IF ( p_FAST%CompAero == Module_AD14 ) THEN + CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN + CALL AD_CopyContState (AD%x( STATE_PRED), AD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyDiscState (AD%xd(STATE_PRED), AD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyConstrState (AD%z( STATE_PRED), AD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AD_CopyOtherState (AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + + ! InflowWind: copy final predictions to actual states; copy current outputs to next + IF ( p_FAST%CompInflow == Module_IfW ) THEN + CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_PRED), IfW%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + + ! ServoDyn: copy final predictions to actual states; copy current outputs to next + IF ( p_FAST%CompServo == Module_SrvD ) THEN + CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_PRED), SrvD%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + + ! HydroDyn: copy final predictions to actual states + IF ( p_FAST%CompHydro == Module_HD ) THEN + CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + + ! SubDyn: copy final predictions to actual states + IF ( p_FAST%CompSub == Module_SD ) THEN + CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL SD_CopyOtherState (SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + + ! MAP: copy final predictions to actual states + IF (p_FAST%CompMooring == Module_MAP) THEN + CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_PRED), MAPp%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSEIF (p_FAST%CompMooring == Module_MD) THEN + CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL MD_CopyOtherState (MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN + CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_PRED), FEAM%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSEIF (p_FAST%CompMooring == Module_Orca) THEN + CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_PRED), Orca%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + + ! IceFloe: copy final predictions to actual states + IF ( p_FAST%CompIce == Module_IceF ) THEN + CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSEIF ( p_FAST%CompIce == Module_IceD ) THEN + DO i=1,p_FAST%numIceLegs + CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_PRED), IceD%OtherSt( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + END IF + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! We've advanced everything to the next time step: + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + !! update the global time + + m_FAST%t_global = t_global_next + +END SUBROUTINE FAST_AdvanceToNextTimeStep +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_WriteOutput for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_WriteOutput_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CALL FAST_WriteOutput(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & + Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, & + Turbine%Orca, Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + +END SUBROUTINE FAST_WriteOutput_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine advances the time step from n_t_global to n_t_global + 1 and does all the relvant copying of data +SUBROUTINE FAST_WriteOutput(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + 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, k ! generic loop counters + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_WriteOutput' + + + ErrStat = ErrID_None + ErrMsg = "" + + !---------------------------------------------------------------------------------------- + !! Check to see if we should output data this time step: + !---------------------------------------------------------------------------------------- + + CALL WriteOutputToFile(n_t_global, m_FAST%t_global, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & + SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + !---------------------------------------------------------------------------------------- + !! Display simulation status every SttsTime-seconds (i.e., n_SttsTime steps): + !---------------------------------------------------------------------------------------- + + IF (p_FAST%WrSttsTime) then + IF ( MOD( n_t_global + 1, p_FAST%n_SttsTime ) == 0 ) THEN + + if (.not. Cmpl4SFun) then + CALL SimStatus( m_FAST%TiLstPrn, m_FAST%PrevClockTime, m_FAST%t_global, p_FAST%TMax, p_FAST%TDesc ) + end if + + ENDIF + ENDIF + +END SUBROUTINE FAST_WriteOutput +!---------------------------------------------------------------------------------------------------------------------------------- !> Routine that calls FAST_Solution for one instance of a Turbine data structure. This is a separate subroutine so that the FAST !! driver programs do not need to change or operate on the individual module level. SUBROUTINE FAST_Solution_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) @@ -4756,14 +7510,14 @@ SUBROUTINE FAST_Solution_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None CALL FAST_Solution(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) END SUBROUTINE FAST_Solution_T !---------------------------------------------------------------------------------------------------------------------------------- !> This routine takes data from n_t_global and gets values at n_t_global + 1 -SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & +SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time @@ -4778,6 +7532,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< Supercontroller Exchange data @@ -4863,7 +7618,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, !! !! gives predicted values at t+dt !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - CALL FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, HD, SD, ExtPtfm, & + CALL FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -4880,7 +7635,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, !! STATE_PRED values contain values at t_global_next. !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - CALL FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & + CALL FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN @@ -4894,7 +7649,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, !END IF CALL CalcOutputs_And_SolveForInputs( n_t_global, t_global_next, STATE_PRED, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & - p_FAST, m_FAST, WriteThisStep, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + p_FAST, m_FAST, WriteThisStep, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN @@ -4975,7 +7730,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AD14_CopyOtherState (AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN + ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN CALL AD_CopyContState (AD%x( STATE_PRED), AD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AD_CopyDiscState (AD%xd(STATE_PRED), AD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) @@ -6399,7 +9154,7 @@ SUBROUTINE FAST_Linearize_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg) end if CALL CalcOutputs_And_SolveForInputs( -1, t_global, STATE_CURR, Turbine%m_FAST%calcJacobian, Turbine%m_FAST%NextJacCalcTime, & - Turbine%p_FAST, Turbine%m_FAST, .false., Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & + Turbine%p_FAST, Turbine%m_FAST, .false., Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, & Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN @@ -7386,7 +10141,7 @@ SUBROUTINE FAST_RestoreForVTKModeShape_Tary(t_initial, Turbine, InputFileName, E end if CALL FAST_RestoreForVTKModeShape_T(t_initial, Turbine(i_turb)%p_FAST, Turbine(i_turb)%y_FAST, Turbine(i_turb)%m_FAST, & - Turbine(i_turb)%ED, Turbine(i_turb)%BD, Turbine(i_turb)%SrvD, Turbine(i_turb)%AD14, Turbine(i_turb)%AD, Turbine(i_turb)%IfW, Turbine(i_turb)%ExtInfw, & + Turbine(i_turb)%ED, Turbine(i_turb)%BD, Turbine(i_turb)%SrvD, Turbine(i_turb)%AD14, Turbine(i_turb)%AD, Turbine(i_turb)%ExtLd, Turbine(i_turb)%IfW, Turbine(i_turb)%ExtInfw, & Turbine(i_turb)%SeaSt, Turbine(i_turb)%HD, Turbine(i_turb)%SD, Turbine(i_turb)%ExtPtfm, Turbine(i_turb)%MAP, Turbine(i_turb)%FEAM, Turbine(i_turb)%MD, Turbine(i_turb)%Orca, & Turbine(i_turb)%IceF, Turbine(i_turb)%IceD, Turbine(i_turb)%MeshMapData, trim(InputFileName), ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -7397,7 +10152,7 @@ END SUBROUTINE FAST_RestoreForVTKModeShape_Tary !---------------------------------------------------------------------------------------------------------------------------------- !> This routine calculates the motions generated by mode shapes and outputs VTK data for it -SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & +SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, InputFileName, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time @@ -7411,6 +10166,7 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< ExtLoads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data @@ -7515,7 +10271,7 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, IF (ErrStat >= AbortErrLev) RETURN CALL CalcOutputs_And_SolveForInputs( -1, m_FAST%Lin%LinTimes(iLinTime), STATE_CURR, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & - p_FAST, m_FAST, .true., ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + p_FAST, m_FAST, .true., ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN @@ -7547,7 +10303,7 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, IF (ErrStat >= AbortErrLev) RETURN CALL CalcOutputs_And_SolveForInputs( -1, m_FAST%Lin%LinTimes(iLinTime), STATE_CURR, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & - p_FAST, m_FAST, .true., ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + p_FAST, m_FAST, .true., ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN diff --git a/modules/openfast-library/src/FAST_Types.f90 b/modules/openfast-library/src/FAST_Types.f90 index 7e2ec05633..d99d8021ec 100644 --- a/modules/openfast-library/src/FAST_Types.f90 +++ b/modules/openfast-library/src/FAST_Types.f90 @@ -37,6 +37,7 @@ MODULE FAST_Types USE InflowWind_Types USE AeroDyn14_Types USE AeroDyn_Types +USE ExtLoads_Types USE SubDyn_Types USE HydroDyn_Types USE IceFloe_Types @@ -54,23 +55,24 @@ MODULE FAST_Types INTEGER(IntKi), PUBLIC, PARAMETER :: Module_None = 0 ! No module selected [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_Glue = 1 ! Glue code [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_IfW = 2 ! InflowWind [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ExtInfw = 3 + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ExtInfw = 3 ! ExternalInflow [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ED = 4 ! ElastoDyn [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_BD = 5 ! BeamDyn [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_AD14 = 6 ! AeroDyn14 [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_AD = 7 ! AeroDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SrvD = 8 ! ServoDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SeaSt = 9 ! SeaState [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_HD = 10 ! HydroDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SD = 11 ! SubDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ExtPtfm = 12 ! External Platform Loading MCKF [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_MAP = 13 ! MAP (Mooring Analysis Program) [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_FEAM = 14 ! FEAMooring [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_MD = 15 ! MoorDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_Orca = 16 ! OrcaFlex integration (HD/Mooring) [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_IceF = 17 ! IceFloe [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_IceD = 18 ! IceDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: NumModules = 18 ! The number of modules available in FAST [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ExtLd = 8 ! AeroDyn [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SrvD = 9 ! ServoDyn [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SeaSt = 10 ! SeaState [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_HD = 11 ! HydroDyn [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SD = 12 ! SubDyn [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ExtPtfm = 13 ! External Platform Loading MCKF [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_MAP = 14 ! MAP (Mooring Analysis Program) [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_FEAM = 15 ! FEAMooring [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_MD = 16 ! MoorDyn [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_Orca = 17 ! OrcaFlex integration (HD/Mooring) [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_IceF = 18 ! IceFloe [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_IceD = 19 ! IceDyn [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: NumModules = 20 ! The number of modules available in FAST [-] INTEGER(IntKi), PUBLIC, PARAMETER :: MaxNBlades = 3 ! Maximum number of blades allowed on a turbine [-] INTEGER(IntKi), PUBLIC, PARAMETER :: IceD_MaxLegs = 4 ! because I don't know how many legs there are before calling IceD_Init and I don't want to copy the data because of sibling mesh issues, I'm going to allocate IceD based on this number [-] ! ========= FAST_VTK_BLSurfaceType ======= @@ -375,7 +377,9 @@ MODULE FAST_Types TYPE(IceD_OutputType) , DIMENSION(:), ALLOCATABLE :: y !< System outputs [-] TYPE(IceD_MiscVarType) , DIMENSION(:), ALLOCATABLE :: m !< Misc/optimization variables [-] TYPE(IceD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(IceD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE IceDyn_Data ! ======================= ! ========= BeamDyn_Data ======= @@ -391,61 +395,71 @@ MODULE FAST_Types TYPE(BD_OutputType) , DIMENSION(:,:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(BD_OutputType) , DIMENSION(:), ALLOCATABLE :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(BD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(BD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE BeamDyn_Data ! ======================= ! ========= ElastoDyn_Data ======= TYPE, PUBLIC :: ElastoDyn_Data - TYPE(ED_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(ED_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(ED_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(ED_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(ED_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(ED_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(ED_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(ED_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(ED_ParameterType) :: p !< Parameters [-] TYPE(ED_InputType) :: u !< System inputs [-] TYPE(ED_OutputType) :: y !< System outputs [-] TYPE(ED_MiscVarType) :: m !< Misc (optimization) variables not associated with time [-] TYPE(ED_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] + TYPE(ED_OutputType) , DIMENSION(:), ALLOCATABLE :: Output_bak !< Backup Array of outputs associated with InputTimes [-] TYPE(ED_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(ED_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(ED_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE ElastoDyn_Data ! ======================= ! ========= ServoDyn_Data ======= TYPE, PUBLIC :: ServoDyn_Data - TYPE(SrvD_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(SrvD_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(SrvD_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(SrvD_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(SrvD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(SrvD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(SrvD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(SrvD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(SrvD_ParameterType) :: p !< Parameters [-] TYPE(SrvD_InputType) :: u !< System inputs [-] TYPE(SrvD_OutputType) :: y !< System outputs [-] TYPE(SrvD_MiscVarType) :: m !< Misc (optimization) variables not associated with time [-] + TYPE(SrvD_MiscVarType) :: m_bak !< Backup Misc (optimization) variables not associated with time [-] TYPE(SrvD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(SrvD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(SrvD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(SrvD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE ServoDyn_Data ! ======================= ! ========= AeroDyn14_Data ======= TYPE, PUBLIC :: AeroDyn14_Data - TYPE(AD14_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(AD14_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(AD14_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(AD14_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(AD14_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(AD14_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(AD14_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(AD14_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(AD14_ParameterType) :: p !< Parameters [-] TYPE(AD14_InputType) :: u !< System inputs [-] TYPE(AD14_OutputType) :: y !< System outputs [-] TYPE(AD14_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(AD14_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(AD14_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE AeroDyn14_Data ! ======================= ! ========= AeroDyn_Data ======= TYPE, PUBLIC :: AeroDyn_Data - TYPE(AD_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(AD_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(AD_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(AD_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(AD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(AD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(AD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(AD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(AD_ParameterType) :: p !< Parameters [-] TYPE(AD_InputType) :: u !< System inputs [-] TYPE(AD_OutputType) :: y !< System outputs [-] @@ -453,15 +467,30 @@ MODULE FAST_Types TYPE(AD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(AD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(AD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(AD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE AeroDyn_Data ! ======================= +! ========= ExtLoads_Data ======= + TYPE, PUBLIC :: ExtLoads_Data + TYPE(ExtLd_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] + TYPE(ExtLd_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] + TYPE(ExtLd_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] + TYPE(ExtLd_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(ExtLd_ParameterType) :: p !< Parameters [-] + TYPE(ExtLd_InputType) :: u !< System inputs [-] + TYPE(ExtLd_OutputType) :: y !< System outputs [-] + TYPE(ExtLd_MiscVarType) :: m !< Misc/optimization variables [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + END TYPE ExtLoads_Data +! ======================= ! ========= InflowWind_Data ======= TYPE, PUBLIC :: InflowWind_Data - TYPE(InflowWind_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(InflowWind_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(InflowWind_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(InflowWind_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(InflowWind_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(InflowWind_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(InflowWind_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(InflowWind_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(InflowWind_ParameterType) :: p !< Parameters [-] TYPE(InflowWind_InputType) :: u !< System inputs [-] TYPE(InflowWind_OutputType) :: y !< System outputs [-] @@ -469,7 +498,9 @@ MODULE FAST_Types TYPE(InflowWind_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(InflowWind_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(InflowWind_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(InflowWind_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE InflowWind_Data ! ======================= ! ========= ExternalInflow_Data ======= @@ -489,56 +520,62 @@ MODULE FAST_Types ! ======================= ! ========= SubDyn_Data ======= TYPE, PUBLIC :: SubDyn_Data - TYPE(SD_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(SD_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(SD_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(SD_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(SD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(SD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(SD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(SD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(SD_ParameterType) :: p !< Parameters [-] TYPE(SD_InputType) :: u !< System inputs [-] TYPE(SD_OutputType) :: y !< System outputs [-] TYPE(SD_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(SD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(SD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] TYPE(SD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(SD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE SubDyn_Data ! ======================= ! ========= ExtPtfm_Data ======= TYPE, PUBLIC :: ExtPtfm_Data - TYPE(ExtPtfm_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(ExtPtfm_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(ExtPtfm_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(ExtPtfm_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(ExtPtfm_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(ExtPtfm_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(ExtPtfm_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(ExtPtfm_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(ExtPtfm_ParameterType) :: p !< Parameters [-] TYPE(ExtPtfm_InputType) :: u !< System inputs [-] TYPE(ExtPtfm_OutputType) :: y !< System outputs [-] TYPE(ExtPtfm_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(ExtPtfm_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(ExtPtfm_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE ExtPtfm_Data ! ======================= ! ========= SeaState_Data ======= TYPE, PUBLIC :: SeaState_Data - TYPE(SeaSt_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(SeaSt_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(SeaSt_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(SeaSt_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(SeaSt_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(SeaSt_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(SeaSt_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(SeaSt_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(SeaSt_ParameterType) :: p !< Parameters [-] TYPE(SeaSt_InputType) :: u !< System inputs [-] TYPE(SeaSt_OutputType) :: y !< System outputs [-] TYPE(SeaSt_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(SeaSt_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(SeaSt_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] TYPE(SeaSt_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(SeaSt_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE SeaState_Data ! ======================= ! ========= HydroDyn_Data ======= TYPE, PUBLIC :: HydroDyn_Data - TYPE(HydroDyn_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(HydroDyn_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(HydroDyn_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(HydroDyn_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(HydroDyn_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(HydroDyn_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(HydroDyn_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(HydroDyn_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(HydroDyn_ParameterType) :: p !< Parameters [-] TYPE(HydroDyn_InputType) :: u !< System inputs [-] TYPE(HydroDyn_OutputType) :: y !< System outputs [-] @@ -546,28 +583,32 @@ MODULE FAST_Types TYPE(HydroDyn_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(HydroDyn_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(HydroDyn_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(HydroDyn_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE HydroDyn_Data ! ======================= ! ========= IceFloe_Data ======= TYPE, PUBLIC :: IceFloe_Data - TYPE(IceFloe_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(IceFloe_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(IceFloe_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(IceFloe_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(IceFloe_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(IceFloe_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(IceFloe_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(IceFloe_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(IceFloe_ParameterType) :: p !< Parameters [-] TYPE(IceFloe_InputType) :: u !< System inputs [-] TYPE(IceFloe_OutputType) :: y !< System outputs [-] TYPE(IceFloe_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(IceFloe_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(IceFloe_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE IceFloe_Data ! ======================= ! ========= MAP_Data ======= TYPE, PUBLIC :: MAP_Data - TYPE(MAP_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(MAP_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(MAP_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] + TYPE(MAP_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(MAP_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(MAP_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] TYPE(MAP_OtherStateType) :: OtherSt !< Other/optimization states [-] TYPE(MAP_ParameterType) :: p !< Parameters [-] TYPE(MAP_InputType) :: u !< System inputs [-] @@ -576,29 +617,33 @@ MODULE FAST_Types TYPE(MAP_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(MAP_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(MAP_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(MAP_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE MAP_Data ! ======================= ! ========= FEAMooring_Data ======= TYPE, PUBLIC :: FEAMooring_Data - TYPE(FEAM_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(FEAM_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(FEAM_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(FEAM_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(FEAM_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(FEAM_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(FEAM_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(FEAM_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(FEAM_ParameterType) :: p !< Parameters [-] TYPE(FEAM_InputType) :: u !< System inputs [-] TYPE(FEAM_OutputType) :: y !< System outputs [-] TYPE(FEAM_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(FEAM_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(FEAM_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE FEAMooring_Data ! ======================= ! ========= MoorDyn_Data ======= TYPE, PUBLIC :: MoorDyn_Data - TYPE(MD_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(MD_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(MD_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(MD_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(MD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(MD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(MD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(MD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(MD_ParameterType) :: p !< Parameters [-] TYPE(MD_InputType) :: u !< System inputs [-] TYPE(MD_OutputType) :: y !< System outputs [-] @@ -606,21 +651,25 @@ MODULE FAST_Types TYPE(MD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(MD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(MD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(MD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE MoorDyn_Data ! ======================= ! ========= OrcaFlex_Data ======= TYPE, PUBLIC :: OrcaFlex_Data - TYPE(Orca_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(Orca_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(Orca_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(Orca_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(Orca_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] + TYPE(Orca_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] + TYPE(Orca_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(Orca_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] TYPE(Orca_ParameterType) :: p !< Parameters [-] TYPE(Orca_InputType) :: u !< System inputs [-] TYPE(Orca_OutputType) :: y !< System outputs [-] TYPE(Orca_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(Orca_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(Orca_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] END TYPE OrcaFlex_Data ! ======================= ! ========= FAST_ModuleMapType ======= @@ -648,7 +697,7 @@ MODULE FAST_Types TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: SStC_P_P_2_SubStructure !< Map ServoDyn/SStC platform point mesh load to SubDyn/ElastoDyn point load mesh [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: SubStructure_2_SStC_P_P !< Map SubDyn y3mesh or ED platform mesh motion to ServoDyn/SStC point mesh [-] TYPE(MeshMapType) :: ED_P_2_SrvD_P_P !< Map ElastoDyn platform point mesh motion to ServoDyn point mesh -- for passing to controller [-] - TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BDED_L_2_AD_L_B !< Map ElastoDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BDED_L_2_AD_L_B !< Map ElastoDyn/BeamDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: AD_L_2_BDED_B !< Map AeroDyn14 InputMarkers or AeroDyn BladeLoad line2 meshes to ElastoDyn BladePtLoad point meshes or BeamDyn BldMotion line2 meshes [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BD_L_2_BD_L !< Map BeamDyn BldMotion output meshes to locations on the BD input DistrLoad mesh stored in MeshMapType%y_BD_BldMotion_4Loads (BD input and output meshes are not siblings and in fact have nodes at different locations [-] TYPE(MeshMapType) :: ED_P_2_AD_P_N !< Map ElastoDyn Nacelle point motion mesh to AeroDyn Nacelle point motion mesh [-] @@ -660,6 +709,14 @@ MODULE FAST_Types TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: ED_P_2_AD_P_R !< Map ElastoDyn BladeRootMotion point meshes to AeroDyn BladeRootMotion point meshes [-] TYPE(MeshMapType) :: ED_P_2_AD_P_H !< Map ElastoDyn HubPtMotion point mesh to AeroDyn HubMotion point mesh [-] TYPE(MeshMapType) :: AD_P_2_ED_P_H !< Map AeroDyn HubLoad point mesh to ElastoDyn HubPtLoad point mesh [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BDED_L_2_ExtLd_P_B !< Map ElastoDyn/BeamDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to ExtLoads point meshes [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: ExtLd_P_2_BDED_B !< Map ExtLoads at points to ElastoDyn BladePtLoad point meshes or BeamDyn BldMotion line2 meshes [-] + TYPE(MeshMapType) :: ED_L_2_ExtLd_P_T !< Map ElastoDyn TowerLn2Mesh line2 mesh to ExtLoads point mesh [-] + TYPE(MeshMapType) :: ExtLd_P_2_ED_P_T !< Map ExtLoads TowerLoad point mesh to ElastoDyn TowerPtLoads point mesh [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: ED_P_2_ExtLd_P_R !< Map ElastoDyn BladeRootMotion point meshes to ExtLoads BladeRootMotion point meshes [-] + TYPE(MeshMapType) :: ED_P_2_ExtLd_P_H !< Map ElastoDyn HubPtMotion point mesh to ExtLoads HubMotion point mesh [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: AD_L_2_ExtLd_B !< Map AeroDyn line loads on blades to ExtLoads point loads [-] + TYPE(MeshMapType) :: AD_L_2_ExtLd_T !< Map AeroDyn line loads on tower to ExtKoads point loads [-] TYPE(MeshMapType) :: IceF_P_2_SD_P !< Map IceFloe point mesh to SubDyn LMesh point mesh [-] TYPE(MeshMapType) :: SDy3_P_2_IceF_P !< Map SubDyn y3Mesh point mesh to IceFloe point mesh [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: IceD_P_2_SD_P !< Map IceDyn point mesh to SubDyn LMesh point mesh [-] @@ -728,6 +785,8 @@ MODULE FAST_Types TYPE(AD14_InitOutputType) :: OutData_AD14 !< AD14 Initialization output data [-] TYPE(AD_InitInputType) :: InData_AD !< AD Initialization input data [-] TYPE(AD_InitOutputType) :: OutData_AD !< AD Initialization output data [-] + TYPE(ExtLd_InitInputType) :: InData_ExtLd !< ExtLd Initialization input data [-] + TYPE(ExtLd_InitOutputType) :: OutData_ExtLd !< ExtLd Initialization output data [-] TYPE(InflowWind_InitInputType) :: InData_IfW !< IfW Initialization input data [-] TYPE(InflowWind_InitOutputType) :: OutData_IfW !< IfW Initialization output data [-] TYPE(ExtInfw_InitInputType) :: InData_ExtInfw !< ExtInfw Initialization input data [-] @@ -775,6 +834,14 @@ MODULE FAST_Types INTEGER(IntKi) :: NumActForcePtsBlade !< number of actuator line force points in blade [-] INTEGER(IntKi) :: NumActForcePtsTower !< number of actuator line force points in tower [-] INTEGER(IntKi) :: NodeClusterType !< Node clustering for actuator line (0 - Uniform, 1 - Non-uniform clustered towards tip) [-] + REAL(DbKi) :: DTdriver = -1 !< External driver time step [s] + LOGICAL :: TwrAero = .false. !< Is Tower aerodynamics enabled for ExtLoads module? [-] + REAL(ReKi) :: az_blend_mean !< Mean azimuth at which to blend the external and aerodyn loads [-] + REAL(ReKi) :: az_blend_delta !< Mean azimuth at which to blend the external and aerodyn loads [-] + REAL(ReKi) :: vel_mean !< Mean velocity at reference height [m/s] + REAL(ReKi) :: wind_dir !< Wind direction in compass angle [degrees] + REAL(ReKi) :: z_ref !< Reference height for velocity profile [m] + REAL(ReKi) :: shear_exp !< Shear exponent [-] END TYPE FAST_ExternInitType ! ======================= ! ========= FAST_TurbineType ======= @@ -789,6 +856,7 @@ MODULE FAST_Types TYPE(ServoDyn_Data) :: SrvD !< Data for the ServoDyn module [-] TYPE(AeroDyn_Data) :: AD !< Data for the AeroDyn module [-] TYPE(AeroDyn14_Data) :: AD14 !< Data for the AeroDyn14 module [-] + TYPE(ExtLoads_Data) :: ExtLd !< Data for the External loads module [-] TYPE(InflowWind_Data) :: IfW !< Data for InflowWind module [-] TYPE(ExternalInflow_Data) :: ExtInfw !< Data for ExternalInflow integration module [-] TYPE(SCDataEx_Data) :: SC_DX !< Data for SuperController integration module [-] @@ -16394,6 +16462,26 @@ SUBROUTINE FAST_CopyIceDyn_Data( SrcIceDyn_DataData, DstIceDyn_DataData, CtrlCod ENDDO ENDDO ENDIF +IF (ALLOCATED(SrcIceDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcIceDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcIceDyn_DataData%Input_bak,1) + i2_l = LBOUND(SrcIceDyn_DataData%Input_bak,2) + i2_u = UBOUND(SrcIceDyn_DataData%Input_bak,2) + IF (.NOT. ALLOCATED(DstIceDyn_DataData%Input_bak)) THEN + ALLOCATE(DstIceDyn_DataData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i2 = LBOUND(SrcIceDyn_DataData%Input_bak,2), UBOUND(SrcIceDyn_DataData%Input_bak,2) + DO i1 = LBOUND(SrcIceDyn_DataData%Input_bak,1), UBOUND(SrcIceDyn_DataData%Input_bak,1) + CALL IceD_CopyInput( SrcIceDyn_DataData%Input_bak(i1,i2), DstIceDyn_DataData%Input_bak(i1,i2), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + ENDDO +ENDIF IF (ALLOCATED(SrcIceDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcIceDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcIceDyn_DataData%InputTimes,1) @@ -16407,6 +16495,20 @@ SUBROUTINE FAST_CopyIceDyn_Data( SrcIceDyn_DataData, DstIceDyn_DataData, CtrlCod END IF END IF DstIceDyn_DataData%InputTimes = SrcIceDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcIceDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcIceDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcIceDyn_DataData%InputTimes_bak,1) + i2_l = LBOUND(SrcIceDyn_DataData%InputTimes_bak,2) + i2_u = UBOUND(SrcIceDyn_DataData%InputTimes_bak,2) + IF (.NOT. ALLOCATED(DstIceDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstIceDyn_DataData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstIceDyn_DataData%InputTimes_bak = SrcIceDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyIceDyn_Data @@ -16504,8 +16606,20 @@ SUBROUTINE FAST_DestroyIceDyn_Data( IceDyn_DataData, ErrStat, ErrMsg, DEALLOCATE ENDDO DEALLOCATE(IceDyn_DataData%Input) ENDIF +IF (ALLOCATED(IceDyn_DataData%Input_bak)) THEN +DO i2 = LBOUND(IceDyn_DataData%Input_bak,2), UBOUND(IceDyn_DataData%Input_bak,2) +DO i1 = LBOUND(IceDyn_DataData%Input_bak,1), UBOUND(IceDyn_DataData%Input_bak,1) + CALL IceD_DestroyInput( IceDyn_DataData%Input_bak(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO +ENDDO + DEALLOCATE(IceDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(IceDyn_DataData%InputTimes)) THEN DEALLOCATE(IceDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(IceDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(IceDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyIceDyn_Data @@ -16762,11 +16876,41 @@ SUBROUTINE FAST_PackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Input_bak upper/lower bounds for each dimension + DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL IceD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*2 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -17188,6 +17332,52 @@ SUBROUTINE FAST_PackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_bak,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL IceD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -17208,6 +17398,26 @@ SUBROUTINE FAST_PackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_bak,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%InputTimes_bak,2), UBOUND(InData%InputTimes_bak,2) + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF END SUBROUTINE FAST_PackIceDyn_Data SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -17767,6 +17977,67 @@ SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Input_bak,2), UBOUND(OutData%Input_bak,2) + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 IceD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1,i2), ErrStat2, ErrMsg2 ) ! Input_bak + 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 DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -17790,6 +18061,29 @@ SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%InputTimes_bak,2), UBOUND(OutData%InputTimes_bak,2) + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF END SUBROUTINE FAST_UnPackIceDyn_Data SUBROUTINE FAST_CopyBeamDyn_Data( SrcBeamDyn_DataData, DstBeamDyn_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -18008,6 +18302,26 @@ SUBROUTINE FAST_CopyBeamDyn_Data( SrcBeamDyn_DataData, DstBeamDyn_DataData, Ctrl ENDDO ENDDO ENDIF +IF (ALLOCATED(SrcBeamDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcBeamDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcBeamDyn_DataData%Input_bak,1) + i2_l = LBOUND(SrcBeamDyn_DataData%Input_bak,2) + i2_u = UBOUND(SrcBeamDyn_DataData%Input_bak,2) + IF (.NOT. ALLOCATED(DstBeamDyn_DataData%Input_bak)) THEN + ALLOCATE(DstBeamDyn_DataData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBeamDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i2 = LBOUND(SrcBeamDyn_DataData%Input_bak,2), UBOUND(SrcBeamDyn_DataData%Input_bak,2) + DO i1 = LBOUND(SrcBeamDyn_DataData%Input_bak,1), UBOUND(SrcBeamDyn_DataData%Input_bak,1) + CALL BD_CopyInput( SrcBeamDyn_DataData%Input_bak(i1,i2), DstBeamDyn_DataData%Input_bak(i1,i2), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + ENDDO +ENDIF IF (ALLOCATED(SrcBeamDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcBeamDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcBeamDyn_DataData%InputTimes,1) @@ -18021,6 +18335,20 @@ SUBROUTINE FAST_CopyBeamDyn_Data( SrcBeamDyn_DataData, DstBeamDyn_DataData, Ctrl END IF END IF DstBeamDyn_DataData%InputTimes = SrcBeamDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcBeamDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcBeamDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcBeamDyn_DataData%InputTimes_bak,1) + i2_l = LBOUND(SrcBeamDyn_DataData%InputTimes_bak,2) + i2_u = UBOUND(SrcBeamDyn_DataData%InputTimes_bak,2) + IF (.NOT. ALLOCATED(DstBeamDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstBeamDyn_DataData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBeamDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBeamDyn_DataData%InputTimes_bak = SrcBeamDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyBeamDyn_Data @@ -18134,8 +18462,20 @@ SUBROUTINE FAST_DestroyBeamDyn_Data( BeamDyn_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(BeamDyn_DataData%Input) ENDIF +IF (ALLOCATED(BeamDyn_DataData%Input_bak)) THEN +DO i2 = LBOUND(BeamDyn_DataData%Input_bak,2), UBOUND(BeamDyn_DataData%Input_bak,2) +DO i1 = LBOUND(BeamDyn_DataData%Input_bak,1), UBOUND(BeamDyn_DataData%Input_bak,1) + CALL BD_DestroyInput( BeamDyn_DataData%Input_bak(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO +ENDDO + DEALLOCATE(BeamDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(BeamDyn_DataData%InputTimes)) THEN DEALLOCATE(BeamDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(BeamDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(BeamDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyBeamDyn_Data @@ -18440,11 +18780,41 @@ SUBROUTINE FAST_PackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Input_bak upper/lower bounds for each dimension + DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL BD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*2 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -18953,6 +19323,52 @@ SUBROUTINE FAST_PackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_bak,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL BD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -18973,6 +19389,26 @@ SUBROUTINE FAST_PackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_bak,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%InputTimes_bak,2), UBOUND(InData%InputTimes_bak,2) + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF END SUBROUTINE FAST_PackBeamDyn_Data SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -19649,6 +20085,67 @@ SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Input_bak,2), UBOUND(OutData%Input_bak,2) + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 BD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1,i2), ErrStat2, ErrMsg2 ) ! Input_bak + 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 DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -19672,6 +20169,29 @@ SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%InputTimes_bak,2), UBOUND(OutData%InputTimes_bak,2) + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF END SUBROUTINE FAST_UnPackBeamDyn_Data SUBROUTINE FAST_CopyElastoDyn_Data( SrcElastoDyn_DataData, DstElastoDyn_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -19736,6 +20256,22 @@ SUBROUTINE FAST_CopyElastoDyn_Data( SrcElastoDyn_DataData, DstElastoDyn_DataData CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO +ENDIF +IF (ALLOCATED(SrcElastoDyn_DataData%Output_bak)) THEN + i1_l = LBOUND(SrcElastoDyn_DataData%Output_bak,1) + i1_u = UBOUND(SrcElastoDyn_DataData%Output_bak,1) + IF (.NOT. ALLOCATED(DstElastoDyn_DataData%Output_bak)) THEN + ALLOCATE(DstElastoDyn_DataData%Output_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstElastoDyn_DataData%Output_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcElastoDyn_DataData%Output_bak,1), UBOUND(SrcElastoDyn_DataData%Output_bak,1) + CALL ED_CopyOutput( SrcElastoDyn_DataData%Output_bak(i1), DstElastoDyn_DataData%Output_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO ENDIF CALL ED_CopyOutput( SrcElastoDyn_DataData%y_interp, DstElastoDyn_DataData%y_interp, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) @@ -19756,6 +20292,22 @@ SUBROUTINE FAST_CopyElastoDyn_Data( SrcElastoDyn_DataData, DstElastoDyn_DataData IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcElastoDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcElastoDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcElastoDyn_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstElastoDyn_DataData%Input_bak)) THEN + ALLOCATE(DstElastoDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstElastoDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcElastoDyn_DataData%Input_bak,1), UBOUND(SrcElastoDyn_DataData%Input_bak,1) + CALL ED_CopyInput( SrcElastoDyn_DataData%Input_bak(i1), DstElastoDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcElastoDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcElastoDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcElastoDyn_DataData%InputTimes,1) @@ -19767,6 +20319,18 @@ SUBROUTINE FAST_CopyElastoDyn_Data( SrcElastoDyn_DataData, DstElastoDyn_DataData END IF END IF DstElastoDyn_DataData%InputTimes = SrcElastoDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcElastoDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcElastoDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcElastoDyn_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstElastoDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstElastoDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstElastoDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstElastoDyn_DataData%InputTimes_bak = SrcElastoDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyElastoDyn_Data @@ -19821,6 +20385,13 @@ SUBROUTINE FAST_DestroyElastoDyn_Data( ElastoDyn_DataData, ErrStat, ErrMsg, DEAL CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ElastoDyn_DataData%Output) +ENDIF +IF (ALLOCATED(ElastoDyn_DataData%Output_bak)) THEN +DO i1 = LBOUND(ElastoDyn_DataData%Output_bak,1), UBOUND(ElastoDyn_DataData%Output_bak,1) + CALL ED_DestroyOutput( ElastoDyn_DataData%Output_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ElastoDyn_DataData%Output_bak) ENDIF CALL ED_DestroyOutput( ElastoDyn_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -19831,8 +20402,18 @@ SUBROUTINE FAST_DestroyElastoDyn_Data( ElastoDyn_DataData, ErrStat, ErrMsg, DEAL ENDDO DEALLOCATE(ElastoDyn_DataData%Input) ENDIF +IF (ALLOCATED(ElastoDyn_DataData%Input_bak)) THEN +DO i1 = LBOUND(ElastoDyn_DataData%Input_bak,1), UBOUND(ElastoDyn_DataData%Input_bak,1) + CALL ED_DestroyInput( ElastoDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ElastoDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(ElastoDyn_DataData%InputTimes)) THEN DEALLOCATE(ElastoDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(ElastoDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(ElastoDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyElastoDyn_Data @@ -20038,6 +20619,29 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, DEALLOCATE(Int_Buf) END IF END DO + END IF + Int_BufSz = Int_BufSz + 1 ! Output_bak allocated yes/no + IF ( ALLOCATED(InData%Output_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Output_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Output_bak,1), UBOUND(InData%Output_bak,1) + Int_BufSz = Int_BufSz + 3 ! Output_bak: size of buffers for each call to pack subtype + CALL ED_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Output_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Output_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Output_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Output_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO END IF Int_BufSz = Int_BufSz + 3 ! y_interp: size of buffers for each call to pack subtype CALL ED_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, .TRUE. ) ! y_interp @@ -20079,11 +20683,39 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL ED_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -20384,6 +21016,47 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Output_bak) ) 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%Output_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Output_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Output_bak,1), UBOUND(InData%Output_bak,1) + CALL ED_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Output_bak + 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 DO + END IF CALL ED_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, OnlySize ) ! y_interp CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -20453,6 +21126,47 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL ED_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -20468,6 +21182,21 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackElastoDyn_Data SUBROUTINE FAST_UnPackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -20889,6 +21618,62 @@ SUBROUTINE FAST_UnPackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Output_bak 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%Output_bak)) DEALLOCATE(OutData%Output_bak) + ALLOCATE(OutData%Output_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Output_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Output_bak,1), UBOUND(OutData%Output_bak,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 ED_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%Output_bak(i1), ErrStat2, ErrMsg2 ) ! Output_bak + 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 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -20985,6 +21770,62 @@ SUBROUTINE FAST_UnPackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 ED_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -21003,6 +21844,24 @@ SUBROUTINE FAST_UnPackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackElastoDyn_Data SUBROUTINE FAST_CopyServoDyn_Data( SrcServoDyn_DataData, DstServoDyn_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -21052,6 +21911,9 @@ SUBROUTINE FAST_CopyServoDyn_Data( SrcServoDyn_DataData, DstServoDyn_DataData, C CALL SrvD_CopyMisc( SrcServoDyn_DataData%m, DstServoDyn_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL SrvD_CopyMisc( SrcServoDyn_DataData%m_bak, DstServoDyn_DataData%m_bak, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcServoDyn_DataData%Output)) THEN i1_l = LBOUND(SrcServoDyn_DataData%Output,1) i1_u = UBOUND(SrcServoDyn_DataData%Output,1) @@ -21087,6 +21949,22 @@ SUBROUTINE FAST_CopyServoDyn_Data( SrcServoDyn_DataData, DstServoDyn_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcServoDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcServoDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcServoDyn_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstServoDyn_DataData%Input_bak)) THEN + ALLOCATE(DstServoDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstServoDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcServoDyn_DataData%Input_bak,1), UBOUND(SrcServoDyn_DataData%Input_bak,1) + CALL SrvD_CopyInput( SrcServoDyn_DataData%Input_bak(i1), DstServoDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcServoDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcServoDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcServoDyn_DataData%InputTimes,1) @@ -21098,6 +21976,18 @@ SUBROUTINE FAST_CopyServoDyn_Data( SrcServoDyn_DataData, DstServoDyn_DataData, C END IF END IF DstServoDyn_DataData%InputTimes = SrcServoDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcServoDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcServoDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcServoDyn_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstServoDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstServoDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstServoDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstServoDyn_DataData%InputTimes_bak = SrcServoDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyServoDyn_Data @@ -21146,6 +22036,8 @@ SUBROUTINE FAST_DestroyServoDyn_Data( ServoDyn_DataData, ErrStat, ErrMsg, DEALLO CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL SrvD_DestroyMisc( ServoDyn_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SrvD_DestroyMisc( ServoDyn_DataData%m_bak, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ServoDyn_DataData%Output)) THEN DO i1 = LBOUND(ServoDyn_DataData%Output,1), UBOUND(ServoDyn_DataData%Output,1) CALL SrvD_DestroyOutput( ServoDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -21162,8 +22054,18 @@ SUBROUTINE FAST_DestroyServoDyn_Data( ServoDyn_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(ServoDyn_DataData%Input) ENDIF +IF (ALLOCATED(ServoDyn_DataData%Input_bak)) THEN +DO i1 = LBOUND(ServoDyn_DataData%Input_bak,1), UBOUND(ServoDyn_DataData%Input_bak,1) + CALL SrvD_DestroyInput( ServoDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ServoDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(ServoDyn_DataData%InputTimes)) THEN DEALLOCATE(ServoDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(ServoDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(ServoDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyServoDyn_Data @@ -21347,6 +22249,23 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! m_bak: size of buffers for each call to pack subtype + CALL SrvD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m_bak, ErrStat2, ErrMsg2, .TRUE. ) ! m_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! m_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! m_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! m_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 1 ! Output allocated yes/no IF ( ALLOCATED(InData%Output) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Output upper/lower bounds for each dimension @@ -21410,11 +22329,39 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL SrvD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -21674,6 +22621,34 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + CALL SrvD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m_bak, ErrStat2, ErrMsg2, OnlySize ) ! m_bak + 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%Output) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -21784,6 +22759,47 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL SrvD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -21799,6 +22815,21 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackServoDyn_Data SUBROUTINE FAST_UnPackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -22164,6 +23195,46 @@ SUBROUTINE FAST_UnPackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta 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 SrvD_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m_bak, ErrStat2, ErrMsg2 ) ! m_bak + 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 ! Output not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -22316,6 +23387,62 @@ SUBROUTINE FAST_UnPackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 SrvD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -22334,6 +23461,24 @@ SUBROUTINE FAST_UnPackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackServoDyn_Data SUBROUTINE FAST_CopyAeroDyn14_Data( SrcAeroDyn14_DataData, DstAeroDyn14_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -22399,6 +23544,22 @@ SUBROUTINE FAST_CopyAeroDyn14_Data( SrcAeroDyn14_DataData, DstAeroDyn14_DataData IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcAeroDyn14_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcAeroDyn14_DataData%Input_bak,1) + i1_u = UBOUND(SrcAeroDyn14_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstAeroDyn14_DataData%Input_bak)) THEN + ALLOCATE(DstAeroDyn14_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn14_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcAeroDyn14_DataData%Input_bak,1), UBOUND(SrcAeroDyn14_DataData%Input_bak,1) + CALL AD14_CopyInput( SrcAeroDyn14_DataData%Input_bak(i1), DstAeroDyn14_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcAeroDyn14_DataData%InputTimes)) THEN i1_l = LBOUND(SrcAeroDyn14_DataData%InputTimes,1) i1_u = UBOUND(SrcAeroDyn14_DataData%InputTimes,1) @@ -22410,6 +23571,18 @@ SUBROUTINE FAST_CopyAeroDyn14_Data( SrcAeroDyn14_DataData, DstAeroDyn14_DataData END IF END IF DstAeroDyn14_DataData%InputTimes = SrcAeroDyn14_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcAeroDyn14_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcAeroDyn14_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcAeroDyn14_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstAeroDyn14_DataData%InputTimes_bak)) THEN + ALLOCATE(DstAeroDyn14_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn14_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstAeroDyn14_DataData%InputTimes_bak = SrcAeroDyn14_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyAeroDyn14_Data @@ -22465,8 +23638,18 @@ SUBROUTINE FAST_DestroyAeroDyn14_Data( AeroDyn14_DataData, ErrStat, ErrMsg, DEAL ENDDO DEALLOCATE(AeroDyn14_DataData%Input) ENDIF +IF (ALLOCATED(AeroDyn14_DataData%Input_bak)) THEN +DO i1 = LBOUND(AeroDyn14_DataData%Input_bak,1), UBOUND(AeroDyn14_DataData%Input_bak,1) + CALL AD14_DestroyInput( AeroDyn14_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(AeroDyn14_DataData%Input_bak) +ENDIF IF (ALLOCATED(AeroDyn14_DataData%InputTimes)) THEN DEALLOCATE(AeroDyn14_DataData%InputTimes) +ENDIF +IF (ALLOCATED(AeroDyn14_DataData%InputTimes_bak)) THEN + DEALLOCATE(AeroDyn14_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyAeroDyn14_Data @@ -22673,11 +23856,39 @@ SUBROUTINE FAST_PackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL AD14_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -22978,6 +24189,47 @@ SUBROUTINE FAST_PackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL AD14_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -22993,6 +24245,21 @@ SUBROUTINE FAST_PackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackAeroDyn14_Data SUBROUTINE FAST_UnPackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -23414,6 +24681,62 @@ SUBROUTINE FAST_UnPackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 AD14_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -23432,6 +24755,24 @@ SUBROUTINE FAST_UnPackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackAeroDyn14_Data SUBROUTINE FAST_CopyAeroDyn_Data( SrcAeroDyn_DataData, DstAeroDyn_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -23516,6 +24857,22 @@ SUBROUTINE FAST_CopyAeroDyn_Data( SrcAeroDyn_DataData, DstAeroDyn_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcAeroDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcAeroDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcAeroDyn_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstAeroDyn_DataData%Input_bak)) THEN + ALLOCATE(DstAeroDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcAeroDyn_DataData%Input_bak,1), UBOUND(SrcAeroDyn_DataData%Input_bak,1) + CALL AD_CopyInput( SrcAeroDyn_DataData%Input_bak(i1), DstAeroDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcAeroDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcAeroDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcAeroDyn_DataData%InputTimes,1) @@ -23527,6 +24884,18 @@ SUBROUTINE FAST_CopyAeroDyn_Data( SrcAeroDyn_DataData, DstAeroDyn_DataData, Ctrl END IF END IF DstAeroDyn_DataData%InputTimes = SrcAeroDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcAeroDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcAeroDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcAeroDyn_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstAeroDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstAeroDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstAeroDyn_DataData%InputTimes_bak = SrcAeroDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyAeroDyn_Data @@ -23591,8 +24960,18 @@ SUBROUTINE FAST_DestroyAeroDyn_Data( AeroDyn_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(AeroDyn_DataData%Input) ENDIF +IF (ALLOCATED(AeroDyn_DataData%Input_bak)) THEN +DO i1 = LBOUND(AeroDyn_DataData%Input_bak,1), UBOUND(AeroDyn_DataData%Input_bak,1) + CALL AD_DestroyInput( AeroDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(AeroDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(AeroDyn_DataData%InputTimes)) THEN DEALLOCATE(AeroDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(AeroDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(AeroDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyAeroDyn_Data @@ -23839,11 +25218,39 @@ SUBROUTINE FAST_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -24213,6 +25620,47 @@ SUBROUTINE FAST_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -24228,6 +25676,21 @@ SUBROUTINE FAST_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackAeroDyn_Data SUBROUTINE FAST_UnPackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -24745,6 +26208,62 @@ SUBROUTINE FAST_UnPackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 AD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -24763,11 +26282,29 @@ SUBROUTINE FAST_UnPackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackAeroDyn_Data - SUBROUTINE FAST_CopyInflowWind_Data( SrcInflowWind_DataData, DstInflowWind_DataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(InflowWind_Data), INTENT(IN) :: SrcInflowWind_DataData - TYPE(InflowWind_Data), INTENT(INOUT) :: DstInflowWind_DataData + SUBROUTINE FAST_CopyExtLoads_Data( SrcExtLoads_DataData, DstExtLoads_DataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLoads_Data), INTENT(INOUT) :: SrcExtLoads_DataData + TYPE(ExtLoads_Data), INTENT(INOUT) :: DstExtLoads_DataData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -24776,93 +26313,58 @@ SUBROUTINE FAST_CopyInflowWind_Data( SrcInflowWind_DataData, DstInflowWind_DataD INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_CopyInflowWind_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_CopyExtLoads_Data' ! ErrStat = ErrID_None ErrMsg = "" - DO i1 = LBOUND(SrcInflowWind_DataData%x,1), UBOUND(SrcInflowWind_DataData%x,1) - CALL InflowWind_CopyContState( SrcInflowWind_DataData%x(i1), DstInflowWind_DataData%x(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcExtLoads_DataData%x,1), UBOUND(SrcExtLoads_DataData%x,1) + CALL ExtLd_CopyContState( SrcExtLoads_DataData%x(i1), DstExtLoads_DataData%x(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO - DO i1 = LBOUND(SrcInflowWind_DataData%xd,1), UBOUND(SrcInflowWind_DataData%xd,1) - CALL InflowWind_CopyDiscState( SrcInflowWind_DataData%xd(i1), DstInflowWind_DataData%xd(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcExtLoads_DataData%xd,1), UBOUND(SrcExtLoads_DataData%xd,1) + CALL ExtLd_CopyDiscState( SrcExtLoads_DataData%xd(i1), DstExtLoads_DataData%xd(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO - DO i1 = LBOUND(SrcInflowWind_DataData%z,1), UBOUND(SrcInflowWind_DataData%z,1) - CALL InflowWind_CopyConstrState( SrcInflowWind_DataData%z(i1), DstInflowWind_DataData%z(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcExtLoads_DataData%z,1), UBOUND(SrcExtLoads_DataData%z,1) + CALL ExtLd_CopyConstrState( SrcExtLoads_DataData%z(i1), DstExtLoads_DataData%z(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO - DO i1 = LBOUND(SrcInflowWind_DataData%OtherSt,1), UBOUND(SrcInflowWind_DataData%OtherSt,1) - CALL InflowWind_CopyOtherState( SrcInflowWind_DataData%OtherSt(i1), DstInflowWind_DataData%OtherSt(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcExtLoads_DataData%OtherSt,1), UBOUND(SrcExtLoads_DataData%OtherSt,1) + CALL ExtLd_CopyOtherState( SrcExtLoads_DataData%OtherSt(i1), DstExtLoads_DataData%OtherSt(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO - CALL InflowWind_CopyParam( SrcInflowWind_DataData%p, DstInflowWind_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyInput( SrcInflowWind_DataData%u, DstInflowWind_DataData%u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL ExtLd_CopyParam( SrcExtLoads_DataData%p, DstExtLoads_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyOutput( SrcInflowWind_DataData%y, DstInflowWind_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyMisc( SrcInflowWind_DataData%m, DstInflowWind_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcInflowWind_DataData%Output)) THEN - i1_l = LBOUND(SrcInflowWind_DataData%Output,1) - i1_u = UBOUND(SrcInflowWind_DataData%Output,1) - IF (.NOT. ALLOCATED(DstInflowWind_DataData%Output)) THEN - ALLOCATE(DstInflowWind_DataData%Output(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%Output.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcInflowWind_DataData%Output,1), UBOUND(SrcInflowWind_DataData%Output,1) - CALL InflowWind_CopyOutput( SrcInflowWind_DataData%Output(i1), DstInflowWind_DataData%Output(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL ExtLd_CopyInput( SrcExtLoads_DataData%u, DstExtLoads_DataData%u, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF - CALL InflowWind_CopyOutput( SrcInflowWind_DataData%y_interp, DstInflowWind_DataData%y_interp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL ExtLd_CopyOutput( SrcExtLoads_DataData%y, DstExtLoads_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcInflowWind_DataData%Input)) THEN - i1_l = LBOUND(SrcInflowWind_DataData%Input,1) - i1_u = UBOUND(SrcInflowWind_DataData%Input,1) - IF (.NOT. ALLOCATED(DstInflowWind_DataData%Input)) THEN - ALLOCATE(DstInflowWind_DataData%Input(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%Input.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcInflowWind_DataData%Input,1), UBOUND(SrcInflowWind_DataData%Input,1) - CALL InflowWind_CopyInput( SrcInflowWind_DataData%Input(i1), DstInflowWind_DataData%Input(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL ExtLd_CopyMisc( SrcExtLoads_DataData%m, DstExtLoads_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcInflowWind_DataData%InputTimes)) THEN - i1_l = LBOUND(SrcInflowWind_DataData%InputTimes,1) - i1_u = UBOUND(SrcInflowWind_DataData%InputTimes,1) - IF (.NOT. ALLOCATED(DstInflowWind_DataData%InputTimes)) THEN - ALLOCATE(DstInflowWind_DataData%InputTimes(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcExtLoads_DataData%InputTimes)) THEN + i1_l = LBOUND(SrcExtLoads_DataData%InputTimes,1) + i1_u = UBOUND(SrcExtLoads_DataData%InputTimes,1) + IF (.NOT. ALLOCATED(DstExtLoads_DataData%InputTimes)) THEN + ALLOCATE(DstExtLoads_DataData%InputTimes(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%InputTimes.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstExtLoads_DataData%InputTimes.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInflowWind_DataData%InputTimes = SrcInflowWind_DataData%InputTimes + DstExtLoads_DataData%InputTimes = SrcExtLoads_DataData%InputTimes ENDIF - END SUBROUTINE FAST_CopyInflowWind_Data + END SUBROUTINE FAST_CopyExtLoads_Data - SUBROUTINE FAST_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(InflowWind_Data), INTENT(INOUT) :: InflowWind_DataData + SUBROUTINE FAST_DestroyExtLoads_Data( ExtLoads_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLoads_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers @@ -24871,7 +26373,7 @@ SUBROUTINE FAST_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg, DE LOGICAL :: DEALLOCATEpointers_local INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyInflowWind_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyExtLoads_Data' ErrStat = ErrID_None ErrMsg = "" @@ -24882,56 +26384,40 @@ SUBROUTINE FAST_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg, DE DEALLOCATEpointers_local = .true. END IF -DO i1 = LBOUND(InflowWind_DataData%x,1), UBOUND(InflowWind_DataData%x,1) - CALL InflowWind_DestroyContState( InflowWind_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +DO i1 = LBOUND(ExtLoads_DataData%x,1), UBOUND(ExtLoads_DataData%x,1) + CALL ExtLd_DestroyContState( ExtLoads_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO -DO i1 = LBOUND(InflowWind_DataData%xd,1), UBOUND(InflowWind_DataData%xd,1) - CALL InflowWind_DestroyDiscState( InflowWind_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +DO i1 = LBOUND(ExtLoads_DataData%xd,1), UBOUND(ExtLoads_DataData%xd,1) + CALL ExtLd_DestroyDiscState( ExtLoads_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO -DO i1 = LBOUND(InflowWind_DataData%z,1), UBOUND(InflowWind_DataData%z,1) - CALL InflowWind_DestroyConstrState( InflowWind_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +DO i1 = LBOUND(ExtLoads_DataData%z,1), UBOUND(ExtLoads_DataData%z,1) + CALL ExtLd_DestroyConstrState( ExtLoads_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO -DO i1 = LBOUND(InflowWind_DataData%OtherSt,1), UBOUND(InflowWind_DataData%OtherSt,1) - CALL InflowWind_DestroyOtherState( InflowWind_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +DO i1 = LBOUND(ExtLoads_DataData%OtherSt,1), UBOUND(ExtLoads_DataData%OtherSt,1) + CALL ExtLd_DestroyOtherState( ExtLoads_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL InflowWind_DestroyParam( InflowWind_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL InflowWind_DestroyInput( InflowWind_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL InflowWind_DestroyOutput( InflowWind_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL ExtLd_DestroyParam( ExtLoads_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL InflowWind_DestroyMisc( InflowWind_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) -IF (ALLOCATED(InflowWind_DataData%Output)) THEN -DO i1 = LBOUND(InflowWind_DataData%Output,1), UBOUND(InflowWind_DataData%Output,1) - CALL InflowWind_DestroyOutput( InflowWind_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL ExtLd_DestroyInput( ExtLoads_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) -ENDDO - DEALLOCATE(InflowWind_DataData%Output) -ENDIF - CALL InflowWind_DestroyOutput( InflowWind_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL ExtLd_DestroyOutput( ExtLoads_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) -IF (ALLOCATED(InflowWind_DataData%Input)) THEN -DO i1 = LBOUND(InflowWind_DataData%Input,1), UBOUND(InflowWind_DataData%Input,1) - CALL InflowWind_DestroyInput( InflowWind_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL ExtLd_DestroyMisc( ExtLoads_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) -ENDDO - DEALLOCATE(InflowWind_DataData%Input) -ENDIF -IF (ALLOCATED(InflowWind_DataData%InputTimes)) THEN - DEALLOCATE(InflowWind_DataData%InputTimes) +IF (ALLOCATED(ExtLoads_DataData%InputTimes)) THEN + DEALLOCATE(ExtLoads_DataData%InputTimes) ENDIF - END SUBROUTINE FAST_DestroyInflowWind_Data + END SUBROUTINE FAST_DestroyExtLoads_Data - SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE FAST_PackExtLoads_Data( 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(InflowWind_Data), INTENT(IN) :: InData + TYPE(ExtLoads_Data), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -24946,7 +26432,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_PackInflowWind_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_PackExtLoads_Data' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -24965,7 +26451,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ! Allocate buffers for subtypes, if any (we'll get sizes from these) DO i1 = LBOUND(InData%x,1), UBOUND(InData%x,1) Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype - CALL InflowWind_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x(i1), ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL ExtLd_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x(i1), ErrStat2, ErrMsg2, .TRUE. ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -24984,7 +26470,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END DO DO i1 = LBOUND(InData%xd,1), UBOUND(InData%xd,1) Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype - CALL InflowWind_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd(i1), ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL ExtLd_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd(i1), ErrStat2, ErrMsg2, .TRUE. ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25003,7 +26489,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END DO DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype - CALL InflowWind_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z(i1), ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL ExtLd_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z(i1), ErrStat2, ErrMsg2, .TRUE. ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25022,7 +26508,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END DO DO i1 = LBOUND(InData%OtherSt,1), UBOUND(InData%OtherSt,1) Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype - CALL InflowWind_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt(i1), ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt + CALL ExtLd_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt(i1), ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25040,7 +26526,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END IF END DO Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype - CALL InflowWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + CALL ExtLd_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25057,7 +26543,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u + CALL ExtLd_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25074,7 +26560,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype - CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL ExtLd_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25091,7 +26577,7 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype - CALL InflowWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL ExtLd_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25107,69 +26593,6 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1 ! Output allocated yes/no - IF ( ALLOCATED(InData%Output) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Output upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) - Int_BufSz = Int_BufSz + 3 ! Output: size of buffers for each call to pack subtype - CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Output - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Output - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Output - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Output - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - Int_BufSz = Int_BufSz + 3 ! y_interp: size of buffers for each call to pack subtype - CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, .TRUE. ) ! y_interp - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! y_interp - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! y_interp - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! y_interp - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! Input allocated yes/no - IF ( ALLOCATED(InData%Input) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) - Int_BufSz = Int_BufSz + 3 ! Input: size of buffers for each call to pack subtype - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Input - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension @@ -25198,6 +26621,1141 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat 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%x,1), UBOUND(InData%x,1) + CALL ExtLd_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x(i1), ErrStat2, ErrMsg2, OnlySize ) ! x + 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 DO + DO i1 = LBOUND(InData%xd,1), UBOUND(InData%xd,1) + CALL ExtLd_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd(i1), ErrStat2, ErrMsg2, OnlySize ) ! xd + 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 DO + DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) + CALL ExtLd_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z(i1), ErrStat2, ErrMsg2, OnlySize ) ! z + 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 DO + DO i1 = LBOUND(InData%OtherSt,1), UBOUND(InData%OtherSt,1) + CALL ExtLd_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt(i1), ErrStat2, ErrMsg2, OnlySize ) ! OtherSt + 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 DO + CALL ExtLd_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + 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 ExtLd_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u + 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 ExtLd_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + 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 ExtLd_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + 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%InputTimes) ) 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%InputTimes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes,1), UBOUND(InData%InputTimes,1) + DbKiBuf(Db_Xferred) = InData%InputTimes(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE FAST_PackExtLoads_Data + + SUBROUTINE FAST_UnPackExtLoads_Data( 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(ExtLoads_Data), 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 = 'FAST_UnPackExtLoads_Data' + ! 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%x,1) + i1_u = UBOUND(OutData%x,1) + DO i1 = LBOUND(OutData%x,1), UBOUND(OutData%x,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 ExtLd_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x(i1), ErrStat2, ErrMsg2 ) ! x + 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 + i1_l = LBOUND(OutData%xd,1) + i1_u = UBOUND(OutData%xd,1) + DO i1 = LBOUND(OutData%xd,1), UBOUND(OutData%xd,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 ExtLd_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd(i1), ErrStat2, ErrMsg2 ) ! xd + 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 + i1_l = LBOUND(OutData%z,1) + i1_u = UBOUND(OutData%z,1) + DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,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 ExtLd_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z(i1), ErrStat2, ErrMsg2 ) ! z + 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 + i1_l = LBOUND(OutData%OtherSt,1) + i1_u = UBOUND(OutData%OtherSt,1) + DO i1 = LBOUND(OutData%OtherSt,1), UBOUND(OutData%OtherSt,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 ExtLd_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt(i1), ErrStat2, ErrMsg2 ) ! OtherSt + 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 + 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 ExtLd_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p + 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 ExtLd_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + 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 ExtLd_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + 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 ExtLd_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + 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 ! InputTimes 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%InputTimes)) DEALLOCATE(OutData%InputTimes) + ALLOCATE(OutData%InputTimes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes,1), UBOUND(OutData%InputTimes,1) + OutData%InputTimes(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE FAST_UnPackExtLoads_Data + + SUBROUTINE FAST_CopyInflowWind_Data( SrcInflowWind_DataData, DstInflowWind_DataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(InflowWind_Data), INTENT(IN) :: SrcInflowWind_DataData + TYPE(InflowWind_Data), INTENT(INOUT) :: DstInflowWind_DataData + 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 = 'FAST_CopyInflowWind_Data' +! + ErrStat = ErrID_None + ErrMsg = "" + DO i1 = LBOUND(SrcInflowWind_DataData%x,1), UBOUND(SrcInflowWind_DataData%x,1) + CALL InflowWind_CopyContState( SrcInflowWind_DataData%x(i1), DstInflowWind_DataData%x(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + DO i1 = LBOUND(SrcInflowWind_DataData%xd,1), UBOUND(SrcInflowWind_DataData%xd,1) + CALL InflowWind_CopyDiscState( SrcInflowWind_DataData%xd(i1), DstInflowWind_DataData%xd(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + DO i1 = LBOUND(SrcInflowWind_DataData%z,1), UBOUND(SrcInflowWind_DataData%z,1) + CALL InflowWind_CopyConstrState( SrcInflowWind_DataData%z(i1), DstInflowWind_DataData%z(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + DO i1 = LBOUND(SrcInflowWind_DataData%OtherSt,1), UBOUND(SrcInflowWind_DataData%OtherSt,1) + CALL InflowWind_CopyOtherState( SrcInflowWind_DataData%OtherSt(i1), DstInflowWind_DataData%OtherSt(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + CALL InflowWind_CopyParam( SrcInflowWind_DataData%p, DstInflowWind_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyInput( SrcInflowWind_DataData%u, DstInflowWind_DataData%u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyOutput( SrcInflowWind_DataData%y, DstInflowWind_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyMisc( SrcInflowWind_DataData%m, DstInflowWind_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcInflowWind_DataData%Output)) THEN + i1_l = LBOUND(SrcInflowWind_DataData%Output,1) + i1_u = UBOUND(SrcInflowWind_DataData%Output,1) + IF (.NOT. ALLOCATED(DstInflowWind_DataData%Output)) THEN + ALLOCATE(DstInflowWind_DataData%Output(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%Output.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInflowWind_DataData%Output,1), UBOUND(SrcInflowWind_DataData%Output,1) + CALL InflowWind_CopyOutput( SrcInflowWind_DataData%Output(i1), DstInflowWind_DataData%Output(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL InflowWind_CopyOutput( SrcInflowWind_DataData%y_interp, DstInflowWind_DataData%y_interp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcInflowWind_DataData%Input)) THEN + i1_l = LBOUND(SrcInflowWind_DataData%Input,1) + i1_u = UBOUND(SrcInflowWind_DataData%Input,1) + IF (.NOT. ALLOCATED(DstInflowWind_DataData%Input)) THEN + ALLOCATE(DstInflowWind_DataData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%Input.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInflowWind_DataData%Input,1), UBOUND(SrcInflowWind_DataData%Input,1) + CALL InflowWind_CopyInput( SrcInflowWind_DataData%Input(i1), DstInflowWind_DataData%Input(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcInflowWind_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcInflowWind_DataData%Input_bak,1) + i1_u = UBOUND(SrcInflowWind_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstInflowWind_DataData%Input_bak)) THEN + ALLOCATE(DstInflowWind_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInflowWind_DataData%Input_bak,1), UBOUND(SrcInflowWind_DataData%Input_bak,1) + CALL InflowWind_CopyInput( SrcInflowWind_DataData%Input_bak(i1), DstInflowWind_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcInflowWind_DataData%InputTimes)) THEN + i1_l = LBOUND(SrcInflowWind_DataData%InputTimes,1) + i1_u = UBOUND(SrcInflowWind_DataData%InputTimes,1) + IF (.NOT. ALLOCATED(DstInflowWind_DataData%InputTimes)) THEN + ALLOCATE(DstInflowWind_DataData%InputTimes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%InputTimes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInflowWind_DataData%InputTimes = SrcInflowWind_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcInflowWind_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcInflowWind_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcInflowWind_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstInflowWind_DataData%InputTimes_bak)) THEN + ALLOCATE(DstInflowWind_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInflowWind_DataData%InputTimes_bak = SrcInflowWind_DataData%InputTimes_bak +ENDIF + END SUBROUTINE FAST_CopyInflowWind_Data + + SUBROUTINE FAST_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(InflowWind_Data), INTENT(INOUT) :: InflowWind_DataData + 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 = 'FAST_DestroyInflowWind_Data' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +DO i1 = LBOUND(InflowWind_DataData%x,1), UBOUND(InflowWind_DataData%x,1) + CALL InflowWind_DestroyContState( InflowWind_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO +DO i1 = LBOUND(InflowWind_DataData%xd,1), UBOUND(InflowWind_DataData%xd,1) + CALL InflowWind_DestroyDiscState( InflowWind_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO +DO i1 = LBOUND(InflowWind_DataData%z,1), UBOUND(InflowWind_DataData%z,1) + CALL InflowWind_DestroyConstrState( InflowWind_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO +DO i1 = LBOUND(InflowWind_DataData%OtherSt,1), UBOUND(InflowWind_DataData%OtherSt,1) + CALL InflowWind_DestroyOtherState( InflowWind_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + CALL InflowWind_DestroyParam( InflowWind_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInput( InflowWind_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOutput( InflowWind_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyMisc( InflowWind_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(InflowWind_DataData%Output)) THEN +DO i1 = LBOUND(InflowWind_DataData%Output,1), UBOUND(InflowWind_DataData%Output,1) + CALL InflowWind_DestroyOutput( InflowWind_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(InflowWind_DataData%Output) +ENDIF + CALL InflowWind_DestroyOutput( InflowWind_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(InflowWind_DataData%Input)) THEN +DO i1 = LBOUND(InflowWind_DataData%Input,1), UBOUND(InflowWind_DataData%Input,1) + CALL InflowWind_DestroyInput( InflowWind_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(InflowWind_DataData%Input) +ENDIF +IF (ALLOCATED(InflowWind_DataData%Input_bak)) THEN +DO i1 = LBOUND(InflowWind_DataData%Input_bak,1), UBOUND(InflowWind_DataData%Input_bak,1) + CALL InflowWind_DestroyInput( InflowWind_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(InflowWind_DataData%Input_bak) +ENDIF +IF (ALLOCATED(InflowWind_DataData%InputTimes)) THEN + DEALLOCATE(InflowWind_DataData%InputTimes) +ENDIF +IF (ALLOCATED(InflowWind_DataData%InputTimes_bak)) THEN + DEALLOCATE(InflowWind_DataData%InputTimes_bak) +ENDIF + END SUBROUTINE FAST_DestroyInflowWind_Data + + SUBROUTINE FAST_PackInflowWind_Data( 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(InflowWind_Data), 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 = 'FAST_PackInflowWind_Data' + ! 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) + DO i1 = LBOUND(InData%x,1), UBOUND(InData%x,1) + Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype + CALL InflowWind_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x(i1), ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! x + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! x + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! x + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + DO i1 = LBOUND(InData%xd,1), UBOUND(InData%xd,1) + Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype + CALL InflowWind_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd(i1), ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! xd + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! xd + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! xd + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) + Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype + CALL InflowWind_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z(i1), ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! z + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! z + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! z + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + DO i1 = LBOUND(InData%OtherSt,1), UBOUND(InData%OtherSt,1) + Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype + CALL InflowWind_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt(i1), ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! OtherSt + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! OtherSt + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! OtherSt + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype + CALL InflowWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! p + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! p + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! p + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype + CALL InflowWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! m + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! m + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! m + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! Output allocated yes/no + IF ( ALLOCATED(InData%Output) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Output upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) + Int_BufSz = Int_BufSz + 3 ! Output: size of buffers for each call to pack subtype + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Output + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Output + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Output + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Output + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! y_interp: size of buffers for each call to pack subtype + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, .TRUE. ) ! y_interp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y_interp + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y_interp + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y_interp + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! Input allocated yes/no + IF ( ALLOCATED(InData%Input) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) + Int_BufSz = Int_BufSz + 3 ! Input: size of buffers for each call to pack subtype + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no + IF ( ALLOCATED(InData%InputTimes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes + END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + 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 @@ -25544,6 +28102,47 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -25559,6 +28158,21 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackInflowWind_Data SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -25971,15 +28585,69 @@ SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL InflowWind_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%Output(i1), ErrStat2, ErrMsg2 ) ! Output + CALL InflowWind_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%Output(i1), ErrStat2, ErrMsg2 ) ! Output + 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 + 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_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y_interp, ErrStat2, ErrMsg2 ) ! y_interp 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 ! Input 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%Input)) DEALLOCATE(OutData%Input) + ALLOCATE(OutData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input,1), UBOUND(OutData%Input,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -26013,27 +28681,29 @@ SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL InflowWind_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y_interp, ErrStat2, ErrMsg2 ) ! y_interp + CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input(i1), ErrStat2, ErrMsg2 ) ! Input 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 ! Input not allocated + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input)) DEALLOCATE(OutData%Input) - ALLOCATE(OutData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input,1), UBOUND(OutData%Input,1) + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -26067,7 +28737,7 @@ SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input(i1), ErrStat2, ErrMsg2 ) ! Input + CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -26094,6 +28764,24 @@ SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackInflowWind_Data SUBROUTINE FAST_CopyExternalInflow_Data( SrcExternalInflow_DataData, DstExternalInflow_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -27053,6 +29741,22 @@ SUBROUTINE FAST_CopySubDyn_Data( SrcSubDyn_DataData, DstSubDyn_DataData, CtrlCod IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcSubDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcSubDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcSubDyn_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstSubDyn_DataData%Input_bak)) THEN + ALLOCATE(DstSubDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSubDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcSubDyn_DataData%Input_bak,1), UBOUND(SrcSubDyn_DataData%Input_bak,1) + CALL SD_CopyInput( SrcSubDyn_DataData%Input_bak(i1), DstSubDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcSubDyn_DataData%Output)) THEN i1_l = LBOUND(SrcSubDyn_DataData%Output,1) i1_u = UBOUND(SrcSubDyn_DataData%Output,1) @@ -27083,6 +29787,18 @@ SUBROUTINE FAST_CopySubDyn_Data( SrcSubDyn_DataData, DstSubDyn_DataData, CtrlCod END IF END IF DstSubDyn_DataData%InputTimes = SrcSubDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcSubDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcSubDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcSubDyn_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstSubDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstSubDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSubDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstSubDyn_DataData%InputTimes_bak = SrcSubDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopySubDyn_Data @@ -27138,6 +29854,13 @@ SUBROUTINE FAST_DestroySubDyn_Data( SubDyn_DataData, ErrStat, ErrMsg, DEALLOCATE ENDDO DEALLOCATE(SubDyn_DataData%Input) ENDIF +IF (ALLOCATED(SubDyn_DataData%Input_bak)) THEN +DO i1 = LBOUND(SubDyn_DataData%Input_bak,1), UBOUND(SubDyn_DataData%Input_bak,1) + CALL SD_DestroyInput( SubDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(SubDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(SubDyn_DataData%Output)) THEN DO i1 = LBOUND(SubDyn_DataData%Output,1), UBOUND(SubDyn_DataData%Output,1) CALL SD_DestroyOutput( SubDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -27149,6 +29872,9 @@ SUBROUTINE FAST_DestroySubDyn_Data( SubDyn_DataData, ErrStat, ErrMsg, DEALLOCATE CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(SubDyn_DataData%InputTimes)) THEN DEALLOCATE(SubDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(SubDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(SubDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroySubDyn_Data @@ -27355,6 +30081,29 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL SD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! Output allocated yes/no IF ( ALLOCATED(InData%Output) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Output upper/lower bounds for each dimension @@ -27400,6 +30149,11 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -27700,6 +30454,47 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL SD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%Output) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -27784,6 +30579,21 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackSubDyn_Data SUBROUTINE FAST_UnPackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -28205,6 +31015,62 @@ SUBROUTINE FAST_UnPackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 SD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! Output not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -28319,6 +31185,24 @@ SUBROUTINE FAST_UnPackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackSubDyn_Data SUBROUTINE FAST_CopyExtPtfm_Data( SrcExtPtfm_DataData, DstExtPtfm_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -28384,6 +31268,22 @@ SUBROUTINE FAST_CopyExtPtfm_Data( SrcExtPtfm_DataData, DstExtPtfm_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcExtPtfm_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcExtPtfm_DataData%Input_bak,1) + i1_u = UBOUND(SrcExtPtfm_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstExtPtfm_DataData%Input_bak)) THEN + ALLOCATE(DstExtPtfm_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstExtPtfm_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcExtPtfm_DataData%Input_bak,1), UBOUND(SrcExtPtfm_DataData%Input_bak,1) + CALL ExtPtfm_CopyInput( SrcExtPtfm_DataData%Input_bak(i1), DstExtPtfm_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcExtPtfm_DataData%InputTimes)) THEN i1_l = LBOUND(SrcExtPtfm_DataData%InputTimes,1) i1_u = UBOUND(SrcExtPtfm_DataData%InputTimes,1) @@ -28395,6 +31295,18 @@ SUBROUTINE FAST_CopyExtPtfm_Data( SrcExtPtfm_DataData, DstExtPtfm_DataData, Ctrl END IF END IF DstExtPtfm_DataData%InputTimes = SrcExtPtfm_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcExtPtfm_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcExtPtfm_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcExtPtfm_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstExtPtfm_DataData%InputTimes_bak)) THEN + ALLOCATE(DstExtPtfm_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstExtPtfm_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstExtPtfm_DataData%InputTimes_bak = SrcExtPtfm_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyExtPtfm_Data @@ -28450,8 +31362,18 @@ SUBROUTINE FAST_DestroyExtPtfm_Data( ExtPtfm_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(ExtPtfm_DataData%Input) ENDIF +IF (ALLOCATED(ExtPtfm_DataData%Input_bak)) THEN +DO i1 = LBOUND(ExtPtfm_DataData%Input_bak,1), UBOUND(ExtPtfm_DataData%Input_bak,1) + CALL ExtPtfm_DestroyInput( ExtPtfm_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ExtPtfm_DataData%Input_bak) +ENDIF IF (ALLOCATED(ExtPtfm_DataData%InputTimes)) THEN DEALLOCATE(ExtPtfm_DataData%InputTimes) +ENDIF +IF (ALLOCATED(ExtPtfm_DataData%InputTimes_bak)) THEN + DEALLOCATE(ExtPtfm_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyExtPtfm_Data @@ -28658,11 +31580,39 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -28866,35 +31816,74 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL ExtPtfm_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + CALL ExtPtfm_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + 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 ExtPtfm_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + 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%Input) ) 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%Input,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input,1) + 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 ExtPtfm_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) + CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -28922,18 +31911,20 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%Input) ) THEN + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) - CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -28978,6 +31969,21 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackExtPtfm_Data SUBROUTINE FAST_UnPackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -29399,6 +32405,62 @@ SUBROUTINE FAST_UnPackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 ExtPtfm_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -29417,6 +32479,24 @@ SUBROUTINE FAST_UnPackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackExtPtfm_Data SUBROUTINE FAST_CopySeaState_Data( SrcSeaState_DataData, DstSeaState_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -29482,6 +32562,22 @@ SUBROUTINE FAST_CopySeaState_Data( SrcSeaState_DataData, DstSeaState_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcSeaState_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcSeaState_DataData%Input_bak,1) + i1_u = UBOUND(SrcSeaState_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstSeaState_DataData%Input_bak)) THEN + ALLOCATE(DstSeaState_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSeaState_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcSeaState_DataData%Input_bak,1), UBOUND(SrcSeaState_DataData%Input_bak,1) + CALL SeaSt_CopyInput( SrcSeaState_DataData%Input_bak(i1), DstSeaState_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcSeaState_DataData%Output)) THEN i1_l = LBOUND(SrcSeaState_DataData%Output,1) i1_u = UBOUND(SrcSeaState_DataData%Output,1) @@ -29512,6 +32608,18 @@ SUBROUTINE FAST_CopySeaState_Data( SrcSeaState_DataData, DstSeaState_DataData, C END IF END IF DstSeaState_DataData%InputTimes = SrcSeaState_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcSeaState_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcSeaState_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcSeaState_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstSeaState_DataData%InputTimes_bak)) THEN + ALLOCATE(DstSeaState_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSeaState_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstSeaState_DataData%InputTimes_bak = SrcSeaState_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopySeaState_Data @@ -29567,6 +32675,13 @@ SUBROUTINE FAST_DestroySeaState_Data( SeaState_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(SeaState_DataData%Input) ENDIF +IF (ALLOCATED(SeaState_DataData%Input_bak)) THEN +DO i1 = LBOUND(SeaState_DataData%Input_bak,1), UBOUND(SeaState_DataData%Input_bak,1) + CALL SeaSt_DestroyInput( SeaState_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(SeaState_DataData%Input_bak) +ENDIF IF (ALLOCATED(SeaState_DataData%Output)) THEN DO i1 = LBOUND(SeaState_DataData%Output,1), UBOUND(SeaState_DataData%Output,1) CALL SeaSt_DestroyOutput( SeaState_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -29578,6 +32693,9 @@ SUBROUTINE FAST_DestroySeaState_Data( SeaState_DataData, ErrStat, ErrMsg, DEALLO CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(SeaState_DataData%InputTimes)) THEN DEALLOCATE(SeaState_DataData%InputTimes) +ENDIF +IF (ALLOCATED(SeaState_DataData%InputTimes_bak)) THEN + DEALLOCATE(SeaState_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroySeaState_Data @@ -29784,6 +32902,29 @@ SUBROUTINE FAST_PackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL SeaSt_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! Output allocated yes/no IF ( ALLOCATED(InData%Output) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Output upper/lower bounds for each dimension @@ -29829,6 +32970,11 @@ SUBROUTINE FAST_PackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -30127,89 +33273,145 @@ SUBROUTINE FAST_PackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END IF - IF ( .NOT. ALLOCATED(InData%Output) ) THEN + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL SeaSt_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF + IF ( .NOT. ALLOCATED(InData%Output) ) 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%Output,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Output,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) + CALL SeaSt_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, OnlySize ) ! Output + 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 DO + END IF + CALL SeaSt_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, OnlySize ) ! y_interp + 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%InputTimes) ) 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%Output,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Output,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) - CALL SeaSt_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, OnlySize ) ! Output - 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 DO + DO i1 = LBOUND(InData%InputTimes,1), UBOUND(InData%InputTimes,1) + DbKiBuf(Db_Xferred) = InData%InputTimes(i1) + Db_Xferred = Db_Xferred + 1 + END DO END IF - CALL SeaSt_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, OnlySize ) ! y_interp - 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%InputTimes) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes,1), UBOUND(InData%InputTimes,1) - DbKiBuf(Db_Xferred) = InData%InputTimes(i1) + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -30634,6 +33836,62 @@ SUBROUTINE FAST_UnPackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 SeaSt_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! Output not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -30748,6 +34006,24 @@ SUBROUTINE FAST_UnPackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackSeaState_Data SUBROUTINE FAST_CopyHydroDyn_Data( SrcHydroDyn_DataData, DstHydroDyn_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -30832,6 +34108,22 @@ SUBROUTINE FAST_CopyHydroDyn_Data( SrcHydroDyn_DataData, DstHydroDyn_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcHydroDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcHydroDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcHydroDyn_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstHydroDyn_DataData%Input_bak)) THEN + ALLOCATE(DstHydroDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHydroDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcHydroDyn_DataData%Input_bak,1), UBOUND(SrcHydroDyn_DataData%Input_bak,1) + CALL HydroDyn_CopyInput( SrcHydroDyn_DataData%Input_bak(i1), DstHydroDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcHydroDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcHydroDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcHydroDyn_DataData%InputTimes,1) @@ -30843,6 +34135,18 @@ SUBROUTINE FAST_CopyHydroDyn_Data( SrcHydroDyn_DataData, DstHydroDyn_DataData, C END IF END IF DstHydroDyn_DataData%InputTimes = SrcHydroDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcHydroDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcHydroDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcHydroDyn_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstHydroDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstHydroDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHydroDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstHydroDyn_DataData%InputTimes_bak = SrcHydroDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyHydroDyn_Data @@ -30907,8 +34211,18 @@ SUBROUTINE FAST_DestroyHydroDyn_Data( HydroDyn_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(HydroDyn_DataData%Input) ENDIF +IF (ALLOCATED(HydroDyn_DataData%Input_bak)) THEN +DO i1 = LBOUND(HydroDyn_DataData%Input_bak,1), UBOUND(HydroDyn_DataData%Input_bak,1) + CALL HydroDyn_DestroyInput( HydroDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(HydroDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(HydroDyn_DataData%InputTimes)) THEN DEALLOCATE(HydroDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(HydroDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(HydroDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyHydroDyn_Data @@ -31155,11 +34469,39 @@ SUBROUTINE FAST_PackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL HydroDyn_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -31529,6 +34871,47 @@ SUBROUTINE FAST_PackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL HydroDyn_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -31544,6 +34927,21 @@ SUBROUTINE FAST_PackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackHydroDyn_Data SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -31956,15 +35354,69 @@ SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL HydroDyn_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%Output(i1), ErrStat2, ErrMsg2 ) ! Output + CALL HydroDyn_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%Output(i1), ErrStat2, ErrMsg2 ) ! Output + 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 + 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 HydroDyn_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y_interp, ErrStat2, ErrMsg2 ) ! y_interp 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 ! Input 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%Input)) DEALLOCATE(OutData%Input) + ALLOCATE(OutData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input,1), UBOUND(OutData%Input,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -31998,27 +35450,29 @@ SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL HydroDyn_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y_interp, ErrStat2, ErrMsg2 ) ! y_interp + CALL HydroDyn_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input(i1), ErrStat2, ErrMsg2 ) ! Input 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 ! Input not allocated + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input)) DEALLOCATE(OutData%Input) - ALLOCATE(OutData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input,1), UBOUND(OutData%Input,1) + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -32052,7 +35506,7 @@ SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL HydroDyn_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input(i1), ErrStat2, ErrMsg2 ) ! Input + CALL HydroDyn_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -32079,6 +35533,24 @@ SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackHydroDyn_Data SUBROUTINE FAST_CopyIceFloe_Data( SrcIceFloe_DataData, DstIceFloe_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -32144,6 +35616,22 @@ SUBROUTINE FAST_CopyIceFloe_Data( SrcIceFloe_DataData, DstIceFloe_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcIceFloe_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcIceFloe_DataData%Input_bak,1) + i1_u = UBOUND(SrcIceFloe_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstIceFloe_DataData%Input_bak)) THEN + ALLOCATE(DstIceFloe_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceFloe_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcIceFloe_DataData%Input_bak,1), UBOUND(SrcIceFloe_DataData%Input_bak,1) + CALL IceFloe_CopyInput( SrcIceFloe_DataData%Input_bak(i1), DstIceFloe_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcIceFloe_DataData%InputTimes)) THEN i1_l = LBOUND(SrcIceFloe_DataData%InputTimes,1) i1_u = UBOUND(SrcIceFloe_DataData%InputTimes,1) @@ -32155,6 +35643,18 @@ SUBROUTINE FAST_CopyIceFloe_Data( SrcIceFloe_DataData, DstIceFloe_DataData, Ctrl END IF END IF DstIceFloe_DataData%InputTimes = SrcIceFloe_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcIceFloe_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcIceFloe_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcIceFloe_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstIceFloe_DataData%InputTimes_bak)) THEN + ALLOCATE(DstIceFloe_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceFloe_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstIceFloe_DataData%InputTimes_bak = SrcIceFloe_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyIceFloe_Data @@ -32210,8 +35710,18 @@ SUBROUTINE FAST_DestroyIceFloe_Data( IceFloe_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(IceFloe_DataData%Input) ENDIF +IF (ALLOCATED(IceFloe_DataData%Input_bak)) THEN +DO i1 = LBOUND(IceFloe_DataData%Input_bak,1), UBOUND(IceFloe_DataData%Input_bak,1) + CALL IceFloe_DestroyInput( IceFloe_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(IceFloe_DataData%Input_bak) +ENDIF IF (ALLOCATED(IceFloe_DataData%InputTimes)) THEN DEALLOCATE(IceFloe_DataData%InputTimes) +ENDIF +IF (ALLOCATED(IceFloe_DataData%InputTimes_bak)) THEN + DEALLOCATE(IceFloe_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyIceFloe_Data @@ -32418,11 +35928,39 @@ SUBROUTINE FAST_PackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL IceFloe_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -32723,6 +36261,47 @@ SUBROUTINE FAST_PackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL IceFloe_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -32738,6 +36317,21 @@ SUBROUTINE FAST_PackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackIceFloe_Data SUBROUTINE FAST_UnPackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -33159,6 +36753,62 @@ SUBROUTINE FAST_UnPackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 IceFloe_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -33177,6 +36827,24 @@ SUBROUTINE FAST_UnPackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackIceFloe_Data SUBROUTINE FAST_CopyMAP_Data( SrcMAP_DataData, DstMAP_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -33259,6 +36927,22 @@ SUBROUTINE FAST_CopyMAP_Data( SrcMAP_DataData, DstMAP_DataData, CtrlCode, ErrSta IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcMAP_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcMAP_DataData%Input_bak,1) + i1_u = UBOUND(SrcMAP_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstMAP_DataData%Input_bak)) THEN + ALLOCATE(DstMAP_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMAP_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMAP_DataData%Input_bak,1), UBOUND(SrcMAP_DataData%Input_bak,1) + CALL MAP_CopyInput( SrcMAP_DataData%Input_bak(i1), DstMAP_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcMAP_DataData%InputTimes)) THEN i1_l = LBOUND(SrcMAP_DataData%InputTimes,1) i1_u = UBOUND(SrcMAP_DataData%InputTimes,1) @@ -33270,6 +36954,18 @@ SUBROUTINE FAST_CopyMAP_Data( SrcMAP_DataData, DstMAP_DataData, CtrlCode, ErrSta END IF END IF DstMAP_DataData%InputTimes = SrcMAP_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcMAP_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcMAP_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcMAP_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstMAP_DataData%InputTimes_bak)) THEN + ALLOCATE(DstMAP_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMAP_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMAP_DataData%InputTimes_bak = SrcMAP_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyMAP_Data @@ -33332,8 +37028,18 @@ SUBROUTINE FAST_DestroyMAP_Data( MAP_DataData, ErrStat, ErrMsg, DEALLOCATEpointe ENDDO DEALLOCATE(MAP_DataData%Input) ENDIF +IF (ALLOCATED(MAP_DataData%Input_bak)) THEN +DO i1 = LBOUND(MAP_DataData%Input_bak,1), UBOUND(MAP_DataData%Input_bak,1) + CALL MAP_DestroyInput( MAP_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MAP_DataData%Input_bak) +ENDIF IF (ALLOCATED(MAP_DataData%InputTimes)) THEN DEALLOCATE(MAP_DataData%InputTimes) +ENDIF +IF (ALLOCATED(MAP_DataData%InputTimes_bak)) THEN + DEALLOCATE(MAP_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyMAP_Data @@ -33578,11 +37284,39 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -33699,8 +37433,64 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - CALL MAP_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt + END DO + CALL MAP_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt + 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 MAP_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + 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 MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33728,7 +37518,7 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MAP_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + CALL MAP_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33756,7 +37546,7 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u + CALL MAP_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt_old, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt_old CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33784,7 +37574,18 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MAP_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + IF ( .NOT. ALLOCATED(InData%Output) ) 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%Output,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Output,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) + CALL MAP_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, OnlySize ) ! Output CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33812,7 +37613,9 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MAP_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt_old, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt_old + END DO + END IF + CALL MAP_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, OnlySize ) ! y_interp CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33840,18 +37643,18 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%Output) ) THEN + IF ( .NOT. ALLOCATED(InData%Input) ) 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%Output,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Output,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) - CALL MAP_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, OnlySize ) ! Output + DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) + CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33881,46 +37684,18 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ENDIF END DO END IF - CALL MAP_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, OnlySize ) ! y_interp - 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%Input) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) - CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33965,6 +37740,21 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackMAP_Data SUBROUTINE FAST_UnPackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -34478,6 +38268,62 @@ SUBROUTINE FAST_UnPackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 MAP_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -34496,6 +38342,24 @@ SUBROUTINE FAST_UnPackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackMAP_Data SUBROUTINE FAST_CopyFEAMooring_Data( SrcFEAMooring_DataData, DstFEAMooring_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -34561,6 +38425,22 @@ SUBROUTINE FAST_CopyFEAMooring_Data( SrcFEAMooring_DataData, DstFEAMooring_DataD IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcFEAMooring_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcFEAMooring_DataData%Input_bak,1) + i1_u = UBOUND(SrcFEAMooring_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstFEAMooring_DataData%Input_bak)) THEN + ALLOCATE(DstFEAMooring_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEAMooring_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcFEAMooring_DataData%Input_bak,1), UBOUND(SrcFEAMooring_DataData%Input_bak,1) + CALL FEAM_CopyInput( SrcFEAMooring_DataData%Input_bak(i1), DstFEAMooring_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcFEAMooring_DataData%InputTimes)) THEN i1_l = LBOUND(SrcFEAMooring_DataData%InputTimes,1) i1_u = UBOUND(SrcFEAMooring_DataData%InputTimes,1) @@ -34572,6 +38452,18 @@ SUBROUTINE FAST_CopyFEAMooring_Data( SrcFEAMooring_DataData, DstFEAMooring_DataD END IF END IF DstFEAMooring_DataData%InputTimes = SrcFEAMooring_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcFEAMooring_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcFEAMooring_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcFEAMooring_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstFEAMooring_DataData%InputTimes_bak)) THEN + ALLOCATE(DstFEAMooring_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEAMooring_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstFEAMooring_DataData%InputTimes_bak = SrcFEAMooring_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyFEAMooring_Data @@ -34627,8 +38519,18 @@ SUBROUTINE FAST_DestroyFEAMooring_Data( FEAMooring_DataData, ErrStat, ErrMsg, DE ENDDO DEALLOCATE(FEAMooring_DataData%Input) ENDIF +IF (ALLOCATED(FEAMooring_DataData%Input_bak)) THEN +DO i1 = LBOUND(FEAMooring_DataData%Input_bak,1), UBOUND(FEAMooring_DataData%Input_bak,1) + CALL FEAM_DestroyInput( FEAMooring_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(FEAMooring_DataData%Input_bak) +ENDIF IF (ALLOCATED(FEAMooring_DataData%InputTimes)) THEN DEALLOCATE(FEAMooring_DataData%InputTimes) +ENDIF +IF (ALLOCATED(FEAMooring_DataData%InputTimes_bak)) THEN + DEALLOCATE(FEAMooring_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyFEAMooring_Data @@ -34835,11 +38737,39 @@ SUBROUTINE FAST_PackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL FEAM_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -35140,6 +39070,47 @@ SUBROUTINE FAST_PackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL FEAM_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -35155,6 +39126,21 @@ SUBROUTINE FAST_PackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackFEAMooring_Data SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -35433,7 +39419,47 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL FEAM_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + CALL FEAM_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + 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 FEAM_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -35473,13 +39499,27 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL FEAM_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + CALL FEAM_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m 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 ! Input 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%Input)) DEALLOCATE(OutData%Input) + ALLOCATE(OutData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input,1), UBOUND(OutData%Input,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -35513,27 +39553,29 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL FEAM_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + CALL FEAM_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input(i1), ErrStat2, ErrMsg2 ) ! Input 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 ! Input not allocated + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input)) DEALLOCATE(OutData%Input) - ALLOCATE(OutData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input,1), UBOUND(OutData%Input,1) + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -35567,7 +39609,7 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL FEAM_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input(i1), ErrStat2, ErrMsg2 ) ! Input + CALL FEAM_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -35594,6 +39636,24 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackFEAMooring_Data SUBROUTINE FAST_CopyMoorDyn_Data( SrcMoorDyn_DataData, DstMoorDyn_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -35678,6 +39738,22 @@ SUBROUTINE FAST_CopyMoorDyn_Data( SrcMoorDyn_DataData, DstMoorDyn_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcMoorDyn_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcMoorDyn_DataData%Input_bak,1) + i1_u = UBOUND(SrcMoorDyn_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstMoorDyn_DataData%Input_bak)) THEN + ALLOCATE(DstMoorDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMoorDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMoorDyn_DataData%Input_bak,1), UBOUND(SrcMoorDyn_DataData%Input_bak,1) + CALL MD_CopyInput( SrcMoorDyn_DataData%Input_bak(i1), DstMoorDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcMoorDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcMoorDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcMoorDyn_DataData%InputTimes,1) @@ -35689,6 +39765,18 @@ SUBROUTINE FAST_CopyMoorDyn_Data( SrcMoorDyn_DataData, DstMoorDyn_DataData, Ctrl END IF END IF DstMoorDyn_DataData%InputTimes = SrcMoorDyn_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcMoorDyn_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcMoorDyn_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcMoorDyn_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstMoorDyn_DataData%InputTimes_bak)) THEN + ALLOCATE(DstMoorDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMoorDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMoorDyn_DataData%InputTimes_bak = SrcMoorDyn_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyMoorDyn_Data @@ -35753,8 +39841,18 @@ SUBROUTINE FAST_DestroyMoorDyn_Data( MoorDyn_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(MoorDyn_DataData%Input) ENDIF +IF (ALLOCATED(MoorDyn_DataData%Input_bak)) THEN +DO i1 = LBOUND(MoorDyn_DataData%Input_bak,1), UBOUND(MoorDyn_DataData%Input_bak,1) + CALL MD_DestroyInput( MoorDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MoorDyn_DataData%Input_bak) +ENDIF IF (ALLOCATED(MoorDyn_DataData%InputTimes)) THEN DEALLOCATE(MoorDyn_DataData%InputTimes) +ENDIF +IF (ALLOCATED(MoorDyn_DataData%InputTimes_bak)) THEN + DEALLOCATE(MoorDyn_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyMoorDyn_Data @@ -36001,11 +40099,39 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -36375,6 +40501,47 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -36390,6 +40557,21 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackMoorDyn_Data SUBROUTINE FAST_UnPackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -36907,6 +41089,62 @@ SUBROUTINE FAST_UnPackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 MD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -36925,6 +41163,24 @@ SUBROUTINE FAST_UnPackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackMoorDyn_Data SUBROUTINE FAST_CopyOrcaFlex_Data( SrcOrcaFlex_DataData, DstOrcaFlex_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -36990,6 +41246,22 @@ SUBROUTINE FAST_CopyOrcaFlex_Data( SrcOrcaFlex_DataData, DstOrcaFlex_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcOrcaFlex_DataData%Input_bak)) THEN + i1_l = LBOUND(SrcOrcaFlex_DataData%Input_bak,1) + i1_u = UBOUND(SrcOrcaFlex_DataData%Input_bak,1) + IF (.NOT. ALLOCATED(DstOrcaFlex_DataData%Input_bak)) THEN + ALLOCATE(DstOrcaFlex_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOrcaFlex_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOrcaFlex_DataData%Input_bak,1), UBOUND(SrcOrcaFlex_DataData%Input_bak,1) + CALL Orca_CopyInput( SrcOrcaFlex_DataData%Input_bak(i1), DstOrcaFlex_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcOrcaFlex_DataData%InputTimes)) THEN i1_l = LBOUND(SrcOrcaFlex_DataData%InputTimes,1) i1_u = UBOUND(SrcOrcaFlex_DataData%InputTimes,1) @@ -37001,6 +41273,18 @@ SUBROUTINE FAST_CopyOrcaFlex_Data( SrcOrcaFlex_DataData, DstOrcaFlex_DataData, C END IF END IF DstOrcaFlex_DataData%InputTimes = SrcOrcaFlex_DataData%InputTimes +ENDIF +IF (ALLOCATED(SrcOrcaFlex_DataData%InputTimes_bak)) THEN + i1_l = LBOUND(SrcOrcaFlex_DataData%InputTimes_bak,1) + i1_u = UBOUND(SrcOrcaFlex_DataData%InputTimes_bak,1) + IF (.NOT. ALLOCATED(DstOrcaFlex_DataData%InputTimes_bak)) THEN + ALLOCATE(DstOrcaFlex_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOrcaFlex_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOrcaFlex_DataData%InputTimes_bak = SrcOrcaFlex_DataData%InputTimes_bak ENDIF END SUBROUTINE FAST_CopyOrcaFlex_Data @@ -37056,8 +41340,18 @@ SUBROUTINE FAST_DestroyOrcaFlex_Data( OrcaFlex_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(OrcaFlex_DataData%Input) ENDIF +IF (ALLOCATED(OrcaFlex_DataData%Input_bak)) THEN +DO i1 = LBOUND(OrcaFlex_DataData%Input_bak,1), UBOUND(OrcaFlex_DataData%Input_bak,1) + CALL Orca_DestroyInput( OrcaFlex_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(OrcaFlex_DataData%Input_bak) +ENDIF IF (ALLOCATED(OrcaFlex_DataData%InputTimes)) THEN DEALLOCATE(OrcaFlex_DataData%InputTimes) +ENDIF +IF (ALLOCATED(OrcaFlex_DataData%InputTimes_bak)) THEN + DEALLOCATE(OrcaFlex_DataData%InputTimes_bak) ENDIF END SUBROUTINE FAST_DestroyOrcaFlex_Data @@ -37264,11 +41558,39 @@ SUBROUTINE FAST_PackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no + IF ( ALLOCATED(InData%Input_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype + CALL Orca_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no + IF ( ALLOCATED(InData%InputTimes_bak) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -37569,6 +41891,47 @@ SUBROUTINE FAST_PackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Input_bak) ) 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%Input_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) + CALL Orca_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + 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 DO + END IF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -37584,6 +41947,21 @@ SUBROUTINE FAST_PackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) 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%InputTimes_bak,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_PackOrcaFlex_Data SUBROUTINE FAST_UnPackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -38005,6 +42383,62 @@ SUBROUTINE FAST_UnPackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak 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%Input_bak)) DEALLOCATE(OutData%Input_bak) + ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,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 Orca_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + 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 ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -38023,6 +42457,24 @@ SUBROUTINE FAST_UnPackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) + ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) + OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE FAST_UnPackOrcaFlex_Data SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -38383,6 +42835,82 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%AD_P_2_ED_P_H, DstModuleMapTypeData%AD_P_2_ED_P_H, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcModuleMapTypeData%BDED_L_2_ExtLd_P_B)) THEN + i1_l = LBOUND(SrcModuleMapTypeData%BDED_L_2_ExtLd_P_B,1) + i1_u = UBOUND(SrcModuleMapTypeData%BDED_L_2_ExtLd_P_B,1) + IF (.NOT. ALLOCATED(DstModuleMapTypeData%BDED_L_2_ExtLd_P_B)) THEN + ALLOCATE(DstModuleMapTypeData%BDED_L_2_ExtLd_P_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstModuleMapTypeData%BDED_L_2_ExtLd_P_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcModuleMapTypeData%BDED_L_2_ExtLd_P_B,1), UBOUND(SrcModuleMapTypeData%BDED_L_2_ExtLd_P_B,1) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%BDED_L_2_ExtLd_P_B(i1), DstModuleMapTypeData%BDED_L_2_ExtLd_P_B(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcModuleMapTypeData%ExtLd_P_2_BDED_B)) THEN + i1_l = LBOUND(SrcModuleMapTypeData%ExtLd_P_2_BDED_B,1) + i1_u = UBOUND(SrcModuleMapTypeData%ExtLd_P_2_BDED_B,1) + IF (.NOT. ALLOCATED(DstModuleMapTypeData%ExtLd_P_2_BDED_B)) THEN + ALLOCATE(DstModuleMapTypeData%ExtLd_P_2_BDED_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstModuleMapTypeData%ExtLd_P_2_BDED_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcModuleMapTypeData%ExtLd_P_2_BDED_B,1), UBOUND(SrcModuleMapTypeData%ExtLd_P_2_BDED_B,1) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ExtLd_P_2_BDED_B(i1), DstModuleMapTypeData%ExtLd_P_2_BDED_B(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_L_2_ExtLd_P_T, DstModuleMapTypeData%ED_L_2_ExtLd_P_T, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ExtLd_P_2_ED_P_T, DstModuleMapTypeData%ExtLd_P_2_ED_P_T, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcModuleMapTypeData%ED_P_2_ExtLd_P_R)) THEN + i1_l = LBOUND(SrcModuleMapTypeData%ED_P_2_ExtLd_P_R,1) + i1_u = UBOUND(SrcModuleMapTypeData%ED_P_2_ExtLd_P_R,1) + IF (.NOT. ALLOCATED(DstModuleMapTypeData%ED_P_2_ExtLd_P_R)) THEN + ALLOCATE(DstModuleMapTypeData%ED_P_2_ExtLd_P_R(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstModuleMapTypeData%ED_P_2_ExtLd_P_R.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcModuleMapTypeData%ED_P_2_ExtLd_P_R,1), UBOUND(SrcModuleMapTypeData%ED_P_2_ExtLd_P_R,1) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_ExtLd_P_R(i1), DstModuleMapTypeData%ED_P_2_ExtLd_P_R(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_ExtLd_P_H, DstModuleMapTypeData%ED_P_2_ExtLd_P_H, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcModuleMapTypeData%AD_L_2_ExtLd_B)) THEN + i1_l = LBOUND(SrcModuleMapTypeData%AD_L_2_ExtLd_B,1) + i1_u = UBOUND(SrcModuleMapTypeData%AD_L_2_ExtLd_B,1) + IF (.NOT. ALLOCATED(DstModuleMapTypeData%AD_L_2_ExtLd_B)) THEN + ALLOCATE(DstModuleMapTypeData%AD_L_2_ExtLd_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstModuleMapTypeData%AD_L_2_ExtLd_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcModuleMapTypeData%AD_L_2_ExtLd_B,1), UBOUND(SrcModuleMapTypeData%AD_L_2_ExtLd_B,1) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%AD_L_2_ExtLd_B(i1), DstModuleMapTypeData%AD_L_2_ExtLd_B(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%AD_L_2_ExtLd_T, DstModuleMapTypeData%AD_L_2_ExtLd_T, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%IceF_P_2_SD_P, DstModuleMapTypeData%IceF_P_2_SD_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -38753,6 +43281,42 @@ SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg, DEALLO CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(ModuleMapTypeData%BDED_L_2_ExtLd_P_B)) THEN +DO i1 = LBOUND(ModuleMapTypeData%BDED_L_2_ExtLd_P_B,1), UBOUND(ModuleMapTypeData%BDED_L_2_ExtLd_P_B,1) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BDED_L_2_ExtLd_P_B(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ModuleMapTypeData%BDED_L_2_ExtLd_P_B) +ENDIF +IF (ALLOCATED(ModuleMapTypeData%ExtLd_P_2_BDED_B)) THEN +DO i1 = LBOUND(ModuleMapTypeData%ExtLd_P_2_BDED_B,1), UBOUND(ModuleMapTypeData%ExtLd_P_2_BDED_B,1) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ExtLd_P_2_BDED_B(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ModuleMapTypeData%ExtLd_P_2_BDED_B) +ENDIF + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_ExtLd_P_T, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ExtLd_P_2_ED_P_T, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(ModuleMapTypeData%ED_P_2_ExtLd_P_R)) THEN +DO i1 = LBOUND(ModuleMapTypeData%ED_P_2_ExtLd_P_R,1), UBOUND(ModuleMapTypeData%ED_P_2_ExtLd_P_R,1) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_ExtLd_P_R(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ModuleMapTypeData%ED_P_2_ExtLd_P_R) +ENDIF + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_ExtLd_P_H, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(ModuleMapTypeData%AD_L_2_ExtLd_B)) THEN +DO i1 = LBOUND(ModuleMapTypeData%AD_L_2_ExtLd_B,1), UBOUND(ModuleMapTypeData%AD_L_2_ExtLd_B,1) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_L_2_ExtLd_B(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ModuleMapTypeData%AD_L_2_ExtLd_B) +ENDIF + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_L_2_ExtLd_T, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%IceF_P_2_SD_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_IceF_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -39437,145 +44001,305 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_N: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_N + Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_N: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_N + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_N + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_N + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_N + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_TF: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_TF + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_TF + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_TF + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_TF: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_TF + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_TF + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_TF + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! ED_L_2_AD_L_T: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2, .TRUE. ) ! ED_L_2_AD_L_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_L_2_AD_L_T + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_L_2_AD_L_T + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_L_2_AD_L_T + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AD_L_2_ED_P_T: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2, .TRUE. ) ! AD_L_2_ED_P_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_L_2_ED_P_T + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_L_2_ED_P_T + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_L_2_ED_P_T + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! ED_P_2_AD_P_R allocated yes/no + IF ( ALLOCATED(InData%ED_P_2_AD_P_R) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ED_P_2_AD_P_R upper/lower bounds for each dimension + DO i1 = LBOUND(InData%ED_P_2_AD_P_R,1), UBOUND(InData%ED_P_2_AD_P_R,1) + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_R: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_R + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_R + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_R + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_R + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_H: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_H + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_H + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_H + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_H + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_H: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_H + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_H + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_H + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_H + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! BDED_L_2_ExtLd_P_B allocated yes/no + IF ( ALLOCATED(InData%BDED_L_2_ExtLd_P_B) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BDED_L_2_ExtLd_P_B upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BDED_L_2_ExtLd_P_B,1), UBOUND(InData%BDED_L_2_ExtLd_P_B,1) + Int_BufSz = Int_BufSz + 3 ! BDED_L_2_ExtLd_P_B: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BDED_L_2_ExtLd_P_B(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BDED_L_2_ExtLd_P_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_N + IF(ALLOCATED(Re_Buf)) THEN ! BDED_L_2_ExtLd_P_B Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_N + IF(ALLOCATED(Db_Buf)) THEN ! BDED_L_2_ExtLd_P_B Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_N + IF(ALLOCATED(Int_Buf)) THEN ! BDED_L_2_ExtLd_P_B Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_TF: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_TF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! ExtLd_P_2_BDED_B allocated yes/no + IF ( ALLOCATED(InData%ExtLd_P_2_BDED_B) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ExtLd_P_2_BDED_B upper/lower bounds for each dimension + DO i1 = LBOUND(InData%ExtLd_P_2_BDED_B,1), UBOUND(InData%ExtLd_P_2_BDED_B,1) + Int_BufSz = Int_BufSz + 3 ! ExtLd_P_2_BDED_B: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ExtLd_P_2_BDED_B(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ExtLd_P_2_BDED_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_TF + IF(ALLOCATED(Re_Buf)) THEN ! ExtLd_P_2_BDED_B Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_TF + IF(ALLOCATED(Db_Buf)) THEN ! ExtLd_P_2_BDED_B Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_TF + IF(ALLOCATED(Int_Buf)) THEN ! ExtLd_P_2_BDED_B Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_TF: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_TF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! ED_L_2_ExtLd_P_T: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_ExtLd_P_T, ErrStat2, ErrMsg2, .TRUE. ) ! ED_L_2_ExtLd_P_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_TF + IF(ALLOCATED(Re_Buf)) THEN ! ED_L_2_ExtLd_P_T Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_TF + IF(ALLOCATED(Db_Buf)) THEN ! ED_L_2_ExtLd_P_T Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_TF + IF(ALLOCATED(Int_Buf)) THEN ! ED_L_2_ExtLd_P_T Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! ED_L_2_AD_L_T: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2, .TRUE. ) ! ED_L_2_AD_L_T + Int_BufSz = Int_BufSz + 3 ! ExtLd_P_2_ED_P_T: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ExtLd_P_2_ED_P_T, ErrStat2, ErrMsg2, .TRUE. ) ! ExtLd_P_2_ED_P_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! ED_L_2_AD_L_T + IF(ALLOCATED(Re_Buf)) THEN ! ExtLd_P_2_ED_P_T Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_L_2_AD_L_T + IF(ALLOCATED(Db_Buf)) THEN ! ExtLd_P_2_ED_P_T Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_L_2_AD_L_T + IF(ALLOCATED(Int_Buf)) THEN ! ExtLd_P_2_ED_P_T Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! AD_L_2_ED_P_T: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2, .TRUE. ) ! AD_L_2_ED_P_T + Int_BufSz = Int_BufSz + 1 ! ED_P_2_ExtLd_P_R allocated yes/no + IF ( ALLOCATED(InData%ED_P_2_ExtLd_P_R) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ED_P_2_ExtLd_P_R upper/lower bounds for each dimension + DO i1 = LBOUND(InData%ED_P_2_ExtLd_P_R,1), UBOUND(InData%ED_P_2_ExtLd_P_R,1) + Int_BufSz = Int_BufSz + 3 ! ED_P_2_ExtLd_P_R: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_ExtLd_P_R(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_ExtLd_P_R CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AD_L_2_ED_P_T + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_ExtLd_P_R Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD_L_2_ED_P_T + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_ExtLd_P_R Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD_L_2_ED_P_T + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_ExtLd_P_R Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1 ! ED_P_2_AD_P_R allocated yes/no - IF ( ALLOCATED(InData%ED_P_2_AD_P_R) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! ED_P_2_AD_P_R upper/lower bounds for each dimension - DO i1 = LBOUND(InData%ED_P_2_AD_P_R,1), UBOUND(InData%ED_P_2_AD_P_R,1) - Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_R: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_R + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! ED_P_2_ExtLd_P_H: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_ExtLd_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_ExtLd_P_H CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_R + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_ExtLd_P_H Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_R + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_ExtLd_P_H Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_R + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_ExtLd_P_H Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - END DO - END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_H: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_H + Int_BufSz = Int_BufSz + 1 ! AD_L_2_ExtLd_B allocated yes/no + IF ( ALLOCATED(InData%AD_L_2_ExtLd_B) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AD_L_2_ExtLd_B upper/lower bounds for each dimension + DO i1 = LBOUND(InData%AD_L_2_ExtLd_B,1), UBOUND(InData%AD_L_2_ExtLd_B,1) + Int_BufSz = Int_BufSz + 3 ! AD_L_2_ExtLd_B: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ExtLd_B(i1), ErrStat2, ErrMsg2, .TRUE. ) ! AD_L_2_ExtLd_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_H + IF(ALLOCATED(Re_Buf)) THEN ! AD_L_2_ExtLd_B Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_H + IF(ALLOCATED(Db_Buf)) THEN ! AD_L_2_ExtLd_B Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_H + IF(ALLOCATED(Int_Buf)) THEN ! AD_L_2_ExtLd_B Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_H: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_H + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! AD_L_2_ExtLd_T: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ExtLd_T, ErrStat2, ErrMsg2, .TRUE. ) ! AD_L_2_ExtLd_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_H + IF(ALLOCATED(Re_Buf)) THEN ! AD_L_2_ExtLd_T Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_H + IF(ALLOCATED(Db_Buf)) THEN ! AD_L_2_ExtLd_T Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_H + IF(ALLOCATED(Int_Buf)) THEN ! AD_L_2_ExtLd_T Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -40488,18 +45212,476 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%ED_L_2_TStC_P_T) ) THEN + IF ( .NOT. ALLOCATED(InData%ED_L_2_TStC_P_T) ) 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%ED_L_2_TStC_P_T,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_L_2_TStC_P_T,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ED_L_2_TStC_P_T,1), UBOUND(InData%ED_L_2_TStC_P_T,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_TStC_P_T(i1), ErrStat2, ErrMsg2, OnlySize ) ! ED_L_2_TStC_P_T + 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 DO + END IF + IF ( .NOT. ALLOCATED(InData%TStC_P_2_ED_P_T) ) 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%TStC_P_2_ED_P_T,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TStC_P_2_ED_P_T,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TStC_P_2_ED_P_T,1), UBOUND(InData%TStC_P_2_ED_P_T,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%TStC_P_2_ED_P_T(i1), ErrStat2, ErrMsg2, OnlySize ) ! TStC_P_2_ED_P_T + 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 DO + END IF + IF ( .NOT. ALLOCATED(InData%ED_L_2_BStC_P_B) ) 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%ED_L_2_BStC_P_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_L_2_BStC_P_B,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ED_L_2_BStC_P_B,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_L_2_BStC_P_B,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%ED_L_2_BStC_P_B,2), UBOUND(InData%ED_L_2_BStC_P_B,2) + DO i1 = LBOUND(InData%ED_L_2_BStC_P_B,1), UBOUND(InData%ED_L_2_BStC_P_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! ED_L_2_BStC_P_B + 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 DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BStC_P_2_ED_P_B) ) 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%BStC_P_2_ED_P_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_ED_P_B,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BStC_P_2_ED_P_B,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_ED_P_B,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BStC_P_2_ED_P_B,2), UBOUND(InData%BStC_P_2_ED_P_B,2) + DO i1 = LBOUND(InData%BStC_P_2_ED_P_B,1), UBOUND(InData%BStC_P_2_ED_P_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BStC_P_2_ED_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! BStC_P_2_ED_P_B + 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 DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BD_L_2_BStC_P_B) ) 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%BD_L_2_BStC_P_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BD_L_2_BStC_P_B,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BD_L_2_BStC_P_B,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BD_L_2_BStC_P_B,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BD_L_2_BStC_P_B,2), UBOUND(InData%BD_L_2_BStC_P_B,2) + DO i1 = LBOUND(InData%BD_L_2_BStC_P_B,1), UBOUND(InData%BD_L_2_BStC_P_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BD_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! BD_L_2_BStC_P_B + 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 DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BStC_P_2_BD_P_B) ) 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%BStC_P_2_BD_P_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_BD_P_B,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BStC_P_2_BD_P_B,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_BD_P_B,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BStC_P_2_BD_P_B,2), UBOUND(InData%BStC_P_2_BD_P_B,2) + DO i1 = LBOUND(InData%BStC_P_2_BD_P_B,1), UBOUND(InData%BStC_P_2_BD_P_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BStC_P_2_BD_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! BStC_P_2_BD_P_B + 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 DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%SStC_P_P_2_SubStructure) ) 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%SStC_P_P_2_SubStructure,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SStC_P_P_2_SubStructure,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%SStC_P_P_2_SubStructure,1), UBOUND(InData%SStC_P_P_2_SubStructure,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SStC_P_P_2_SubStructure(i1), ErrStat2, ErrMsg2, OnlySize ) ! SStC_P_P_2_SubStructure + 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 DO + END IF + IF ( .NOT. ALLOCATED(InData%SubStructure_2_SStC_P_P) ) 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%SubStructure_2_SStC_P_P,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SubStructure_2_SStC_P_P,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%SubStructure_2_SStC_P_P,1), UBOUND(InData%SubStructure_2_SStC_P_P,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SubStructure_2_SStC_P_P(i1), ErrStat2, ErrMsg2, OnlySize ) ! SubStructure_2_SStC_P_P + 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 DO + END IF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_SrvD_P_P, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_SrvD_P_P + 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%BDED_L_2_AD_L_B) ) 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%BDED_L_2_AD_L_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BDED_L_2_AD_L_B,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BDED_L_2_AD_L_B,1), UBOUND(InData%BDED_L_2_AD_L_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BDED_L_2_AD_L_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! BDED_L_2_AD_L_B + 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 DO + END IF + IF ( .NOT. ALLOCATED(InData%AD_L_2_BDED_B) ) 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%AD_L_2_BDED_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AD_L_2_BDED_B,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AD_L_2_BDED_B,1), UBOUND(InData%AD_L_2_BDED_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_BDED_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! AD_L_2_BDED_B + 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 DO + END IF + IF ( .NOT. ALLOCATED(InData%BD_L_2_BD_L) ) 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%ED_L_2_TStC_P_T,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_L_2_TStC_P_T,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%BD_L_2_BD_L,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BD_L_2_BD_L,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%ED_L_2_TStC_P_T,1), UBOUND(InData%ED_L_2_TStC_P_T,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_TStC_P_T(i1), ErrStat2, ErrMsg2, OnlySize ) ! ED_L_2_TStC_P_T + DO i1 = LBOUND(InData%BD_L_2_BD_L,1), UBOUND(InData%BD_L_2_BD_L,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BD_L_2_BD_L(i1), ErrStat2, ErrMsg2, OnlySize ) ! BD_L_2_BD_L CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40529,18 +45711,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%TStC_P_2_ED_P_T) ) 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%TStC_P_2_ED_P_T,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TStC_P_2_ED_P_T,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TStC_P_2_ED_P_T,1), UBOUND(InData%TStC_P_2_ED_P_T,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%TStC_P_2_ED_P_T(i1), ErrStat2, ErrMsg2, OnlySize ) ! TStC_P_2_ED_P_T + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_N CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40568,24 +45739,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END IF - IF ( .NOT. ALLOCATED(InData%ED_L_2_BStC_P_B) ) 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%ED_L_2_BStC_P_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_L_2_BStC_P_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ED_L_2_BStC_P_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_L_2_BStC_P_B,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%ED_L_2_BStC_P_B,2), UBOUND(InData%ED_L_2_BStC_P_B,2) - DO i1 = LBOUND(InData%ED_L_2_BStC_P_B,1), UBOUND(InData%ED_L_2_BStC_P_B,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! ED_L_2_BStC_P_B + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_N CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40613,25 +45767,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BStC_P_2_ED_P_B) ) 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%BStC_P_2_ED_P_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_ED_P_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BStC_P_2_ED_P_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_ED_P_B,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%BStC_P_2_ED_P_B,2), UBOUND(InData%BStC_P_2_ED_P_B,2) - DO i1 = LBOUND(InData%BStC_P_2_ED_P_B,1), UBOUND(InData%BStC_P_2_ED_P_B,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BStC_P_2_ED_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! BStC_P_2_ED_P_B + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_TF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40659,25 +45795,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BD_L_2_BStC_P_B) ) 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%BD_L_2_BStC_P_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BD_L_2_BStC_P_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BD_L_2_BStC_P_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BD_L_2_BStC_P_B,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%BD_L_2_BStC_P_B,2), UBOUND(InData%BD_L_2_BStC_P_B,2) - DO i1 = LBOUND(InData%BD_L_2_BStC_P_B,1), UBOUND(InData%BD_L_2_BStC_P_B,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BD_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! BD_L_2_BStC_P_B + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_TF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40705,25 +45823,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BStC_P_2_BD_P_B) ) 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%BStC_P_2_BD_P_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_BD_P_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BStC_P_2_BD_P_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BStC_P_2_BD_P_B,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%BStC_P_2_BD_P_B,2), UBOUND(InData%BStC_P_2_BD_P_B,2) - DO i1 = LBOUND(InData%BStC_P_2_BD_P_B,1), UBOUND(InData%BStC_P_2_BD_P_B,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BStC_P_2_BD_P_B(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! BStC_P_2_BD_P_B + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2, OnlySize ) ! ED_L_2_AD_L_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40751,21 +45851,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%SStC_P_P_2_SubStructure) ) 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%SStC_P_P_2_SubStructure,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SStC_P_P_2_SubStructure,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%SStC_P_P_2_SubStructure,1), UBOUND(InData%SStC_P_P_2_SubStructure,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SStC_P_P_2_SubStructure(i1), ErrStat2, ErrMsg2, OnlySize ) ! SStC_P_P_2_SubStructure + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2, OnlySize ) ! AD_L_2_ED_P_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40793,20 +45879,18 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END IF - IF ( .NOT. ALLOCATED(InData%SubStructure_2_SStC_P_P) ) THEN + IF ( .NOT. ALLOCATED(InData%ED_P_2_AD_P_R) ) 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%SubStructure_2_SStC_P_P,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SubStructure_2_SStC_P_P,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%ED_P_2_AD_P_R,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_P_2_AD_P_R,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%SubStructure_2_SStC_P_P,1), UBOUND(InData%SubStructure_2_SStC_P_P,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SubStructure_2_SStC_P_P(i1), ErrStat2, ErrMsg2, OnlySize ) ! SubStructure_2_SStC_P_P + DO i1 = LBOUND(InData%ED_P_2_AD_P_R,1), UBOUND(InData%ED_P_2_AD_P_R,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_R CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40836,7 +45920,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_SrvD_P_P, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_SrvD_P_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_H CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40864,18 +45948,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%BDED_L_2_AD_L_B) ) 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%BDED_L_2_AD_L_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BDED_L_2_AD_L_B,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BDED_L_2_AD_L_B,1), UBOUND(InData%BDED_L_2_AD_L_B,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BDED_L_2_AD_L_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! BDED_L_2_AD_L_B + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_H CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40903,20 +45976,18 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END DO - END IF - IF ( .NOT. ALLOCATED(InData%AD_L_2_BDED_B) ) THEN + IF ( .NOT. ALLOCATED(InData%BDED_L_2_ExtLd_P_B) ) 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%AD_L_2_BDED_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AD_L_2_BDED_B,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%BDED_L_2_ExtLd_P_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BDED_L_2_ExtLd_P_B,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%AD_L_2_BDED_B,1), UBOUND(InData%AD_L_2_BDED_B,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_BDED_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! AD_L_2_BDED_B + DO i1 = LBOUND(InData%BDED_L_2_ExtLd_P_B,1), UBOUND(InData%BDED_L_2_ExtLd_P_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BDED_L_2_ExtLd_P_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! BDED_L_2_ExtLd_P_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40946,18 +46017,18 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%BD_L_2_BD_L) ) THEN + IF ( .NOT. ALLOCATED(InData%ExtLd_P_2_BDED_B) ) 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%BD_L_2_BD_L,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BD_L_2_BD_L,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%ExtLd_P_2_BDED_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ExtLd_P_2_BDED_B,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%BD_L_2_BD_L,1), UBOUND(InData%BD_L_2_BD_L,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%BD_L_2_BD_L(i1), ErrStat2, ErrMsg2, OnlySize ) ! BD_L_2_BD_L + DO i1 = LBOUND(InData%ExtLd_P_2_BDED_B,1), UBOUND(InData%ExtLd_P_2_BDED_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ExtLd_P_2_BDED_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! ExtLd_P_2_BDED_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40987,7 +46058,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_N + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_ExtLd_P_T, ErrStat2, ErrMsg2, OnlySize ) ! ED_L_2_ExtLd_P_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41015,7 +46086,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_N + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ExtLd_P_2_ED_P_T, ErrStat2, ErrMsg2, OnlySize ) ! ExtLd_P_2_ED_P_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41043,63 +46114,18 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_TF - 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 NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_TF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%ED_P_2_ExtLd_P_R) ) 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%ED_P_2_ExtLd_P_R,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_P_2_ExtLd_P_R,1) + 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 NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2, OnlySize ) ! ED_L_2_AD_L_T + DO i1 = LBOUND(InData%ED_P_2_ExtLd_P_R,1), UBOUND(InData%ED_P_2_ExtLd_P_R,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_ExtLd_P_R(i1), ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_ExtLd_P_R CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41127,7 +46153,9 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2, OnlySize ) ! AD_L_2_ED_P_T + END DO + END IF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_ExtLd_P_H, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_ExtLd_P_H CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41155,18 +46183,18 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%ED_P_2_AD_P_R) ) THEN + IF ( .NOT. ALLOCATED(InData%AD_L_2_ExtLd_B) ) 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%ED_P_2_AD_P_R,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_P_2_AD_P_R,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AD_L_2_ExtLd_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AD_L_2_ExtLd_B,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%ED_P_2_AD_P_R,1), UBOUND(InData%ED_P_2_AD_P_R,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_R + DO i1 = LBOUND(InData%AD_L_2_ExtLd_B,1), UBOUND(InData%AD_L_2_ExtLd_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ExtLd_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! AD_L_2_ExtLd_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41196,35 +46224,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_H - 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 NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_H + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_L_2_ExtLd_T, ErrStat2, ErrMsg2, OnlySize ) ! AD_L_2_ExtLd_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42190,7 +47190,423 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_BD_P_Hub(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_BD_P_Hub + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_BD_P_Hub(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_BD_P_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) + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) ! ED_P_2_HD_PRP_P + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SubStructure_2_HD_W_P, ErrStat2, ErrMsg2 ) ! SubStructure_2_HD_W_P + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_W_P_2_SubStructure, ErrStat2, ErrMsg2 ) ! HD_W_P_2_SubStructure + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SubStructure_2_HD_M_P, ErrStat2, ErrMsg2 ) ! SubStructure_2_HD_M_P + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_M_P_2_SubStructure, ErrStat2, ErrMsg2 ) ! HD_M_P_2_SubStructure + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Structure_2_Mooring, ErrStat2, ErrMsg2 ) ! Structure_2_Mooring + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Mooring_2_Structure, ErrStat2, ErrMsg2 ) ! Mooring_2_Structure + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_SD_TP, ErrStat2, ErrMsg2 ) ! ED_P_2_SD_TP + 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SD_TP_2_ED_P, ErrStat2, ErrMsg2 ) ! SD_TP_2_ED_P + 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 ! ED_P_2_NStC_P_N 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%ED_P_2_NStC_P_N)) DEALLOCATE(OutData%ED_P_2_NStC_P_N) + ALLOCATE(OutData%ED_P_2_NStC_P_N(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_NStC_P_N.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ED_P_2_NStC_P_N,1), UBOUND(OutData%ED_P_2_NStC_P_N,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_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_NStC_P_N(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_NStC_P_N CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42199,6 +47615,20 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NStC_P_2_ED_P_N 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%NStC_P_2_ED_P_N)) DEALLOCATE(OutData%NStC_P_2_ED_P_N) + ALLOCATE(OutData%NStC_P_2_ED_P_N(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NStC_P_2_ED_P_N.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%NStC_P_2_ED_P_N,1), UBOUND(OutData%NStC_P_2_ED_P_N,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42232,53 +47662,29 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) ! ED_P_2_HD_PRP_P - 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SubStructure_2_HD_W_P, ErrStat2, ErrMsg2 ) ! SubStructure_2_HD_W_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%NStC_P_2_ED_P_N(i1), ErrStat2, ErrMsg2 ) ! NStC_P_2_ED_P_N 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 ! ED_L_2_TStC_P_T 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%ED_L_2_TStC_P_T)) DEALLOCATE(OutData%ED_L_2_TStC_P_T) + ALLOCATE(OutData%ED_L_2_TStC_P_T(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_L_2_TStC_P_T.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ED_L_2_TStC_P_T,1), UBOUND(OutData%ED_L_2_TStC_P_T,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42312,13 +47718,29 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_W_P_2_SubStructure, ErrStat2, ErrMsg2 ) ! HD_W_P_2_SubStructure + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_TStC_P_T(i1), ErrStat2, ErrMsg2 ) ! ED_L_2_TStC_P_T 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 ! TStC_P_2_ED_P_T 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%TStC_P_2_ED_P_T)) DEALLOCATE(OutData%TStC_P_2_ED_P_T) + ALLOCATE(OutData%TStC_P_2_ED_P_T(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TStC_P_2_ED_P_T.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TStC_P_2_ED_P_T,1), UBOUND(OutData%TStC_P_2_ED_P_T,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42352,13 +47774,33 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SubStructure_2_HD_M_P, ErrStat2, ErrMsg2 ) ! SubStructure_2_HD_M_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%TStC_P_2_ED_P_T(i1), ErrStat2, ErrMsg2 ) ! TStC_P_2_ED_P_T 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 ! ED_L_2_BStC_P_B 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%ED_L_2_BStC_P_B)) DEALLOCATE(OutData%ED_L_2_BStC_P_B) + ALLOCATE(OutData%ED_L_2_BStC_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_L_2_BStC_P_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%ED_L_2_BStC_P_B,2), UBOUND(OutData%ED_L_2_BStC_P_B,2) + DO i1 = LBOUND(OutData%ED_L_2_BStC_P_B,1), UBOUND(OutData%ED_L_2_BStC_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42392,13 +47834,34 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_M_P_2_SubStructure, ErrStat2, ErrMsg2 ) ! HD_M_P_2_SubStructure + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! ED_L_2_BStC_P_B 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 DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BStC_P_2_ED_P_B 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%BStC_P_2_ED_P_B)) DEALLOCATE(OutData%BStC_P_2_ED_P_B) + ALLOCATE(OutData%BStC_P_2_ED_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BStC_P_2_ED_P_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BStC_P_2_ED_P_B,2), UBOUND(OutData%BStC_P_2_ED_P_B,2) + DO i1 = LBOUND(OutData%BStC_P_2_ED_P_B,1), UBOUND(OutData%BStC_P_2_ED_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42432,13 +47895,34 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Structure_2_Mooring, ErrStat2, ErrMsg2 ) ! Structure_2_Mooring + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BStC_P_2_ED_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! BStC_P_2_ED_P_B 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 DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BD_L_2_BStC_P_B 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%BD_L_2_BStC_P_B)) DEALLOCATE(OutData%BD_L_2_BStC_P_B) + ALLOCATE(OutData%BD_L_2_BStC_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BD_L_2_BStC_P_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BD_L_2_BStC_P_B,2), UBOUND(OutData%BD_L_2_BStC_P_B,2) + DO i1 = LBOUND(OutData%BD_L_2_BStC_P_B,1), UBOUND(OutData%BD_L_2_BStC_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42472,13 +47956,34 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Mooring_2_Structure, ErrStat2, ErrMsg2 ) ! Mooring_2_Structure + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BD_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! BD_L_2_BStC_P_B 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 DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BStC_P_2_BD_P_B 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%BStC_P_2_BD_P_B)) DEALLOCATE(OutData%BStC_P_2_BD_P_B) + ALLOCATE(OutData%BStC_P_2_BD_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BStC_P_2_BD_P_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BStC_P_2_BD_P_B,2), UBOUND(OutData%BStC_P_2_BD_P_B,2) + DO i1 = LBOUND(OutData%BStC_P_2_BD_P_B,1), UBOUND(OutData%BStC_P_2_BD_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42512,13 +48017,30 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_SD_TP, ErrStat2, ErrMsg2 ) ! ED_P_2_SD_TP + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BStC_P_2_BD_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! BStC_P_2_BD_P_B 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 DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SStC_P_P_2_SubStructure 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%SStC_P_P_2_SubStructure)) DEALLOCATE(OutData%SStC_P_P_2_SubStructure) + ALLOCATE(OutData%SStC_P_P_2_SubStructure(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SStC_P_P_2_SubStructure.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%SStC_P_P_2_SubStructure,1), UBOUND(OutData%SStC_P_P_2_SubStructure,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42552,27 +48074,29 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SD_TP_2_ED_P, ErrStat2, ErrMsg2 ) ! SD_TP_2_ED_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SStC_P_P_2_SubStructure(i1), ErrStat2, ErrMsg2 ) ! SStC_P_P_2_SubStructure 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 ! ED_P_2_NStC_P_N not allocated + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SubStructure_2_SStC_P_P 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%ED_P_2_NStC_P_N)) DEALLOCATE(OutData%ED_P_2_NStC_P_N) - ALLOCATE(OutData%ED_P_2_NStC_P_N(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%SubStructure_2_SStC_P_P)) DEALLOCATE(OutData%SubStructure_2_SStC_P_P) + ALLOCATE(OutData%SubStructure_2_SStC_P_P(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_NStC_P_N.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SubStructure_2_SStC_P_P.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%ED_P_2_NStC_P_N,1), UBOUND(OutData%ED_P_2_NStC_P_N,1) + DO i1 = LBOUND(OutData%SubStructure_2_SStC_P_P,1), UBOUND(OutData%SubStructure_2_SStC_P_P,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42606,7 +48130,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_NStC_P_N(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_NStC_P_N + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SubStructure_2_SStC_P_P(i1), ErrStat2, ErrMsg2 ) ! SubStructure_2_SStC_P_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42615,20 +48139,6 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NStC_P_2_ED_P_N 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%NStC_P_2_ED_P_N)) DEALLOCATE(OutData%NStC_P_2_ED_P_N) - ALLOCATE(OutData%NStC_P_2_ED_P_N(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NStC_P_2_ED_P_N.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%NStC_P_2_ED_P_N,1), UBOUND(OutData%NStC_P_2_ED_P_N,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42662,29 +48172,27 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%NStC_P_2_ED_P_N(i1), ErrStat2, ErrMsg2 ) ! NStC_P_2_ED_P_N + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_SrvD_P_P, ErrStat2, ErrMsg2 ) ! ED_P_2_SrvD_P_P 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 ! ED_L_2_TStC_P_T not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BDED_L_2_AD_L_B 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%ED_L_2_TStC_P_T)) DEALLOCATE(OutData%ED_L_2_TStC_P_T) - ALLOCATE(OutData%ED_L_2_TStC_P_T(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BDED_L_2_AD_L_B)) DEALLOCATE(OutData%BDED_L_2_AD_L_B) + ALLOCATE(OutData%BDED_L_2_AD_L_B(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_L_2_TStC_P_T.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BDED_L_2_AD_L_B.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%ED_L_2_TStC_P_T,1), UBOUND(OutData%ED_L_2_TStC_P_T,1) + DO i1 = LBOUND(OutData%BDED_L_2_AD_L_B,1), UBOUND(OutData%BDED_L_2_AD_L_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42718,7 +48226,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_TStC_P_T(i1), ErrStat2, ErrMsg2 ) ! ED_L_2_TStC_P_T + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BDED_L_2_AD_L_B(i1), ErrStat2, ErrMsg2 ) ! BDED_L_2_AD_L_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42727,20 +48235,20 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TStC_P_2_ED_P_T not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AD_L_2_BDED_B 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%TStC_P_2_ED_P_T)) DEALLOCATE(OutData%TStC_P_2_ED_P_T) - ALLOCATE(OutData%TStC_P_2_ED_P_T(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%AD_L_2_BDED_B)) DEALLOCATE(OutData%AD_L_2_BDED_B) + ALLOCATE(OutData%AD_L_2_BDED_B(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TStC_P_2_ED_P_T.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AD_L_2_BDED_B.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TStC_P_2_ED_P_T,1), UBOUND(OutData%TStC_P_2_ED_P_T,1) + DO i1 = LBOUND(OutData%AD_L_2_BDED_B,1), UBOUND(OutData%AD_L_2_BDED_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42774,7 +48282,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%TStC_P_2_ED_P_T(i1), ErrStat2, ErrMsg2 ) ! TStC_P_2_ED_P_T + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_BDED_B(i1), ErrStat2, ErrMsg2 ) ! AD_L_2_BDED_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42783,24 +48291,20 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ED_L_2_BStC_P_B not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BD_L_2_BD_L 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%ED_L_2_BStC_P_B)) DEALLOCATE(OutData%ED_L_2_BStC_P_B) - ALLOCATE(OutData%ED_L_2_BStC_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BD_L_2_BD_L)) DEALLOCATE(OutData%BD_L_2_BD_L) + ALLOCATE(OutData%BD_L_2_BD_L(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_L_2_BStC_P_B.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BD_L_2_BD_L.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%ED_L_2_BStC_P_B,2), UBOUND(OutData%ED_L_2_BStC_P_B,2) - DO i1 = LBOUND(OutData%ED_L_2_BStC_P_B,1), UBOUND(OutData%ED_L_2_BStC_P_B,1) + DO i1 = LBOUND(OutData%BD_L_2_BD_L,1), UBOUND(OutData%BD_L_2_BD_L,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42834,7 +48338,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! ED_L_2_BStC_P_B + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BD_L_2_BD_L(i1), ErrStat2, ErrMsg2 ) ! BD_L_2_BD_L CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42842,26 +48346,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO - END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BStC_P_2_ED_P_B 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%BStC_P_2_ED_P_B)) DEALLOCATE(OutData%BStC_P_2_ED_P_B) - ALLOCATE(OutData%BStC_P_2_ED_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BStC_P_2_ED_P_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%BStC_P_2_ED_P_B,2), UBOUND(OutData%BStC_P_2_ED_P_B,2) - DO i1 = LBOUND(OutData%BStC_P_2_ED_P_B,1), UBOUND(OutData%BStC_P_2_ED_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42895,34 +48380,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BStC_P_2_ED_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! BStC_P_2_ED_P_B + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_N 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 DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BD_L_2_BStC_P_B 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%BD_L_2_BStC_P_B)) DEALLOCATE(OutData%BD_L_2_BStC_P_B) - ALLOCATE(OutData%BD_L_2_BStC_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BD_L_2_BStC_P_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%BD_L_2_BStC_P_B,2), UBOUND(OutData%BD_L_2_BStC_P_B,2) - DO i1 = LBOUND(OutData%BD_L_2_BStC_P_B,1), UBOUND(OutData%BD_L_2_BStC_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42956,34 +48420,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BD_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! BD_L_2_BStC_P_B + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_N 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 DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BStC_P_2_BD_P_B 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%BStC_P_2_BD_P_B)) DEALLOCATE(OutData%BStC_P_2_BD_P_B) - ALLOCATE(OutData%BStC_P_2_BD_P_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BStC_P_2_BD_P_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%BStC_P_2_BD_P_B,2), UBOUND(OutData%BStC_P_2_BD_P_B,2) - DO i1 = LBOUND(OutData%BStC_P_2_BD_P_B,1), UBOUND(OutData%BStC_P_2_BD_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43017,30 +48460,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BStC_P_2_BD_P_B(i1,i2), ErrStat2, ErrMsg2 ) ! BStC_P_2_BD_P_B + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_TF 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 DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SStC_P_P_2_SubStructure 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%SStC_P_P_2_SubStructure)) DEALLOCATE(OutData%SStC_P_P_2_SubStructure) - ALLOCATE(OutData%SStC_P_P_2_SubStructure(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SStC_P_P_2_SubStructure.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%SStC_P_P_2_SubStructure,1), UBOUND(OutData%SStC_P_P_2_SubStructure,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43074,29 +48500,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SStC_P_P_2_SubStructure(i1), ErrStat2, ErrMsg2 ) ! SStC_P_P_2_SubStructure + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_TF 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 ! SubStructure_2_SStC_P_P 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%SubStructure_2_SStC_P_P)) DEALLOCATE(OutData%SubStructure_2_SStC_P_P) - ALLOCATE(OutData%SubStructure_2_SStC_P_P(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SubStructure_2_SStC_P_P.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%SubStructure_2_SStC_P_P,1), UBOUND(OutData%SubStructure_2_SStC_P_P,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43130,15 +48540,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SubStructure_2_SStC_P_P(i1), ErrStat2, ErrMsg2 ) ! SubStructure_2_SStC_P_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2 ) ! ED_L_2_AD_L_T 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 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43172,27 +48580,27 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_SrvD_P_P, ErrStat2, ErrMsg2 ) ! ED_P_2_SrvD_P_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2 ) ! AD_L_2_ED_P_T 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 ! BDED_L_2_AD_L_B not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ED_P_2_AD_P_R 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%BDED_L_2_AD_L_B)) DEALLOCATE(OutData%BDED_L_2_AD_L_B) - ALLOCATE(OutData%BDED_L_2_AD_L_B(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%ED_P_2_AD_P_R)) DEALLOCATE(OutData%ED_P_2_AD_P_R) + ALLOCATE(OutData%ED_P_2_AD_P_R(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BDED_L_2_AD_L_B.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_AD_P_R.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BDED_L_2_AD_L_B,1), UBOUND(OutData%BDED_L_2_AD_L_B,1) + DO i1 = LBOUND(OutData%ED_P_2_AD_P_R,1), UBOUND(OutData%ED_P_2_AD_P_R,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43226,7 +48634,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BDED_L_2_AD_L_B(i1), ErrStat2, ErrMsg2 ) ! BDED_L_2_AD_L_B + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_R CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -43235,20 +48643,6 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AD_L_2_BDED_B 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%AD_L_2_BDED_B)) DEALLOCATE(OutData%AD_L_2_BDED_B) - ALLOCATE(OutData%AD_L_2_BDED_B(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AD_L_2_BDED_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%AD_L_2_BDED_B,1), UBOUND(OutData%AD_L_2_BDED_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43282,29 +48676,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_BDED_B(i1), ErrStat2, ErrMsg2 ) ! AD_L_2_BDED_B + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_H 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 ! BD_L_2_BD_L 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%BD_L_2_BD_L)) DEALLOCATE(OutData%BD_L_2_BD_L) - ALLOCATE(OutData%BD_L_2_BD_L(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BD_L_2_BD_L.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BD_L_2_BD_L,1), UBOUND(OutData%BD_L_2_BD_L,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43338,15 +48716,27 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BD_L_2_BD_L(i1), ErrStat2, ErrMsg2 ) ! BD_L_2_BD_L + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_H 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 ! BDED_L_2_ExtLd_P_B 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%BDED_L_2_ExtLd_P_B)) DEALLOCATE(OutData%BDED_L_2_ExtLd_P_B) + ALLOCATE(OutData%BDED_L_2_ExtLd_P_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BDED_L_2_ExtLd_P_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BDED_L_2_ExtLd_P_B,1), UBOUND(OutData%BDED_L_2_ExtLd_P_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43380,13 +48770,29 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_N + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BDED_L_2_ExtLd_P_B(i1), ErrStat2, ErrMsg2 ) ! BDED_L_2_ExtLd_P_B 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 ! ExtLd_P_2_BDED_B 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%ExtLd_P_2_BDED_B)) DEALLOCATE(OutData%ExtLd_P_2_BDED_B) + ALLOCATE(OutData%ExtLd_P_2_BDED_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ExtLd_P_2_BDED_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ExtLd_P_2_BDED_B,1), UBOUND(OutData%ExtLd_P_2_BDED_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43420,13 +48826,15 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_N + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ExtLd_P_2_BDED_B(i1), ErrStat2, ErrMsg2 ) ! ExtLd_P_2_BDED_B 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 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43460,7 +48868,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_TF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_ExtLd_P_T, ErrStat2, ErrMsg2 ) ! ED_L_2_ExtLd_P_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -43500,13 +48908,27 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_TF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ExtLd_P_2_ED_P_T, ErrStat2, ErrMsg2 ) ! ExtLd_P_2_ED_P_T 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 ! ED_P_2_ExtLd_P_R 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%ED_P_2_ExtLd_P_R)) DEALLOCATE(OutData%ED_P_2_ExtLd_P_R) + ALLOCATE(OutData%ED_P_2_ExtLd_P_R(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_ExtLd_P_R.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ED_P_2_ExtLd_P_R,1), UBOUND(OutData%ED_P_2_ExtLd_P_R,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43540,13 +48962,15 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2 ) ! ED_L_2_AD_L_T + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_ExtLd_P_R(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_ExtLd_P_R 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 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43580,27 +49004,27 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2 ) ! AD_L_2_ED_P_T + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_ExtLd_P_H, ErrStat2, ErrMsg2 ) ! ED_P_2_ExtLd_P_H 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 ! ED_P_2_AD_P_R not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AD_L_2_ExtLd_B 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%ED_P_2_AD_P_R)) DEALLOCATE(OutData%ED_P_2_AD_P_R) - ALLOCATE(OutData%ED_P_2_AD_P_R(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%AD_L_2_ExtLd_B)) DEALLOCATE(OutData%AD_L_2_ExtLd_B) + ALLOCATE(OutData%AD_L_2_ExtLd_B(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_AD_P_R.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AD_L_2_ExtLd_B.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%ED_P_2_AD_P_R,1), UBOUND(OutData%ED_P_2_AD_P_R,1) + DO i1 = LBOUND(OutData%AD_L_2_ExtLd_B,1), UBOUND(OutData%AD_L_2_ExtLd_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -43634,7 +49058,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_R + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_ExtLd_B(i1), ErrStat2, ErrMsg2 ) ! AD_L_2_ExtLd_B CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -43676,47 +49100,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_H - 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_H + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_ExtLd_T, ErrStat2, ErrMsg2 ) ! AD_L_2_ExtLd_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -45426,6 +50810,12 @@ SUBROUTINE FAST_CopyInitData( SrcInitDataData, DstInitDataData, CtrlCode, ErrSta CALL AD_CopyInitOutput( SrcInitDataData%OutData_AD, DstInitDataData%OutData_AD, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL ExtLd_CopyInitInput( SrcInitDataData%InData_ExtLd, DstInitDataData%InData_ExtLd, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL ExtLd_CopyInitOutput( SrcInitDataData%OutData_ExtLd, DstInitDataData%OutData_ExtLd, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL InflowWind_CopyInitInput( SrcInitDataData%InData_IfW, DstInitDataData%InData_IfW, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -45546,6 +50936,10 @@ SUBROUTINE FAST_DestroyInitData( InitDataData, ErrStat, ErrMsg, DEALLOCATEpointe CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL AD_DestroyInitOutput( InitDataData%OutData_AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ExtLd_DestroyInitInput( InitDataData%InData_ExtLd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ExtLd_DestroyInitOutput( InitDataData%OutData_ExtLd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL InflowWind_DestroyInitInput( InitDataData%InData_IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL InflowWind_DestroyInitOutput( InitDataData%OutData_IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -45808,6 +51202,40 @@ SUBROUTINE FAST_PackInitData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! InData_ExtLd: size of buffers for each call to pack subtype + CALL ExtLd_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%InData_ExtLd, ErrStat2, ErrMsg2, .TRUE. ) ! InData_ExtLd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! InData_ExtLd + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! InData_ExtLd + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! InData_ExtLd + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! OutData_ExtLd: size of buffers for each call to pack subtype + CALL ExtLd_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%OutData_ExtLd, ErrStat2, ErrMsg2, .TRUE. ) ! OutData_ExtLd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! OutData_ExtLd + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! OutData_ExtLd + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! OutData_ExtLd + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! InData_IfW: size of buffers for each call to pack subtype CALL InflowWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%InData_IfW, ErrStat2, ErrMsg2, .TRUE. ) ! InData_IfW CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -46512,6 +51940,62 @@ SUBROUTINE FAST_PackInitData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs 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 ExtLd_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%InData_ExtLd, ErrStat2, ErrMsg2, OnlySize ) ! InData_ExtLd + 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 ExtLd_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%OutData_ExtLd, ErrStat2, ErrMsg2, OnlySize ) ! OutData_ExtLd + 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 @@ -47650,6 +53134,86 @@ SUBROUTINE FAST_UnPackInitData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er 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 ExtLd_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%InData_ExtLd, ErrStat2, ErrMsg2 ) ! InData_ExtLd + 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 ExtLd_UnpackInitOutput( Re_Buf, Db_Buf, Int_Buf, OutData%OutData_ExtLd, ErrStat2, ErrMsg2 ) ! OutData_ExtLd + 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) @@ -48671,6 +54235,14 @@ SUBROUTINE FAST_CopyExternInitType( SrcExternInitTypeData, DstExternInitTypeData DstExternInitTypeData%NumActForcePtsBlade = SrcExternInitTypeData%NumActForcePtsBlade DstExternInitTypeData%NumActForcePtsTower = SrcExternInitTypeData%NumActForcePtsTower DstExternInitTypeData%NodeClusterType = SrcExternInitTypeData%NodeClusterType + DstExternInitTypeData%DTdriver = SrcExternInitTypeData%DTdriver + DstExternInitTypeData%TwrAero = SrcExternInitTypeData%TwrAero + DstExternInitTypeData%az_blend_mean = SrcExternInitTypeData%az_blend_mean + DstExternInitTypeData%az_blend_delta = SrcExternInitTypeData%az_blend_delta + DstExternInitTypeData%vel_mean = SrcExternInitTypeData%vel_mean + DstExternInitTypeData%wind_dir = SrcExternInitTypeData%wind_dir + DstExternInitTypeData%z_ref = SrcExternInitTypeData%z_ref + DstExternInitTypeData%shear_exp = SrcExternInitTypeData%shear_exp END SUBROUTINE FAST_CopyExternInitType SUBROUTINE FAST_DestroyExternInitType( ExternInitTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) @@ -48764,6 +54336,14 @@ SUBROUTINE FAST_PackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 1 ! NumActForcePtsBlade Int_BufSz = Int_BufSz + 1 ! NumActForcePtsTower Int_BufSz = Int_BufSz + 1 ! NodeClusterType + Db_BufSz = Db_BufSz + 1 ! DTdriver + Int_BufSz = Int_BufSz + 1 ! TwrAero + Re_BufSz = Re_BufSz + 1 ! az_blend_mean + Re_BufSz = Re_BufSz + 1 ! az_blend_delta + Re_BufSz = Re_BufSz + 1 ! vel_mean + Re_BufSz = Re_BufSz + 1 ! wind_dir + Re_BufSz = Re_BufSz + 1 ! z_ref + Re_BufSz = Re_BufSz + 1 ! shear_exp IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -48865,6 +54445,22 @@ SUBROUTINE FAST_PackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NodeClusterType Int_Xferred = Int_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%DTdriver + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrAero, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%az_blend_mean + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%az_blend_delta + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%vel_mean + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%wind_dir + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%z_ref + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%shear_exp + Re_Xferred = Re_Xferred + 1 END SUBROUTINE FAST_PackExternInitType SUBROUTINE FAST_UnPackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -48982,6 +54578,22 @@ SUBROUTINE FAST_UnPackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Xferred = Int_Xferred + 1 OutData%NodeClusterType = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%DTdriver = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%TwrAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrAero) + Int_Xferred = Int_Xferred + 1 + OutData%az_blend_mean = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%az_blend_delta = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%vel_mean = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%wind_dir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%z_ref = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%shear_exp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE FAST_UnPackExternInitType SUBROUTINE FAST_CopyTurbineType( SrcTurbineTypeData, DstTurbineTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -49026,6 +54638,9 @@ SUBROUTINE FAST_CopyTurbineType( SrcTurbineTypeData, DstTurbineTypeData, CtrlCod CALL FAST_Copyaerodyn14_data( SrcTurbineTypeData%AD14, DstTurbineTypeData%AD14, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL FAST_Copyextloads_data( SrcTurbineTypeData%ExtLd, DstTurbineTypeData%ExtLd, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL FAST_Copyinflowwind_data( SrcTurbineTypeData%IfW, DstTurbineTypeData%IfW, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -49106,6 +54721,8 @@ SUBROUTINE FAST_DestroyTurbineType( TurbineTypeData, ErrStat, ErrMsg, DEALLOCATE CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL FAST_Destroyaerodyn14_data( TurbineTypeData%AD14, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyextloads_data( TurbineTypeData%ExtLd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL FAST_Destroyinflowwind_data( TurbineTypeData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) CALL FAST_Destroyexternalinflow_data( TurbineTypeData%ExtInfw, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -49324,6 +54941,23 @@ SUBROUTINE FAST_PackTurbineType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! ExtLd: size of buffers for each call to pack subtype + CALL FAST_Packextloads_data( Re_Buf, Db_Buf, Int_Buf, InData%ExtLd, ErrStat2, ErrMsg2, .TRUE. ) ! ExtLd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ExtLd + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ExtLd + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ExtLd + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! IfW: size of buffers for each call to pack subtype CALL FAST_Packinflowwind_data( Re_Buf, Db_Buf, Int_Buf, InData%IfW, ErrStat2, ErrMsg2, .TRUE. ) ! IfW CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -49802,6 +55436,34 @@ SUBROUTINE FAST_PackTurbineType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er 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 FAST_Packextloads_data( Re_Buf, Db_Buf, Int_Buf, InData%ExtLd, ErrStat2, ErrMsg2, OnlySize ) ! ExtLd + 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 @@ -50577,6 +56239,46 @@ SUBROUTINE FAST_UnPackTurbineType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, 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 FAST_Unpackextloads_data( Re_Buf, Db_Buf, Int_Buf, OutData%ExtLd, ErrStat2, ErrMsg2 ) ! ExtLd + 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) From d34deab4af29ec0cac9e5709eaa1b1e1f24b4c8b Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Thu, 13 Jul 2023 13:09:57 +0000 Subject: [PATCH 02/91] Install libnetcdf-dev in GH Actions This library is needed by openfastcpplib --- .github/workflows/automated-dev-tests.yml | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index f8e2b398c0..8324591a0d 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -166,7 +166,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev # gcovr + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev # gcovr - name: Setup workspace run: cmake -E make_directory ${{runner.workspace}}/openfast/build - name: Configure build @@ -216,7 +216,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Build OpenFAST C-Interfaces working-directory: ${{runner.workspace}}/openfast/build run: | @@ -247,7 +247,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Build OpenFAST glue-code working-directory: ${{runner.workspace}}/openfast/build run: | @@ -278,7 +278,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Build FAST.Farm working-directory: ${{runner.workspace}}/openfast/build run: | @@ -370,7 +370,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Run AeroDyn tests uses: ./.github/actions/tests-module-aerodyn with: @@ -419,7 +419,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -478,7 +478,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" vtk sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Run Interface / API tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -517,7 +517,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -564,7 +564,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -608,7 +608,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -652,7 +652,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -696,7 +696,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -740,7 +740,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -784,7 +784,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | @@ -828,7 +828,7 @@ jobs: python -m pip install --upgrade pip pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | From b4ac67a953e1a785feaa0df50260f0f051127349 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Thu, 13 Jul 2023 16:25:03 +0000 Subject: [PATCH 03/91] Disable C++ regression test until it is updated --- reg_tests/CTestList.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 428b149b41..6267db9b3c 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -294,7 +294,7 @@ of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerod # OpenFAST C++ API test if(BUILD_OPENFAST_CPP_API) - of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") + # of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") endif() # OpenFAST C++ Driver test for OpenFAST Library From eed049168e17dcd1827c5ff94de929350d6b331f Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 14 Jul 2023 16:56:50 -0600 Subject: [PATCH 04/91] Fix FAST_Library.f90 after rebasing onto the update ExtInflow (from dev) --- modules/openfast-library/src/FAST_Library.f90 | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 9977338aa0..38b93fa258 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -728,8 +728,15 @@ subroutine FAST_AL_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, NumBlElem_c = Turbine(iTurb)%AD14%Input(1)%InputMarkers(1)%Nnodes NumTwrElem_c = 0 ! Don't care about Aerodyn14 anymore ELSEIF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD) THEN - NumBl_c = SIZE(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion) - NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes + IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors)) THEN + IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion)) THEN + NumBl_c = SIZE(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion) + END IF + END IF + IF (NumBl_c > 0) THEN + NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes + END IF +!FIXME: need some checks on this. If the Tower mesh is not initialized, this will be garbage NumTwrElem_c = Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Nnodes ELSE NumBl_c = 0 @@ -1030,15 +1037,12 @@ subroutine SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Ou ExtInfw_Input_from_FAST%pxVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxVel_Len; ExtInfw_Input_from_FAST%pxVel = Turbine(iTurb)%ExtInfw%u%c_obj%pxVel ExtInfw_Input_from_FAST%pyVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyVel_Len; ExtInfw_Input_from_FAST%pyVel = Turbine(iTurb)%ExtInfw%u%c_obj%pyVel ExtInfw_Input_from_FAST%pzVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzVel_Len; ExtInfw_Input_from_FAST%pzVel = Turbine(iTurb)%ExtInfw%u%c_obj%pzVel - ExtInfw_Input_from_FAST%pxDotVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotVel_Len; ExtInfw_Input_from_FAST%pxDotVel = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotVel - ExtInfw_Input_from_FAST%pyDotVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotVel_Len; ExtInfw_Input_from_FAST%pyDotVel = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotVel - ExtInfw_Input_from_FAST%pzDotVel_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotVel_Len; ExtInfw_Input_from_FAST%pzDotVel = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotVel ExtInfw_Input_from_FAST%pxForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxForce_Len; ExtInfw_Input_from_FAST%pxForce = Turbine(iTurb)%ExtInfw%u%c_obj%pxForce ExtInfw_Input_from_FAST%pyForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyForce_Len; ExtInfw_Input_from_FAST%pyForce = Turbine(iTurb)%ExtInfw%u%c_obj%pyForce ExtInfw_Input_from_FAST%pzForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzForce_Len; ExtInfw_Input_from_FAST%pzForce = Turbine(iTurb)%ExtInfw%u%c_obj%pzForce - ExtInfw_Input_from_FAST%pxDotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotForce_Len; ExtInfw_Input_from_FAST%pxDotForce = Turbine(iTurb)%ExtInfw%u%c_obj%pxDotForce - ExtInfw_Input_from_FAST%pyDotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotForce_Len; ExtInfw_Input_from_FAST%pyDotForce = Turbine(iTurb)%ExtInfw%u%c_obj%pyDotForce - ExtInfw_Input_from_FAST%pzDotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotForce_Len; ExtInfw_Input_from_FAST%pzDotForce = Turbine(iTurb)%ExtInfw%u%c_obj%pzDotForce + ExtInfw_Input_from_FAST%xdotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%xdotForce_Len; ExtInfw_Input_from_FAST%xdotForce = Turbine(iTurb)%ExtInfw%u%c_obj%xdotForce + ExtInfw_Input_from_FAST%ydotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%ydotForce_Len; ExtInfw_Input_from_FAST%ydotForce = Turbine(iTurb)%ExtInfw%u%c_obj%ydotForce + ExtInfw_Input_from_FAST%zdotForce_Len = Turbine(iTurb)%ExtInfw%u%c_obj%zdotForce_Len; ExtInfw_Input_from_FAST%zdotForce = Turbine(iTurb)%ExtInfw%u%c_obj%zdotForce ExtInfw_Input_from_FAST%pOrientation_Len = Turbine(iTurb)%ExtInfw%u%c_obj%pOrientation_Len; ExtInfw_Input_from_FAST%pOrientation = Turbine(iTurb)%ExtInfw%u%c_obj%pOrientation ExtInfw_Input_from_FAST%fx_Len = Turbine(iTurb)%ExtInfw%u%c_obj%fx_Len; ExtInfw_Input_from_FAST%fx = Turbine(iTurb)%ExtInfw%u%c_obj%fx ExtInfw_Input_from_FAST%fy_Len = Turbine(iTurb)%ExtInfw%u%c_obj%fy_Len; ExtInfw_Input_from_FAST%fy = Turbine(iTurb)%ExtInfw%u%c_obj%fy @@ -1047,7 +1051,6 @@ subroutine SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Ou ExtInfw_Input_from_FAST%momenty_Len = Turbine(iTurb)%ExtInfw%u%c_obj%momenty_Len; ExtInfw_Input_from_FAST%momenty = Turbine(iTurb)%ExtInfw%u%c_obj%momenty ExtInfw_Input_from_FAST%momentz_Len = Turbine(iTurb)%ExtInfw%u%c_obj%momentz_Len; ExtInfw_Input_from_FAST%momentz = Turbine(iTurb)%ExtInfw%u%c_obj%momentz ExtInfw_Input_from_FAST%forceNodesChord_Len = Turbine(iTurb)%ExtInfw%u%c_obj%forceNodesChord_Len; ExtInfw_Input_from_FAST%forceNodesChord = Turbine(iTurb)%ExtInfw%u%c_obj%forceNodesChord - ExtInfw_Input_from_FAST%forceRHloc_Len = Turbine(iTurb)%ExtInfw%u%c_obj%forceRHloc_Len; ExtInfw_Input_from_FAST%forceRHloc = Turbine(iTurb)%ExtInfw%u%c_obj%forceRHloc if (Turbine(iTurb)%p_FAST%UseSC) then SC_DX_Input_from_FAST%toSC_Len = Turbine(iTurb)%SC_DX%u%c_obj%toSC_Len From 8d9ad2b5aecf83dd06d2bdc601b7e9de8f56641a Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Thu, 2 Nov 2023 13:57:50 -0600 Subject: [PATCH 05/91] Adds standalone mode (Farmsize = -1) and fixes pinned rod inertial forces --- modules/moordyn/src/MoorDyn.f90 | 61 ++++++++++++++++-------- modules/moordyn/src/MoorDyn_Driver.f90 | 41 +++++++++++++--- modules/moordyn/src/MoorDyn_Registry.txt | 5 +- modules/moordyn/src/MoorDyn_Rod.f90 | 7 ++- modules/moordyn/src/MoorDyn_Types.f90 | 2 + 5 files changed, 83 insertions(+), 33 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 2bc70eedc2..c342cc189e 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -201,6 +201,8 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er m%PtfmInit = InitInp%PtfmInit(:,1) ! is this copying necssary in case this is an individual instance in FAST.Farm? + p%Standalone = InitInp%Standalone + ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) @@ -208,7 +210,10 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL WrScr(' >>> MoorDyn is running in array mode <<< ') ! could make sure the size of this is right: SIZE(InitInp%FarmCoupledKinematics) p%nTurbines = InitInp%FarmSize - else ! FarmSize==0 indicates normal, FAST module mode + else if (InitInp%FarmSize < 0) then ! Farmsize==-1 indicates standlone, run MoorDyn as a standalone code with no openfast coupling + p%Standalone = 1 + p%nTurbines = 1 + else ! FarmSize==0 indicates normal, FAST module mode p%nTurbines = 1 ! if a regular FAST module mode, we treat it like a nTurbine=1 farm case END IF @@ -1009,7 +1014,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er else if ((let1 == "CONNECT") .or. (let1 == "CON") .or. (let1 == "FREE")) then m%RodList(l)%typeNum = 0 - p%nFreeRods=p%nFreeRods+1 ! add this pinned rod to the free list because it is half free + p%nFreeRods=p%nFreeRods+1 m%RodStateIs1(p%nFreeRods) = Nx+1 m%RodStateIsN(p%nFreeRods) = Nx+12 @@ -1769,14 +1774,18 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) ! defaults to identity orientation matrix !TODO: >>> should also maybe set reference orientation (which might make part of a couple lines down redundant) <<< - ! calculate initial point relative position, adjusted due to initial platform translations - u%CoupledKinematics(iTurb)%TranslationDisp(:,J) = InitInp%PtfmInit(1:3,iTurb) - rRef(1:3) OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Body's relative orientation with the turbine's initial orientation u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body <<< ! set absolute initial positions in MoorDyn - m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + IF (p%Standalone == 1) THEN + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + ELSE + ! calculate initial point relative position, adjusted due to initial platform translations + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) = InitInp%PtfmInit(1:3,iTurb) - rRef(1:3) + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + ENDIF m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6))))) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! set node as point element @@ -1793,18 +1802,24 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er OrMatRef = TRANSPOSE( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! for now set reference orientation as per input file <<< CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation - ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math - u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) - u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) - u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) - OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Rod's relative orientation with the turbine's initial orientation u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< ! set absolute initial positions in MoorDyn - m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + IF (p%Standalone == 1) THEN + m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + ELSE + ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) + m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + ENDIF m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, OrMatRef)) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation + + m%RodList(m%CpldRodIs(l,iTurb))%r6 = [0,0,-5,0,0,-1] ! Hack for testing the pinned rods + ! >>> still need to set Rod initial orientations accounting for PtfmInit rotation <<< CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) @@ -1819,15 +1834,17 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! set reference position as per input file <<< what about turbine positions in array? rRef(1:3) = m%PointList(m%CpldPointIs(l,iTurb))%r CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) - - ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math - u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) - u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) - u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) - + ! set absolute initial positions in MoorDyn - m%PointList(m%CpldPointIs(l,iTurb))%r = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) - + IF (p%Standalone == 1) THEN + m%PointList(m%CpldPointIs(l,iTurb))%r = u%CoupledKinematics(iTurb)%Position(:,J) + ELSE + ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) + m%PointList(m%CpldPointIs(l,iTurb))%r = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + ENDIF CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! lastly, do this to set the attached line endpoint positions: @@ -2973,8 +2990,10 @@ SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, Er END DO DO l = 1,p%nCpldRods(iTurb) - CALL Rod_DoRHS(m%RodList(m%CpldRodIs(l,iTurb)), m, p) - ! NOTE: this won't compute net loads on Rod. Need Rod_GetNetForceAndMass for that. Change? <<<< + IF (m%RodList(m%CpldRodIs(l,iTurb))%typeNum /= -1) THEN ! For a coupled pinned rod, Rod_GetStateDeriv already calls doRHS + CALL Rod_DoRHS(m%RodList(m%CpldRodIs(l,iTurb)), m, p) + ! NOTE: this won't compute net loads on Rod. Need Rod_GetNetForceAndMass for that. Change? <<<< + ENDIF END DO DO l = 1,p%nCpldBodies(iTurb) diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 83e2e5e65b..46ed87cd17 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -173,6 +173,11 @@ PROGRAM MoorDyn_Driver ! do OpenFAST vs FAST.Farm related setup MD_InitInp%FarmSize = drvrInitInp%FarmSize + IF (MD_InitInp%FarmSize < 0) THEN + MD_InitInp%Standalone = 1 + ELSE + MD_InitInp%Standalone = 0 + ENDIF if (drvrInitInp%FarmSize > 0) then ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) nTurbines = drvrInitInp%FarmSize @@ -493,7 +498,11 @@ PROGRAM MoorDyn_Driver J = 1 ! the starting index of the relevant DOFs in the input array ! any coupled bodies (type -1) DO l = 1,MD_p%nCpldBodies(iTurb) - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + IF (MD_InitInp%Standalone == 1) THEN + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) + ELSE + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + ENDIF MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) ! full Euler angle approach MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -507,7 +516,11 @@ PROGRAM MoorDyn_Driver ! any coupled rods (type -1 or -2) >>> need to make rotations ignored if it's a pinned rod <<< DO l = 1,MD_p%nCpldRods(iTurb) - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + IF (MD_InitInp%Standalone == 1) THEN + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) + ELSE + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + ENDIF MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -521,7 +534,11 @@ PROGRAM MoorDyn_Driver ! any coupled points (type -1) DO l = 1, MD_p%nCpldPoints(iTurb) - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + IF (MD_InitInp%Standalone == 1) THEN + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) + ELSE + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + ENDIF MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = 0.0_DbKi !rdd_in(i, J:J+2) @@ -582,7 +599,11 @@ PROGRAM MoorDyn_Driver J = 1 ! the starting index of the relevant DOFs in the input array ! any coupled bodies (type -1) DO l = 1,MD_p%nCpldBodies(iTurb) - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + IF (MD_InitInp%Standalone == 1) THEN + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) + ELSE + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + ENDIF MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) ! full Euler angle approach MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -596,7 +617,11 @@ PROGRAM MoorDyn_Driver ! any coupled rods (type -1 or -2) >>> need to make rotations ignored if it's a pinned rod <<< DO l = 1,MD_p%nCpldRods(iTurb) - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + IF (MD_InitInp%Standalone == 1) THEN + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) + ELSE + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + ENDIF MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -610,7 +635,11 @@ PROGRAM MoorDyn_Driver ! any coupled points (type -1) DO l = 1, MD_p%nCpldPoints(iTurb) - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + IF (MD_InitInp%Standalone == 1) THEN + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) + ELSE + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + ENDIF MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = 0.0_DbKi !rdd_in(i, J:J+2) diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 7965106d56..48baad2dd0 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -24,7 +24,8 @@ typedef MoorDyn/MD InitInputType ReKi g - -99 typedef ^ ^ ReKi rhoW - -999.9 - "sea density" "[kg/m^3]" typedef ^ ^ ReKi WtrDepth - -999.9 - "depth of water" "[m]" typedef ^ ^ ReKi PtfmInit {:}{:} - - "initial position of platform(s) shape: 6, nTurbines" - -typedef ^ ^ IntKi FarmSize - 0 - "Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0" - +typedef ^ ^ IntKi FarmSize - 0 - "Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0, standalone mode if -1" - +typedef ^ ^ IntKi Standalone - 0 - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - typedef ^ ^ ReKi TurbineRefPos {:}{:} - - "reference position of turbines in farm, shape: 3, nTurbines" - typedef ^ ^ ReKi Tmax - - - "simulation duration" "[s]" typedef ^ ^ CHARACTER(1024) FileName - "" - "MoorDyn input file" @@ -148,7 +149,7 @@ typedef ^ ^ DbKi M {3}{3} typedef ^ MD_Rod IntKi IdNum - - - "integer identifier of this Line" typedef ^ ^ CHARACTER(10) type - - - "type of Rod. should match one of RodProp names" typedef ^ ^ IntKi PropsIdNum - - - "the IdNum of the associated rod properties" - -typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=fixed, 1=vessel, 2=point" +typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=fixed, 1=vessel, 2=point, -1=coupledpinned" typedef ^ ^ IntKi AttachedA {10} - - "list of IdNums of lines attached to end A" typedef ^ ^ IntKi AttachedB {10} - - "list of IdNums of lines attached to end B" typedef ^ ^ IntKi TopA {10} - - "list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A)" diff --git a/modules/moordyn/src/MoorDyn_Rod.f90 b/modules/moordyn/src/MoorDyn_Rod.f90 index f7f25e4d93..feb5e6dc53 100644 --- a/modules/moordyn/src/MoorDyn_Rod.f90 +++ b/modules/moordyn/src/MoorDyn_Rod.f90 @@ -491,8 +491,7 @@ SUBROUTINE Rod_GetStateDeriv(Rod, Xd, m, p) ELSE ! pinned rod, 6 states (rotational only) ! account for moment in response to end A acceleration due to inertial coupling (off-diagonal sub-matrix terms) - !Fnet(4:6) = Fnet(4:6) - MATMUL(M_out(4:6,1:3), Rod%a6(1:3)) ! <<0 [-] + INTEGER(IntKi) :: Standalone = 0 !< Indicates MoorDyn run as standalone code if 1, coupled if 0, standalone mode if -1 [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TurbineRefPos !< reference position of turbines in farm, shape: 3, nTurbines [-] REAL(ReKi) :: Tmax !< simulation duration [[s]] CHARACTER(1024) :: FileName !< MoorDyn input file [-] @@ -459,6 +460,7 @@ MODULE MoorDyn_Types INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: dxIdx_map2_xStateIdx !< Mapping array from index of dX array to corresponding state index [-] LOGICAL :: VisMeshes !< Using visualization meshes as requested by glue code [-] TYPE(VisDiam) , DIMENSION(:), ALLOCATABLE :: VisRodsDiam !< Diameters for visualization of rods [-] + INTEGER(IntKi) :: Standalone !< Indicates MoorDyn run as standalone code if 1, coupled if 0 [-] END TYPE MD_ParameterType ! ======================= ! ========= MD_InputType ======= From 6d16c6e518c1441d38c7cb1bc5c611deaca3c396 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Thu, 2 Nov 2023 14:03:15 -0600 Subject: [PATCH 06/91] Additonaly standalone variable in registry --- modules/moordyn/src/MoorDyn_Registry.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 48baad2dd0..440a83b940 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -428,6 +428,7 @@ typedef ^ ^ Integer Jac_nx - typedef ^ ^ Integer dxIdx_map2_xStateIdx {:} - - "Mapping array from index of dX array to corresponding state index" - typedef ^ ^ Logical VisMeshes - - - "Using visualization meshes as requested by glue code" - typedef ^ ^ VisDiam VisRodsDiam {:} - - "Diameters for visualization of rods" - +typedef ^ ^ IntKi Standalone - - - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - # ============================== Inputs ============================================================================================================================================ From 5ccfb2f06762627271ae547ffcd8ccd1fec18560 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Thu, 2 Nov 2023 17:14:25 -0600 Subject: [PATCH 07/91] Smoother handling of standalone --- modules/moordyn/src/MoorDyn.f90 | 48 ++++++++++---------------- modules/moordyn/src/MoorDyn_Driver.f90 | 13 ++++--- 2 files changed, 25 insertions(+), 36 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 2f9f5821bd..a3f12e8399 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -1768,24 +1768,21 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er J = J + 1 rRef = m%BodyList(m%CpldBodyIs(l,iTurb))%r6 ! for now set reference position as per input file <<< - !OrMatRef = CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) ! defaults to identity orientation matrix - !TODO: >>> should also maybe set reference orientation (which might make part of a couple lines down redundant) <<< - - - OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Body's relative orientation with the turbine's initial orientation - u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body <<< ! set absolute initial positions in MoorDyn - IF (p%Standalone == 1) THEN - m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) - ELSE + IF (p%Standalone /= 1) THEN + !TODO: >>> should also maybe set reference orientation (which might make part of a couple lines down redundant) <<< + OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Body's relative orientation with the turbine's initial orientation + u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body <<< + ! calculate initial point relative position, adjusted due to initial platform translations u%CoupledKinematics(iTurb)%TranslationDisp(:,J) = InitInp%PtfmInit(1:3,iTurb) - rRef(1:3) m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6))))) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation ENDIF - m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6))))) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! set node as point element @@ -1798,29 +1795,24 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er J = J + 1 rRef = m%RodList(m%CpldRodIs(l,iTurb))%r6 ! for now set reference position as per input file <<< - OrMatRef = TRANSPOSE( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! for now set reference orientation as per input file <<< - CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation - - OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Rod's relative orientation with the turbine's initial orientation - u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< - + ! set absolute initial positions in MoorDyn - IF (p%Standalone == 1) THEN - m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) - ELSE + IF (p%Standalone /= 1) THEN + OrMatRef = TRANSPOSE( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! for now set reference orientation as per input file <<< + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation + OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Rod's relative orientation with the turbine's initial orientation + u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< + ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, OrMatRef)) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation ENDIF - m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, OrMatRef)) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation - - m%RodList(m%CpldRodIs(l,iTurb))%r6 = [0,0,-5,0,0,-1] ! Hack for testing the pinned rods - ! >>> still need to set Rod initial orientations accounting for PtfmInit rotation <<< - + CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! lastly, do this to set the attached line endpoint positions: @@ -1832,12 +1824,10 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! set reference position as per input file <<< what about turbine positions in array? rRef(1:3) = m%PointList(m%CpldPointIs(l,iTurb))%r - CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) - + ! set absolute initial positions in MoorDyn - IF (p%Standalone == 1) THEN - m%PointList(m%CpldPointIs(l,iTurb))%r = u%CoupledKinematics(iTurb)%Position(:,J) - ELSE + IF (p%Standalone /= 1) THEN + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index ca250b3585..5902736cd5 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -172,15 +172,14 @@ PROGRAM MoorDyn_Driver ! do OpenFAST vs FAST.Farm related setup MD_InitInp%FarmSize = drvrInitInp%FarmSize - IF (MD_InitInp%FarmSize < 0) THEN - MD_InitInp%Standalone = 1 - ELSE - MD_InitInp%Standalone = 0 - ENDIF + MD_InitInp%Standalone = 0 if (drvrInitInp%FarmSize > 0) then ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) nTurbines = drvrInitInp%FarmSize - else ! FarmSize==0 indicates normal, FAST module mode + else if (drvrInitInp%FarmSize < 0) then ! FarmSize<0 indicates standalone mode + MD_InitInp%Standalone = 1 + nTurbines = 1 ! to keep routines happy + else ! FarmSize==0 indicates normal, FAST module mode nTurbines = 1 ! if a regular FAST module mode, we treat it like a nTurbine=1 farm case end if @@ -589,7 +588,7 @@ PROGRAM MoorDyn_Driver MD_uTimes(2) = MD_uTimes(1) - dtC !MD_uTimes(3) = MD_uTimes(2) - dtC - ! update coupled object kinematics iff we're reading input time series + ! update coupled object kinematics if we're reading input time series if (drvrInitInp%InputsMod == 1 ) then DO iTurb = 1, MD_p%nTurbines From a733f8e3f0ef57411cb34d8c24ef28ea3062e7d1 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Mon, 6 Nov 2023 17:30:36 -0700 Subject: [PATCH 08/91] Coupled pinned bodies --- modules/moordyn/src/MoorDyn.f90 | 120 +++++++++++++------- modules/moordyn/src/MoorDyn_Body.f90 | 133 ++++++++++++++++------- modules/moordyn/src/MoorDyn_Registry.txt | 6 +- 3 files changed, 175 insertions(+), 84 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index a3f12e8399..da79fe50a3 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -773,7 +773,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er else CALL SetErrStat( ErrID_Fatal, 'Body '//trim(Num2LStr(l))//' CG entry (col 10) must have 1 or 3 numbers.' , ErrStat, ErrMsg, RoutineName ) end if - ! process mements of inertia + ! process moments of inertia CALL SplitByBars(tempString3, N, tempStrings) if (N == 1) then ! if only one entry, use it for all directions READ(tempString3, *) m%BodyList(l)%BodyI(1) @@ -839,6 +839,20 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er m%CpldBodyIs(p%nCpldBodies(1),1) = l ! body initial position due to coupling will be adjusted later + + else if ((let1 == "VESSELPINNED") .or. (let1 == "VESPIN") .or. (let1 == "COUPLEDPINNED") .or. (let1 == "CPLDPIN")) then ! if a pinned coupled body, add to list and add + m%BodyList(l)%typeNum = 2 + + p%nCpldBodies(1)=p%nCpldBodies(1)+1 ! add + p%nFreeBodies =p%nFreeBodies+1 ! add this pinned body to the free list because it is half free + + m%BodyStateIs1(p%nFreeBodies) = Nx+1 + m%BodyStateIsN(p%nFreeBodies) = Nx+6 + Nx = Nx + 6 ! add 6 state variables for each pinned body + + m%CpldBodyIs(p%nCpldBodies(1),1) = l + m%FreeBodyIs(p%nFreeBodies) = l + ! TODO: add option for body coupling to different turbines in FAST.Farm <<< @@ -1010,7 +1024,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! TODO: add option for body coupling to different turbines in FAST.Farm <<< - else if ((let1 == "CONNECT") .or. (let1 == "CON") .or. (let1 == "FREE")) then + else if ((let1 == "ROD") .or. (let1 == "R") .or. (let1 == "FREE")) then m%RodList(l)%typeNum = 0 p%nFreeRods=p%nFreeRods+1 @@ -1949,7 +1963,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! >>> maybe this should be skipped <<<< - ! Go through Bodys and write the coordinates to the state vector + ! Go through free Bodys (including pinned) and write the coordinates to the state vector DO l = 1,p%nFreeBodies CALL Body_Initialize(m%BodyList(m%FreeBodyIs(l)), x%states(m%BodyStateIs1(l) : m%BodyStateIsN(l)), m) END DO @@ -2972,8 +2986,8 @@ SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, Er DO iTurb = 1,p%nTurbines DO l = 1,p%nCpldPoints(iTurb) - ! >>>>>>>> here we should pass along accelerations and include inertial loads in the calculation!!! <<>>>>>>> here we should pass along accelerations and include inertial loads in the calculation!!! << 0) print *, "initializing Body ", Body%idNum + + ! the r6 and v6 vectors should have already been set + ! r and rd of ends have already been set by setup function or by parent object <<<<< right? <<<<< + + if (Body%typeNum == 0) then ! free body type + + ! assign initial body kinematics to state vector + states(1:6 ) = Body%v6 ! zero velocities for initialization (set to 0 in Body_Setup) + states(7:12) = Body%r6 + + else if (Body%typeNum ==2 ) then ! pinned rod type (coupled or attached to something previously via setPinKin) + + states(1:3) = Body%v6(4:6) ! zero velocities for initialization (set to 0 in Body_Setup) + states(4:6) = Body%r6(4:6) ! body orentations + + end if + ! set positions of any dependent points and rods now (before they are initialized) CALL Body_SetDependentKin(Body, 0.0_DbKi, m) @@ -203,12 +216,12 @@ END SUBROUTINE Body_InitializeUnfree ! set kinematics for Bodies if they are coupled (or ground) !-------------------------------------------------------------- - SUBROUTINE Body_SetKinematics(Body, r_in, v_in, a_in, t, m) + SUBROUTINE Body_SetKinematics(Body, r6_in, v6_in, a6_in, t, m) Type(MD_Body), INTENT(INOUT) :: Body ! the Body object - Real(DbKi), INTENT(IN ) :: r_in(6) ! 6-DOF position - Real(DbKi), INTENT(IN ) :: v_in(6) ! 6-DOF velocity - Real(DbKi), INTENT(IN ) :: a_in(6) ! 6-DOF acceleration (only used for coupled rods) + Real(DbKi), INTENT(IN ) :: r6_in(6) ! 6-DOF position + Real(DbKi), INTENT(IN ) :: v6_in(6) ! 6-DOF velocity + Real(DbKi), INTENT(IN ) :: a6_in(6) ! 6-DOF acceleration (only used for coupled rods) Real(DbKi), INTENT(IN ) :: t ! instantaneous time TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects (for simplicity, since Bodies deal with Rods and Points) @@ -218,26 +231,24 @@ SUBROUTINE Body_SetKinematics(Body, r_in, v_in, a_in, t, m) ! store current time Body%time = t - ! if (abs(Body%typeNum) == 2) then ! body coupled in 6 DOF, or ground - Body%r6 = r_in - Body%v6 = v_in - Body%a6 = a_in + if (Body%typeNum == 2) then ! body pinned to coupling point + + ! set Body translational kinematics based on BCs (linear model for now) + Body%r6(1:3) = r6_in(1:3) + Body%v6(1:3) = v6_in(1:3) + Body%a6(1:3) = a6_in(1:3) + + ! Body rotations are left alone and will be handled, along with passing kinematics to dependent objects, by separate call to setState + + else ! body rigidly coupled to coupling point + Body%r6 = r6_in + Body%v6 = v6_in + Body%a6 = a6_in ! since this body has no states and all DOFs have been set, pass its kinematics to dependent attachments CALL Body_SetDependentKin(Body, t, m) - - ! else if (abs(Body%typeNum) == 1) then ! body pinned at reference point - ! - ! ! set Body *end A only* kinematics based on BCs (linear model for now) - ! Body%r6(1:3) = r_in(1:3) - ! Body%v6(1:3) = v_in(1:3) - ! - ! ! Body is pinned so only ref point posiiton is specified, rotations are left alone and will be - ! ! handled, along with passing kinematics to attached objects, by separate call to setState - ! - ! else - ! print *, "Error: Body_SetKinematics called for a free Body." ! <<< - ! end if + + end if END SUBROUTINE Body_SetKinematics !-------------------------------------------------------------- @@ -257,14 +268,26 @@ SUBROUTINE Body_SetState(Body, X, t, m) ! store current time Body%time = t + if (Body%typeNum == 0) then ! free Body type - - Body%r6 = X(7:12) ! get positions - Body%v6 = X(1:6) ! get velocities - + Body%r6 = X(7:12) ! get positions + Body%v6 = X(1:6) ! get velocities + + ! set positions of any dependent points and rods + CALL Body_SetDependentKin(Body, t, m) + + else if (Body%typeNum == 2) then + + Body%r6(4:6) = X(4:6) ! get positions + Body%v6(4:6) = X(1:3) ! get velocities + - ! set positions of any dependent points and rods - CALL Body_SetDependentKin(Body, t, m) + ! set positions of any dependent points and rods + CALL Body_SetDependentKin(Body, t, m) + + else + print *, "Error: Body::setState called for a non-free Body type in MoorDyn" ! <<< + end if END SUBROUTINE Body_SetState !-------------------------------------------------------------- @@ -336,6 +359,8 @@ SUBROUTINE Body_GetStateDeriv(Body, Xd, m, p) INTEGER(IntKi) :: J ! index + Real(DbKi) :: Fnet (6) ! net force and moment about reference point + Real(DbKi) :: acc(6) ! 6DOF acceleration vector Real(DbKi) :: y_temp (6) ! temporary vector for LU decomposition @@ -349,15 +374,35 @@ SUBROUTINE Body_GetStateDeriv(Body, Xd, m, p) CALL Body_DoRHS(Body, m, p) - ! solve for accelerations in [M]{a}={f} using LU decomposition - CALL LUsolve(6, Body%M, LU_temp, Body%F6net, y_temp, acc) + IF (Body%typeNum == 0) THEN ! Free body + + ! solve for accelerations in [M]{a}={f} using LU decomposition + CALL LUsolve(6, Body%M, LU_temp, Body%F6net, y_temp, acc) - ! fill in state derivatives - Xd(7:12) = Body%v6 ! dxdt = V (velocities) - Xd(1:6) = acc ! dVdt = a (accelerations) + ! fill in state derivatives + Xd(7:12) = Body%v6 ! dxdt = V (velocities) + Xd(1:6) = acc ! dVdt = a (accelerations) - ! store accelerations in case they're useful as output - Body%a6 = acc + ! store accelerations in case they're useful as output + Body%a6 = acc + + ELSE ! Pinned Body, 6 states (rotational only) + + ! Account for moment response due to inertial coupling + Fnet = Body%F6net + Fnet(4:6) = Fnet(4:6) - MATMUL(Body%M(4:6,1:3), Body%a6(1:3)) + + ! solve for accelerations in [M]{a}={f} using LU decomposition + CALL LUsolve(3, Body%M(4:6,4:6), LU_temp(4:6,4:6), Fnet(4:6), y_temp(4:6), acc(4:6)) + + ! fill in state derivatives + Xd(4:6) = Body%v6(4:6) ! dxdt = V (velocities) + Xd(1:3) = acc(4:6) ! dVdt = a (accelerations) + + ! store accelerations in case they're useful as output + Body%a6(4:6) = acc(4:6) + + ENDIF ! check for NaNs (should check all state derivatives, not just first 6) DO J = 1, 6 @@ -477,9 +522,15 @@ SUBROUTINE Body_GetCoupledForce(Body, Fnet_out, m, p) ! add inertial loads as appropriate if (Body%typeNum == -1) then - F6_iner = 0.0_DbKi !-MATMUL(Body%M, Body%a6) <<<<<<<< why does including F6_iner cause instability??? + F6_iner = -MATMUL(Body%M, Body%a6) ! <<<<<<<< why does including F6_iner cause instability??? Fnet_out = Body%F6net + F6_iner ! add inertial loads - + + else if (Body%typeNum == 2) then ! pinned coupled body + ! inertial loads ... from input translational ... and solved rotational ... acceleration + F6_iner(1:3) = -MATMUL(Body%M6net(1:3,1:3), Body%a6(1:3)) - MATMUL(Body%M6net(1:3,4:6), Body%a6(4:6)) + Fnet_out(1:3) = Body%F6net(1:3) + F6_iner(1:3) ! add translational inertial loads + Fnet_out(4:6) = 0.0_DbKi + else print *, "ERROR, Body_GetCoupledForce called for wrong (non-coupled) body type in MoorDyn!" end if diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 7f29fcb13d..a8406ef193 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -88,7 +88,7 @@ typedef ^ ^ DbKi CaEnd - # this is the Body type, which holds data for each body object typedef ^ MD_Body IntKi IdNum - - - "integer identifier of this Point" -typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=free, 1=fixed, -1=vessel" +typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=free, 1=fixed, -1=coupled, 2=coupledpinned" typedef ^ ^ IntKi AttachedC {30} - - "list of IdNums of points attached to this body" typedef ^ ^ IntKi AttachedR {30} - - "list of IdNums of rods attached to this body" typedef ^ ^ IntKi nAttachedC - 0 - "number of attached points" @@ -117,7 +117,7 @@ typedef ^ ^ DbKi rCG {3} # this is the Point type, which holds data for each point object typedef ^ MD_Point IntKi IdNum - - - "integer identifier of this point" typedef ^ ^ CHARACTER(10) type - - - "type of point: fix, vessel, point" -typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 1=fixed, -1=vessel, 0=free" +typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 1=fixed, -1=coupled, 0=free" typedef ^ ^ IntKi Attached {10} - - "list of IdNums of lines attached to this point node" typedef ^ ^ IntKi Top {10} - - "list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A)" typedef ^ ^ IntKi nAttached - 0 - "number of attached lines" @@ -143,7 +143,7 @@ typedef ^ ^ DbKi M {3}{3} typedef ^ MD_Rod IntKi IdNum - - - "integer identifier of this Line" typedef ^ ^ CHARACTER(10) type - - - "type of Rod. should match one of RodProp names" typedef ^ ^ IntKi PropsIdNum - - - "the IdNum of the associated rod properties" - -typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=fixed, 1=vessel, 2=point, -1=coupledpinned" +typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=free, 1=pinned, 2=fixed, -1=coupledpinned, -2=coupled" typedef ^ ^ IntKi AttachedA {10} - - "list of IdNums of lines attached to end A" typedef ^ ^ IntKi AttachedB {10} - - "list of IdNums of lines attached to end B" typedef ^ ^ IntKi TopA {10} - - "list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A)" From f1116d7051226c1245b288e84ae60bf233324974 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Mon, 13 Nov 2023 11:11:33 -0700 Subject: [PATCH 09/91] Fix segfault in HD when 0 outputs specified This commit fixes a bug where HydroDyn would segfault if no outputs were specified in the input file. --- modules/hydrodyn/src/HydroDyn_Input.f90 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/hydrodyn/src/HydroDyn_Input.f90 b/modules/hydrodyn/src/HydroDyn_Input.f90 index fcbac6fa6c..a9fe940189 100644 --- a/modules/hydrodyn/src/HydroDyn_Input.f90 +++ b/modules/hydrodyn/src/HydroDyn_Input.f90 @@ -3105,7 +3105,18 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, Interval, InputFileData, ErrS IF (ErrStat >= AbortErrLev ) RETURN DEALLOCATE(foundMask) - + + ELSE + + ! Set number of outputs to zero + InputFileData%NumOuts = 0 + InputFileData%Waves2%NumOuts = 0 + InputFileData%Morison%NumOuts = 0 + + ! Allocate outlist with zero length + call AllocAry(InputFileData%OutList, 0, "InputFileData%OutList", ErrStat2, ErrMsg2); + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + END IF ! Now that we have the sub-lists organized, lets do some additional validation. From 188bccdc255d3188c77b0e1e729a86640e4bec2f Mon Sep 17 00:00:00 2001 From: Bonnie Jonkman Date: Tue, 14 Nov 2023 08:55:37 -0700 Subject: [PATCH 10/91] UA driver: vs build - vs project didn't like a `UA_OUTS` as both a preprocessor directive and value inside a type - vs project needed LinDyn added to it - moved override of UA_OUTS to UA driver and added initialization in BEMT & FVW so people could override the value before compiling if they wanted to debug UA inside of AeroDyn. --- modules/aerodyn/src/BEMT.f90 | 2 + modules/aerodyn/src/FVW.f90 | 2 + modules/aerodyn/src/UA_Dvr_Subs.f90 | 64 ++++++++++++----------- modules/aerodyn/src/UnsteadyAero.f90 | 13 ++--- vs-build/RunRegistry.bat | 8 +++ vs-build/UnsteadyAero/UnsteadyAero.vfproj | 37 ++++++++++--- 6 files changed, 80 insertions(+), 46 deletions(-) diff --git a/modules/aerodyn/src/BEMT.f90 b/modules/aerodyn/src/BEMT.f90 index 9c50d3fcdc..00b6bba973 100644 --- a/modules/aerodyn/src/BEMT.f90 +++ b/modules/aerodyn/src/BEMT.f90 @@ -137,6 +137,8 @@ subroutine BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat, errMs Init_UA_Data%ShedEffect = .true. ! This should be true when coupled to BEM Init_UA_Data%WrSum = InitInp%SumPrint + Init_UA_Data%UA_OUTS = 0 + end subroutine BEMT_Set_UA_InitData diff --git a/modules/aerodyn/src/FVW.f90 b/modules/aerodyn/src/FVW.f90 index 616d96ffc7..a44b75294c 100644 --- a/modules/aerodyn/src/FVW.f90 +++ b/modules/aerodyn/src/FVW.f90 @@ -1600,6 +1600,8 @@ subroutine UA_Init_Wrapper(AFInfo, InitInp, interval, p, x, xd, OtherState, m, E Init_UA_Data%a_s = InitInp%a_s ! Speed of sound, m/s Init_UA_Data%ShedEffect = .False. ! Important, when coupling UA wih vortex code, shed vorticity is inherently accounted for Init_UA_Data%WrSum = InitInp%SumPrint + Init_UA_Data%UA_OUTS = 0 + allocate(Init_UA_Data%UAOff_innerNode(1), stat=errStat2) allocate(Init_UA_Data%UAOff_outerNode(1), stat=errStat2) Init_UA_Data%UAOff_innerNode(1) = InitInp%W(iW)%UAOff_innerNode diff --git a/modules/aerodyn/src/UA_Dvr_Subs.f90 b/modules/aerodyn/src/UA_Dvr_Subs.f90 index 323f62c52b..3caefbf5b3 100644 --- a/modules/aerodyn/src/UA_Dvr_Subs.f90 +++ b/modules/aerodyn/src/UA_Dvr_Subs.f90 @@ -401,6 +401,10 @@ subroutine driverInputsToUAInitData(p, InitInData, AFI_Params, AFIndx, errStat, errStat = ErrID_None errMsg = '' InitInData%UA_OUTS = 1 ! 0=None, 1=Write Outputs, 2=Separate File +#ifdef ADD_UA_OUTS + InitInData%UA_OUTS = 2 ! Compiler Flag Override, 2=Write a separate file +#endif + ! -- UA Init Input Data InitInData%nNodesPerBlade = 1 @@ -959,36 +963,36 @@ subroutine Dvr_WriteOutputs(nt, t, dvr, out, errStat, errMsg) ! Driver outputs j = 1 if (dvr%p%SimMod==3) then - ! TODO harmonization - out%outLine(j) = dvr%U0(1, 1) ; j=j+1 ! Ux - out%outLine(j) = dvr%U0(1, 2) ; j=j+1 ! Uy - out%outLine(j) = dvr%m%Vst_Q(1) ; j=j+1 ! VSTx_Q - out%outLine(j) = dvr%m%Vst_Q(2) ; j=j+1 ! VSTy_Q - out%outLine(j) = dvr%m%Vst_T(1) ; j=j+1 ! VSTx_T - out%outLine(j) = dvr%m%Vst_T(2) ; j=j+1 ! VSTy_T - out%outLine(j) = dvr%m%Vrel_Q(1) ; j=j+1 ! Vrelx_Q - out%outLine(j) = dvr%m%Vrel_Q(2) ; j=j+1 ! Vrely_Q - out%outLine(j) = dvr%m%Vrel_T(1) ; j=j+1 ! Vrelx_T - out%outLine(j) = dvr%m%Vrel_T(2) ; j=j+1 ! Vrely_T - out%outLine(j) = sqrt(dvr%m%Vrel_norm2_Q) ; j=j+1 ! Vrel_Q - out%outLine(j) = sqrt(dvr%m%Vrel_norm2_T) ; j=j+1 ! Vrel_T - out%outLine(j) = dvr%m%alpha_Q*R2D ; j=j+1 ! alpha_Q - out%outLine(j) = dvr%m%alpha_T*R2D ; j=j+1 ! alpha_T - out%outLine(j) = dvr%m%phi_Q *R2D ; j=j+1 ! phi_Q - out%outLine(j) = dvr%m%phi_T *R2D ; j=j+1 ! phi_T - out%outLine(j) = dvr%m%twist_full*R2D ; j=j+1 ! twist_full - out%outLine(j) = dvr%m%Re ; j=j+1 ! Re_T - out%outLine(j) = dvr%m%L ; j=j+1 ! L - out%outLine(j) = dvr%m%D ; j=j+1 ! D - out%outLine(j) = dvr%m%tau_Q ; j=j+1 ! M - out%outLine(j) = dvr%m%FxA ; j=j+1 ! Fx_A - out%outLine(j) = dvr%m%FyA ; j=j+1 ! Fy_A - out%outLine(j) = dvr%m%tau_A ; j=j+1 ! M_A - out%outLine(j) = dvr%m%GF(1) ; j=j+1 ! GFx - out%outLine(j) = dvr%m%GF(2) ; j=j+1 ! GFy - out%outLine(j) = dvr%m%GF(3) ; j=j+1 ! GFM - ! LD Outputs - out%outLine(nDV+1:nDV+nLD) = dvr%LD_y%WriteOutput(1:nLD) + ! TODO harmonization + out%outLine(j) = dvr%U0(1, 1) ; j=j+1 ! Ux + out%outLine(j) = dvr%U0(1, 2) ; j=j+1 ! Uy + out%outLine(j) = dvr%m%Vst_Q(1) ; j=j+1 ! VSTx_Q + out%outLine(j) = dvr%m%Vst_Q(2) ; j=j+1 ! VSTy_Q + out%outLine(j) = dvr%m%Vst_T(1) ; j=j+1 ! VSTx_T + out%outLine(j) = dvr%m%Vst_T(2) ; j=j+1 ! VSTy_T + out%outLine(j) = dvr%m%Vrel_Q(1) ; j=j+1 ! Vrelx_Q + out%outLine(j) = dvr%m%Vrel_Q(2) ; j=j+1 ! Vrely_Q + out%outLine(j) = dvr%m%Vrel_T(1) ; j=j+1 ! Vrelx_T + out%outLine(j) = dvr%m%Vrel_T(2) ; j=j+1 ! Vrely_T + out%outLine(j) = sqrt(dvr%m%Vrel_norm2_Q) ; j=j+1 ! Vrel_Q + out%outLine(j) = sqrt(dvr%m%Vrel_norm2_T) ; j=j+1 ! Vrel_T + out%outLine(j) = dvr%m%alpha_Q*R2D ; j=j+1 ! alpha_Q + out%outLine(j) = dvr%m%alpha_T*R2D ; j=j+1 ! alpha_T + out%outLine(j) = dvr%m%phi_Q *R2D ; j=j+1 ! phi_Q + out%outLine(j) = dvr%m%phi_T *R2D ; j=j+1 ! phi_T + out%outLine(j) = dvr%m%twist_full*R2D ; j=j+1 ! twist_full + out%outLine(j) = dvr%m%Re ; j=j+1 ! Re_T + out%outLine(j) = dvr%m%L ; j=j+1 ! L + out%outLine(j) = dvr%m%D ; j=j+1 ! D + out%outLine(j) = dvr%m%tau_Q ; j=j+1 ! M + out%outLine(j) = dvr%m%FxA ; j=j+1 ! Fx_A + out%outLine(j) = dvr%m%FyA ; j=j+1 ! Fy_A + out%outLine(j) = dvr%m%tau_A ; j=j+1 ! M_A + out%outLine(j) = dvr%m%GF(1) ; j=j+1 ! GFx + out%outLine(j) = dvr%m%GF(2) ; j=j+1 ! GFy + out%outLine(j) = dvr%m%GF(3) ; j=j+1 ! GFM + ! LD Outputs + out%outLine(nDV+1:nDV+nLD) = dvr%LD_y%WriteOutput(1:nLD) endif ! UA Outputs out%outLine(nDV+nLD+1:nDV+nLD+nUA) = dvr%UA_y%WriteOutput(1:nUA) diff --git a/modules/aerodyn/src/UnsteadyAero.f90 b/modules/aerodyn/src/UnsteadyAero.f90 index 63118ccab8..501f57e0e9 100644 --- a/modules/aerodyn/src/UnsteadyAero.f90 +++ b/modules/aerodyn/src/UnsteadyAero.f90 @@ -522,7 +522,7 @@ subroutine ComputeKelvinChain( i, j, u, p, xd, OtherState, misc, AFInfo, KC, BL_ KC%Cn_q_circ = KC%C_nalpha_circ*KC%q_f_cur/2.0 - KC%X3 - KC%X4 ! Eqn 1.16 - else ! these aren't used (they are possibly output to UA output file (when UA_OUTS defined) file, though) + else ! these aren't used (they are possibly output to UA output file when UA_OUTS is > 0 file, though) KC%X3 = 0.0_ReKi KC%X4 = 0.0_ReKi KC%Cn_q_circ = 0.0_ReKi @@ -748,9 +748,6 @@ subroutine UA_SetParameters( dt, InitInp, p, AFInfo, AFIndx, ErrStat, ErrMsg ) p%Flookup = InitInp%Flookup p%ShedEffect = InitInp%ShedEffect p%UA_OUTS = InitInp%UA_OUTS -#ifdef UA_OUTS - p%UA_OUTS = 2 ! Compiler Flag Override, 2=Write a separate file -#endif if (p%UAMod==UA_HGM .or. p%UAMod==UA_HGMV) then UA_NumLinStates = 4 @@ -1443,7 +1440,7 @@ subroutine UA_Init_Outputs(InitInp, p, y, InitOut, errStat, errMsg) WRITE (p%unOutFile,'(:,A,'//trim( p%OutSFmt )//')', ADVANCE='no' ) p%Delim, trim(InitOut%WriteOutputUnt(i)) end do WRITE (p%unOutFile,'()', IOSTAT=ErrStat2) ! write the line return - elseif ((p%NumOuts > 0) .and. p%UA_OUTS==2) then + else call WrScr(' UA: saving write outputs') @@ -3844,9 +3841,9 @@ subroutine BV_CalcOutput() ! --- Recompute variables, for temporary output to file only ! Calculate deltas to negative and positive stall angle (delN, and delP) if (p%UA_OUTS>0) then - call BV_delNP(adotnorm, alpha_34, alphaLag_D, BL_p, OtherState%activeD(i,j), delN, delP) - call BV_getGammas(tc=AFInfo%RelThickness, umach=0.0_ReKi, gammaL=gammaL, gammaD=gammaD) - TransA = BV_TransA(BL_p) + call BV_delNP(adotnorm, alpha_34, alphaLag_D, BL_p, OtherState%activeD(i,j), delN, delP) + call BV_getGammas(tc=AFInfo%RelThickness, umach=0.0_ReKi, gammaL=gammaL, gammaD=gammaD) + TransA = BV_TransA(BL_p) endif ! --- Cl, _, at effective angle of attack alphaE diff --git a/vs-build/RunRegistry.bat b/vs-build/RunRegistry.bat index 2649627f6b..af15365556 100644 --- a/vs-build/RunRegistry.bat +++ b/vs-build/RunRegistry.bat @@ -44,6 +44,8 @@ SET SrvD_Loc=%Modules_Loc%\servodyn\src SET BD_Loc=%Modules_Loc%\beamdyn\src SET SC_Loc=%Modules_Loc%\supercontroller\src +SET LD_Loc=%Modules_Loc%\lindyn\src + SET AWAE_Loc=%Modules_Loc%\awae\src SET WD_Loc=%Modules_Loc%\wakedynamics\src SET Farm_Loc=%Root_Loc%\glue-codes\fast-farm\src @@ -165,6 +167,12 @@ SET Output_Loc=%CURR_LOC% %REGISTRY% "%CURR_LOC%\UnsteadyAero_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -O "%Output_Loc%" GOTO checkError +:LD +SET CURR_LOC=%LD_Loc% +SET Output_Loc=%CURR_LOC% +%REGISTRY% "%CURR_LOC%\LinDyn_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -O "%Output_Loc%" +GOTO checkError + :FVW SET CURR_LOC=%AD_Loc% SET Output_Loc=%CURR_LOC% diff --git a/vs-build/UnsteadyAero/UnsteadyAero.vfproj b/vs-build/UnsteadyAero/UnsteadyAero.vfproj index 321fd8c587..066fc3feb7 100644 --- a/vs-build/UnsteadyAero/UnsteadyAero.vfproj +++ b/vs-build/UnsteadyAero/UnsteadyAero.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -55,7 +55,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -120,6 +120,27 @@ + + + + + + + + + + + + + + + + + + + + + From 694096202dde6b22ad582f94adcbd58135f131c5 Mon Sep 17 00:00:00 2001 From: Bonnie Jonkman Date: Tue, 14 Nov 2023 10:12:12 -0700 Subject: [PATCH 11/91] LinDyn: states should be reals, not logicals This would have caused issues when merging with the dev-unstable branch of OpenFAST --- modules/lindyn/src/LinDyn_Registry.txt | 4 ++-- modules/lindyn/src/LinDyn_Types.f90 | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/modules/lindyn/src/LinDyn_Registry.txt b/modules/lindyn/src/LinDyn_Registry.txt index a5dd46dee8..6140a54fab 100644 --- a/modules/lindyn/src/LinDyn_Registry.txt +++ b/modules/lindyn/src/LinDyn_Registry.txt @@ -39,10 +39,10 @@ typedef ^ ^ IntKi typedef ^ ContinuousStateType ReKi q {:} - - "Continuous states q =(x,xdot)" "-" # Discrete (non-differentiable) states: -typedef ^ DiscreteStateType Logical Dummy - - - "" - +typedef ^ DiscreteStateType SiKi Dummy - - - "" - # Constraint states: -typedef ^ ConstraintStateType Logical Dummy - - - "" - +typedef ^ ConstraintStateType SiKi Dummy - - - "" - # Other states: typedef ^ OtherStateType LD_ContinuousStateType xdot {:} - - "Previous state derivs for m-step time integrator" diff --git a/modules/lindyn/src/LinDyn_Types.f90 b/modules/lindyn/src/LinDyn_Types.f90 index ef28a6f104..778bb39cee 100644 --- a/modules/lindyn/src/LinDyn_Types.f90 +++ b/modules/lindyn/src/LinDyn_Types.f90 @@ -72,12 +72,12 @@ MODULE LinDyn_Types ! ======================= ! ========= LD_DiscreteStateType ======= TYPE, PUBLIC :: LD_DiscreteStateType - LOGICAL :: Dummy !< [-] + REAL(SiKi) :: Dummy !< [-] END TYPE LD_DiscreteStateType ! ======================= ! ========= LD_ConstraintStateType ======= TYPE, PUBLIC :: LD_ConstraintStateType - LOGICAL :: Dummy !< [-] + REAL(SiKi) :: Dummy !< [-] END TYPE LD_ConstraintStateType ! ======================= ! ========= LD_OtherStateType ======= @@ -1800,7 +1800,7 @@ SUBROUTINE LD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Dummy + Re_BufSz = Re_BufSz + 1 ! Dummy IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1828,8 +1828,8 @@ SUBROUTINE LD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%Dummy, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Dummy + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_PackDiscState SUBROUTINE LD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1858,8 +1858,8 @@ SUBROUTINE LD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%Dummy = TRANSFER(IntKiBuf(Int_Xferred), OutData%Dummy) - Int_Xferred = Int_Xferred + 1 + OutData%Dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_UnPackDiscState SUBROUTINE LD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) @@ -1937,7 +1937,7 @@ SUBROUTINE LD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Dummy + Re_BufSz = Re_BufSz + 1 ! Dummy IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1965,8 +1965,8 @@ SUBROUTINE LD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%Dummy, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Dummy + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_PackConstrState SUBROUTINE LD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1995,8 +1995,8 @@ SUBROUTINE LD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%Dummy = TRANSFER(IntKiBuf(Int_Xferred), OutData%Dummy) - Int_Xferred = Int_Xferred + 1 + OutData%Dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_UnPackConstrState SUBROUTINE LD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) From abbfd59f953aca4b2a291a042e522467b4f0aea5 Mon Sep 17 00:00:00 2001 From: Bonnie Jonkman Date: Tue, 14 Nov 2023 10:17:59 -0700 Subject: [PATCH 12/91] fix typo in RoutineName parameter --- modules/aerodyn/src/UA_Dvr_Subs.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aerodyn/src/UA_Dvr_Subs.f90 b/modules/aerodyn/src/UA_Dvr_Subs.f90 index 3caefbf5b3..2d4cfd569f 100644 --- a/modules/aerodyn/src/UA_Dvr_Subs.f90 +++ b/modules/aerodyn/src/UA_Dvr_Subs.f90 @@ -193,7 +193,7 @@ subroutine ReadDriverInputFile( FileName, InitInp, ErrStat, ErrMsg ) type(FileInfoType) :: FI !< The derived type for holding the file information. integer(IntKi) :: errStat2 ! Status of error message character(1024) :: errMsg2 ! Error message if ErrStat /= ErrID_None - character(*), parameter :: RoutineName = 'ReadDriverfilename' + character(*), parameter :: RoutineName = 'ReadDriverInputFile' ! Initialize the echo file unit to -1 which is the default to prevent echoing, we will alter this based on user input UnEcho = -1 ErrStat = ErrID_None From 4cc616f15b5b156e27f55628de36ad5574ad5b57 Mon Sep 17 00:00:00 2001 From: Bonnie Jonkman Date: Thu, 16 Nov 2023 09:49:52 -0700 Subject: [PATCH 13/91] UA: minor updates - update extension of UA output files - explicitly initialize `d_34_to_ac` --- modules/aerodyn/src/BEMT.f90 | 3 ++- modules/aerodyn/src/FVW.f90 | 3 ++- modules/aerodyn/src/UA_Dvr_Subs.f90 | 2 +- modules/aerodyn/src/UnsteadyAero.f90 | 4 ++-- modules/nwtc-library/src/NWTC_Num.f90 | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/aerodyn/src/BEMT.f90 b/modules/aerodyn/src/BEMT.f90 index 00b6bba973..b99c3a6658 100644 --- a/modules/aerodyn/src/BEMT.f90 +++ b/modules/aerodyn/src/BEMT.f90 @@ -126,7 +126,7 @@ subroutine BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat, errMs call move_alloc(InitInp%UAOff_outerNode, Init_UA_Data%UAOff_outerNode) Init_UA_Data%dt = interval - Init_UA_Data%OutRootName = InitInp%RootName ! was 'Debug.UA' + Init_UA_Data%OutRootName = trim(InitInp%RootName)//'.UA' Init_UA_Data%numBlades = InitInp%numBlades Init_UA_Data%nNodesPerBlade = InitInp%numBladeNodes @@ -138,6 +138,7 @@ subroutine BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat, errMs Init_UA_Data%WrSum = InitInp%SumPrint Init_UA_Data%UA_OUTS = 0 + Init_UA_Data%d_34_to_ac = 0.5_ReKi end subroutine BEMT_Set_UA_InitData diff --git a/modules/aerodyn/src/FVW.f90 b/modules/aerodyn/src/FVW.f90 index a44b75294c..9c454c0388 100644 --- a/modules/aerodyn/src/FVW.f90 +++ b/modules/aerodyn/src/FVW.f90 @@ -1591,7 +1591,7 @@ subroutine UA_Init_Wrapper(AFInfo, InitInp, interval, p, x, xd, OtherState, m, E Init_UA_Data%c(i,1) = p%W(iW)%chord_LL(i) ! NOTE: InitInp chord move-allocd to p end do Init_UA_Data%dt = interval - Init_UA_Data%OutRootName = trim(InitInp%RootName)//'W'//num2lstr(iW) + Init_UA_Data%OutRootName = trim(InitInp%RootName)//'W'//num2lstr(iW)//'.UA' Init_UA_Data%numBlades = 1 Init_UA_Data%nNodesPerBlade = InitInp%numBladeNodes ! At AeroDyn ndoes, not CP @@ -1601,6 +1601,7 @@ subroutine UA_Init_Wrapper(AFInfo, InitInp, interval, p, x, xd, OtherState, m, E Init_UA_Data%ShedEffect = .False. ! Important, when coupling UA wih vortex code, shed vorticity is inherently accounted for Init_UA_Data%WrSum = InitInp%SumPrint Init_UA_Data%UA_OUTS = 0 + Init_UA_Data%d_34_to_ac = 0.5_ReKi allocate(Init_UA_Data%UAOff_innerNode(1), stat=errStat2) allocate(Init_UA_Data%UAOff_outerNode(1), stat=errStat2) diff --git a/modules/aerodyn/src/UA_Dvr_Subs.f90 b/modules/aerodyn/src/UA_Dvr_Subs.f90 index 2d4cfd569f..1d7e12f955 100644 --- a/modules/aerodyn/src/UA_Dvr_Subs.f90 +++ b/modules/aerodyn/src/UA_Dvr_Subs.f90 @@ -420,7 +420,7 @@ subroutine driverInputsToUAInitData(p, InitInData, AFI_Params, AFIndx, errStat, InitInData%c(1,1) = p%Chord InitInData%UAMod = p%UAMod InitInData%Flookup = p%Flookup - InitInData%OutRootName = p%OutRootName + InitInData%OutRootName = trim(p%OutRootName)//'.UA' InitInData%WrSum = p%SumPrint InitInData%d_34_to_ac = p%d_34_to_ac ! d_34_to_ac = d_QT ~0.5 [-], Approximated using y coordinate diff --git a/modules/aerodyn/src/UnsteadyAero.f90 b/modules/aerodyn/src/UnsteadyAero.f90 index 501f57e0e9..8cebfedb42 100644 --- a/modules/aerodyn/src/UnsteadyAero.f90 +++ b/modules/aerodyn/src/UnsteadyAero.f90 @@ -1416,11 +1416,11 @@ subroutine UA_Init_Outputs(InitInp, p, y, InitOut, errStat, errMsg) ! --- Write to File if ((p%NumOuts > 0) .and. p%UA_OUTS==2) then - call WrScr(' UA: Writing separate output file: '//trim((InitInp%OutRootName)//'.UA.out')) + call WrScr(' UA: Writing separate output file: '//trim((InitInp%OutRootName)//'.out')) CALL GetNewUnit( p%unOutFile, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return - CALL OpenFOutFile ( p%unOutFile, trim(InitInp%OutRootName)//'.UA.out', ErrStat2, ErrMsg2 ) + CALL OpenFOutFile ( p%unOutFile, trim(InitInp%OutRootName)//'.out', ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return diff --git a/modules/nwtc-library/src/NWTC_Num.f90 b/modules/nwtc-library/src/NWTC_Num.f90 index 3c2be77d25..66148d1e3d 100644 --- a/modules/nwtc-library/src/NWTC_Num.f90 +++ b/modules/nwtc-library/src/NWTC_Num.f90 @@ -4984,7 +4984,7 @@ FUNCTION RegCubicSplineInterpM ( X, XAry, YAry, DelX, Coef, ErrStat, ErrMsg ) RE RETURN END FUNCTION RegCubicSplineInterpM ! ( X, XAry, YAry, DelX, Coef, ErrStat, ErrMsg ) !======================================================================= -!> This routine is used to integrate funciton f over the interval [a, b]. This routine +!> This routine is used to integrate function f over the interval [a, b]. This routine !! is useful for sufficiently smooth (e.g., analytic) integrands, integrated over !! intervals which contain no singularities, and where the endpoints are also nonsingular. !! From b48c9b22ac1f7fd782d67839108f13a1f4aba99f Mon Sep 17 00:00:00 2001 From: Hannah Ross Date: Mon, 20 Nov 2023 16:18:28 -0700 Subject: [PATCH 14/91] Update r-tests --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index b81574809d..db771e5f3b 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit b81574809dc4733c1da7d35aa86fb25d72bf2fe1 +Subproject commit db771e5f3b0d21ef999fa6b5374e9bc4914aecce From b97952506a89a465f880713dc302517faecd24b4 Mon Sep 17 00:00:00 2001 From: Hannah Ross Date: Mon, 20 Nov 2023 17:43:16 -0700 Subject: [PATCH 15/91] Update r-tests --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index db771e5f3b..58ced27ad1 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit db771e5f3b0d21ef999fa6b5374e9bc4914aecce +Subproject commit 58ced27ad1e6ca167ba174046891c63185b18901 From 0cebc49748ed4e239a73692e973ad4420c1da78d Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Wed, 22 Nov 2023 15:08:19 -0800 Subject: [PATCH 16/91] Correction to force output --- modules/moordyn/src/MoorDyn_Body.f90 | 14 ++++++++------ modules/moordyn/src/MoorDyn_Driver.f90 | 12 ++++++------ modules/moordyn/src/MoorDyn_Rod.f90 | 9 +++++---- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_Body.f90 b/modules/moordyn/src/MoorDyn_Body.f90 index 27bde873c7..f520265fae 100644 --- a/modules/moordyn/src/MoorDyn_Body.f90 +++ b/modules/moordyn/src/MoorDyn_Body.f90 @@ -221,7 +221,7 @@ SUBROUTINE Body_SetKinematics(Body, r6_in, v6_in, a6_in, t, m) Type(MD_Body), INTENT(INOUT) :: Body ! the Body object Real(DbKi), INTENT(IN ) :: r6_in(6) ! 6-DOF position Real(DbKi), INTENT(IN ) :: v6_in(6) ! 6-DOF velocity - Real(DbKi), INTENT(IN ) :: a6_in(6) ! 6-DOF acceleration (only used for coupled rods) + Real(DbKi), INTENT(IN ) :: a6_in(6) ! 6-DOF acceleration Real(DbKi), INTENT(IN ) :: t ! instantaneous time TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects (for simplicity, since Bodies deal with Rods and Points) @@ -386,7 +386,7 @@ SUBROUTINE Body_GetStateDeriv(Body, Xd, m, p) ! store accelerations in case they're useful as output Body%a6 = acc - ELSE ! Pinned Body, 6 states (rotational only) + ELSE ! Pinned Body, 3 states (rotational only) ! Account for moment response due to inertial coupling Fnet = Body%F6net @@ -523,13 +523,15 @@ SUBROUTINE Body_GetCoupledForce(Body, Fnet_out, m, p) if (Body%typeNum == -1) then F6_iner = -MATMUL(Body%M, Body%a6) ! <<<<<<<< why does including F6_iner cause instability??? - Fnet_out = Body%F6net + F6_iner ! add inertial loads + Body%F6net = Body%F6net + F6_iner ! add inertial loads + Fnet_out = Body%F6net else if (Body%typeNum == 2) then ! pinned coupled body ! inertial loads ... from input translational ... and solved rotational ... acceleration - F6_iner(1:3) = -MATMUL(Body%M6net(1:3,1:3), Body%a6(1:3)) - MATMUL(Body%M6net(1:3,4:6), Body%a6(4:6)) - Fnet_out(1:3) = Body%F6net(1:3) + F6_iner(1:3) ! add translational inertial loads - Fnet_out(4:6) = 0.0_DbKi + F6_iner(1:3) = -MATMUL(Body%M(1:3,1:3), Body%a6(1:3)) - MATMUL(Body%M(1:3,4:6), Body%a6(4:6)) + Body%F6net(1:3) = Body%F6net(1:3) + F6_iner(1:3) ! add translational inertial loads + Body%F6net(4:6) = 0.0_DbKi + Fnet_out = Body%F6net else print *, "ERROR, Body_GetCoupledForce called for wrong (non-coupled) body type in MoorDyn!" diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 5902736cd5..219dfe0f2a 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -90,7 +90,7 @@ PROGRAM MoorDyn_Driver INTEGER(IntKi) :: nt ! number of coupling time steps to use in simulation REAL(DbKi) :: t ! current time (s) - REAL(DbKi) :: tMax ! sim end time (s) + REAL(DbKi) :: TMax ! sim end time (s) REAL(DbKi) :: dtC ! fixed/constant global time step REAL(DbKi) :: frac ! fraction used in interpolation @@ -304,7 +304,7 @@ PROGRAM MoorDyn_Driver ! specify stepping details - nt = tMax/dtC - 1 ! number of coupling time steps + nt = TMax/dtC - 1 ! number of coupling time steps ! allocate space for processed motion array @@ -451,11 +451,11 @@ PROGRAM MoorDyn_Driver else - nt = tMax/dtC - 1 ! number of coupling time steps + nt = TMax/dtC - 1 ! number of coupling time steps end if CALL WrScr(" ") - call WrScr("Tmax - "//trim(Num2LStr(tMax))//" and nt="//trim(Num2LStr(nt))) + call WrScr("Tmax - "//trim(Num2LStr(TMax))//" and nt="//trim(Num2LStr(nt))) CALL WrScr(" ") @@ -569,7 +569,7 @@ PROGRAM MoorDyn_Driver call WrScr("Doing time marching now...") - CALL SimStatus_FirstTime( PrevSimTime, PrevClockTime, SimStrtTime, SimStrtCPU, t, tMax ) + CALL SimStatus_FirstTime( PrevSimTime, PrevClockTime, SimStrtTime, SimStrtCPU, t, TMax ) DO i = 1,nt @@ -579,7 +579,7 @@ PROGRAM MoorDyn_Driver if ( MOD( i, 20 ) == 0 ) THEN - CALL SimStatus( PrevSimTime, PrevClockTime, t, tMax ) + CALL SimStatus( PrevSimTime, PrevClockTime, t, TMax ) end if ! shift older inputs back in the buffer diff --git a/modules/moordyn/src/MoorDyn_Rod.f90 b/modules/moordyn/src/MoorDyn_Rod.f90 index e0e9d7cb2c..7302214f9d 100644 --- a/modules/moordyn/src/MoorDyn_Rod.f90 +++ b/modules/moordyn/src/MoorDyn_Rod.f90 @@ -1016,14 +1016,15 @@ SUBROUTINE Rod_GetCoupledForce(Rod, Fnet_out, m, p) if (Rod%typeNum == -2) then F6_iner = -MATMUL(Rod%M6net, Rod%a6) ! inertial loads - Fnet_out = Rod%F6net + F6_iner ! add inertial loads - + Rod%F6net = Rod%F6net + F6_iner ! add inertial loads + Fnet_out = Rod%F6net ! pinned coupled rod else if (Rod%typeNum == -1) then ! inertial loads ... from input translational ... and solved rotational ... acceleration F6_iner(1:3) = -MATMUL(Rod%M6net(1:3,1:3), Rod%a6(1:3)) - MATMUL(Rod%M6net(1:3,4:6), Rod%a6(4:6)) - Fnet_out(1:3) = Rod%F6net(1:3) + F6_iner(1:3) ! add translational inertial loads - Fnet_out(4:6) = 0.0_DbKi + Rod%F6net(1:3) = Rod%F6net(1:3) + F6_iner(1:3) ! add translational inertial loads + Rod%F6net(4:6) = 0.0_DbKi + Fnet_out = Rod%F6net else print *, "ERROR, Rod_GetCoupledForce called for wrong (non-coupled) rod type!" end if From 96eb6b65cfbb51ab644f1ebe5186b452f1ed8e85 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 3 Dec 2023 11:34:10 -0700 Subject: [PATCH 17/91] ADI: probably memory leak in ADI_UpdateStates The ADI_UpdateStates routine makes a copy of the AD_Input, but never destroyed that data after usage. This could lead to memory continously getting allocated during a simulation with either ADI_C_Binding or the AD driver. --- modules/aerodyn/src/AeroDyn_Inflow.f90 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/aerodyn/src/AeroDyn_Inflow.f90 b/modules/aerodyn/src/AeroDyn_Inflow.f90 index e513c1085f..6dd7773665 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow.f90 @@ -228,10 +228,15 @@ subroutine ADI_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, m, errSta ! Get state variables at next step: INPUT at step nt - 1, OUTPUT at step nt call AD_UpdateStates(t, n, u_AD(:), utimes(:), p%AD, x%AD, xd%AD, z%AD, OtherState%AD, m%AD, errStat2, errMsg2); if(Failed()) return + call CleanUp() + contains subroutine CleanUp() !call ADI_DestroyConstrState(z_guess, errStat2, errMsg2); if(Failed()) return + do it=1,size(utimes) + call AD_DestroyInput(u_AD(it), errStat2, errMsg2); if(Failed()) return + enddo end subroutine logical function Failed() From abbb24003847e75e74d1307571963e711b827946 Mon Sep 17 00:00:00 2001 From: Ganesh Vijayakumar Date: Mon, 4 Dec 2023 13:04:28 -0700 Subject: [PATCH 18/91] Changes to help compile --- glue-codes/openfast-cpp/src/OpenFAST.H | 21 +- glue-codes/openfast-cpp/src/OpenFAST.cpp | 408 ++++++------------ .../src/ExternalInflow_Registry.txt | 6 + modules/openfast-library/src/FAST_Library.f90 | 304 ++++++------- modules/openfast-library/src/FAST_Library.h | 29 +- 5 files changed, 283 insertions(+), 485 deletions(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.H b/glue-codes/openfast-cpp/src/OpenFAST.H index ed93214575..8635f373dc 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.H +++ b/glue-codes/openfast-cpp/src/OpenFAST.H @@ -64,6 +64,8 @@ struct turbineDataType { int numForcePtsTwr; //! Total number of actuator points int numForcePts; + //! Node clustering type + int nodeClusterType; //! Inflow Type - 1 (InflowWind) or 2 (Externally specified) int inflowType; //! Drag coefficient of nacelle @@ -324,15 +326,10 @@ class OpenFAST { //! Array containing forces and deflections data for blade-resolved FSI simulations. std::vector> brFSIData; -<<<<<<< HEAD //! Data structure to get forces and deflections from ExternalInflow module in OpenFAST std::vector extinfw_i_f_FAST; // Input from OpenFAST //! Data structure to send velocity information to ExternalInflow module in OpenFAST std::vector extinfw_o_t_FAST; // Output to OpenFAST -======= - std::vector cDriver_Input_from_FAST; - std::vector cDriver_Output_to_FAST; ->>>>>>> OpenFAST/dev //! Data structure to get deflections from ExternalLoads module in OpenFAST std::vector extld_i_f_FAST; // Input from OpenFAST @@ -441,16 +438,7 @@ class OpenFAST { float & fy, float & fz); -<<<<<<< HEAD //! Allocate turbine number 'iTurbGlob' to the processor with global MPI rank 'procNo'. MUST be called from every MPI rank. -======= - hid_t openVelocityDataFile(bool createFile); - void readVelocityData(int nTimesteps); - void writeVelocityData(hid_t h5file, int iTurb, int iTimestep, ExtInfw_InputType_t iData, ExtInfw_OutputType_t oData); - herr_t closeVelocityDataFile(int nt_global, hid_t velDataFile); - void backupVelocityDataFile(int curTimeStep, hid_t & velDataFile); - ->>>>>>> OpenFAST/dev void setTurbineProcNo(int iTurbGlob, int procNo) { turbineMapGlobToProc[iTurbGlob] = procNo; } //! Allocate all turbines to processors in a round-robin fashion. MUST be called from every MPI rank. void allocateTurbinesToProcsSimple(); @@ -769,7 +757,6 @@ private: void loadSuperController(const fastInputs & fi); -<<<<<<< HEAD //! Apply the velocity data at the Aerodyn nodes in 'velData' to turbine number 'iTurb' at time step 'iPrestart' through the data structure 'cDriver_Output_to_FAST' void applyVelocityData(int iPrestart, int iTurb, ExtInfw_OutputType_t o_t_FAST, std::vector & velData) ; @@ -779,10 +766,6 @@ private: void applyWMrotation(double * wm, double * r, double *rRot, double transpose = 1.0); //! Apply a Direction Cosine Matrix rotation 'dcm' to a vector 'r' into 'rRot'. To optionally transpose the rotation, set 'tranpose=-1.0'. void applyDCMrotation(double * dcm, double * r, double *rRot, double transpose = 1.0); -======= - void setOutputsToFAST(ExtInfw_InputType_t cDriver_Input_from_FAST, ExtInfw_OutputType_t cDriver_Output_to_FAST) ; // An example to set velocities at the Aerodyn nodes - void applyVelocityData(int iPrestart, int iTurb, ExtInfw_OutputType_t cDriver_Output_to_FAST, std::vector & velData) ; ->>>>>>> OpenFAST/dev }; diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 3197cc7c94..0b002df101 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -36,7 +36,7 @@ fast::OpenFAST::OpenFAST() sc = std::unique_ptr(new SuperController); - ncRstVarNames_ = {"time", "rst_filename", "twr_ref_pos", "bld_ref_pos", "nac_ref_pos", "hub_ref_pos", "twr_def", "twr_vel", "twr_ld", "bld_def", "bld_vel", "bld_ld", "hub_def", "hub_vel", "nac_def", "nac_vel", "bld_root_def", "bld_pitch", "x_vel", "xdot_vel", "vel_vel", "x_force", "xdot_force", "orient_force", "vel_force", "force"}; + ncRstVarNames_ = {"time", "rst_filename", "twr_ref_pos", "bld_ref_pos", "nac_ref_pos", "hub_ref_pos", "twr_def", "twr_vel", "twr_ld", "bld_def", "bld_vel", "bld_ld", "hub_def", "hub_vel", "nac_def", "nac_vel", "bld_root_def", "bld_pitch", "x_vel", "vel_vel", "x_force", "xdot_force", "orient_force", "vel_force", "force"}; ncRstDimNames_ = {"n_tsteps", "n_states", "n_twr_data", "n_bld_data", "n_pt_data", "n_bld_root_data", "n_bld_pitch_data", "n_vel_pts_data", "n_force_pts_data", "n_force_pts_orient_data"}; ncOutVarNames_ = {"time", "twr_ref_pos", "twr_ref_orient", "bld_chord", "bld_rloc", "bld_ref_pos", "bld_ref_orient", "hub_ref_pos", "hub_ref_orient", "nac_ref_pos", "nac_ref_orient", "twr_disp", "twr_orient", "twr_vel", "twr_rotvel", "twr_ld", "twr_moment", "bld_disp", "bld_orient", "bld_vel", "bld_rotvel", "bld_ld", "bld_ld_loc", "bld_moment", "hub_disp", "hub_orient", "hub_vel", "hub_rotvel", "nac_disp", "nac_orient", "nac_vel", "nac_rotvel", "bld_root_ref_pos", "bld_root_ref_orient", "bld_root_disp", "bld_root_orient"}; @@ -160,7 +160,7 @@ void fast::OpenFAST::prepareRestartFile(int iTurbLoc) { const std::vector twrDefLoadsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_twr_data"]}; const std::vector bldDefLoadsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_bld_data"]}; const std::vector bldRootDefsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_bld_root_data"]}; - const std::vector bldPitchDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_bld_pitch_data"]}; + const std::vector bldPitchDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_bld_pitch_data"]}; const std::vector ptDefLoadsDims{ncRstDimIDs_["n_tsteps"], ncRstDimIDs_["n_states"], ncRstDimIDs_["n_pt_data"],}; ierr = nc_def_var(ncid, "twr_def", NC_DOUBLE, 3, twrDefLoadsDims.data(), &tmpVarID); @@ -186,7 +186,7 @@ void fast::OpenFAST::prepareRestartFile(int iTurbLoc) { ierr = nc_def_var(ncid, "bld_root_def", NC_DOUBLE, 3, bldRootDefsDims.data(), &tmpVarID); ncRstVarIDs_["bld_root_def"] = tmpVarID; ierr = nc_def_var(ncid, "bld_pitch", NC_DOUBLE, 3, bldPitchDims.data(), &tmpVarID); - ncRstVarIDs_["bld_pitch"] = tmpVarID; + ncRstVarIDs_["bld_pitch"] = tmpVarID; } else if (turbineData[iTurbLoc].sType == EXTINFLOW) { @@ -203,8 +203,6 @@ void fast::OpenFAST::prepareRestartFile(int iTurbLoc) { ierr = nc_def_var(ncid, "x_vel", NC_DOUBLE, 3, velPtsDataDims.data(), &tmpVarID); ncRstVarIDs_["x_vel"] = tmpVarID; - ierr = nc_def_var(ncid, "xdot_vel", NC_DOUBLE, 3, velPtsDataDims.data(), &tmpVarID); - ncRstVarIDs_["xdot_vel"] = tmpVarID; ierr = nc_def_var(ncid, "vel_vel", NC_DOUBLE, 3, velPtsDataDims.data(), &tmpVarID); ncRstVarIDs_["vel_vel"] = tmpVarID; ierr = nc_def_var(ncid, "xref_force", NC_DOUBLE, 1, &ncRstDimIDs_["n_force_pts_data"], &tmpVarID); @@ -425,8 +423,6 @@ void fast::OpenFAST::prepareOutputFile(int iTurbLoc) { ierr = nc_def_var(ncid, "bld_chord", NC_DOUBLE, 2, bldParamDims.data(), &tmpVarID); ncOutVarIDs_["bld_chord"] = tmpVarID; - ierr = nc_def_var(ncid, "bld_rloc", NC_DOUBLE, 2, bldParamDims.data(), &tmpVarID); - ncOutVarIDs_["bld_rloc"] = tmpVarID; ierr = nc_def_var(ncid, "twr_ref_pos", NC_DOUBLE, 2, twrRefDataDims.data(), &tmpVarID); ncOutVarIDs_["twr_ref_pos"] = tmpVarID; @@ -605,14 +601,6 @@ void fast::OpenFAST::prepareOutputFile(int iTurbLoc) { ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_chord"], start_dim.data(), param_count_dim.data(), tmpArray.data()); } - for (size_t iBlade=0; iBlade < nBlades; iBlade++) { - int iStart = 1 + iBlade*nBldPts; - for (size_t i=0; i < nBldPts; i++) - tmpArray[i] = extinfw_i_f_FAST[iTurbLoc].forceRHloc[iStart+i]; - std::vector start_dim{iBlade,0}; - ierr = nc_put_vara_double(ncid, ncOutVarIDs_["bld_rloc"], start_dim.data(), - param_count_dim.data(), tmpArray.data()); - } } } @@ -623,8 +611,6 @@ void fast::OpenFAST::prepareOutputFile(int iTurbLoc) { void fast::OpenFAST::init() { - // Temporary buffer to pass filenames to OpenFAST fortran subroutines - char currentFileName[INTERFACE_STRING_LENGTH]; allocateMemory_preInit(); @@ -634,7 +620,6 @@ void fast::OpenFAST::init() { case fast::trueRestart: for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { -<<<<<<< HEAD findRestartFile(iTurb); findOutputFile(iTurb); @@ -643,38 +628,40 @@ void fast::OpenFAST::init() { tmpRstFileRoot[turbineData[iTurb].FASTRestartFileName.size()] = '\0'; if (turbineData[iTurb].sType == EXTINFLOW) { /* note that this will set nt_global inside the FAST library */ - FAST_AL_CFD_Restart(&iTurb, tmpRstFileRoot, &AbortErrLev, &turbineData[iTurb].dt, &turbineData[iTurb].inflowType, &turbineData[iTurb].numBlades, &turbineData[iTurb].numVelPtsBlade, &turbineData[iTurb].numVelPtsTwr, &ntStart, &extinfw_i_f_FAST[iTurb], &extinfw_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + FAST_ExtInfw_Restart( + &iTurb, + tmpRstFileRoot, + &AbortErrLev, + &turbineData[iTurb].dt, + &turbineData[iTurb].inflowType, + &turbineData[iTurb].numBlades, + &turbineData[iTurb].numVelPtsBlade, + &turbineData[iTurb].numVelPtsTwr, + &ntStart, + &extinfw_i_f_FAST[iTurb], + &extinfw_o_t_FAST[iTurb], + &sc->ip_from_FAST[iTurb], + &sc->op_to_FAST[iTurb], + &ErrStat, + ErrMsg); checkError(ErrStat, ErrMsg); - } else if(turbineData[iTurb].sType == EXTLOADS) { - FAST_BR_CFD_Restart(&iTurb, tmpRstFileRoot, &AbortErrLev, &turbineData[iTurb].dt, &turbineData[iTurb].numBlades, &ntStart, &extld_i_f_FAST[iTurb], &extld_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + FAST_ExtLoads_Restart( + &iTurb, + tmpRstFileRoot, + &AbortErrLev, + &turbineData[iTurb].dt, + &turbineData[iTurb].numBlades, + &ntStart, + &extld_i_f_FAST[iTurb], + &extld_o_t_FAST[iTurb], + &sc->ip_from_FAST[iTurb], + &sc->op_to_FAST[iTurb], + &ErrStat, + ErrMsg); turbineData[iTurb].inflowType = 0; } -======= - /* note that this will set nt_global inside the FAST library */ - std::copy( - CheckpointFileRoot[iTurb].data(), - CheckpointFileRoot[iTurb].data() + (CheckpointFileRoot[iTurb].size() + 1), - currentFileName - ); - FAST_ExtInfw_Restart( - &iTurb, - currentFileName, - &AbortErrLev, - &dtFAST, - &numBlades[iTurb], - &numVelPtsBlade[iTurb], - &ntStart, - &cDriver_Input_from_FAST[iTurb], - &cDriver_Output_to_FAST[iTurb], - &sc.ip_from_FAST[iTurb], - &sc.op_to_FAST[iTurb], - &ErrStat, - ErrMsg - ); - checkError(ErrStat, ErrMsg); ->>>>>>> OpenFAST/dev nt_global = ntStart; allocateMemory_postInit(iTurb); @@ -702,55 +689,44 @@ void fast::OpenFAST::init() { } // this calls the Init() routines of each module for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { -<<<<<<< HEAD -======= - int nodeClusterType = 0; - if (forcePtsBladeDistributionType[iTurb] == "chordClustered") - { - nodeClusterType = 1; - } - std::copy( - FASTInputFileName[iTurb].data(), - FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), - currentFileName - ); - FAST_ExtInfw_Init( - &iTurb, - &tMax, - currentFileName, - &TurbID[iTurb], - &scio.nSC2CtrlGlob, - &scio.nSC2Ctrl, - &scio.nCtrl2SC, - scio.from_SCglob.data(), - scio.from_SC[iTurb].data(), - &numForcePtsBlade[iTurb], - &numForcePtsTwr[iTurb], - TurbineBasePos[iTurb].data(), - &AbortErrLev, - &dtFAST, - &numBlades[iTurb], - &numVelPtsBlade[iTurb], - &nodeClusterType, - &cDriver_Input_from_FAST[iTurb], - &cDriver_Output_to_FAST[iTurb], - &sc.ip_from_FAST[iTurb], - &sc.op_to_FAST[iTurb], - &ErrStat, - ErrMsg - ); - checkError(ErrStat, ErrMsg); ->>>>>>> OpenFAST/dev char tmpOutFileRoot[INTERFACE_STRING_LENGTH]; + char inputFileName[INTERFACE_STRING_LENGTH]; if (turbineData[iTurb].sType == EXTINFLOW) { std::copy( turbineData[iTurb].FASTInputFileName.data(), turbineData[iTurb].FASTInputFileName.data() + (turbineData[iTurb].FASTInputFileName.size() + 1), - currentFileName + inputFileName ); - FAST_AL_CFD_Init( &iTurb, &tMax, turbineData[iTurb].FASTInputFileName.data(), &turbineData[iTurb].TurbID, tmpOutFileRoot, &scio.nSC2CtrlGlob, &scio.nSC2Ctrl, &scio.nCtrl2SC, scio.from_SCglob.data(), scio.from_SC[iTurb].data(), &turbineData[iTurb].numForcePtsBlade, &turbineData[iTurb].numForcePtsTwr, turbineData[iTurb].TurbineBasePos.data(), &AbortErrLev, &dtDriver, &turbineData[iTurb].dt, &turbineData[iTurb].inflowType, &turbineData[iTurb].numBlades, &turbineData[iTurb].numVelPtsBlade, &turbineData[iTurb].numVelPtsTwr, &extinfw_i_f_FAST[iTurb], &extinfw_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + FAST_ExtInfw_Init( + &iTurb, + &tMax, + inputFileName, + &turbineData[iTurb].TurbID, + tmpOutFileRoot, + &scio.nSC2CtrlGlob, + &scio.nSC2Ctrl, + &scio.nCtrl2SC, + scio.from_SCglob.data(), + scio.from_SC[iTurb].data(), + &turbineData[iTurb].numForcePtsBlade, + &turbineData[iTurb].numForcePtsTwr, + turbineData[iTurb].TurbineBasePos.data(), + &AbortErrLev, + &dtDriver, + &turbineData[iTurb].dt, + &turbineData[iTurb].inflowType, + &turbineData[iTurb].numBlades, + &turbineData[iTurb].numVelPtsBlade, + &turbineData[iTurb].numVelPtsTwr, + &turbineData[iTurb].nodeClusterType, + &extinfw_i_f_FAST[iTurb], + &extinfw_o_t_FAST[iTurb], + &sc->ip_from_FAST[iTurb], + &sc->op_to_FAST[iTurb], + &ErrStat, + ErrMsg); checkError(ErrStat, ErrMsg); turbineData[iTurb].numVelPtsTwr = extinfw_o_t_FAST[iTurb].u_Len - turbineData[iTurb].numBlades*turbineData[iTurb].numVelPtsBlade - 1; @@ -761,7 +737,30 @@ void fast::OpenFAST::init() { } else if(turbineData[iTurb].sType == EXTLOADS) { - FAST_BR_CFD_Init(&iTurb, &tMax, turbineData[iTurb].FASTInputFileName.data(), &turbineData[iTurb].TurbID, tmpOutFileRoot, turbineData[iTurb].TurbineBasePos.data(), &AbortErrLev, &dtDriver, &turbineData[iTurb].dt, &turbineData[iTurb].numBlades, &turbineData[iTurb].azBlendMean, &turbineData[iTurb].azBlendDelta, &turbineData[iTurb].velMean, &turbineData[iTurb].windDir, &turbineData[iTurb].zRef, &turbineData[iTurb].shearExp, &extld_i_f_FAST[iTurb], &extld_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + char inputFileName[INTERFACE_STRING_LENGTH]; + FAST_ExtLoads_Init( + &iTurb, + &tMax, + turbineData[iTurb].FASTInputFileName.data(), + &turbineData[iTurb].TurbID, + tmpOutFileRoot, + turbineData[iTurb].TurbineBasePos.data(), + &AbortErrLev, + &dtDriver, + &turbineData[iTurb].dt, + &turbineData[iTurb].numBlades, + &turbineData[iTurb].azBlendMean, + &turbineData[iTurb].azBlendDelta, + &turbineData[iTurb].velMean, + &turbineData[iTurb].windDir, + &turbineData[iTurb].zRef, + &turbineData[iTurb].shearExp, + &extld_i_f_FAST[iTurb], + &extld_o_t_FAST[iTurb], + &sc->ip_from_FAST[iTurb], + &sc->op_to_FAST[iTurb], + &ErrStat, + ErrMsg); checkError(ErrStat, ErrMsg); turbineData[iTurb].inflowType = 0; @@ -796,58 +795,47 @@ void fast::OpenFAST::init() { } for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { -<<<<<<< HEAD -======= - int nodeClusterType = 0; - if (forcePtsBladeDistributionType[iTurb] == "chordClustered") - { - nodeClusterType = 1; - } - std::copy( - FASTInputFileName[iTurb].data(), - FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), - currentFileName - ); - FAST_ExtInfw_Init( - &iTurb, - &tMax, - currentFileName, - &TurbID[iTurb], - &scio.nSC2CtrlGlob, - &scio.nSC2Ctrl, - &scio.nCtrl2SC, - scio.from_SCglob.data(), - scio.from_SC[iTurb].data(), - &numForcePtsBlade[iTurb], - &numForcePtsTwr[iTurb], - TurbineBasePos[iTurb].data(), - &AbortErrLev, - &dtFAST, - &numBlades[iTurb], - &numVelPtsBlade[iTurb], - &nodeClusterType, - &cDriver_Input_from_FAST[iTurb], - &cDriver_Output_to_FAST[iTurb], - &sc.ip_from_FAST[iTurb], - &sc.op_to_FAST[iTurb], - &ErrStat, - ErrMsg - ); - checkError(ErrStat, ErrMsg); ->>>>>>> OpenFAST/dev findOutputFile(iTurb); findRestartFile(iTurb); char tmpOutFileRoot[INTERFACE_STRING_LENGTH]; + char inputFileName[INTERFACE_STRING_LENGTH]; if (turbineData[iTurb].sType == EXTINFLOW) { std::copy( turbineData[iTurb].FASTInputFileName.data(), turbineData[iTurb].FASTInputFileName.data() + (turbineData[iTurb].FASTInputFileName.size() + 1), - currentFileName + inputFileName ); - FAST_AL_CFD_Init( &iTurb, &tMax, turbineData[iTurb].FASTInputFileName.data(), &turbineData[iTurb].TurbID, tmpOutFileRoot, &scio.nSC2CtrlGlob, &scio.nSC2Ctrl, &scio.nCtrl2SC, scio.from_SCglob.data(), scio.from_SC[iTurb].data(), &turbineData[iTurb].numForcePtsBlade, &turbineData[iTurb].numForcePtsTwr, turbineData[iTurb].TurbineBasePos.data(), &AbortErrLev, &dtDriver, &turbineData[iTurb].dt, &turbineData[iTurb].inflowType, &turbineData[iTurb].numBlades, &turbineData[iTurb].numVelPtsBlade, &turbineData[iTurb].numVelPtsTwr, &extinfw_i_f_FAST[iTurb], &extinfw_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], &ErrStat, ErrMsg); + FAST_ExtInfw_Init( + &iTurb, + &tMax, + inputFileName, + &turbineData[iTurb].TurbID, + tmpOutFileRoot, + &scio.nSC2CtrlGlob, + &scio.nSC2Ctrl, + &scio.nCtrl2SC, + scio.from_SCglob.data(), + scio.from_SC[iTurb].data(), + &turbineData[iTurb].numForcePtsBlade, + &turbineData[iTurb].numForcePtsTwr, + turbineData[iTurb].TurbineBasePos.data(), + &AbortErrLev, + &dtDriver, + &turbineData[iTurb].dt, + &turbineData[iTurb].inflowType, + &turbineData[iTurb].numBlades, + &turbineData[iTurb].numVelPtsBlade, + &turbineData[iTurb].numVelPtsTwr, + &turbineData[iTurb].nodeClusterType, + &extinfw_i_f_FAST[iTurb], + &extinfw_o_t_FAST[iTurb], + &sc->ip_from_FAST[iTurb], + &sc->op_to_FAST[iTurb], + &ErrStat, + ErrMsg); checkError(ErrStat, ErrMsg); timeZero = true; @@ -949,12 +937,8 @@ void fast::OpenFAST::solution0(bool writeFiles) { send_data_to_openfast(fast::STATE_NP1); for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { -<<<<<<< HEAD FAST_CFD_Solution0(&iTurb, &ErrStat, ErrMsg); -======= - FAST_ExtInfw_Solution0(&iTurb, &ErrStat, ErrMsg); ->>>>>>> OpenFAST/dev checkError(ErrStat, ErrMsg); FAST_CFD_InitIOarrays_SS(&iTurb, &ErrStat, ErrMsg); @@ -987,14 +971,12 @@ void fast::OpenFAST::set_state_from_state(fast::timeStep fromState, fast::timeSt for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { -<<<<<<< HEAD if (turbineData[iTurb].sType == EXTINFLOW) { int nvelpts = get_numVelPtsLoc(iTurb); int nfpts = get_numForcePtsLoc(iTurb); for (int i=0; i0.) { - calc_nacelle_force ( - cDriver_Output_to_FAST[iTurb].u[0], - cDriver_Output_to_FAST[iTurb].v[0], - cDriver_Output_to_FAST[iTurb].w[0], - nacelle_cd[iTurb], - nacelle_area[iTurb], - air_density[iTurb], - cDriver_Input_from_FAST[iTurb].fx[0], - cDriver_Input_from_FAST[iTurb].fy[0], - cDriver_Input_from_FAST[iTurb].fz[0] - ); - } - - if ( isDebug() ) { - std::ofstream actuatorForcesFile; - actuatorForcesFile.open("actuator_forces.csv") ; - actuatorForcesFile << "# x, y, z, fx, fy, fz" << std::endl ; - for (int iNode=0; iNode < get_numForcePtsLoc(iTurb); iNode++) { - actuatorForcesFile << cDriver_Input_from_FAST[iTurb].pxForce[iNode] << ", " << cDriver_Input_from_FAST[iTurb].pyForce[iNode] << ", " << cDriver_Input_from_FAST[iTurb].pzForce[iNode] << ", " << cDriver_Input_from_FAST[iTurb].fx[iNode] << ", " << cDriver_Input_from_FAST[iTurb].fy[iNode] << ", " << cDriver_Input_from_FAST[iTurb].fz[iNode] << " " << std::endl ; ->>>>>>> OpenFAST/dev } } } @@ -1166,12 +1102,10 @@ void fast::OpenFAST::predict_states() { for (int i=0; i>>>>>> OpenFAST/dev checkError(ErrStat, ErrMsg); } @@ -1680,11 +1602,7 @@ void fast::OpenFAST::setDriverCheckpoint(int nt_checkpoint_driver) { } } -<<<<<<< HEAD void fast::OpenFAST::get_turbineParams(int iTurbGlob, turbineDataType & turbData) { -======= -void fast::OpenFAST::setOutputsToFAST(ExtInfw_InputType_t cDriver_Input_from_FAST, ExtInfw_OutputType_t cDriver_Output_to_FAST){ ->>>>>>> OpenFAST/dev //TODO: Figure out a better copy operator for the turbineDataType struct int iTurbLoc = get_localTurbNo(iTurbGlob); @@ -1729,6 +1647,7 @@ void fast::OpenFAST::setOutputsToFAST(ExtInfw_InputType_t cDriver_Input_from_FAS } + void fast::OpenFAST::checkError(const int ErrStat, const char * ErrMsg) { if (ErrStat != ErrID_None){ @@ -1835,13 +1754,8 @@ void fast::OpenFAST::getForce(double* currentForce, int iNode, int iTurbGlob, fa double fast::OpenFAST::getRHloc(int iNode, int iTurbGlob) { // Return radial location/height along blade/tower at current node of current turbine - int iTurbLoc = get_localTurbNo(iTurbGlob); - if (turbineData[iTurbLoc].sType == EXTINFLOW) { - for(int j=0; j < iTurbLoc; j++) iNode = iNode - get_numForcePtsLoc(iTurbLoc); - return extinfw_i_f_FAST[iTurbLoc].forceRHloc[iNode] ; - } else { - return -1.0; - } + // Inactive for now + return -1.0; } @@ -1995,7 +1909,7 @@ void fast::OpenFAST::computeTorqueThrust(int iTurbGlob, double* torque, double* std::vector hubShftVec(3); getHubShftDir(hubShftVec, iTurbGlob, fast::STATE_NP1); - + int nfpts = get_numForcePtsBlade(iTurbLoc); for (int k=0; k < get_numBladesLoc(iTurbLoc); k++) { for (int j=0; j < nfpts; j++) { @@ -2151,17 +2065,12 @@ void fast::OpenFAST::allocateMemory_preInit() { FAST_AllocateTurbines(&nTurbinesProc, &ErrStat, ErrMsg); // Allocate memory for ExtInfw Input types in FAST -<<<<<<< HEAD extinfw_i_f_FAST.resize(nTurbinesProc) ; extinfw_o_t_FAST.resize(nTurbinesProc) ; // Allocate memory for ExtLd Input types in FAST extld_i_f_FAST.resize(nTurbinesProc) ; extld_o_t_FAST.resize(nTurbinesProc) ; -======= - cDriver_Input_from_FAST.resize(nTurbinesProc) ; - cDriver_Output_to_FAST.resize(nTurbinesProc) ; ->>>>>>> OpenFAST/dev if(scStatus) { std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; @@ -2195,7 +2104,6 @@ void fast::OpenFAST::allocateMemory_postInit(int iTurbLoc) { velForceNodeData[iTurbLoc][3].xref_force.resize(3*nfpts); for(int k=0; k<4; k++) { velForceNodeData[iTurbLoc][k].x_vel.resize(3*nvelpts) ; - velForceNodeData[iTurbLoc][k].xdot_vel.resize(3*nvelpts) ; velForceNodeData[iTurbLoc][k].vel_vel.resize(3*nvelpts) ; velForceNodeData[iTurbLoc][k].x_force.resize(3*nfpts) ; velForceNodeData[iTurbLoc][k].xdot_force.resize(3*nfpts) ; @@ -2459,12 +2367,6 @@ void fast::OpenFAST::get_data_from_openfast(timeStep t) { velForceNodeData[iTurb][t].x_vel[i*3+1] = extinfw_i_f_FAST[iTurb].pyVel[i]; velForceNodeData[iTurb][t].x_vel_resid += (velForceNodeData[iTurb][t].x_vel[i*3+2] - extinfw_i_f_FAST[iTurb].pzVel[i])*(velForceNodeData[iTurb][t].x_vel[i*3+2] - extinfw_i_f_FAST[iTurb].pzVel[i]); velForceNodeData[iTurb][t].x_vel[i*3+2] = extinfw_i_f_FAST[iTurb].pzVel[i]; - velForceNodeData[iTurb][t].xdot_vel_resid += (velForceNodeData[iTurb][t].xdot_vel[i*3+0] - extinfw_i_f_FAST[iTurb].pxdotVel[i])*(velForceNodeData[iTurb][t].xdot_vel[i*3+0] - extinfw_i_f_FAST[iTurb].pxdotVel[i]); - velForceNodeData[iTurb][t].xdot_vel[i*3+0] = extinfw_i_f_FAST[iTurb].pxdotVel[i]; - velForceNodeData[iTurb][t].xdot_vel_resid += (velForceNodeData[iTurb][t].xdot_vel[i*3+1] - extinfw_i_f_FAST[iTurb].pydotVel[i])*(velForceNodeData[iTurb][t].xdot_vel[i*3+1] - extinfw_i_f_FAST[iTurb].pydotVel[i]); - velForceNodeData[iTurb][t].xdot_vel[i*3+1] = extinfw_i_f_FAST[iTurb].pydotVel[i]; - velForceNodeData[iTurb][t].xdot_vel_resid += (velForceNodeData[iTurb][t].xdot_vel[i*3+2] - extinfw_i_f_FAST[iTurb].pzdotVel[i])*(velForceNodeData[iTurb][t].xdot_vel[i*3+2] - extinfw_i_f_FAST[iTurb].pzdotVel[i]); - velForceNodeData[iTurb][t].xdot_vel[i*3+2] = extinfw_i_f_FAST[iTurb].pzdotVel[i]; } for (int i=0; i start_dim{n_tsteps,j,0}; ierr = nc_get_vara_double(ncid, ncRstVarIDs_["x_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_vel.data()); - ierr = nc_get_vara_double(ncid, ncRstVarIDs_["xdot_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_vel.data()); ierr = nc_get_vara_double(ncid, ncRstVarIDs_["vel_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].vel_vel.data()); ierr = nc_get_vara_double(ncid, ncRstVarIDs_["x_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_force.data()); ierr = nc_get_vara_double(ncid, ncRstVarIDs_["xdot_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_force.data()); @@ -2591,7 +2492,7 @@ void fast::OpenFAST::readRestartFile(int iTurbLoc, int n_t_global) { const std::vector twrDataDims{1, 1, static_cast(6*nBRfsiPtsTwr)}; const std::vector bldDataDims{1, 1, static_cast(6*nTotBRfsiPtsBlade)}; const std::vector bldRootDataDims{1, 1, static_cast(6*nBlades)}; - const std::vector bldPitchDataDims{1, 1, static_cast(nBlades)}; + const std::vector bldPitchDataDims{1, 1, static_cast(nBlades)}; const std::vector ptDataDims{1, 1, 6}; for (size_t j=0; j < 4; j++) { // Loop over states - NM2, STATE_NM1, N, NP1 @@ -2617,7 +2518,7 @@ void fast::OpenFAST::readRestartFile(int iTurbLoc, int n_t_global) { } - + } @@ -2996,7 +2897,6 @@ void fast::OpenFAST::writeRestartFile(int iTurbLoc, int n_t_global) { const std::vector start_dim{n_tsteps,j,0}; ierr = nc_put_vara_double(ncid, ncRstVarIDs_["x_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_vel.data()); - ierr = nc_put_vara_double(ncid, ncRstVarIDs_["xdot_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_vel.data()); ierr = nc_put_vara_double(ncid, ncRstVarIDs_["vel_vel"], start_dim.data(), velPtsDataDims.data(), velForceNodeData[iTurbLoc][j].vel_vel.data()); ierr = nc_put_vara_double(ncid, ncRstVarIDs_["x_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].x_force.data()); ierr = nc_put_vara_double(ncid, ncRstVarIDs_["xdot_force"], start_dim.data(), forcePtsDataDims.data(), velForceNodeData[iTurbLoc][j].xdot_force.data()); @@ -3013,7 +2913,7 @@ void fast::OpenFAST::writeRestartFile(int iTurbLoc, int n_t_global) { const std::vector twrDataDims{1, 1, static_cast(6*nPtsTwr)}; const std::vector bldDataDims{1, 1, static_cast(6*nTotBldPts)}; const std::vector bldRootDataDims{1, 1, static_cast(6*nBlades)}; - const std::vector bldPitchDataDims{1, 1, static_cast(nBlades)}; + const std::vector bldPitchDataDims{1, 1, static_cast(nBlades)}; const std::vector ptDataDims{1, 1, 6}; for (size_t j=0; j < 4; j++) { // Loop over states - STATE_NM2, STATE_NM1, STATE_N, STATE_NP1 @@ -3183,7 +3083,7 @@ void fast::OpenFAST::getBladeDisplacements(double* bldDefl, double* bldVel, int << brFSIData[iTurbLoc][t].bld_vel[iRunTot*6+3] << "," << brFSIData[iTurbLoc][t].bld_vel[iRunTot*6+4] << "," << brFSIData[iTurbLoc][t].bld_vel[iRunTot*6+5] << std::endl; - + for (int k=0; k < nSize; k++) { bldDefl[iRunTot*6+k] = brFSIData[iTurbLoc][t].bld_def[iRunTot*6+k]; bldVel[iRunTot*6+k] = brFSIData[iTurbLoc][t].bld_vel[iRunTot*6+k]; @@ -3228,7 +3128,6 @@ void fast::OpenFAST::getTowerRefPositions(double* twrRefPos, int iTurbGlob, int void fast::OpenFAST::getTowerDisplacements(double* twrDefl, double* twrVel, int iTurbGlob, fast::timeStep t, int nSize) { -<<<<<<< HEAD int iTurbLoc = get_localTurbNo(iTurbGlob); int nPtsTwr = turbineData[iTurbLoc].nBRfsiPtsTwr; for (int i=0; i < nPtsTwr; i++) { @@ -3236,38 +3135,6 @@ void fast::OpenFAST::getTowerDisplacements(double* twrDefl, double* twrVel, int twrDefl[i*6+j] = brFSIData[iTurbLoc][t].twr_def[i*6+j]; twrVel[i*6+j] = brFSIData[iTurbLoc][t].twr_vel[i*6+j]; } -======= -void fast::OpenFAST::backupVelocityDataFile(int curTimeStep, hid_t & velDataFile) { - - closeVelocityDataFile(curTimeStep, velDataFile); - - std::ifstream source("velDatafile." + std::to_string(worldMPIRank) + ".h5", std::ios::binary); - std::ofstream dest("velDatafile." + std::to_string(worldMPIRank) + ".h5." + std::to_string(curTimeStep) + ".bak", std::ios::binary); - - dest << source.rdbuf(); - source.close(); - dest.close(); - - velDataFile = openVelocityDataFile(false); -} - -void fast::OpenFAST::writeVelocityData(hid_t h5File, int iTurb, int iTimestep, ExtInfw_InputType_t iData, ExtInfw_OutputType_t oData) { - - hsize_t start[3]; start[0] = iTimestep; start[1] = 0; start[2] = 0; - int nVelPts = get_numVelPtsLoc(iTurb) ; - hsize_t count[3]; count[0] = 1; count[1] = nVelPts; count[2] = 6; - - std::vector tmpVelData; - tmpVelData.resize(nVelPts * 6); - - for (int iNode=0 ; iNode < nVelPts; iNode++) { - tmpVelData[iNode*6 + 0] = iData.pxVel[iNode]; - tmpVelData[iNode*6 + 1] = iData.pyVel[iNode]; - tmpVelData[iNode*6 + 2] = iData.pzVel[iNode]; - tmpVelData[iNode*6 + 3] = oData.u[iNode]; - tmpVelData[iNode*6 + 4] = oData.v[iNode]; - tmpVelData[iNode*6 + 5] = oData.w[iNode]; ->>>>>>> OpenFAST/dev } } @@ -3280,7 +3147,6 @@ void fast::OpenFAST::getHubRefPosition(double* hubRefPos, int iTurbGlob, int nSi } -<<<<<<< HEAD void fast::OpenFAST::getHubDisplacement(double* hubDefl, double* hubVel, int iTurbGlob, fast::timeStep t, int nSize) { int iTurbLoc = get_localTurbNo(iTurbGlob); @@ -3361,7 +3227,7 @@ void fast::OpenFAST::setUniformXBladeForces(double loadX) { int nBldPts = turbineData[iTurb].nBRfsiPtsBlade[iBlade]; dr[iNode] = 0.5*(brFSIData[iTurb][3].bld_rloc[iNode+1] - brFSIData[iTurb][3].bld_rloc[iNode]); iNode++; - + for(int i=1; i < nBldPts-1; i++) { dr[iNode] = 0.5*(brFSIData[iTurb][3].bld_rloc[iNode+1] - brFSIData[iTurb][3].bld_rloc[iNode-1]); iNode++; @@ -3375,14 +3241,6 @@ void fast::OpenFAST::setUniformXBladeForces(double loadX) { setBladeForces(fsiForceBlade, iTurbGlob, fast::STATE_NP1); -======= -void fast::OpenFAST::applyVelocityData(int iPrestart, int iTurb, ExtInfw_OutputType_t cDriver_Output_to_FAST, std::vector & velData) { - int nVelPts = get_numVelPtsLoc(iTurb); - for (int j = 0; j < nVelPts; j++){ - cDriver_Output_to_FAST.u[j] = velData[(iPrestart*nVelPts+j)*6 + 3]; - cDriver_Output_to_FAST.v[j] = velData[(iPrestart*nVelPts+j)*6 + 4]; - cDriver_Output_to_FAST.w[j] = velData[(iPrestart*nVelPts+j)*6 + 5]; ->>>>>>> OpenFAST/dev } } diff --git a/modules/externalinflow/src/ExternalInflow_Registry.txt b/modules/externalinflow/src/ExternalInflow_Registry.txt index e066d5c414..e5659ed467 100644 --- a/modules/externalinflow/src/ExternalInflow_Registry.txt +++ b/modules/externalinflow/src/ExternalInflow_Registry.txt @@ -54,9 +54,15 @@ typedef ExternalInflow/ExtInfw ParameterType IntKi NodeClusterType - typedef ^ InputType ReKi pxVel {:} - - "x position of velocity interface (Aerodyn) nodes" "m" typedef ^ InputType ReKi pyVel {:} - - "y position of velocity interface (Aerodyn) nodes" "m" typedef ^ InputType ReKi pzVel {:} - - "z position of velocity interface (Aerodyn) nodes" "m" +typedef ^ InputType ReKi pxdotVel {:} - - "x of velocity interface (Aerodyn) nodes" "m" +typedef ^ InputType ReKi pydotVel {:} - - "y position of velocity interface (Aerodyn) nodes" "m" +typedef ^ InputType ReKi pzdotVel {:} - - "z position of velocity interface (Aerodyn) nodes" "m" typedef ^ InputType ReKi pxForce {:} - - "x position of actuator force nodes" "m" typedef ^ InputType ReKi pyForce {:} - - "y position of actuator force nodes" "m" typedef ^ InputType ReKi pzForce {:} - - "z position of actuator force nodes" "m" +typedef ^ InputType ReKi pxdotForce {:} - - "x velocity of actuator force nodes" "m/s" +typedef ^ InputType ReKi pydotForce {:} - - "y velocity of actuator force nodes" "m/s" +typedef ^ InputType ReKi pzdotForce {:} - - "z velocity of actuator force nodes" "m/s" typedef ^ InputType ReKi xdotForce {:} - - "x velocity of actuator force nodes" "m/s" typedef ^ InputType ReKi ydotForce {:} - - "y velocity of actuator force nodes" "m/s" typedef ^ InputType ReKi zdotForce {:} - - "z velocity of actuator force nodes" "m/s" diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 38b93fa258..247137d84d 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -508,14 +508,14 @@ subroutine FAST_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, NumOuts_c, d end subroutine FAST_Restart !================================================================================================================================== -subroutine FAST_BR_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, NumBl_c, & +subroutine FAST_ExtLoads_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, NumBl_c, & az_blend_mean_c, az_blend_delta_c, vel_mean_c, wind_dir_c, z_ref_c, shear_exp_c, & - ExtLd_Input_from_FAST, ExtLd_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_BR_CFD_Init') -!DEC$ ATTRIBUTES DLLEXPORT::FAST_BR_CFD_Init + ExtLd_Input_from_FAST, ExtLd_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtLoads_Init') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_ExtLoads_Init IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Init -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Init +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtLoads_Init +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtLoads_Init #endif INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number REAL(C_DOUBLE), INTENT(IN ) :: TMax @@ -546,7 +546,7 @@ subroutine FAST_BR_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, TYPE(FAST_ExternInitType) :: ExternInitData INTEGER(IntKi) :: CompLoadsType - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_BR_CFD_Init' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_ExtLoads_Init' ! transfer the character array from C to a Fortran string: InputFileName = TRANSFER( InputFileName_c, InputFileName ) @@ -604,72 +604,68 @@ subroutine FAST_BR_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, ErrStat_c = ErrStat ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) -end subroutine FAST_BR_CFD_Init - +end subroutine FAST_ExtLoads_Init !================================================================================================================================== -subroutine FAST_AL_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, NumSC2CtrlGlob, NumSC2Ctrl, NumCtrl2SC, InitSCOutputsGlob, InitSCOutputsTurbine, & - NumActForcePtsBlade, NumActForcePtsTower, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, InflowType, NumBl_c, NumBlElem_c, NumTwrElem_c, & - ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_AL_CFD_Init') -!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_Init +subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, NumSC2CtrlGlob, NumSC2Ctrl, NumCtrl2SC, InitSCOutputsGlob, InitSCOutputsTurbine, NumActForcePtsBlade, NumActForcePtsTower, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, InflowType, NumBl_c, NumBlElem_c, NumTwrElem_c, NodeClusterType_c, & + ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtInfw_Init') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Init -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Init +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Init +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Init #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - REAL(C_DOUBLE), INTENT(IN ) :: TMax - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) - INTEGER(C_INT), INTENT(IN ) :: TurbID ! Need not be same as iTurb - INTEGER(C_INT), INTENT(IN ) :: NumSC2CtrlGlob ! Supercontroller global outputs = controller global inputs + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + REAL(C_DOUBLE), INTENT(IN ) :: TMax + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) + INTEGER(C_INT), INTENT(IN ) :: TurbID ! Need not be same as iTurb CHARACTER(KIND=C_CHAR), INTENT( OUT) :: OutFileRoot_c(IntfStrLen) ! Root of output and restart file name - INTEGER(C_INT), INTENT(IN ) :: NumSC2Ctrl ! Supercontroller outputs = controller inputs - INTEGER(C_INT), INTENT(IN ) :: NumCtrl2SC ! controller outputs = Supercontroller inputs - REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsGlob (*) ! Initial Supercontroller global outputs = controller inputs - REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsTurbine (*) ! Initial Supercontroller turbine specific outputs = controller inputs - INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsBlade ! number of actuator line force points in blade - INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsTower ! number of actuator line force points in tower - REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) - REAL(C_DOUBLE), INTENT(IN ) :: dtDriver_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_c - INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c - INTEGER(C_INT), INTENT( OUT) :: InflowType ! inflow type - 1 = From Inflow module, 2 = External - INTEGER(C_INT), INTENT( OUT) :: NumBl_c - INTEGER(C_INT), INTENT( OUT) :: NumBlElem_c - INTEGER(C_INT), INTENT( OUT) :: NumTwrElem_c - TYPE(ExtInfw_InputType_C), INTENT( OUT) :: ExtInfw_Input_from_FAST - TYPE(ExtInfw_OutputType_C),INTENT( OUT) :: ExtInfw_Output_to_FAST + INTEGER(C_INT), INTENT(IN ) :: NumSC2CtrlGlob ! Supercontroller global outputs = controller global inputs + INTEGER(C_INT), INTENT(IN ) :: NumSC2Ctrl ! Supercontroller outputs = controller inputs + INTEGER(C_INT), INTENT(IN ) :: NumCtrl2SC ! controller outputs = Supercontroller inputs + REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsGlob (*) ! Initial Supercontroller global outputs = controller inputs + REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsTurbine (*) ! Initial Supercontroller turbine specific outputs = controller inputs + INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsBlade ! number of actuator line force points in blade + INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsTower ! number of actuator line force points in tower + INTEGER(C_INT), INTENT(IN ):: NodeClusterType_c + REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + REAL(C_DOUBLE), INTENT(IN ) :: dtDriver_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: InflowType ! inflow type - 1 = From Inflow module, 2 = External + INTEGER(C_INT), INTENT( OUT) :: NumBl_c + INTEGER(C_INT), INTENT( OUT) :: NumBlElem_c + INTEGER(C_INT), INTENT( OUT) :: NumTwrElem_c + TYPE(ExtInfw_InputType_C), INTENT(INOUT) :: ExtInfw_Input_from_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes + TYPE(ExtInfw_OutputType_C),INTENT(INOUT) :: ExtInfw_Output_to_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local - CHARACTER(IntfStrLen) :: InputFileName - INTEGER(C_INT) :: i + CHARACTER(IntfStrLen) :: InputFileName + INTEGER(C_INT) :: i TYPE(FAST_ExternInitType) :: ExternInitData - - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_CFD_Init' - - ! transfer the character array from C to a Fortran string: + + ! transfer the character array from C to a Fortran string: InputFileName = TRANSFER( InputFileName_c, InputFileName ) I = INDEX(InputFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) InputFileName = InputFileName(1:I) ! remove it - - ! initialize variables: - n_t_global = 0 + + ! initialize variables: + n_t_global = 0 ErrStat = ErrID_None ErrMsg = "" - + NumBl_c = 0 ! initialize here in case of error NumBlElem_c = 0 ! initialize here in case of error - + ExternInitData%TMax = TMax ExternInitData%TurbineID = TurbID ExternInitData%TurbinePos = TurbPosn ExternInitData%SensorType = SensorType_None ExternInitData%NumCtrl2SC = NumCtrl2SC ExternInitData%NumSC2CtrlGlob = NumSC2CtrlGlob - + if ( NumSC2CtrlGlob > 0 ) then CALL AllocAry( ExternInitData%fromSCGlob, NumSC2CtrlGlob, 'ExternInitData%fromSCGlob', ErrStat, ErrMsg) IF (FAILED()) RETURN @@ -678,7 +674,7 @@ subroutine FAST_AL_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, ExternInitData%fromSCGlob(i) = InitScOutputsGlob(i) end do end if - + ExternInitData%NumSC2Ctrl = NumSC2Ctrl if ( NumSC2Ctrl > 0 ) then CALL AllocAry( ExternInitData%fromSC, NumSC2Ctrl, 'ExternInitData%fromSC', ErrStat, ErrMsg) @@ -688,45 +684,33 @@ subroutine FAST_AL_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, ExternInitData%fromSC(i) = InitScOutputsTurbine(i) end do end if - + ExternInitData%NumActForcePtsBlade = NumActForcePtsBlade ExternInitData%NumActForcePtsTower = NumActForcePtsTower ExternInitData%DTdriver = dtDriver_c + ExternInitData%NodeClusterType = NodeClusterType_c - CALL FAST_InitializeAll_T( t_initial, 1_IntKi, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) + CALL FAST_InitializeAll_T( t_initial, iTurb, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) ! set values for return to ExternalInflow - if (ErrStat .ne. ErrID_None) then - AbortErrLev_c = AbortErrLev - ErrStat_c = ErrStat - ErrMsg_c = TRANSFER( TRIM(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) - return - end if - - dt_c = Turbine(iTurb)%p_FAST%dt - - InflowType = Turbine(iTurb)%p_FAST%CompInflow - - if ( (InflowType == 3) .and. (NumActForcePtsBlade .eq. 0) .and. (NumActForcePtsTower .eq. 0) ) then - CALL SetErrStat(ErrID_Warn, "Number of actuator points is zero when inflow type is 2. Mapping of loads may not work. ", ErrStat, ErrMsg, RoutineName ) - end if - - if ( (InflowType .ne. 3) .and. ((NumActForcePtsBlade .ne. 0) .or. (NumActForcePtsTower .ne. 0)) ) then - !!FAST reassigns CompInflow after reading it to a module number based on an internal list in the FAST_Registry. So 2 in input file becomes 3 inside the code. - CALL SetErrStat(ErrID_Fatal, "Number of requested actuator points is non-zero when inflow type is not 2. Please set number of actuator points to zero when induction is turned on.", ErrStat, ErrMsg, RoutineName ) - ErrStat_c = ErrStat - ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) - return - end if - + AbortErrLev_c = AbortErrLev + dt_c = Turbine(iTurb)%p_FAST%dt + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + + IF ( ErrStat >= AbortErrLev ) THEN + CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) + RETURN + END IF + call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) - - ! 7-Sep-2015: OpenFAST doesn't restrict the number of nodes on each blade mesh to be the same, so if this DOES ever change, - ! we'll need to make ExternalInflow less tied to the AeroDyn mapping. - IF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD14) THEN + + ! 7-Sep-2015: Sang wants these integers for the ExternalInflow mapping, which is tied to the AeroDyn nodes. FAST doesn't restrict the number of nodes on each + ! blade mesh to be the same, so if this DOES ever change, we'll need to make ExternalInflow less tied to the AeroDyn mapping. + IF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD14) THEN NumBl_c = SIZE(Turbine(iTurb)%AD14%Input(1)%InputMarkers) NumBlElem_c = Turbine(iTurb)%AD14%Input(1)%InputMarkers(1)%Nnodes - NumTwrElem_c = 0 ! Don't care about Aerodyn14 anymore ELSEIF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD) THEN IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors)) THEN IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion)) THEN @@ -736,43 +720,34 @@ subroutine FAST_AL_CFD_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, IF (NumBl_c > 0) THEN NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes END IF -!FIXME: need some checks on this. If the Tower mesh is not initialized, this will be garbage - NumTwrElem_c = Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Nnodes - ELSE - NumBl_c = 0 - NumBlElem_c = 0 - NumTwrElem_c = 0 END IF OutFileRoot_c = TRANSFER( trim(Turbine(iTurb)%p_FAST%OutFileRoot)//C_NULL_CHAR, OutFileRoot_c ) - - ErrStat_c = ErrStat - ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) - - contains + +contains LOGICAL FUNCTION FAILED() - - FAILED = ErrStat >= AbortErrLev - - IF (ErrStat > 0) THEN - CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) - - IF ( FAILED ) THEN - - AbortErrLev_c = AbortErrLev - ErrStat_c = ErrStat - ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR - ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - - !IF (ALLOCATED(Turbine)) DEALLOCATE(Turbine) - ! bjj: if there is an error, the driver should call FAST_DeallocateTurbines() instead of putting this deallocate statement here - END IF - END IF - - + + FAILED = ErrStat >= AbortErrLev + + IF (ErrStat > 0) THEN + CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) + + IF ( FAILED ) THEN + + AbortErrLev_c = AbortErrLev + ErrStat_c = ErrStat + ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR + ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + + !IF (ALLOCATED(Turbine)) DEALLOCATE(Turbine) + ! bjj: if there is an error, the driver should call FAST_DeallocateTurbines() instead of putting this deallocate statement here + END IF + END IF + + END FUNCTION FAILED +end subroutine -end subroutine FAST_AL_CFD_Init !================================================================================================================================== subroutine FAST_CFD_Solution0(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Solution0') IMPLICIT NONE @@ -818,107 +793,88 @@ subroutine FAST_CFD_InitIOarrays_SS(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='F end subroutine FAST_CFD_InitIOarrays_SS !================================================================================================================================== -subroutine FAST_AL_CFD_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, InflowType, numblades_c, & - numElementsPerBlade_c, numElementsTower_c, n_t_global_c, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, & - SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_AL_CFD_Restart') -!DEC$ ATTRIBUTES DLLEXPORT::FAST_AL_CFD_Restart +subroutine FAST_ExtInfw_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, numblades_c, numElementsPerBlade_c, numElementsTower_c, n_t_global_c, & + ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtInfw_Restart') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_AL_CFD_Restart -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_AL_CFD_Restart +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Restart +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Restart #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) - INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c - INTEGER(C_INT), INTENT( OUT) :: numblades_c - INTEGER(C_INT), INTENT( OUT) :: numElementsPerBlade_c - INTEGER(C_INT), INTENT( OUT) :: numElementsTower_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_c - INTEGER(C_INT), INTENT( OUT) :: InflowType - INTEGER(C_INT), INTENT( OUT) :: n_t_global_c - TYPE(ExtInfw_InputType_C), INTENT( OUT) :: ExtInfw_Input_from_FAST - TYPE(ExtInfw_OutputType_C),INTENT( OUT) :: ExtInfw_Output_to_FAST + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT( OUT) :: numblades_c + INTEGER(C_INT), INTENT( OUT) :: numElementsPerBlade_c + INTEGER(C_INT), INTENT( OUT) :: numElementsTower_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: n_t_global_c + TYPE(ExtInfw_InputType_C), INTENT(INOUT) :: ExtInfw_Input_from_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes + TYPE(ExtInfw_OutputType_C),INTENT(INOUT) :: ExtInfw_Output_to_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local variables - INTEGER(C_INT) :: NumOuts_c - CHARACTER(IntfStrLen) :: CheckpointRootName + INTEGER(C_INT) :: NumOuts_c + CHARACTER(IntfStrLen) :: CheckpointRootName INTEGER(IntKi) :: I INTEGER(IntKi) :: Unit REAL(DbKi) :: t_initial_out INTEGER(IntKi) :: NumTurbines_out - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' - + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' + CALL NWTC_Init() - ! transfer the character array from C to a Fortran string: + ! transfer the character array from C to a Fortran string: CheckpointRootName = TRANSFER( CheckpointRootName_c, CheckpointRootName ) I = INDEX(CheckpointRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) CheckpointRootName = CheckpointRootName(1:I) ! remove it - + Unit = -1 CALL FAST_RestoreFromCheckpoint_T(t_initial_out, n_t_global, NumTurbines_out, Turbine(iTurb), CheckpointRootName, ErrStat, ErrMsg, Unit ) - + ! check that these are valid: IF (t_initial_out /= t_initial) CALL SetErrStat(ErrID_Fatal, "invalid value of t_initial.", ErrStat, ErrMsg, RoutineName ) IF (NumTurbines_out /= 1) CALL SetErrStat(ErrID_Fatal, "invalid value of NumTurbines.", ErrStat, ErrMsg, RoutineName ) - - ! transfer Fortran variables to C: + + ! transfer Fortran variables to C: n_t_global_c = n_t_global - AbortErrLev_c = AbortErrLev - NumOuts_c = min(MAXOUTPUTS, 1 + SUM( Turbine(iTurb)%y_FAST%numOuts )) ! includes time - + AbortErrLev_c = AbortErrLev + NumOuts_c = min(MAXOUTPUTS, SUM( Turbine(iTurb)%y_FAST%numOuts )) ! includes time if (allocated(Turbine(iTurb)%ad%p%rotors)) then ! this might not be allocated if we had an error earlier numBlades_c = Turbine(iTurb)%ad%p%rotors(1)%numblades numElementsPerBlade_c = Turbine(iTurb)%ad%p%rotors(1)%numblnds ! I'm not sure if FASTv8 can handle different number of blade nodes for each blade. - numElementsTower_c = Turbine(iTurb)%ad%y%rotors(1)%TowerLoad%Nnodes else numBlades_c = 0 numElementsPerBlade_c = 0 - numElementsTower_c = 0 end if - dt_c = Turbine(iTurb)%p_FAST%dt - + numElementsTower_c = Turbine(iTurb)%ad%p%rotors(1)%numtwrnds + + dt_c = Turbine(iTurb)%p_FAST%dt + ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -#ifdef CONSOLE_FILE - if (ErrStat .ne. ErrID_None) call wrscr1(trim(ErrMsg)) -#endif +#ifdef CONSOLE_FILE + if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) +#endif if (ErrStat >= AbortErrLev) return - - call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) - - InflowType = Turbine(iTurb)%p_FAST%CompInflow - - if (ErrStat .ne. ErrID_None) then - call wrscr1(trim(ErrMsg)) - return - end if - - if (dt_c == Turbine(iTurb)%p_FAST%dt) then - CALL SetErrStat(ErrID_Fatal, "Time step specified in C++ API does not match with time step specified in OpenFAST input file.", ErrStat, ErrMsg, RoutineName ) - return - end if - + call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) -end subroutine FAST_AL_CFD_Restart - +end subroutine FAST_ExtInfw_Restart !================================================================================================================================== -subroutine FAST_BR_CFD_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, numblades_c, & +subroutine FAST_ExtLoads_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, numblades_c, & n_t_global_c, ExtLd_Input_from_FAST, ExtLd_Output_to_FAST, & - SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_BR_CFD_Restart') -!DEC$ ATTRIBUTES DLLEXPORT::FAST_BR_CFD_Restart + SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtLoads_Restart') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_ExtLoads_Restart IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!DEC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Restart -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_BR_CFD_Restart +!DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtLoads_Restart +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtLoads_Restart #endif INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) @@ -988,7 +944,7 @@ subroutine FAST_BR_CFD_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, ErrStat_c = ErrStat ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) -end subroutine FAST_BR_CFD_Restart +end subroutine FAST_ExtLoads_Restart !================================================================================================================================== subroutine SetExtLoads_pointers(iTurb, ExtLd_iFromOF, ExtLd_oToOF) diff --git a/modules/openfast-library/src/FAST_Library.h b/modules/openfast-library/src/FAST_Library.h index aa8ccb6005..51269339f0 100644 --- a/modules/openfast-library/src/FAST_Library.h +++ b/modules/openfast-library/src/FAST_Library.h @@ -16,24 +16,19 @@ EXTERNAL_ROUTINE void FAST_AllocateTurbines(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_DeallocateTurbines(int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_AL_CFD_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, - double * dt, int * InflowType, int * NumBl, int * NumBlElem, int * NumTwrElem, int * n_t_global, - ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, - SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, - int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_AL_CFD_Init(int * iTurb, double *TMax, const char *InputFileName, - int * TurbineID, char *OutFileRoot, - int * NumSC2CtrlGlob, int * NumSC2Ctrl, int * NumCtrl2SC, - float * initSCInputsGlob, float * initSCInputsTurbine, - int * NumActForcePtsBlade, int * NumActForcePtsTower, float * TurbinePosition, - int *AbortErrLev, double * dtDriver, double * dt, int * InflowType, - int * NumBl, int * NumBlElem, int * NumTwrElem, - ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, - SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, - int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_ExtInfw_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * InflowType, + int * NumBl, int * NumBlElem, int * NumTwrElem, int * n_t_global, + ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, + int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_ExtInfw_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, char *OutFileRoot, + int * NumSC2CtrlGlob, int * NumSC2Ctrl, int * NumCtrl2SC, float * initSCInputsGlob, float * initSCInputsTurbine, + int * NumActForcePtsBlade, int * NumActForcePtsTower, float * TurbinePosition, int *AbortErrLev, + double * dtDriver, double * dt, int * InflowType, int * NumBl, int * NumBlElem, int * NumTwrElem, int * NodeClusterType, + ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, + int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_BR_CFD_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * n_t_global, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_BR_CFD_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, char *OutFileRoot, float * TurbinePosition, int *AbortErrLev, double * dtDriver, double * dt, int * NumBl, double * az_blend_mean, double * az_blend_delta, double * vel_mean, double * wind_dir, double * z_ref, double * shear_exp, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_ExtLoads_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * n_t_global, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_ExtLoads_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, char *OutFileRoot, float * TurbinePosition, int *AbortErrLev, double * dtDriver, double * dt, int * NumBl, double * az_blend_mean, double * az_blend_delta, double * vel_mean, double * wind_dir, double * z_ref, double * shear_exp, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_Solution0(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_InitIOarrays_SS(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_Prework(int * iTurb, int *ErrStat, char *ErrMsg); From c85a0c89135456eb4460df41836320dd5c2a2a18 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 4 Dec 2023 14:15:49 -0700 Subject: [PATCH 19/91] AD15: memory leak, fix in FVW also --- modules/aerodyn/src/FVW.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/aerodyn/src/FVW.f90 b/modules/aerodyn/src/FVW.f90 index 616d96ffc7..f3cf5fb330 100644 --- a/modules/aerodyn/src/FVW.f90 +++ b/modules/aerodyn/src/FVW.f90 @@ -757,6 +757,7 @@ end subroutine RollBackPreviousTimeStep subroutine CleanUp() call FVW_DestroyConstrState(z_guess, ErrStat2, ErrMsg2); if(Failed()) return + call FVW_DestroyInput(uInterp, ErrStat2, ErrMsg2); if(Failed()) return end subroutine logical function Failed() From a233bc142bf385368b38382e5b637475ebc6e9b2 Mon Sep 17 00:00:00 2001 From: Ganesh Vijayakumar Date: Mon, 4 Dec 2023 15:52:54 -0700 Subject: [PATCH 20/91] Addressing some issues found by Andy --- .../src/ExternalInflow_Registry.txt | 3 - modules/openfast-library/src/FAST_Library.f90 | 436 +++++++++--------- 2 files changed, 230 insertions(+), 209 deletions(-) diff --git a/modules/externalinflow/src/ExternalInflow_Registry.txt b/modules/externalinflow/src/ExternalInflow_Registry.txt index e5659ed467..8f32087734 100644 --- a/modules/externalinflow/src/ExternalInflow_Registry.txt +++ b/modules/externalinflow/src/ExternalInflow_Registry.txt @@ -54,9 +54,6 @@ typedef ExternalInflow/ExtInfw ParameterType IntKi NodeClusterType - typedef ^ InputType ReKi pxVel {:} - - "x position of velocity interface (Aerodyn) nodes" "m" typedef ^ InputType ReKi pyVel {:} - - "y position of velocity interface (Aerodyn) nodes" "m" typedef ^ InputType ReKi pzVel {:} - - "z position of velocity interface (Aerodyn) nodes" "m" -typedef ^ InputType ReKi pxdotVel {:} - - "x of velocity interface (Aerodyn) nodes" "m" -typedef ^ InputType ReKi pydotVel {:} - - "y position of velocity interface (Aerodyn) nodes" "m" -typedef ^ InputType ReKi pzdotVel {:} - - "z position of velocity interface (Aerodyn) nodes" "m" typedef ^ InputType ReKi pxForce {:} - - "x position of actuator force nodes" "m" typedef ^ InputType ReKi pyForce {:} - - "y position of actuator force nodes" "m" typedef ^ InputType ReKi pzForce {:} - - "z position of actuator force nodes" "m" diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 247137d84d..5de7b339f8 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -1,53 +1,53 @@ -! FAST_Library.f90 +! FAST_Library.f90 ! ! FUNCTIONS/SUBROUTINES exported from FAST_Library.dll: -! FAST_Start - subroutine -! FAST_Update - subroutine -! FAST_End - subroutine -! +! FAST_Start - subroutine +! FAST_Update - subroutine +! FAST_End - subroutine +! ! DO NOT REMOVE or MODIFY LINES starting with "!DEC$" or "!GCC$" ! !DEC$ specifies attributes for IVF and !GCC$ specifies attributes for gfortran ! -!================================================================================================================================== +!================================================================================================================================== MODULE FAST_Data USE, INTRINSIC :: ISO_C_Binding USE FAST_Subs ! all of the ModuleName and ModuleName_types modules are inherited from FAST_Subs - + IMPLICIT NONE SAVE - + ! Local parameters: REAL(DbKi), PARAMETER :: t_initial = 0.0_DbKi ! Initial time - INTEGER(IntKi) :: NumTurbines + INTEGER(IntKi) :: NumTurbines INTEGER, PARAMETER :: IntfStrLen = 1025 ! length of strings through the C interface INTEGER(IntKi), PARAMETER :: MAXOUTPUTS = 4000 ! Maximum number of outputs INTEGER(IntKi), PARAMETER :: MAXInitINPUTS = 53 ! Maximum number of initialization values from Simulink INTEGER(IntKi), PARAMETER :: NumFixedInputs = 51 - - + + ! Global (static) data: TYPE(FAST_TurbineType), ALLOCATABLE :: Turbine(:) ! Data for each turbine INTEGER(IntKi) :: n_t_global ! simulation time step, loop counter for global (FAST) simulation INTEGER(IntKi) :: ErrStat ! Error status CHARACTER(IntfStrLen-1) :: ErrMsg ! Error message (this needs to be static so that it will print in Matlab's mex library) - + contains -!================================================================================================================================== +!================================================================================================================================== subroutine FAST_AllocateTurbines(nTurbines, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_AllocateTurbines') - IMPLICIT NONE + IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: FAST_AllocateTurbines !GCC$ ATTRIBUTES DLLEXPORT :: FAST_AllocateTurbines #endif INTEGER(C_INT), INTENT(IN ) :: nTurbines INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + if (nTurbines > 0) then NumTurbines = nTurbines end if - + if (nTurbines > 10) then call wrscr1('Number of turbines is > 10! Are you sure you have enough memory?') call wrscr1('Proceeding anyway.') @@ -63,7 +63,7 @@ subroutine FAST_AllocateTurbines(nTurbines, ErrStat_c, ErrMsg_c) BIND (C, NAME=' ErrMsg = " "//C_NULL_CHAR end if ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - + end subroutine FAST_AllocateTurbines !================================================================================================================================== subroutine FAST_DeallocateTurbines(ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_DeallocateTurbines') @@ -84,35 +84,35 @@ subroutine FAST_DeallocateTurbines(ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_Deal end subroutine !================================================================================================================================== subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, dt_out_c, tmax_c, ErrStat_c, ErrMsg_c, ChannelNames_c, TMax, InitInpAry) BIND (C, NAME='FAST_Sizes') - IMPLICIT NONE + IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: FAST_Sizes !GCC$ ATTRIBUTES DLLEXPORT :: FAST_Sizes #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) - INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c - INTEGER(C_INT), INTENT( OUT) :: NumOuts_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_out_c + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT( OUT) :: NumOuts_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_out_c REAL(C_DOUBLE), INTENT( OUT) :: tmax_c - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ChannelNames_c(ChanLen*MAXOUTPUTS+1) - REAL(C_DOUBLE),OPTIONAL,INTENT(IN ) :: TMax - REAL(C_DOUBLE),OPTIONAL,INTENT(IN ) :: InitInpAry(MAXInitINPUTS) - + REAL(C_DOUBLE),OPTIONAL,INTENT(IN ) :: TMax + REAL(C_DOUBLE),OPTIONAL,INTENT(IN ) :: InitInpAry(MAXInitINPUTS) + ! local - CHARACTER(IntfStrLen) :: InputFileName + CHARACTER(IntfStrLen) :: InputFileName INTEGER :: i, j, k TYPE(FAST_ExternInitType) :: ExternInitData - - ! transfer the character array from C to a Fortran string: + + ! transfer the character array from C to a Fortran string: InputFileName = TRANSFER( InputFileName_c, InputFileName ) I = INDEX(InputFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) InputFileName = InputFileName(1:I) ! remove it - - ! initialize variables: + + ! initialize variables: n_t_global = 0 IF (PRESENT(TMax) .AND. .NOT. PRESENT(InitInpAry)) THEN @@ -130,18 +130,18 @@ subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, dt ExternInitData%TurbinePos = 0.0_ReKi ! turbine position is at the origin ExternInitData%NumCtrl2SC = 0 ExternInitData%NumSC2Ctrl = 0 - ExternInitData%SensorType = NINT(InitInpAry(1)) + ExternInitData%SensorType = NINT(InitInpAry(1)) ! -- MATLAB Integration -- ! Make sure fast farm integration is false ExternInitData%FarmIntegration = .false. ExternInitData%WaveFieldMod = 0 - + IF ( NINT(InitInpAry(2)) == 1 ) THEN ExternInitData%LidRadialVel = .true. ELSE ExternInitData%LidRadialVel = .false. END IF - + CALL FAST_InitializeAll_T( t_initial, iTurb, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData) ELSE @@ -149,8 +149,8 @@ subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, dt CALL FAST_InitializeAll_T( t_initial, iTurb, Turbine(iTurb), ErrStat, ErrMsg, InputFileName) END IF - - AbortErrLev_c = AbortErrLev + + AbortErrLev_c = AbortErrLev NumOuts_c = min(MAXOUTPUTS, SUM( Turbine(iTurb)%y_FAST%numOuts )) dt_c = Turbine(iTurb)%p_FAST%dt dt_out_c = Turbine(iTurb)%p_FAST%DT_Out @@ -159,11 +159,11 @@ subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, dt ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - -#ifdef CONSOLE_FILE + +#ifdef CONSOLE_FILE if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) -#endif - +#endif + ! return the names of the output channels IF ( ALLOCATED( Turbine(iTurb)%y_FAST%ChannelNames ) ) then k = 1; @@ -177,71 +177,71 @@ subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, dt ELSE ChannelNames_c = C_NULL_CHAR END IF - + end subroutine FAST_Sizes !================================================================================================================================== subroutine FAST_Start(iTurb, NumInputs_c, NumOutputs_c, InputAry, OutputAry, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_Start') - IMPLICIT NONE + IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: FAST_Start !GCC$ ATTRIBUTES DLLEXPORT :: FAST_Start #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - INTEGER(C_INT), INTENT(IN ) :: NumInputs_c - INTEGER(C_INT), INTENT(IN ) :: NumOutputs_c + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT(IN ) :: NumInputs_c + INTEGER(C_INT), INTENT(IN ) :: NumOutputs_c REAL(C_DOUBLE), INTENT(IN ) :: InputAry(NumInputs_c) REAL(C_DOUBLE), INTENT( OUT) :: OutputAry(NumOutputs_c) - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + - ! local - CHARACTER(IntfStrLen) :: InputFileName + CHARACTER(IntfStrLen) :: InputFileName INTEGER :: i REAL(ReKi) :: Outputs(NumOutputs_c-1) - + INTEGER(IntKi) :: ErrStat2 ! Error status CHARACTER(IntfStrLen-1) :: ErrMsg2 ! Error message (this needs to be static so that it will print in Matlab's mex library) - - ! initialize variables: + + ! initialize variables: n_t_global = 0 !............................................................................................................................... ! Initialization of solver: (calculate outputs based on states at t=t_initial as well as guesses of inputs and constraint states) - !............................................................................................................................... - CALL FAST_Solution0_T(Turbine(iTurb), ErrStat, ErrMsg ) - + !............................................................................................................................... + CALL FAST_Solution0_T(Turbine(iTurb), ErrStat, ErrMsg ) + if (ErrStat <= AbortErrLev) then ! return outputs here, too IF(NumOutputs_c /= SIZE(Turbine(iTurb)%y_FAST%ChannelNames) ) THEN ErrStat = ErrID_Fatal ErrMsg = trim(ErrMsg)//NewLine//"FAST_Start:size of NumOutputs is invalid." ELSE - - CALL FillOutputAry_T(Turbine(iTurb), Outputs) - OutputAry(1) = Turbine(iTurb)%m_FAST%t_global - OutputAry(2:NumOutputs_c) = Outputs + + CALL FillOutputAry_T(Turbine(iTurb), Outputs) + OutputAry(1) = Turbine(iTurb)%m_FAST%t_global + OutputAry(2:NumOutputs_c) = Outputs CALL FAST_Linearize_T(t_initial, 0, Turbine(iTurb), ErrStat2, ErrMsg2) if (ErrStat2 /= ErrID_None) then ErrStat = max(ErrStat,ErrStat2) ErrMsg = TRIM(ErrMsg)//NewLine//TRIM(ErrMsg2) end if - - + + END IF end if - - + + ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - -#ifdef CONSOLE_FILE + +#ifdef CONSOLE_FILE if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) -#endif - +#endif + end subroutine FAST_Start !================================================================================================================================== subroutine FAST_Update(iTurb, NumInputs_c, NumOutputs_c, InputAry, OutputAry, EndSimulationEarly, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_Update') @@ -250,25 +250,25 @@ subroutine FAST_Update(iTurb, NumInputs_c, NumOutputs_c, InputAry, OutputAry, En !DEC$ ATTRIBUTES DLLEXPORT :: FAST_Update !GCC$ ATTRIBUTES DLLEXPORT :: FAST_Update #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - INTEGER(C_INT), INTENT(IN ) :: NumInputs_c - INTEGER(C_INT), INTENT(IN ) :: NumOutputs_c + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT(IN ) :: NumInputs_c + INTEGER(C_INT), INTENT(IN ) :: NumOutputs_c REAL(C_DOUBLE), INTENT(IN ) :: InputAry(NumInputs_c) REAL(C_DOUBLE), INTENT( OUT) :: OutputAry(NumOutputs_c) LOGICAL(C_BOOL), INTENT( OUT) :: EndSimulationEarly - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local variables REAL(ReKi) :: Outputs(NumOutputs_c-1) INTEGER(IntKi) :: i INTEGER(IntKi) :: ErrStat2 ! Error status CHARACTER(IntfStrLen-1) :: ErrMsg2 ! Error message (this needs to be static so that it will print in Matlab's mex library) - + EndSimulationEarly = .FALSE. - IF ( n_t_global > Turbine(iTurb)%p_FAST%n_TMax_m1 ) THEN !finish - + IF ( n_t_global > Turbine(iTurb)%p_FAST%n_TMax_m1 ) THEN !finish + ! we can't continue because we might over-step some arrays that are allocated to the size of the simulation IF (n_t_global == Turbine(iTurb)%p_FAST%n_TMax_m1 + 1) THEN ! we call update an extra time in Simulink, which we can ignore until the time shift with outputs is solved @@ -276,12 +276,12 @@ subroutine FAST_Update(iTurb, NumInputs_c, NumOutputs_c, InputAry, OutputAry, En ErrStat_c = ErrID_None ErrMsg = C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - ELSE + ELSE ErrStat_c = ErrID_Info ErrMsg = "Simulation completed."//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) END IF - + ELSEIF(NumOutputs_c /= SIZE(Turbine(iTurb)%y_FAST%ChannelNames) ) THEN ErrStat_c = ErrID_Fatal ErrMsg = "FAST_Update:size of OutputAry is invalid or FAST has too many outputs."//C_NULL_CHAR @@ -296,7 +296,7 @@ subroutine FAST_Update(iTurb, NumInputs_c, NumOutputs_c, InputAry, OutputAry, En CALL FAST_SetExternalInputs(iTurb, NumInputs_c, InputAry, Turbine(iTurb)%m_FAST) - CALL FAST_Solution_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + CALL FAST_Solution_T( t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) n_t_global = n_t_global + 1 CALL FAST_Linearize_T( t_initial, n_t_global, Turbine(iTurb), ErrStat2, ErrMsg2) @@ -304,26 +304,26 @@ subroutine FAST_Update(iTurb, NumInputs_c, NumOutputs_c, InputAry, OutputAry, En ErrStat = max(ErrStat,ErrStat2) ErrMsg = TRIM(ErrMsg)//NewLine//TRIM(ErrMsg2) end if - + IF ( Turbine(iTurb)%m_FAST%Lin%FoundSteady) THEN EndSimulationEarly = .TRUE. END IF - + ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) END IF ! set the outputs for external code here - CALL FillOutputAry_T(Turbine(iTurb), Outputs) - OutputAry(1) = Turbine(iTurb)%m_FAST%t_global - OutputAry(2:NumOutputs_c) = Outputs + CALL FillOutputAry_T(Turbine(iTurb), Outputs) + OutputAry(1) = Turbine(iTurb)%m_FAST%t_global + OutputAry(2:NumOutputs_c) = Outputs -#ifdef CONSOLE_FILE +#ifdef CONSOLE_FILE if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) -#endif - -end subroutine FAST_Update +#endif + +end subroutine FAST_Update !================================================================================================================================== ! Get the hub's absolute position, rotation velocity, and orientation DCM for the current time step subroutine FAST_HubPosition(iTurb, AbsPosition_c, RotationalVel_c, Orientation_c, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_HubPosition') @@ -369,14 +369,14 @@ subroutine FAST_SetExternalInputs(iTurb, NumInputs_c, InputAry, m_FAST) USE, INTRINSIC :: ISO_C_Binding USE FAST_Types ! USE FAST_Data, only: NumFixedInputs - + IMPLICIT NONE - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - INTEGER(C_INT), INTENT(IN ) :: NumInputs_c + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT(IN ) :: NumInputs_c REAL(C_DOUBLE), INTENT(IN ) :: InputAry(NumInputs_c) ! Inputs from Simulink TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST ! Miscellaneous variables - + ! set the inputs from external code here... ! transfer inputs from Simulink to FAST IF ( NumInputs_c < NumFixedInputs ) RETURN ! This is an error @@ -391,12 +391,12 @@ subroutine FAST_SetExternalInputs(iTurb, NumInputs_c, InputAry, m_FAST) m_FAST%ExternInput%BlAirfoilCom = InputAry(9:11) m_FAST%ExternInput%CableDeltaL = InputAry(12:31) m_FAST%ExternInput%CableDeltaLdot = InputAry(32:51) - + IF ( NumInputs_c > NumFixedInputs ) THEN ! NumFixedInputs is the fixed number of inputs IF ( NumInputs_c == NumFixedInputs + 3 ) & m_FAST%ExternInput%LidarFocus = InputAry(52:54) - END IF - + END IF + end subroutine FAST_SetExternalInputs !================================================================================================================================== subroutine FAST_End(iTurb, StopTheProgram) BIND (C, NAME='FAST_End') @@ -405,11 +405,11 @@ subroutine FAST_End(iTurb, StopTheProgram) BIND (C, NAME='FAST_End') !DEC$ ATTRIBUTES DLLEXPORT :: FAST_End !GCC$ ATTRIBUTES DLLEXPORT :: FAST_End #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number LOGICAL(C_BOOL), INTENT(IN) :: StopTheProgram ! flag indicating if the program should end (false if there are more turbines to end) CALL ExitThisProgram_T( Turbine(iTurb), ErrID_None, LOGICAL(StopTheProgram)) - + end subroutine FAST_End !================================================================================================================================== subroutine FAST_CreateCheckpoint(iTurb, CheckpointRootName_c, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CreateCheckpoint') @@ -418,41 +418,41 @@ subroutine FAST_CreateCheckpoint(iTurb, CheckpointRootName_c, ErrStat_c, ErrMsg_ !DEC$ ATTRIBUTES DLLEXPORT :: FAST_CreateCheckpoint !GCC$ ATTRIBUTES DLLEXPORT :: FAST_CreateCheckpoint #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local - CHARACTER(IntfStrLen) :: CheckpointRootName + CHARACTER(IntfStrLen) :: CheckpointRootName INTEGER(IntKi) :: I INTEGER(IntKi) :: Unit - - - ! transfer the character array from C to a Fortran string: + + + ! transfer the character array from C to a Fortran string: CheckpointRootName = TRANSFER( CheckpointRootName_c, CheckpointRootName ) I = INDEX(CheckpointRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) CheckpointRootName = CheckpointRootName(1:I) ! remove it - + if ( LEN_TRIM(CheckpointRootName) == 0 ) then CheckpointRootName = TRIM(Turbine(iTurb)%p_FAST%OutFileRoot)//'.'//trim( Num2LStr(n_t_global) ) end if - - + + Unit = -1 CALL FAST_CreateCheckpoint_T(t_initial, n_t_global, 1, Turbine(iTurb), CheckpointRootName, ErrStat, ErrMsg, Unit ) - ! transfer Fortran variables to C: + ! transfer Fortran variables to C: ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -#ifdef CONSOLE_FILE +#ifdef CONSOLE_FILE if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) -#endif - -end subroutine FAST_CreateCheckpoint +#endif + +end subroutine FAST_CreateCheckpoint !================================================================================================================================== subroutine FAST_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, NumOuts_c, dt_c, n_t_global_c, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_Restart') IMPLICIT NONE @@ -460,52 +460,52 @@ subroutine FAST_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, NumOuts_c, d !DEC$ ATTRIBUTES DLLEXPORT :: FAST_Restart !GCC$ ATTRIBUTES DLLEXPORT :: FAST_Restart #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) - INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c - INTEGER(C_INT), INTENT( OUT) :: NumOuts_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_c - INTEGER(C_INT), INTENT( OUT) :: n_t_global_c - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT( OUT) :: NumOuts_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: n_t_global_c + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local - CHARACTER(IntfStrLen) :: CheckpointRootName + CHARACTER(IntfStrLen) :: CheckpointRootName INTEGER(IntKi) :: I INTEGER(IntKi) :: Unit REAL(DbKi) :: t_initial_out INTEGER(IntKi) :: NumTurbines_out - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' - - - ! transfer the character array from C to a Fortran string: + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' + + + ! transfer the character array from C to a Fortran string: CheckpointRootName = TRANSFER( CheckpointRootName_c, CheckpointRootName ) I = INDEX(CheckpointRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) CheckpointRootName = CheckpointRootName(1:I) ! remove it - + Unit = -1 CALL FAST_RestoreFromCheckpoint_T(t_initial_out, n_t_global, NumTurbines_out, Turbine(iTurb), CheckpointRootName, ErrStat, ErrMsg, Unit ) - + ! check that these are valid: IF (t_initial_out /= t_initial) CALL SetErrStat(ErrID_Fatal, "invalid value of t_initial.", ErrStat, ErrMsg, RoutineName ) IF (NumTurbines_out /= 1) CALL SetErrStat(ErrID_Fatal, "invalid value of NumTurbines.", ErrStat, ErrMsg, RoutineName ) - - - ! transfer Fortran variables to C: + + + ! transfer Fortran variables to C: n_t_global_c = n_t_global - AbortErrLev_c = AbortErrLev + AbortErrLev_c = AbortErrLev NumOuts_c = min(MAXOUTPUTS, SUM( Turbine(iTurb)%y_FAST%numOuts )) ! includes time - dt_c = Turbine(iTurb)%p_FAST%dt - + dt_c = Turbine(iTurb)%p_FAST%dt + ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -#ifdef CONSOLE_FILE +#ifdef CONSOLE_FILE if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) -#endif - -end subroutine FAST_Restart +#endif + +end subroutine FAST_Restart !================================================================================================================================== subroutine FAST_ExtLoads_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, NumBl_c, & @@ -613,12 +613,12 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c !DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Init !GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Init #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - REAL(C_DOUBLE), INTENT(IN ) :: TMax - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + REAL(C_DOUBLE), INTENT(IN ) :: TMax + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: InputFileName_c(IntfStrLen) INTEGER(C_INT), INTENT(IN ) :: TurbID ! Need not be same as iTurb CHARACTER(KIND=C_CHAR), INTENT( OUT) :: OutFileRoot_c(IntfStrLen) ! Root of output and restart file name - INTEGER(C_INT), INTENT(IN ) :: NumSC2CtrlGlob ! Supercontroller global outputs = controller global inputs + INTEGER(C_INT), INTENT(IN ) :: NumSC2CtrlGlob ! Supercontroller global outputs = controller global inputs INTEGER(C_INT), INTENT(IN ) :: NumSC2Ctrl ! Supercontroller outputs = controller inputs INTEGER(C_INT), INTENT(IN ) :: NumCtrl2SC ! controller outputs = Supercontroller inputs REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsGlob (*) ! Initial Supercontroller global outputs = controller inputs @@ -626,46 +626,48 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsBlade ! number of actuator line force points in blade INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsTower ! number of actuator line force points in tower INTEGER(C_INT), INTENT(IN ):: NodeClusterType_c - REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) + REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c REAL(C_DOUBLE), INTENT(IN ) :: dtDriver_c REAL(C_DOUBLE), INTENT( OUT) :: dt_c INTEGER(C_INT), INTENT( OUT) :: InflowType ! inflow type - 1 = From Inflow module, 2 = External - INTEGER(C_INT), INTENT( OUT) :: NumBl_c - INTEGER(C_INT), INTENT( OUT) :: NumBlElem_c - INTEGER(C_INT), INTENT( OUT) :: NumTwrElem_c + INTEGER(C_INT), INTENT( OUT) :: NumBl_c + INTEGER(C_INT), INTENT( OUT) :: NumBlElem_c + INTEGER(C_INT), INTENT( OUT) :: NumTwrElem_c TYPE(ExtInfw_InputType_C), INTENT(INOUT) :: ExtInfw_Input_from_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes TYPE(ExtInfw_OutputType_C),INTENT(INOUT) :: ExtInfw_Output_to_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local - CHARACTER(IntfStrLen) :: InputFileName - INTEGER(C_INT) :: i + CHARACTER(IntfStrLen) :: InputFileName + INTEGER(C_INT) :: i TYPE(FAST_ExternInitType) :: ExternInitData - - ! transfer the character array from C to a Fortran string: + + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_ExtInfw_Init' + + ! transfer the character array from C to a Fortran string: InputFileName = TRANSFER( InputFileName_c, InputFileName ) I = INDEX(InputFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) InputFileName = InputFileName(1:I) ! remove it - - ! initialize variables: - n_t_global = 0 + + ! initialize variables: + n_t_global = 0 ErrStat = ErrID_None ErrMsg = "" - + NumBl_c = 0 ! initialize here in case of error NumBlElem_c = 0 ! initialize here in case of error - + ExternInitData%TMax = TMax ExternInitData%TurbineID = TurbID ExternInitData%TurbinePos = TurbPosn ExternInitData%SensorType = SensorType_None ExternInitData%NumCtrl2SC = NumCtrl2SC ExternInitData%NumSC2CtrlGlob = NumSC2CtrlGlob - + if ( NumSC2CtrlGlob > 0 ) then CALL AllocAry( ExternInitData%fromSCGlob, NumSC2CtrlGlob, 'ExternInitData%fromSCGlob', ErrStat, ErrMsg) IF (FAILED()) RETURN @@ -674,7 +676,7 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c ExternInitData%fromSCGlob(i) = InitScOutputsGlob(i) end do end if - + ExternInitData%NumSC2Ctrl = NumSC2Ctrl if ( NumSC2Ctrl > 0 ) then CALL AllocAry( ExternInitData%fromSC, NumSC2Ctrl, 'ExternInitData%fromSC', ErrStat, ErrMsg) @@ -684,7 +686,7 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c ExternInitData%fromSC(i) = InitScOutputsTurbine(i) end do end if - + ExternInitData%NumActForcePtsBlade = NumActForcePtsBlade ExternInitData%NumActForcePtsTower = NumActForcePtsTower ExternInitData%DTdriver = dtDriver_c @@ -693,22 +695,36 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c CALL FAST_InitializeAll_T( t_initial, iTurb, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) ! set values for return to ExternalInflow - AbortErrLev_c = AbortErrLev + AbortErrLev_c = AbortErrLev dt_c = Turbine(iTurb)%p_FAST%dt ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - + + InflowType = Turbine(iTurb)%p_FAST%CompInflow + IF ( ErrStat >= AbortErrLev ) THEN CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) RETURN END IF - + + if ( (InflowType == 3) .and. (NumActForcePtsBlade .eq. 0) .and. (NumActForcePtsTower .eq. 0) ) then + CALL SetErrStat(ErrID_Warn, "Number of actuator points is zero when inflow type is 2. Mapping of loads may not work. ", ErrStat, ErrMsg, RoutineName ) + end if + + if ( (InflowType .ne. 3) .and. ((NumActForcePtsBlade .ne. 0) .or. (NumActForcePtsTower .ne. 0)) ) then + !!FAST reassigns CompInflow after reading it to a module number based on an internal list in the FAST_Registry. So 2 in input file becomes 3 inside the code. + CALL SetErrStat(ErrID_Fatal, "Number of requested actuator points is non-zero when inflow type is not 2. Please set number of actuator points to zero when induction is turned on.", ErrStat, ErrMsg, RoutineName ) + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if + call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) - - ! 7-Sep-2015: Sang wants these integers for the ExternalInflow mapping, which is tied to the AeroDyn nodes. FAST doesn't restrict the number of nodes on each + + ! 7-Sep-2015: Sang wants these integers for the ExternalInflow mapping, which is tied to the AeroDyn nodes. FAST doesn't restrict the number of nodes on each ! blade mesh to be the same, so if this DOES ever change, we'll need to make ExternalInflow less tied to the AeroDyn mapping. - IF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD14) THEN + IF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD14) THEN NumBl_c = SIZE(Turbine(iTurb)%AD14%Input(1)%InputMarkers) NumBlElem_c = Turbine(iTurb)%AD14%Input(1)%InputMarkers(1)%Nnodes ELSEIF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD) THEN @@ -720,33 +736,41 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c IF (NumBl_c > 0) THEN NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes END IF + NumTwrElem_c = Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Nnodes + ELSE + NumBl_c = 0 + NumBlElem_c = 0 + NumTwrElem_c = 0 END IF + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + OutFileRoot_c = TRANSFER( trim(Turbine(iTurb)%p_FAST%OutFileRoot)//C_NULL_CHAR, OutFileRoot_c ) - + contains LOGICAL FUNCTION FAILED() - + FAILED = ErrStat >= AbortErrLev - + IF (ErrStat > 0) THEN CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) - + IF ( FAILED ) THEN - + AbortErrLev_c = AbortErrLev ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) - + !IF (ALLOCATED(Turbine)) DEALLOCATE(Turbine) ! bjj: if there is an error, the driver should call FAST_DeallocateTurbines() instead of putting this deallocate statement here END IF END IF - - + + END FUNCTION FAILED -end subroutine +end subroutine !================================================================================================================================== subroutine FAST_CFD_Solution0(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Solution0') @@ -800,46 +824,46 @@ subroutine FAST_ExtInfw_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c !DEC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Restart !GCC$ ATTRIBUTES DLLEXPORT :: FAST_ExtInfw_Restart #endif - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) - INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + CHARACTER(KIND=C_CHAR), INTENT(IN ) :: CheckpointRootName_c(IntfStrLen) + INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c INTEGER(C_INT), INTENT( OUT) :: numblades_c INTEGER(C_INT), INTENT( OUT) :: numElementsPerBlade_c INTEGER(C_INT), INTENT( OUT) :: numElementsTower_c - REAL(C_DOUBLE), INTENT( OUT) :: dt_c - INTEGER(C_INT), INTENT( OUT) :: n_t_global_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_c + INTEGER(C_INT), INTENT( OUT) :: n_t_global_c TYPE(ExtInfw_InputType_C), INTENT(INOUT) :: ExtInfw_Input_from_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes TYPE(ExtInfw_OutputType_C),INTENT(INOUT) :: ExtInfw_Output_to_FAST !INTENT(INOUT) instead of INTENT(OUT) to avoid gcc compiler warnings about variable tracking sizes TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST - INTEGER(C_INT), INTENT( OUT) :: ErrStat_c - CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - + INTEGER(C_INT), INTENT( OUT) :: ErrStat_c + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) + ! local variables - INTEGER(C_INT) :: NumOuts_c - CHARACTER(IntfStrLen) :: CheckpointRootName + INTEGER(C_INT) :: NumOuts_c + CHARACTER(IntfStrLen) :: CheckpointRootName INTEGER(IntKi) :: I INTEGER(IntKi) :: Unit REAL(DbKi) :: t_initial_out INTEGER(IntKi) :: NumTurbines_out - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' - + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Restart' + CALL NWTC_Init() - ! transfer the character array from C to a Fortran string: + ! transfer the character array from C to a Fortran string: CheckpointRootName = TRANSFER( CheckpointRootName_c, CheckpointRootName ) I = INDEX(CheckpointRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... IF ( I > 0 ) CheckpointRootName = CheckpointRootName(1:I) ! remove it - + Unit = -1 CALL FAST_RestoreFromCheckpoint_T(t_initial_out, n_t_global, NumTurbines_out, Turbine(iTurb), CheckpointRootName, ErrStat, ErrMsg, Unit ) - + ! check that these are valid: IF (t_initial_out /= t_initial) CALL SetErrStat(ErrID_Fatal, "invalid value of t_initial.", ErrStat, ErrMsg, RoutineName ) IF (NumTurbines_out /= 1) CALL SetErrStat(ErrID_Fatal, "invalid value of NumTurbines.", ErrStat, ErrMsg, RoutineName ) - - ! transfer Fortran variables to C: + + ! transfer Fortran variables to C: n_t_global_c = n_t_global - AbortErrLev_c = AbortErrLev + AbortErrLev_c = AbortErrLev NumOuts_c = min(MAXOUTPUTS, SUM( Turbine(iTurb)%y_FAST%numOuts )) ! includes time if (allocated(Turbine(iTurb)%ad%p%rotors)) then ! this might not be allocated if we had an error earlier numBlades_c = Turbine(iTurb)%ad%p%rotors(1)%numblades @@ -850,19 +874,19 @@ subroutine FAST_ExtInfw_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c end if numElementsTower_c = Turbine(iTurb)%ad%p%rotors(1)%numtwrnds - - dt_c = Turbine(iTurb)%p_FAST%dt - + + dt_c = Turbine(iTurb)%p_FAST%dt + ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -#ifdef CONSOLE_FILE +#ifdef CONSOLE_FILE if (ErrStat /= ErrID_None) call wrscr1(trim(ErrMsg)) -#endif +#endif if (ErrStat >= AbortErrLev) return - + call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) end subroutine FAST_ExtInfw_Restart From a492600e9fe89d5fb1a7097a2e781a9672eabb30 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 4 Dec 2023 17:11:39 -0700 Subject: [PATCH 21/91] Revert minor unintended changes --- .../src/ExternalInflow_Registry.txt | 3 -- modules/openfast-library/src/FAST_Library.f90 | 30 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/modules/externalinflow/src/ExternalInflow_Registry.txt b/modules/externalinflow/src/ExternalInflow_Registry.txt index 8f32087734..e066d5c414 100644 --- a/modules/externalinflow/src/ExternalInflow_Registry.txt +++ b/modules/externalinflow/src/ExternalInflow_Registry.txt @@ -57,9 +57,6 @@ typedef ^ InputType ReKi pzVel {:} - - "z position of veloc typedef ^ InputType ReKi pxForce {:} - - "x position of actuator force nodes" "m" typedef ^ InputType ReKi pyForce {:} - - "y position of actuator force nodes" "m" typedef ^ InputType ReKi pzForce {:} - - "z position of actuator force nodes" "m" -typedef ^ InputType ReKi pxdotForce {:} - - "x velocity of actuator force nodes" "m/s" -typedef ^ InputType ReKi pydotForce {:} - - "y velocity of actuator force nodes" "m/s" -typedef ^ InputType ReKi pzdotForce {:} - - "z velocity of actuator force nodes" "m/s" typedef ^ InputType ReKi xdotForce {:} - - "x velocity of actuator force nodes" "m/s" typedef ^ InputType ReKi ydotForce {:} - - "y velocity of actuator force nodes" "m/s" typedef ^ InputType ReKi zdotForce {:} - - "z velocity of actuator force nodes" "m/s" diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 5de7b339f8..db8780f82c 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -695,18 +695,16 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c CALL FAST_InitializeAll_T( t_initial, iTurb, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) ! set values for return to ExternalInflow - AbortErrLev_c = AbortErrLev - dt_c = Turbine(iTurb)%p_FAST%dt - ErrStat_c = ErrStat - ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR - ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) + if (ErrStat .ne. ErrID_None) then + AbortErrLev_c = AbortErrLev + ErrStat_c = ErrStat + ErrMsg_c = TRANSFER( TRIM(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) + return + end if - InflowType = Turbine(iTurb)%p_FAST%CompInflow + dt_c = Turbine(iTurb)%p_FAST%dt - IF ( ErrStat >= AbortErrLev ) THEN - CALL WrScr( "Error in FAST_ExtInfw_Init:FAST_InitializeAll_T" // TRIM(ErrMsg) ) - RETURN - END IF + InflowType = Turbine(iTurb)%p_FAST%CompInflow if ( (InflowType == 3) .and. (NumActForcePtsBlade .eq. 0) .and. (NumActForcePtsTower .eq. 0) ) then CALL SetErrStat(ErrID_Warn, "Number of actuator points is zero when inflow type is 2. Mapping of loads may not work. ", ErrStat, ErrMsg, RoutineName ) @@ -722,11 +720,12 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c call SetExternalInflow_pointers(iTurb, ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST) - ! 7-Sep-2015: Sang wants these integers for the ExternalInflow mapping, which is tied to the AeroDyn nodes. FAST doesn't restrict the number of nodes on each - ! blade mesh to be the same, so if this DOES ever change, we'll need to make ExternalInflow less tied to the AeroDyn mapping. + ! 7-Sep-2015: OpenFAST doesn't restrict the number of nodes on each blade mesh to be the same, so if this DOES ever change, + ! we'll need to make ExternalInflow less tied to the AeroDyn mapping. IF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD14) THEN NumBl_c = SIZE(Turbine(iTurb)%AD14%Input(1)%InputMarkers) NumBlElem_c = Turbine(iTurb)%AD14%Input(1)%InputMarkers(1)%Nnodes + NumTwrElem_c = 0 ! Don't care about Aerodyn14 anymore ELSEIF (Turbine(iTurb)%p_FAST%CompAero == MODULE_AD) THEN IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors)) THEN IF (ALLOCATED(Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion)) THEN @@ -736,6 +735,7 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c IF (NumBl_c > 0) THEN NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes END IF +!FIXME: need some checks on this. If the Tower mesh is not initialized, this will be garbage NumTwrElem_c = Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Nnodes ELSE NumBl_c = 0 @@ -743,12 +743,12 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c NumTwrElem_c = 0 END IF + OutFileRoot_c = TRANSFER( trim(Turbine(iTurb)%p_FAST%OutFileRoot)//C_NULL_CHAR, OutFileRoot_c ) + ErrStat_c = ErrStat ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) - OutFileRoot_c = TRANSFER( trim(Turbine(iTurb)%p_FAST%OutFileRoot)//C_NULL_CHAR, OutFileRoot_c ) - -contains + contains LOGICAL FUNCTION FAILED() FAILED = ErrStat >= AbortErrLev From a6a97a353f2ddf91b8b9ee3d12b69782783aef24 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 4 Dec 2023 17:43:24 -0700 Subject: [PATCH 22/91] Blade Resolved: update FAST_SS_Subs for new ExtLoads module --- modules/openfast-library/src/FAST_SS_Subs.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/openfast-library/src/FAST_SS_Subs.f90 b/modules/openfast-library/src/FAST_SS_Subs.f90 index ca1fb0dd18..f391591f60 100644 --- a/modules/openfast-library/src/FAST_SS_Subs.f90 +++ b/modules/openfast-library/src/FAST_SS_Subs.f90 @@ -99,9 +99,10 @@ SUBROUTINE FAST_InitializeSteadyState_T( Turbine, ErrStat, ErrMsg ) Turbine%TurbID = 1 CALL FAST_InitializeAll( t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, CompAeroMaps, ErrStat, ErrMsg ) + END SUBROUTINE FAST_InitializeSteadyState_T !---------------------------------------------------------------------------------------------------------------------------------- From 4065df8ff4e2949b10b24534afe9e6eb20868243 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 4 Dec 2023 18:12:15 -0700 Subject: [PATCH 23/91] ExtLoads: update simulink CMakeLists.txt --- glue-codes/simulink/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/glue-codes/simulink/CMakeLists.txt b/glue-codes/simulink/CMakeLists.txt index b84ee0d80d..da79175927 100644 --- a/glue-codes/simulink/CMakeLists.txt +++ b/glue-codes/simulink/CMakeLists.txt @@ -72,6 +72,7 @@ target_include_directories(FAST_SFunc PUBLIC $ $ $ + $ ) if(APPLE OR UNIX) target_compile_definitions(FAST_SFunc PRIVATE IMPLICIT_DLLEXPORT) From 38ef4b66ef8a80a4abfae6e84fea0e7bfa8f03b4 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 5 Dec 2023 10:45:12 -0700 Subject: [PATCH 24/91] ExtLoads: one more update to the simulink CMakeLists.txt --- glue-codes/simulink/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/glue-codes/simulink/CMakeLists.txt b/glue-codes/simulink/CMakeLists.txt index da79175927..b2b495ec40 100644 --- a/glue-codes/simulink/CMakeLists.txt +++ b/glue-codes/simulink/CMakeLists.txt @@ -34,6 +34,7 @@ set(MEX_LIBS $ # MATLAB Specific $ $ + $ $ $ $ From c09f2ce56356d1f53beb18e5c01f38c6b86e4d7b Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 5 Dec 2023 13:29:48 -0700 Subject: [PATCH 25/91] ExtLoads: update Simulink create SFunc --- glue-codes/simulink/src/create_FAST_SFunc.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue-codes/simulink/src/create_FAST_SFunc.m b/glue-codes/simulink/src/create_FAST_SFunc.m index 4a7c6fdf54..207128b1ed 100644 --- a/glue-codes/simulink/src/create_FAST_SFunc.m +++ b/glue-codes/simulink/src/create_FAST_SFunc.m @@ -71,7 +71,7 @@ ['-l' libName], ... ['-I' includeDir], ... '-I../../../modules/supercontroller/src', ... % needed for visual studio builds to find "SuperController_Types.h" - '-I../../../modules/openfoam/src', ... % needed for visual studio builds to find "OpenFOAM_Types.h" + '-I../../../modules/externalinflow/src', ... % needed for visual studio builds to find "ExternalInflow_Types.h" '-outdir', outDir, ... ['COMPFLAGS=$COMPFLAGS -MT -DS_FUNCTION_NAME=' mexname], ... '-output', mexname, ... From c0115c014ccb14b1c6fb2f7f6528b7639ca63b1a Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 5 Dec 2023 20:50:16 +0000 Subject: [PATCH 26/91] FAST_subs, don't apply DTdriver if not set This needed to be added because the C++ interface sets DTdriver, but simulink doesn't --- modules/openfast-library/src/FAST_Subs.f90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 1c09e0b137..ec6e8f37f8 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -2036,7 +2036,9 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, END IF IF (PRESENT(DTdriver)) THEN - IF ( ABS( NINT(DTdriver/p%DT) * p%DT - DTdriver ) .lt. 0.001 ) THEN + IF (DTdriver == -1.0_DbKi) THEN + ! DTdriver wasn't set, so don't use it + ELSE IF ( ABS( NINT(DTdriver/p%DT) * p%DT - DTdriver ) .lt. 0.001 ) THEN p%DT_Out = NINT(DTdriver/p%DT) * p%DT p%n_DT_Out = NINT(DTdriver/p%DT) ELSE From c7b0eeced993ac3f71ae3e42f679a79fd6ebd62e Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Tue, 5 Dec 2023 14:38:47 -0700 Subject: [PATCH 27/91] Coupled bodies intialization fix --- modules/moordyn/src/MoorDyn.f90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index da79fe50a3..d0ab4b941c 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -1788,14 +1788,13 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! set absolute initial positions in MoorDyn IF (p%Standalone /= 1) THEN !TODO: >>> should also maybe set reference orientation (which might make part of a couple lines down redundant) <<< - OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Body's relative orientation with the turbine's initial orientation + OrMat2 = MATMUL(OrMat, ( EulerConstruct( rRef(4:6)))) ! combine the Body's relative orientation with the turbine's initial orientation u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body <<< ! calculate initial point relative position, adjusted due to initial platform translations u%CoupledKinematics(iTurb)%TranslationDisp(:,J) = InitInp%PtfmInit(1:3,iTurb) - rRef(1:3) m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) - - m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6))))) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(OrMat2) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation ENDIF CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! set node as point element From db9a370081e88faa765db89a73dd6cdc3576f826 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 5 Dec 2023 14:45:01 -0700 Subject: [PATCH 28/91] ExtLoads: update cpp test case --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index 9a42b24203..4d36d8101c 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 9a42b2420312ab5dfd49065e7ddab6fb69dc7d3f +Subproject commit 4d36d8101cd7d6b3f7169c6d412251b8257f32f2 From 33269e0f4a46cf624d73aa9bdb03ce7a56086ebd Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Wed, 6 Dec 2023 12:33:13 -0700 Subject: [PATCH 29/91] Echo file removed from driver --- modules/moordyn/src/MoorDyn_Driver.f90 | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 219dfe0f2a..27428eb326 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -28,7 +28,7 @@ PROGRAM MoorDyn_Driver IMPLICIT NONE TYPE MD_Drvr_InitInput - LOGICAL :: Echo + ! LOGICAL :: Echo REAL(DbKi) :: Gravity REAL(DbKi) :: rhoW REAL(DbKi) :: WtrDepth @@ -120,7 +120,7 @@ PROGRAM MoorDyn_Driver ErrMsg = "" ErrStat = ErrID_None - UnEcho=-1 + UnEcho=-1 ! set to -1 as echo is no longer used by MD UnIn =-1 ! TODO: Sort out error handling (two sets of flags currently used) @@ -162,7 +162,7 @@ PROGRAM MoorDyn_Driver MD_InitInp%RootName = drvrInitInp%OutRootName MD_InitInp%UsePrimaryInputFile = .TRUE. !MD_InitInp%PassedPrimaryInputData = - MD_InitInp%Echo = drvrInitInp%Echo + ! MD_InitInp%Echo = drvrInitInp%Echo !MD_InitInp%OutList = <<<< never used? MD_InitInp%Linearize = .FALSE. @@ -738,7 +738,7 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp) ! Local variables INTEGER :: J ! generic integer for counting - CHARACTER(1024) :: EchoFile ! Name of MoorDyn echo file + ! CHARACTER(1024) :: EchoFile ! Name of MoorDyn echo file CHARACTER(1024) :: FileName ! Name of MoorDyn input file CHARACTER(1024) :: FilePath ! Name of path to MoorDyn input file @@ -756,17 +756,17 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp) ! Read until "echo" CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 1', ErrStat2, ErrMsg2); call AbortIfFailed() CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 2', ErrStat2, ErrMsg2); call AbortIfFailed() - CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo Input', ErrStat2, ErrMsg2); call AbortIfFailed() - ! If we echo, we rewind - IF ( InitInp%Echo ) THEN - EchoFile = TRIM(FileName)//'.echo' - CALL GetNewUnit( UnEcho ) - CALL OpenEcho ( UnEcho, EchoFile, ErrStat2, ErrMsg2 ); call AbortIfFailed() - REWIND(UnIn) - CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 1', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() - CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 2', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() - CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo the input file data', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() - END IF + ! CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo Input', ErrStat2, ErrMsg2); call AbortIfFailed() + ! ! If we echo, we rewind + ! IF ( InitInp%Echo ) THEN + ! EchoFile = TRIM(FileName)//'.echo' + ! CALL GetNewUnit( UnEcho ) + ! CALL OpenEcho ( UnEcho, EchoFile, ErrStat2, ErrMsg2 ); call AbortIfFailed() + ! REWIND(UnIn) + ! CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 1', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + ! CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 2', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + ! CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo the input file data', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + ! END IF !---------------------- ENVIRONMENTAL CONDITIONS ------------------------------------------------- CALL ReadCom( UnIn, FileName, 'Environmental conditions header', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() CALL ReadVar( UnIn, FileName, InitInp%Gravity, 'Gravity', 'Gravity', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() From 5cc5e19ceb5f68c2b56edd67ff0844b2e5cffbc9 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Wed, 6 Dec 2023 16:03:40 -0700 Subject: [PATCH 30/91] Indexing and building wave grid fix --- modules/moordyn/src/MoorDyn_Misc.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index ddc8bf25a6..d3c6ae542e 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -1736,9 +1736,9 @@ SUBROUTINE gridAxisCoords(coordtype, entries, coordarray, n, ErrStat, ErrMsg) else if (coordtype==2) then coordarray(1) = tempArray(1) coordarray(n) = tempArray(2) - dx = (coordarray(n)-coordarray(0))/REAL(n-1) - do i=2,n-1 - coordarray(i) = coordarray(1) + REAL(i)*dx + dx = (coordarray(n)-coordarray(1))/REAL(n-1) + do i=2,n + coordarray(i) = coordarray(i-1) + dx end do else From 4d0c65d4c318f925c30567da0921d3b08cd8a579 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Sun, 10 Dec 2023 16:39:05 -0700 Subject: [PATCH 31/91] Fix coupled rods initial orentation --- modules/moordyn/src/MoorDyn.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index d0ab4b941c..6e3f63272f 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -1811,9 +1811,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! set absolute initial positions in MoorDyn IF (p%Standalone /= 1) THEN - OrMatRef = TRANSPOSE( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! for now set reference orientation as per input file <<< + OrMatRef = ( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! for now set reference orientation as per input file <<< CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation - OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Rod's relative orientation with the turbine's initial orientation + OrMat2 = MATMUL(OrMat, OrMatRef) ! combine the Rod's relative orientation with the turbine's initial orientation u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math @@ -1821,7 +1821,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) - m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, OrMatRef)) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation + m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = MATMUL(OrMat2 , (/0.0, 0.0, 1.0/) ) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation ENDIF ! >>> still need to set Rod initial orientations accounting for PtfmInit rotation <<< From 0f642c68588aa96d3e4f51a544a9b377f8283109 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Sun, 10 Dec 2023 18:30:45 -0700 Subject: [PATCH 32/91] Added error handling for wave grid coordinate strings --- modules/moordyn/src/MoorDyn_Misc.f90 | 98 ++++++++++++++++------------ 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index d3c6ae542e..23189361f3 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -1387,14 +1387,17 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) READ(UnIn,*, IOSTAT=ErrStat2) coordtype ! get the entry type READ(UnIn,'(A)', IOSTAT=ErrStat2) entries2 ! get entries as string to be processed CALL gridAxisCoords(coordtype, entries2, p%pxWave, p%nxWave, ErrStat2, ErrMsg2) + Call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, 'MD_getWaterKin') ! Y grid points READ(UnIn,*, IOSTAT=ErrStat2) coordtype ! get the entry type READ(UnIn,'(A)', IOSTAT=ErrStat2) entries2 ! get entries as string to be processed CALL gridAxisCoords(coordtype, entries2, p%pyWave, p%nyWave, ErrStat2, ErrMsg2) + Call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, 'MD_getWaterKin') ! Z grid points READ(UnIn,*, IOSTAT=ErrStat2) coordtype ! get the entry type READ(UnIn,'(A)', IOSTAT=ErrStat2) entries2 ! get entries as string to be processed CALL gridAxisCoords(coordtype, entries2, p%pzWave, p%nzWave, ErrStat2, ErrMsg2) + Call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, 'MD_getWaterKin') ! ----- current ----- CALL ReadCom( UnIn, FileName, 'current header', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return CALL ReadVar( UnIn, FileName, p%Current, 'CurrentMod', 'CurrentMod', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return @@ -1707,49 +1710,58 @@ SUBROUTINE gridAxisCoords(coordtype, entries, coordarray, n, ErrStat, ErrMsg) REAL(ReKi) :: tempArray (100) REAL(ReKi) :: dx INTEGER(IntKi) :: nEntries, I - - ! get array of coordinate entries - CALL stringToArray(entries, nEntries, tempArray) - - ! set number of coordinates - if ( coordtype==0) then ! 0: not used - make one grid point at zero - n = 1; - else if (coordtype==1) then ! 1: list values in ascending order - n = nEntries - else if (coordtype==2) then ! 2: uniform specified by -xlim, xlim, num - n = int(tempArray(3)) - else - print *, "Error: invalid coordinate type specified to gridAxisCoords" - end if - - ! allocate coordinate array - CALL AllocAry(coordarray, n, 'x,y, or z grid points' , ErrStat, ErrMsg) - !ALLOCATE ( coordarray(n), STAT=ErrStat) - - ! fill in coordinates - if ( coordtype==0) then - coordarray(1) = 0.0_ReKi - - else if (coordtype==1) then - coordarray(1:n) = tempArray(1:n) - - else if (coordtype==2) then - coordarray(1) = tempArray(1) - coordarray(n) = tempArray(2) - dx = (coordarray(n)-coordarray(1))/REAL(n-1) - do i=2,n - coordarray(i) = coordarray(i-1) + dx - end do - - else - print *, "Error: invalid coordinate type specified to gridAxisCoords" - end if - - print *, "Set water grid coordinates to :" - DO i=1,n - print *, " ", coordarray(i) - end do - + + IF (len(trim(entries)) == len(entries)) THEN + print*, "Warning: Only 120 characters read from wave grid coordinates" + END IF + + IF (entries(len(entries):len(entries)) == ',') THEN + ErrStat = ErrID_Fatal + ErrMsg = 'Last character of wave grid coordinate list cannot be comma' + ELSE + ! get array of coordinate entries + CALL stringToArray(entries, nEntries, tempArray) + + ! set number of coordinates + if ( coordtype==0) then ! 0: not used - make one grid point at zero + n = 1; + else if (coordtype==1) then ! 1: list values in ascending order + n = nEntries + else if (coordtype==2) then ! 2: uniform specified by -xlim, xlim, num + n = int(tempArray(3)) + else + print *, "Error: invalid coordinate type specified to gridAxisCoords" + end if + + ! allocate coordinate array + CALL AllocAry(coordarray, n, 'x,y, or z grid points' , ErrStat, ErrMsg) + !ALLOCATE ( coordarray(n), STAT=ErrStat) + + ! fill in coordinates + if ( coordtype==0) then + coordarray(1) = 0.0_ReKi + + else if (coordtype==1) then + coordarray(1:n) = tempArray(1:n) + + else if (coordtype==2) then + coordarray(1) = tempArray(1) + coordarray(n) = tempArray(2) + dx = (coordarray(n)-coordarray(1))/REAL(n-1) + do i=2,n + coordarray(i) = coordarray(i-1) + dx + end do + + else + print *, "Error: invalid coordinate type specified to gridAxisCoords" + end if + + ! print *, "Set water grid coordinates to :" + ! DO i=1,n + ! print *, " ", coordarray(i) + ! end do + END IF + END SUBROUTINE gridAxisCoords From 69fb0b87f6f55e74dd909085e9ef6d0bf4768aa3 Mon Sep 17 00:00:00 2001 From: Ganesh Vijayakumar Date: Mon, 11 Dec 2023 12:10:04 -0700 Subject: [PATCH 33/91] Fix issues to get C++ API to run --- glue-codes/openfast-cpp/src/FAST_Prog.cpp | 7 +++++-- glue-codes/openfast-cpp/src/OpenFAST.cpp | 16 +++++++++++++--- modules/openfast-library/src/FAST_Library.f90 | 12 +++++++++--- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/glue-codes/openfast-cpp/src/FAST_Prog.cpp b/glue-codes/openfast-cpp/src/FAST_Prog.cpp index ab68e388ef..1143313b3e 100644 --- a/glue-codes/openfast-cpp/src/FAST_Prog.cpp +++ b/glue-codes/openfast-cpp/src/FAST_Prog.cpp @@ -71,6 +71,9 @@ void readTurbineData(int iTurb, fast::fastInputs & fi, YAML::Node turbNode) { get_if_present(turbNode, "num_force_pts_blade", fi.globTurbineData[iTurb].numForcePtsBlade, 0); get_if_present(turbNode, "num_force_pts_tower", fi.globTurbineData[iTurb].numForcePtsTwr, 0); + fi.globTurbineData[iTurb].numForcePts = + fi.globTurbineData[iTurb].numForcePtsBlade + + fi.globTurbineData[iTurb].numForcePtsTwr; float fZero = 0.0; get_if_present(turbNode, "nacelle_cd", fi.globTurbineData[iTurb].nacelle_cd, fZero); @@ -145,7 +148,7 @@ void readInputFile(fast::fastInputs & fi, std::string cInterfaceInputFile, doubl get_if_present(cDriverInp, "set_exp_law_wind", *setExpLawWind, false); get_if_present(cDriverInp, "set_uniform_x_blade_forces", *setUniformXBladeForces, false); if (setUniformXBladeForces) - get_required(cDriverInp, "x_blade_force", *xBladeForce); + get_if_present(cDriverInp, "x_blade_force", *xBladeForce, 0.0); get_if_present(cDriverInp, "super_controller", fi.scStatus, false); if(fi.scStatus) { @@ -197,7 +200,7 @@ int main(int argc, char** argv) { bool setUniformXBladeForces; // Set uniform X blade forces on all blade nodes int nIter; double xBladeForce = 0.0; - + std::string cDriverInputFile=argv[1]; fast::OpenFAST FAST; fast::fastInputs fi ; diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 0b002df101..d9fd1cb20c 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -224,7 +224,8 @@ void fast::OpenFAST::prepareRestartFile(int iTurbLoc) { ierr = nc_enddef(ncid); check_nc_error(ierr, "nc_enddef"); - if (turbineData[iTurbLoc].sType == EXTINFLOW) { + if ( (turbineData[iTurbLoc].sType == EXTINFLOW) && (turbineData[iTurbLoc].inflowType == 2) ) { + int nfpts_data = 3*get_numForcePtsLoc(iTurbLoc); int ierr = nc_put_var_double(ncid, ncRstVarIDs_["xref_force"], velForceNodeData[iTurbLoc][fast::STATE_NP1].xref_force.data()); } @@ -729,6 +730,8 @@ void fast::OpenFAST::init() { ErrMsg); checkError(ErrStat, ErrMsg); + std::cerr << "turbineData[iTurb].inflowType = " << turbineData[iTurb].inflowType << std::endl; + turbineData[iTurb].numVelPtsTwr = extinfw_o_t_FAST[iTurb].u_Len - turbineData[iTurb].numBlades*turbineData[iTurb].numVelPtsBlade - 1; if(turbineData[iTurb].numVelPtsTwr == 0) { turbineData[iTurb].numForcePtsTwr = 0; @@ -2118,6 +2121,11 @@ void fast::OpenFAST::allocateMemory_postInit(int iTurbLoc) { } } } + std::cerr << "turbineData[iTurbLoc].inflowType " << turbineData[iTurbLoc].inflowType << std::endl; + std::cerr << "turbineData[iTurbLoc].numForcePtsTwr = " << turbineData[iTurbLoc].numForcePtsTwr << std::endl; + std::cerr << "turbineData[iTurbLoc].numForcePtsBlade = " << turbineData[iTurbLoc].numForcePtsBlade << std::endl; + std::cerr << "turbineData[iTurbLoc].numForcePts = " << turbineData[iTurbLoc].numForcePts << std::endl; + } else if (turbineData[iTurbLoc].sType == EXTLOADS) { turbineData[iTurbLoc].nBRfsiPtsBlade.resize(turbineData[iTurbLoc].numBlades); @@ -2360,6 +2368,8 @@ void fast::OpenFAST::get_data_from_openfast(timeStep t) { if (turbineData[iTurb].inflowType == 2) { int nvelpts = get_numVelPtsLoc(iTurb); int nfpts = get_numForcePtsLoc(iTurb); + std::cerr << "nvelpts = " << nvelpts << std::endl; + std::cerr << "nfpts = " << nfpts << " " << get_numForcePtsBladeLoc(iTurb) << " " << get_numForcePtsTwrLoc(iTurb) << std::endl; for (int i=0; i Date: Mon, 11 Dec 2023 15:16:08 -0700 Subject: [PATCH 34/91] ExtLoads: rename `Input_bak` to `Input_Saved` etc. for clarity --- .../openfast-library/src/FAST_Registry.txt | 68 +- modules/openfast-library/src/FAST_Subs.f90 | 212 +- modules/openfast-library/src/FAST_Types.f90 | 1920 ++++++++--------- 3 files changed, 1100 insertions(+), 1100 deletions(-) diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index 37b8a5b85b..07a57f7c18 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -57,7 +57,7 @@ param ^ - INTEGER Module_MD - 16 - "MoorDyn" - param ^ - INTEGER Module_Orca - 17 - "OrcaFlex integration (HD/Mooring)" - param ^ - INTEGER Module_IceF - 18 - "IceFloe" - param ^ - INTEGER Module_IceD - 19 - "IceDyn" - -param ^ - INTEGER NumModules - 20 - "The number of modules available in FAST" - +param ^ - INTEGER NumModules - 19 - "The number of modules available in FAST" - # Other Constants param ^ - INTEGER MaxNBlades - 3 - "Maximum number of blades allowed on a turbine" - param ^ - INTEGER IceD_MaxLegs - 4 - "because I don't know how many legs there are before calling IceD_Init and I don't want to copy the data because of sibling mesh issues, I'm going to allocate IceD based on this number" - @@ -406,9 +406,9 @@ typedef ^ ^ IceD_InputType u {:} - - "System inputs" typedef ^ ^ IceD_OutputType y {:} - - "System outputs" typedef ^ ^ IceD_MiscVarType m {:} - - "Misc/optimization variables" typedef ^ ^ IceD_InputType Input {:}{:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ IceD_InputType Input_bak {:}{:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ IceD_InputType Input_Saved {:}{:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:}{:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:}{:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:}{:} - - "Backup Array of times associated with Input Array" # ..... BeamDyn data ....................................................................................................... # [ the last dimension of each allocatable array is for the instance of BeamDyn being used ] @@ -424,9 +424,9 @@ typedef ^ ^ BD_MiscVarType m {:} - - "Misc/optimization variables" typedef ^ ^ BD_OutputType Output {:}{:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ BD_OutputType y_interp {:} - - "interpolated system outputs for CalcSteady" typedef ^ ^ BD_InputType Input {:}{:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ BD_InputType Input_bak {:}{:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ BD_InputType Input_Saved {:}{:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:}{:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:}{:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:}{:} - - "Backup Array of times associated with Input Array" # ..... ElastoDyn data ....................................................................................................... typedef FAST ElastoDyn_Data ED_ContinuousStateType x {4} - - "Continuous states" @@ -441,9 +441,9 @@ typedef ^ ^ ED_OutputType Output {:} - - "Array of outputs associated with CalcS typedef ^ ^ ED_OutputType Output_bak {:} - - "Backup Array of outputs associated with InputTimes" typedef ^ ^ ED_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ ED_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ ED_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ ED_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... ServoDyn data ....................................................................................................... @@ -459,9 +459,9 @@ typedef ^ ^ SrvD_MiscVarType m_bak - - - "Backup Misc (optimization) variables n typedef ^ ^ SrvD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ SrvD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ SrvD_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ SrvD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ SrvD_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... AeroDyn14 data ....................................................................................................... typedef FAST AeroDyn14_Data AD14_ContinuousStateType x {4} - - "Continuous states" @@ -473,9 +473,9 @@ typedef ^ ^ AD14_InputType u - - - "System inputs" typedef ^ ^ AD14_OutputType y - - - "System outputs" typedef ^ ^ AD14_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ AD14_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ AD14_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ AD14_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... AeroDyn data ....................................................................................................... typedef FAST AeroDyn_Data AD_ContinuousStateType x {4} - - "Continuous states" @@ -489,9 +489,9 @@ typedef ^ ^ AD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ AD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ AD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ AD_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ AD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ AD_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... ExtLoads data ....................................................................................................... typedef FAST ExtLoads_Data ExtLd_ContinuousStateType x {2} - - "Continuous states" @@ -516,9 +516,9 @@ typedef ^ ^ InflowWind_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ InflowWind_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ InflowWind_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ InflowWind_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ InflowWind_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ InflowWind_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... ExternalInflow integration data ....................................................................................................... typedef FAST ExternalInflow_Data ExtInfw_InputType u - - - "System inputs" @@ -541,11 +541,11 @@ typedef ^ ^ SD_InputType u - - - "System inputs" typedef ^ ^ SD_OutputType y - - - "System outputs" typedef ^ ^ SD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ SD_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ SD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ SD_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ SD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ SD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... ExtPtfm data ....................................................................................................... typedef FAST ExtPtfm_Data ExtPtfm_ContinuousStateType x {4} - - "Continuous states" @@ -557,9 +557,9 @@ typedef ^ ^ ExtPtfm_InputType u - - - "System inputs" typedef ^ ^ ExtPtfm_OutputType y - - - "System outputs" typedef ^ ^ ExtPtfm_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ ExtPtfm_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ ExtPtfm_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ ExtPtfm_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... SeaState data ....................................................................................................... typedef FAST SeaState_Data SeaSt_ContinuousStateType x {4} - - "Continuous states" @@ -571,11 +571,11 @@ typedef ^ ^ SeaSt_InputType u - - - "System inputs" typedef ^ ^ SeaSt_OutputType y - - - "System outputs" typedef ^ ^ SeaSt_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ SeaSt_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ SeaSt_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ SeaSt_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ SeaSt_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ SeaSt_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... HydroDyn data ....................................................................................................... typedef FAST HydroDyn_Data HydroDyn_ContinuousStateType x {4} - - "Continuous states" @@ -589,9 +589,9 @@ typedef ^ ^ HydroDyn_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ HydroDyn_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ HydroDyn_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ HydroDyn_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ HydroDyn_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ HydroDyn_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... IceFloe data ....................................................................................................... typedef FAST IceFloe_Data IceFloe_ContinuousStateType x {4} - - "Continuous states" @@ -603,9 +603,9 @@ typedef ^ ^ IceFloe_InputType u - - - "System inputs" typedef ^ ^ IceFloe_OutputType y - - - "System outputs" typedef ^ ^ IceFloe_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ IceFloe_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ IceFloe_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ IceFloe_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... MAP data ....................................................................................................... typedef FAST MAP_Data MAP_ContinuousStateType x {4} - - "Continuous states" @@ -619,9 +619,9 @@ typedef ^ ^ MAP_OtherStateType OtherSt_old - - - "Other/optimization states (cop typedef ^ ^ MAP_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ MAP_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ MAP_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ MAP_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ MAP_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... FEAMooring data ....................................................................................................... typedef FAST FEAMooring_Data FEAM_ContinuousStateType x {4} - - "Continuous states" @@ -633,9 +633,9 @@ typedef ^ ^ FEAM_InputType u - - - "System inputs" typedef ^ ^ FEAM_OutputType y - - - "System outputs" typedef ^ ^ FEAM_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ FEAM_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ FEAM_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ FEAM_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... MoorDyn data ....................................................................................................... typedef FAST MoorDyn_Data MD_ContinuousStateType x {4} - - "Continuous states" @@ -649,9 +649,9 @@ typedef ^ ^ MD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ MD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" typedef ^ ^ MD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ MD_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ MD_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ MD_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... OrcaFlex data ....................................................................................................... typedef FAST OrcaFlex_Data Orca_ContinuousStateType x {4} - - "Continuous states" @@ -663,9 +663,9 @@ typedef ^ ^ Orca_InputType u - - - "System inputs" typedef ^ ^ Orca_OutputType y - - - "System outputs" typedef ^ ^ Orca_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ Orca_InputType Input {:} - - "Array of inputs associated with InputTimes" -typedef ^ ^ Orca_InputType Input_bak {:} - - "Backup Array of inputs associated with InputTimes" +typedef ^ ^ Orca_InputType Input_Saved {:} - - "Backup Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" -typedef ^ ^ DbKi InputTimes_bak {:} - - "Backup Array of times associated with Input Array" +typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... FAST_ModuleMapType data ....................................................................................................... # ! Data structures for mapping and coupling the various modules together @@ -700,7 +700,7 @@ typedef ^ FAST_ModuleMapType MeshMapType SubStructure_2_SStC_P_P {:} - - "Map Su # ED --> SrvD -- PlatformPtMesh motion to SrvD%PtfmMotionMesh for passing to DLL typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_SrvD_P_P - - - "Map ElastoDyn platform point mesh motion to ServoDyn point mesh -- for passing to controller" # ED/BD <-> AD (blades) -typedef ^ FAST_ModuleMapType MeshMapType BDED_L_2_AD_L_B {:} - - "Map ElastoDyn/BeamDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes" +typedef ^ FAST_ModuleMapType MeshMapType BDED_L_2_AD_L_B {:} - - "Map ElastoDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes" typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_BDED_B {:} - - "Map AeroDyn14 InputMarkers or AeroDyn BladeLoad line2 meshes to ElastoDyn BladePtLoad point meshes or BeamDyn BldMotion line2 meshes" typedef ^ FAST_ModuleMapType MeshMapType BD_L_2_BD_L {:} - - "Map BeamDyn BldMotion output meshes to locations on the BD input DistrLoad mesh stored in MeshMapType%y_BD_BldMotion_4Loads (BD input and output meshes are not siblings and in fact have nodes at different locations" # ED <-> AD (nacelle, tower, hub, blade root, tailfin) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index ec6e8f37f8..c130da47e4 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -242,9 +242,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( ED%Input_bak( p_FAST%InterpOrder+1 ), ED%InputTimes_bak( p_FAST%InterpOrder+1 ), ED%Output_bak( p_FAST%InterpOrder+1 ),STAT = ErrStat2 ) + ALLOCATE( ED%Input_Saved( p_FAST%InterpOrder+1 ), ED%InputTimes_Saved( p_FAST%InterpOrder+1 ), ED%Output_bak( p_FAST%InterpOrder+1 ),STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating ED%Input_bak, ED%Output_bak, and ED%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating ED%Input_Saved, ED%Output_bak, and ED%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -332,9 +332,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( BD%Input_bak( p_FAST%InterpOrder+1, p_FAST%nBeams ), BD%InputTimes_bak( p_FAST%InterpOrder+1, p_FAST%nBeams ), STAT = ErrStat2 ) + ALLOCATE( BD%Input_Saved( p_FAST%InterpOrder+1, p_FAST%nBeams ), BD%InputTimes_Saved( p_FAST%InterpOrder+1, p_FAST%nBeams ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating BD%Input_bak and BD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating BD%Input_Saved and BD%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -448,9 +448,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( AD14%Input_bak( p_FAST%InterpOrder+1 ), AD14%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( AD14%Input_Saved( p_FAST%InterpOrder+1 ), AD14%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating AD14%Input_bak and AD14%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating AD14%Input_Saved and AD14%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -462,7 +462,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( AD%Input_bak( p_FAST%InterpOrder+1 ), AD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( AD%Input_Saved( p_FAST%InterpOrder+1 ), AD%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating AD%Input and AD%InputTimes.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() @@ -627,9 +627,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( IfW%Input_bak( p_FAST%InterpOrder+1 ), IfW%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( IfW%Input_Saved( p_FAST%InterpOrder+1 ), IfW%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating IfW%Input_bak and IfW%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating IfW%Input_Saved and IfW%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -848,9 +848,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( SeaSt%Input_bak( p_FAST%InterpOrder+1 ), SeaSt%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( SeaSt%Input_Saved( p_FAST%InterpOrder+1 ), SeaSt%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating SeaSt%Input_bak and SeaSt%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating SeaSt%Input_Saved and SeaSt%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -944,9 +944,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( HD%Input_bak( p_FAST%InterpOrder+1 ), HD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( HD%Input_Saved( p_FAST%InterpOrder+1 ), HD%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating HD%Input_bak and HD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating HD%Input_Saved and HD%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1006,9 +1006,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( SD%Input_bak( p_FAST%InterpOrder+1 ), SD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( SD%Input_Saved( p_FAST%InterpOrder+1 ), SD%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating SD%Input_bak and SD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating SD%Input_Saved and SD%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1020,9 +1020,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( ExtPtfm%Input_bak( p_FAST%InterpOrder+1 ), ExtPtfm%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( ExtPtfm%Input_Saved( p_FAST%InterpOrder+1 ), ExtPtfm%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating ExtPtfm%Input_bak and ExtPtfm%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating ExtPtfm%Input_Saved and ExtPtfm%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1118,9 +1118,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - ALLOCATE( MAPp%Input_bak( p_FAST%InterpOrder+1 ), MAPp%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( MAPp%Input_Saved( p_FAST%InterpOrder+1 ), MAPp%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating MAPp%Input_bak and MAPp%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating MAPp%Input_Saved and MAPp%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1130,9 +1130,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - ALLOCATE( MD%Input_bak( p_FAST%InterpOrder+1 ), MD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( MD%Input_Saved( p_FAST%InterpOrder+1 ), MD%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating MD%Input_bak and MD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating MD%Input_Saved and MD%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1142,9 +1142,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - ALLOCATE( FEAM%Input_bak( p_FAST%InterpOrder+1 ), FEAM%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( FEAM%Input_Saved( p_FAST%InterpOrder+1 ), FEAM%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating FEAM%Input_bak and FEAM%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating FEAM%Input_Saved and FEAM%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1154,9 +1154,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - ALLOCATE( Orca%Input_bak( p_FAST%InterpOrder+1 ), Orca%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( Orca%Input_Saved( p_FAST%InterpOrder+1 ), Orca%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating Orca%Input_bak and Orca%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating Orca%Input_Saved and Orca%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1317,9 +1317,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( IceF%Input_bak( p_FAST%InterpOrder+1 ), IceF%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( IceF%Input_Saved( p_FAST%InterpOrder+1 ), IceF%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating IceF%Input_bak and IceF%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating IceF%Input_Saved and IceF%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1341,9 +1341,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( IceD%Input_bak( p_FAST%InterpOrder+1, IceDim ), IceD%InputTimes_bak( p_FAST%InterpOrder+1, IceDim ), STAT = ErrStat2 ) + ALLOCATE( IceD%Input_Saved( p_FAST%InterpOrder+1, IceDim ), IceD%InputTimes_Saved( p_FAST%InterpOrder+1, IceDim ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating IceD%Input_bak and IceD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating IceD%Input_Saved and IceD%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -1450,9 +1450,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - ALLOCATE( SrvD%Input_bak( p_FAST%InterpOrder+1 ), SrvD%InputTimes_bak( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) + ALLOCATE( SrvD%Input_Saved( p_FAST%InterpOrder+1 ), SrvD%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating SrvD%Input_bak and SrvD%InputTimes_bak.",ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal,"Error allocating SrvD%Input_Saved and SrvD%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF @@ -5686,12 +5686,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! order = SIZE(ED%Input) DO j = 1, p_FAST%InterpOrder + 1 - ED%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + ED%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !ED_OutputTimes(p_FAST%InterpOrder + 1 + j) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL ED_CopyInput (ED%Input(1), ED%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyInput (ED%Input(1), ED%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL ED_CopyOutput (ED%y, ED%Output_bak(1), MESH_NEWCOPY, Errstat2, ErrMsg2) !BJJ: THIS IS REALLY ONLY NECESSARY FOR ED-HD COUPLING AT THE MOMENT @@ -5722,11 +5722,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - BD%InputTimes_bak(j,k) = t_initial - (j - 1) * p_FAST%dt + BD%InputTimes_Saved(j,k) = t_initial - (j - 1) * p_FAST%dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL BD_CopyInput (BD%Input(1,k), BD%Input_bak(j,k), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyInput (BD%Input(1,k), BD%Input_Saved(j,k), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -5759,12 +5759,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Initialize Input-Output arrays for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - SrvD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + SrvD%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !SrvD_OutputTimes(j) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL SrvD_CopyInput (SrvD%Input(1), SrvD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyInput (SrvD%Input(1), SrvD%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -5798,11 +5798,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - AD14%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + AD14%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL AD14_CopyInput (AD14%Input(1), AD14%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyInput (AD14%Input(1), AD14%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -5830,11 +5830,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - AD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + AD%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL AD_CopyInput (AD%Input(1), AD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyInput (AD%Input(1), AD%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -5866,12 +5866,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - IfW%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + IfW%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !IfW%OutputTimes(i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL InflowWind_CopyInput (IfW%Input(1), IfW%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyInput (IfW%Input(1), IfW%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -5901,12 +5901,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD IF ( p_FAST%CompHydro == Module_HD ) THEN ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - HD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + HD%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !HD_OutputTimes(i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL HydroDyn_CopyInput (HD%Input(1), HD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyInput (HD%Input(1), HD%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -5937,12 +5937,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - SD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + SD%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !SD_OutputTimes(i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL SD_CopyInput (SD%Input(1), SD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyInput (SD%Input(1), SD%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -5970,11 +5970,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - ExtPtfm%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + ExtPtfm%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL ExtPtfm_CopyInput (ExtPtfm%Input(1), ExtPtfm%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyInput (ExtPtfm%Input(1), ExtPtfm%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6005,12 +6005,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - MAPp%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + MAPp%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !MAP_OutputTimes(i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL MAP_CopyInput (MAPp%Input(1), MAPp%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MAP_CopyInput (MAPp%Input(1), MAPp%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6042,12 +6042,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - MD%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + MD%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !MD_OutputTimes(i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL MD_CopyInput (MD%Input(1), MD%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyInput (MD%Input(1), MD%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6077,12 +6077,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - FEAM%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + FEAM%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !FEAM_OutputTimes(i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL FEAM_CopyInput (FEAM%Input(1), FEAM%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyInput (FEAM%Input(1), FEAM%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6110,11 +6110,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - Orca%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + Orca%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL Orca_CopyInput (Orca%Input(1), Orca%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyInput (Orca%Input(1), Orca%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6145,12 +6145,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - IceF%InputTimes_bak(j) = t_initial - (j - 1) * p_FAST%dt + IceF%InputTimes_Saved(j) = t_initial - (j - 1) * p_FAST%dt !IceF_OutputTimes(i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL IceFloe_CopyInput (IceF%Input(1), IceF%Input_bak(j), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyInput (IceF%Input(1), IceF%Input_Saved(j), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6180,12 +6180,12 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - IceD%InputTimes_bak(j,i) = t_initial - (j - 1) * p_FAST%dt + IceD%InputTimes_Saved(j,i) = t_initial - (j - 1) * p_FAST%dt !IceD%OutputTimes(j,i) = t_initial - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL IceD_CopyInput (IceD%Input(1,i), IceD%Input_bak(j,i), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyInput (IceD%Input(1,i), IceD%Input_Saved(j,i), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6299,7 +6299,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL ED_CopyInput (ED%Input_bak(j), ED%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyInput (ED%Input_Saved(j), ED%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO CALL ED_CopyOutput (ED%Output_bak(1), ED%y, MESH_UPDATECOPY, Errstat2, ErrMsg2) @@ -6335,7 +6335,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL BD_CopyInput (BD%Input_bak(j,k), BD%Input(j,k), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyInput (BD%Input_Saved(j,k), BD%Input(j,k), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6382,7 +6382,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL SrvD_CopyInput (SrvD%Input_bak(j), SrvD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyInput (SrvD%Input_Saved(j), SrvD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6417,7 +6417,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL AD14_CopyInput (AD14%Input_bak(j), AD14%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyInput (AD14%Input_Saved(j), AD14%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6447,7 +6447,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL AD_CopyInput (AD%Input_bak(j), AD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyInput (AD%Input_Saved(j), AD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6480,7 +6480,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL InflowWind_CopyInput (IfW%Input_bak(j), IfW%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyInput (IfW%Input_Saved(j), IfW%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6513,7 +6513,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL HydroDyn_CopyInput (HD%Input_bak(j), HD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyInput (HD%Input_Saved(j), HD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6547,7 +6547,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL SD_CopyInput (SD%Input_bak(j), SD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyInput (SD%Input_Saved(j), SD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6577,7 +6577,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL ExtPtfm_CopyInput (ExtPtfm%Input_bak(j), ExtPtfm%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyInput (ExtPtfm%Input_Saved(j), ExtPtfm%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6611,7 +6611,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL MAP_CopyInput (MAPp%Input_bak(j), MAPp%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyInput (MAPp%Input_Saved(j), MAPp%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6642,7 +6642,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL MD_CopyInput (MD%Input_bak(j), MD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyInput (MD%Input_Saved(j), MD%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6673,7 +6673,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL FEAM_CopyInput (FEAM%Input_bak(j), FEAM%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyInput (FEAM%Input_Saved(j), FEAM%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6703,7 +6703,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL Orca_CopyInput (Orca%Input_bak(j), Orca%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyInput (Orca%Input_Saved(j), Orca%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6737,7 +6737,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL IceFloe_CopyInput (IceF%Input_bak(j), IceF%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyInput (IceF%Input_Saved(j), IceF%Input(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6770,7 +6770,7 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL IceD_CopyInput (IceD%Input_bak(j,i), IceD%Input(j,i), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyInput (IceD%Input_Saved(j,i), IceD%Input(j,i), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6882,11 +6882,11 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, !---------------------------------------------------------------------------------------- DO j = 1, p_FAST%InterpOrder + 1 - ED%InputTimes_bak(j) = ED%InputTimes(j) + ED%InputTimes_Saved(j) = ED%InputTimes(j) END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL ED_CopyInput (ED%Input(j), ED%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyInput (ED%Input(j), ED%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO CALL ED_CopyOutput (ED%y, ED%Output_bak(1), MESH_UPDATECOPY, Errstat2, ErrMsg2) @@ -6918,11 +6918,11 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - BD%InputTimes_bak(j,k) = BD%InputTimes(j,k) + BD%InputTimes_Saved(j,k) = BD%InputTimes(j,k) END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL BD_CopyInput (BD%Input(j,k), BD%Input_bak(j,k), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyInput (BD%Input(j,k), BD%Input_Saved(j,k), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6951,11 +6951,11 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Initialize Input-Output arrays for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - SrvD%InputTimes_bak(j) = SrvD%InputTimes(j) + SrvD%InputTimes_Saved(j) = SrvD%InputTimes(j) END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL SrvD_CopyInput (SrvD%Input(j), SrvD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyInput (SrvD%Input(j), SrvD%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6986,11 +6986,11 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - AD14%InputTimes_bak(j) = AD14%InputTimes(j) + AD14%InputTimes_Saved(j) = AD14%InputTimes(j) END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL AD14_CopyInput (AD14%Input(j), AD14%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyInput (AD14%Input(j), AD14%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7016,11 +7016,11 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - AD%InputTimes_bak(j) = AD%InputTimes(j) + AD%InputTimes_Saved(j) = AD%InputTimes(j) END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL AD_CopyInput (AD%Input(j), AD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyInput (AD%Input(j), AD%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7048,12 +7048,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - IfW%InputTimes_bak(j) = IfW%InputTimes(j) + IfW%InputTimes_Saved(j) = IfW%InputTimes(j) !IfW%OutputTimes(i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL InflowWind_CopyInput (IfW%Input(j), IfW%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyInput (IfW%Input(j), IfW%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7081,12 +7081,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, IF ( p_FAST%CompHydro == Module_HD ) THEN ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - HD%InputTimes_bak(j) = HD%InputTimes(j) + HD%InputTimes_Saved(j) = HD%InputTimes(j) !HD_OutputTimes(i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL HydroDyn_CopyInput (HD%Input(j), HD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyInput (HD%Input(j), HD%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7115,12 +7115,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - SD%InputTimes_bak(j) = SD%InputTimes(j) + SD%InputTimes_Saved(j) = SD%InputTimes(j) !SD_OutputTimes(i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL SD_CopyInput (SD%Input(j), SD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyInput (SD%Input(j), SD%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7146,11 +7146,11 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - ExtPtfm%InputTimes_bak(j) = ExtPtfm%InputTimes(j) + ExtPtfm%InputTimes_Saved(j) = ExtPtfm%InputTimes(j) END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL ExtPtfm_CopyInput (ExtPtfm%Input(j), ExtPtfm%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyInput (ExtPtfm%Input(j), ExtPtfm%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7179,12 +7179,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - MAPp%InputTimes_bak(j) = MAPp%InputTimes(j) + MAPp%InputTimes_Saved(j) = MAPp%InputTimes(j) !MAP_OutputTimes(i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL MAP_CopyInput (MAPp%Input(j), MAPp%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyInput (MAPp%Input(j), MAPp%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7210,12 +7210,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - MD%InputTimes_bak(j) = MD%InputTimes(j) + MD%InputTimes_Saved(j) = MD%InputTimes(j) !MD_OutputTimes(i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL MD_CopyInput (MD%Input(j), MD%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyInput (MD%Input(j), MD%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7241,12 +7241,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - FEAM%InputTimes_bak(j) = FEAM%InputTimes(j) + FEAM%InputTimes_Saved(j) = FEAM%InputTimes(j) !FEAM_OutputTimes(i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL FEAM_CopyInput (FEAM%Input(j), FEAM%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyInput (FEAM%Input(j), FEAM%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7272,11 +7272,11 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - Orca%InputTimes_bak(j) = Orca%InputTimes(j) + Orca%InputTimes_Saved(j) = Orca%InputTimes(j) END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL Orca_CopyInput (Orca%Input(j), Orca%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyInput (Orca%Input(j), Orca%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7305,12 +7305,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - IceF%InputTimes_bak(j) = IceF%InputTimes(j) + IceF%InputTimes_Saved(j) = IceF%InputTimes(j) !IceF_OutputTimes(i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL IceFloe_CopyInput (IceF%Input(j), IceF%Input_bak(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyInput (IceF%Input(j), IceF%Input_Saved(j), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -7338,12 +7338,12 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! Copy values for interpolation/extrapolation: DO j = 1, p_FAST%InterpOrder + 1 - IceD%InputTimes_bak(j,i) = IceD%InputTimes(j,i) + IceD%InputTimes_Saved(j,i) = IceD%InputTimes(j,i) !IceD%OutputTimes(j,i) = t_global - (j - 1) * dt END DO DO j = 1, p_FAST%InterpOrder + 1 - CALL IceD_CopyInput (IceD%Input(j,i), IceD%Input_bak(j,i), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyInput (IceD%Input(j,i), IceD%Input_Saved(j,i), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO diff --git a/modules/openfast-library/src/FAST_Types.f90 b/modules/openfast-library/src/FAST_Types.f90 index 6e6b59889b..06aa8e9627 100644 --- a/modules/openfast-library/src/FAST_Types.f90 +++ b/modules/openfast-library/src/FAST_Types.f90 @@ -72,7 +72,7 @@ MODULE FAST_Types INTEGER(IntKi), PUBLIC, PARAMETER :: Module_Orca = 17 ! OrcaFlex integration (HD/Mooring) [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_IceF = 18 ! IceFloe [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_IceD = 19 ! IceDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: NumModules = 20 ! The number of modules available in FAST [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: NumModules = 19 ! The number of modules available in FAST [-] INTEGER(IntKi), PUBLIC, PARAMETER :: MaxNBlades = 3 ! Maximum number of blades allowed on a turbine [-] INTEGER(IntKi), PUBLIC, PARAMETER :: IceD_MaxLegs = 4 ! because I don't know how many legs there are before calling IceD_Init and I don't want to copy the data because of sibling mesh issues, I'm going to allocate IceD based on this number [-] INTEGER(IntKi), PUBLIC, PARAMETER :: SS_Indx_Pitch = 1 ! pitch [-] @@ -402,9 +402,9 @@ MODULE FAST_Types TYPE(IceD_OutputType) , DIMENSION(:), ALLOCATABLE :: y !< System outputs [-] TYPE(IceD_MiscVarType) , DIMENSION(:), ALLOCATABLE :: m !< Misc/optimization variables [-] TYPE(IceD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(IceD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(IceD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE IceDyn_Data ! ======================= ! ========= BeamDyn_Data ======= @@ -420,9 +420,9 @@ MODULE FAST_Types TYPE(BD_OutputType) , DIMENSION(:,:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(BD_OutputType) , DIMENSION(:), ALLOCATABLE :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(BD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(BD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(BD_InputType) , DIMENSION(:,:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE BeamDyn_Data ! ======================= ! ========= ElastoDyn_Data ======= @@ -439,9 +439,9 @@ MODULE FAST_Types TYPE(ED_OutputType) , DIMENSION(:), ALLOCATABLE :: Output_bak !< Backup Array of outputs associated with InputTimes [-] TYPE(ED_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(ED_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(ED_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(ED_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE ElastoDyn_Data ! ======================= ! ========= ServoDyn_Data ======= @@ -458,9 +458,9 @@ MODULE FAST_Types TYPE(SrvD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(SrvD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(SrvD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(SrvD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(SrvD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE ServoDyn_Data ! ======================= ! ========= AeroDyn14_Data ======= @@ -474,9 +474,9 @@ MODULE FAST_Types TYPE(AD14_OutputType) :: y !< System outputs [-] TYPE(AD14_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(AD14_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(AD14_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(AD14_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE AeroDyn14_Data ! ======================= ! ========= AeroDyn_Data ======= @@ -492,9 +492,9 @@ MODULE FAST_Types TYPE(AD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(AD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(AD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(AD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(AD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE AeroDyn_Data ! ======================= ! ========= ExtLoads_Data ======= @@ -523,9 +523,9 @@ MODULE FAST_Types TYPE(InflowWind_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(InflowWind_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(InflowWind_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(InflowWind_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(InflowWind_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE InflowWind_Data ! ======================= ! ========= ExternalInflow_Data ======= @@ -554,11 +554,11 @@ MODULE FAST_Types TYPE(SD_OutputType) :: y !< System outputs [-] TYPE(SD_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(SD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(SD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(SD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] TYPE(SD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(SD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE SubDyn_Data ! ======================= ! ========= ExtPtfm_Data ======= @@ -572,9 +572,9 @@ MODULE FAST_Types TYPE(ExtPtfm_OutputType) :: y !< System outputs [-] TYPE(ExtPtfm_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(ExtPtfm_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(ExtPtfm_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(ExtPtfm_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE ExtPtfm_Data ! ======================= ! ========= SeaState_Data ======= @@ -588,11 +588,11 @@ MODULE FAST_Types TYPE(SeaSt_OutputType) :: y !< System outputs [-] TYPE(SeaSt_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(SeaSt_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(SeaSt_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(SeaSt_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] TYPE(SeaSt_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(SeaSt_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE SeaState_Data ! ======================= ! ========= HydroDyn_Data ======= @@ -608,9 +608,9 @@ MODULE FAST_Types TYPE(HydroDyn_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(HydroDyn_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(HydroDyn_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(HydroDyn_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(HydroDyn_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE HydroDyn_Data ! ======================= ! ========= IceFloe_Data ======= @@ -624,9 +624,9 @@ MODULE FAST_Types TYPE(IceFloe_OutputType) :: y !< System outputs [-] TYPE(IceFloe_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(IceFloe_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(IceFloe_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(IceFloe_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE IceFloe_Data ! ======================= ! ========= MAP_Data ======= @@ -642,9 +642,9 @@ MODULE FAST_Types TYPE(MAP_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(MAP_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(MAP_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(MAP_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(MAP_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE MAP_Data ! ======================= ! ========= FEAMooring_Data ======= @@ -658,9 +658,9 @@ MODULE FAST_Types TYPE(FEAM_OutputType) :: y !< System outputs [-] TYPE(FEAM_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(FEAM_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(FEAM_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(FEAM_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE FEAMooring_Data ! ======================= ! ========= MoorDyn_Data ======= @@ -676,9 +676,9 @@ MODULE FAST_Types TYPE(MD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] TYPE(MD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] TYPE(MD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(MD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(MD_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE MoorDyn_Data ! ======================= ! ========= OrcaFlex_Data ======= @@ -692,9 +692,9 @@ MODULE FAST_Types TYPE(Orca_OutputType) :: y !< System outputs [-] TYPE(Orca_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(Orca_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] - TYPE(Orca_InputType) , DIMENSION(:), ALLOCATABLE :: Input_bak !< Backup Array of inputs associated with InputTimes [-] + TYPE(Orca_InputType) , DIMENSION(:), ALLOCATABLE :: Input_Saved !< Backup Array of inputs associated with InputTimes [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_bak !< Backup Array of times associated with Input Array [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes_Saved !< Backup Array of times associated with Input Array [-] END TYPE OrcaFlex_Data ! ======================= ! ========= FAST_ModuleMapType ======= @@ -722,7 +722,7 @@ MODULE FAST_Types TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: SStC_P_P_2_SubStructure !< Map ServoDyn/SStC platform point mesh load to SubDyn/ElastoDyn point load mesh [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: SubStructure_2_SStC_P_P !< Map SubDyn y3mesh or ED platform mesh motion to ServoDyn/SStC point mesh [-] TYPE(MeshMapType) :: ED_P_2_SrvD_P_P !< Map ElastoDyn platform point mesh motion to ServoDyn point mesh -- for passing to controller [-] - TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BDED_L_2_AD_L_B !< Map ElastoDyn/BeamDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BDED_L_2_AD_L_B !< Map ElastoDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: AD_L_2_BDED_B !< Map AeroDyn14 InputMarkers or AeroDyn BladeLoad line2 meshes to ElastoDyn BladePtLoad point meshes or BeamDyn BldMotion line2 meshes [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BD_L_2_BD_L !< Map BeamDyn BldMotion output meshes to locations on the BD input DistrLoad mesh stored in MeshMapType%y_BD_BldMotion_4Loads (BD input and output meshes are not siblings and in fact have nodes at different locations [-] TYPE(MeshMapType) :: ED_P_2_AD_P_N !< Map ElastoDyn Nacelle point motion mesh to AeroDyn Nacelle point motion mesh [-] @@ -16850,21 +16850,21 @@ SUBROUTINE FAST_CopyIceDyn_Data( SrcIceDyn_DataData, DstIceDyn_DataData, CtrlCod ENDDO ENDDO ENDIF -IF (ALLOCATED(SrcIceDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcIceDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcIceDyn_DataData%Input_bak,1) - i2_l = LBOUND(SrcIceDyn_DataData%Input_bak,2) - i2_u = UBOUND(SrcIceDyn_DataData%Input_bak,2) - IF (.NOT. ALLOCATED(DstIceDyn_DataData%Input_bak)) THEN - ALLOCATE(DstIceDyn_DataData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcIceDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcIceDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcIceDyn_DataData%Input_Saved,1) + i2_l = LBOUND(SrcIceDyn_DataData%Input_Saved,2) + i2_u = UBOUND(SrcIceDyn_DataData%Input_Saved,2) + IF (.NOT. ALLOCATED(DstIceDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstIceDyn_DataData%Input_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i2 = LBOUND(SrcIceDyn_DataData%Input_bak,2), UBOUND(SrcIceDyn_DataData%Input_bak,2) - DO i1 = LBOUND(SrcIceDyn_DataData%Input_bak,1), UBOUND(SrcIceDyn_DataData%Input_bak,1) - CALL IceD_CopyInput( SrcIceDyn_DataData%Input_bak(i1,i2), DstIceDyn_DataData%Input_bak(i1,i2), CtrlCode, ErrStat2, ErrMsg2 ) + DO i2 = LBOUND(SrcIceDyn_DataData%Input_Saved,2), UBOUND(SrcIceDyn_DataData%Input_Saved,2) + DO i1 = LBOUND(SrcIceDyn_DataData%Input_Saved,1), UBOUND(SrcIceDyn_DataData%Input_Saved,1) + CALL IceD_CopyInput( SrcIceDyn_DataData%Input_Saved(i1,i2), DstIceDyn_DataData%Input_Saved(i1,i2), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -16884,19 +16884,19 @@ SUBROUTINE FAST_CopyIceDyn_Data( SrcIceDyn_DataData, DstIceDyn_DataData, CtrlCod END IF DstIceDyn_DataData%InputTimes = SrcIceDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcIceDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcIceDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcIceDyn_DataData%InputTimes_bak,1) - i2_l = LBOUND(SrcIceDyn_DataData%InputTimes_bak,2) - i2_u = UBOUND(SrcIceDyn_DataData%InputTimes_bak,2) - IF (.NOT. ALLOCATED(DstIceDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstIceDyn_DataData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcIceDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcIceDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcIceDyn_DataData%InputTimes_Saved,1) + i2_l = LBOUND(SrcIceDyn_DataData%InputTimes_Saved,2) + i2_u = UBOUND(SrcIceDyn_DataData%InputTimes_Saved,2) + IF (.NOT. ALLOCATED(DstIceDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstIceDyn_DataData%InputTimes_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstIceDyn_DataData%InputTimes_bak = SrcIceDyn_DataData%InputTimes_bak + DstIceDyn_DataData%InputTimes_Saved = SrcIceDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyIceDyn_Data @@ -16994,20 +16994,20 @@ SUBROUTINE FAST_DestroyIceDyn_Data( IceDyn_DataData, ErrStat, ErrMsg, DEALLOCATE ENDDO DEALLOCATE(IceDyn_DataData%Input) ENDIF -IF (ALLOCATED(IceDyn_DataData%Input_bak)) THEN -DO i2 = LBOUND(IceDyn_DataData%Input_bak,2), UBOUND(IceDyn_DataData%Input_bak,2) -DO i1 = LBOUND(IceDyn_DataData%Input_bak,1), UBOUND(IceDyn_DataData%Input_bak,1) - CALL IceD_DestroyInput( IceDyn_DataData%Input_bak(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(IceDyn_DataData%Input_Saved)) THEN +DO i2 = LBOUND(IceDyn_DataData%Input_Saved,2), UBOUND(IceDyn_DataData%Input_Saved,2) +DO i1 = LBOUND(IceDyn_DataData%Input_Saved,1), UBOUND(IceDyn_DataData%Input_Saved,1) + CALL IceD_DestroyInput( IceDyn_DataData%Input_Saved(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO - DEALLOCATE(IceDyn_DataData%Input_bak) + DEALLOCATE(IceDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(IceDyn_DataData%InputTimes)) THEN DEALLOCATE(IceDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(IceDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(IceDyn_DataData%InputTimes_bak) +IF (ALLOCATED(IceDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(IceDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyIceDyn_Data @@ -17264,25 +17264,25 @@ SUBROUTINE FAST_PackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Input_bak upper/lower bounds for each dimension - DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL IceD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Input_Saved upper/lower bounds for each dimension + DO i2 = LBOUND(InData%Input_Saved,2), UBOUND(InData%Input_Saved,2) + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL IceD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1,i2), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -17294,10 +17294,10 @@ SUBROUTINE FAST_PackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + 2*2 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -17720,22 +17720,22 @@ SUBROUTINE FAST_PackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_bak,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL IceD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i2 = LBOUND(InData%Input_Saved,2), UBOUND(InData%Input_Saved,2) + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL IceD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -17786,22 +17786,22 @@ SUBROUTINE FAST_PackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_bak,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%InputTimes_bak,2), UBOUND(InData%InputTimes_bak,2) - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1,i2) + DO i2 = LBOUND(InData%InputTimes_Saved,2), UBOUND(InData%InputTimes_Saved,2) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1,i2) Db_Xferred = Db_Xferred + 1 END DO END DO @@ -18365,7 +18365,7 @@ SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -18375,14 +18375,14 @@ SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Input_bak,2), UBOUND(OutData%Input_bak,2) - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i2 = LBOUND(OutData%Input_Saved,2), UBOUND(OutData%Input_Saved,2) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -18416,7 +18416,7 @@ SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IceD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1,i2), ErrStat2, ErrMsg2 ) ! Input_bak + CALL IceD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1,i2), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -18449,7 +18449,7 @@ SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -18459,15 +18459,15 @@ SUBROUTINE FAST_UnPackIceDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%InputTimes_bak,2), UBOUND(OutData%InputTimes_bak,2) - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1,i2) = DbKiBuf(Db_Xferred) + DO i2 = LBOUND(OutData%InputTimes_Saved,2), UBOUND(OutData%InputTimes_Saved,2) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1,i2) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END DO @@ -18690,21 +18690,21 @@ SUBROUTINE FAST_CopyBeamDyn_Data( SrcBeamDyn_DataData, DstBeamDyn_DataData, Ctrl ENDDO ENDDO ENDIF -IF (ALLOCATED(SrcBeamDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcBeamDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcBeamDyn_DataData%Input_bak,1) - i2_l = LBOUND(SrcBeamDyn_DataData%Input_bak,2) - i2_u = UBOUND(SrcBeamDyn_DataData%Input_bak,2) - IF (.NOT. ALLOCATED(DstBeamDyn_DataData%Input_bak)) THEN - ALLOCATE(DstBeamDyn_DataData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcBeamDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcBeamDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcBeamDyn_DataData%Input_Saved,1) + i2_l = LBOUND(SrcBeamDyn_DataData%Input_Saved,2) + i2_u = UBOUND(SrcBeamDyn_DataData%Input_Saved,2) + IF (.NOT. ALLOCATED(DstBeamDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstBeamDyn_DataData%Input_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBeamDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBeamDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i2 = LBOUND(SrcBeamDyn_DataData%Input_bak,2), UBOUND(SrcBeamDyn_DataData%Input_bak,2) - DO i1 = LBOUND(SrcBeamDyn_DataData%Input_bak,1), UBOUND(SrcBeamDyn_DataData%Input_bak,1) - CALL BD_CopyInput( SrcBeamDyn_DataData%Input_bak(i1,i2), DstBeamDyn_DataData%Input_bak(i1,i2), CtrlCode, ErrStat2, ErrMsg2 ) + DO i2 = LBOUND(SrcBeamDyn_DataData%Input_Saved,2), UBOUND(SrcBeamDyn_DataData%Input_Saved,2) + DO i1 = LBOUND(SrcBeamDyn_DataData%Input_Saved,1), UBOUND(SrcBeamDyn_DataData%Input_Saved,1) + CALL BD_CopyInput( SrcBeamDyn_DataData%Input_Saved(i1,i2), DstBeamDyn_DataData%Input_Saved(i1,i2), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -18724,19 +18724,19 @@ SUBROUTINE FAST_CopyBeamDyn_Data( SrcBeamDyn_DataData, DstBeamDyn_DataData, Ctrl END IF DstBeamDyn_DataData%InputTimes = SrcBeamDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcBeamDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcBeamDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcBeamDyn_DataData%InputTimes_bak,1) - i2_l = LBOUND(SrcBeamDyn_DataData%InputTimes_bak,2) - i2_u = UBOUND(SrcBeamDyn_DataData%InputTimes_bak,2) - IF (.NOT. ALLOCATED(DstBeamDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstBeamDyn_DataData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcBeamDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcBeamDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcBeamDyn_DataData%InputTimes_Saved,1) + i2_l = LBOUND(SrcBeamDyn_DataData%InputTimes_Saved,2) + i2_u = UBOUND(SrcBeamDyn_DataData%InputTimes_Saved,2) + IF (.NOT. ALLOCATED(DstBeamDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstBeamDyn_DataData%InputTimes_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBeamDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBeamDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstBeamDyn_DataData%InputTimes_bak = SrcBeamDyn_DataData%InputTimes_bak + DstBeamDyn_DataData%InputTimes_Saved = SrcBeamDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyBeamDyn_Data @@ -18850,20 +18850,20 @@ SUBROUTINE FAST_DestroyBeamDyn_Data( BeamDyn_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(BeamDyn_DataData%Input) ENDIF -IF (ALLOCATED(BeamDyn_DataData%Input_bak)) THEN -DO i2 = LBOUND(BeamDyn_DataData%Input_bak,2), UBOUND(BeamDyn_DataData%Input_bak,2) -DO i1 = LBOUND(BeamDyn_DataData%Input_bak,1), UBOUND(BeamDyn_DataData%Input_bak,1) - CALL BD_DestroyInput( BeamDyn_DataData%Input_bak(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(BeamDyn_DataData%Input_Saved)) THEN +DO i2 = LBOUND(BeamDyn_DataData%Input_Saved,2), UBOUND(BeamDyn_DataData%Input_Saved,2) +DO i1 = LBOUND(BeamDyn_DataData%Input_Saved,1), UBOUND(BeamDyn_DataData%Input_Saved,1) + CALL BD_DestroyInput( BeamDyn_DataData%Input_Saved(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO - DEALLOCATE(BeamDyn_DataData%Input_bak) + DEALLOCATE(BeamDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(BeamDyn_DataData%InputTimes)) THEN DEALLOCATE(BeamDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(BeamDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(BeamDyn_DataData%InputTimes_bak) +IF (ALLOCATED(BeamDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(BeamDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyBeamDyn_Data @@ -19168,25 +19168,25 @@ SUBROUTINE FAST_PackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Input_bak upper/lower bounds for each dimension - DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL BD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Input_Saved upper/lower bounds for each dimension + DO i2 = LBOUND(InData%Input_Saved,2), UBOUND(InData%Input_Saved,2) + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL BD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1,i2), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -19198,10 +19198,10 @@ SUBROUTINE FAST_PackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_BufSz = Int_BufSz + 2*2 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -19711,22 +19711,22 @@ SUBROUTINE FAST_PackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_bak,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Input_bak,2), UBOUND(InData%Input_bak,2) - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL BD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i2 = LBOUND(InData%Input_Saved,2), UBOUND(InData%Input_Saved,2) + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL BD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1,i2), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -19777,22 +19777,22 @@ SUBROUTINE FAST_PackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_bak,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%InputTimes_bak,2), UBOUND(InData%InputTimes_bak,2) - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1,i2) + DO i2 = LBOUND(InData%InputTimes_Saved,2), UBOUND(InData%InputTimes_Saved,2) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1,i2) Db_Xferred = Db_Xferred + 1 END DO END DO @@ -20473,7 +20473,7 @@ SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -20483,14 +20483,14 @@ SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Input_bak,2), UBOUND(OutData%Input_bak,2) - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i2 = LBOUND(OutData%Input_Saved,2), UBOUND(OutData%Input_Saved,2) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -20524,7 +20524,7 @@ SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL BD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1,i2), ErrStat2, ErrMsg2 ) ! Input_bak + CALL BD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1,i2), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -20557,7 +20557,7 @@ SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -20567,15 +20567,15 @@ SUBROUTINE FAST_UnPackBeamDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%InputTimes_bak,2), UBOUND(OutData%InputTimes_bak,2) - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1,i2) = DbKiBuf(Db_Xferred) + DO i2 = LBOUND(OutData%InputTimes_Saved,2), UBOUND(OutData%InputTimes_Saved,2) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1,i2) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END DO @@ -20680,18 +20680,18 @@ SUBROUTINE FAST_CopyElastoDyn_Data( SrcElastoDyn_DataData, DstElastoDyn_DataData IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcElastoDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcElastoDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcElastoDyn_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstElastoDyn_DataData%Input_bak)) THEN - ALLOCATE(DstElastoDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcElastoDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcElastoDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcElastoDyn_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstElastoDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstElastoDyn_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstElastoDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstElastoDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcElastoDyn_DataData%Input_bak,1), UBOUND(SrcElastoDyn_DataData%Input_bak,1) - CALL ED_CopyInput( SrcElastoDyn_DataData%Input_bak(i1), DstElastoDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcElastoDyn_DataData%Input_Saved,1), UBOUND(SrcElastoDyn_DataData%Input_Saved,1) + CALL ED_CopyInput( SrcElastoDyn_DataData%Input_Saved(i1), DstElastoDyn_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -20708,17 +20708,17 @@ SUBROUTINE FAST_CopyElastoDyn_Data( SrcElastoDyn_DataData, DstElastoDyn_DataData END IF DstElastoDyn_DataData%InputTimes = SrcElastoDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcElastoDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcElastoDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcElastoDyn_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstElastoDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstElastoDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcElastoDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcElastoDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcElastoDyn_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstElastoDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstElastoDyn_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstElastoDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstElastoDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstElastoDyn_DataData%InputTimes_bak = SrcElastoDyn_DataData%InputTimes_bak + DstElastoDyn_DataData%InputTimes_Saved = SrcElastoDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyElastoDyn_Data @@ -20790,18 +20790,18 @@ SUBROUTINE FAST_DestroyElastoDyn_Data( ElastoDyn_DataData, ErrStat, ErrMsg, DEAL ENDDO DEALLOCATE(ElastoDyn_DataData%Input) ENDIF -IF (ALLOCATED(ElastoDyn_DataData%Input_bak)) THEN -DO i1 = LBOUND(ElastoDyn_DataData%Input_bak,1), UBOUND(ElastoDyn_DataData%Input_bak,1) - CALL ED_DestroyInput( ElastoDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(ElastoDyn_DataData%Input_Saved)) THEN +DO i1 = LBOUND(ElastoDyn_DataData%Input_Saved,1), UBOUND(ElastoDyn_DataData%Input_Saved,1) + CALL ED_DestroyInput( ElastoDyn_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(ElastoDyn_DataData%Input_bak) + DEALLOCATE(ElastoDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(ElastoDyn_DataData%InputTimes)) THEN DEALLOCATE(ElastoDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(ElastoDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(ElastoDyn_DataData%InputTimes_bak) +IF (ALLOCATED(ElastoDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(ElastoDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyElastoDyn_Data @@ -21071,24 +21071,24 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL ED_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL ED_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -21099,10 +21099,10 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -21514,18 +21514,18 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL ED_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL ED_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -21570,18 +21570,18 @@ SUBROUTINE FAST_PackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -22158,20 +22158,20 @@ SUBROUTINE FAST_UnPackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -22205,7 +22205,7 @@ SUBROUTINE FAST_UnPackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL ED_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL ED_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -22232,21 +22232,21 @@ SUBROUTINE FAST_UnPackElastoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -22337,18 +22337,18 @@ SUBROUTINE FAST_CopyServoDyn_Data( SrcServoDyn_DataData, DstServoDyn_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcServoDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcServoDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcServoDyn_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstServoDyn_DataData%Input_bak)) THEN - ALLOCATE(DstServoDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcServoDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcServoDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcServoDyn_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstServoDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstServoDyn_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstServoDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstServoDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcServoDyn_DataData%Input_bak,1), UBOUND(SrcServoDyn_DataData%Input_bak,1) - CALL SrvD_CopyInput( SrcServoDyn_DataData%Input_bak(i1), DstServoDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcServoDyn_DataData%Input_Saved,1), UBOUND(SrcServoDyn_DataData%Input_Saved,1) + CALL SrvD_CopyInput( SrcServoDyn_DataData%Input_Saved(i1), DstServoDyn_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -22365,17 +22365,17 @@ SUBROUTINE FAST_CopyServoDyn_Data( SrcServoDyn_DataData, DstServoDyn_DataData, C END IF DstServoDyn_DataData%InputTimes = SrcServoDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcServoDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcServoDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcServoDyn_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstServoDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstServoDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcServoDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcServoDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcServoDyn_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstServoDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstServoDyn_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstServoDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstServoDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstServoDyn_DataData%InputTimes_bak = SrcServoDyn_DataData%InputTimes_bak + DstServoDyn_DataData%InputTimes_Saved = SrcServoDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyServoDyn_Data @@ -22442,18 +22442,18 @@ SUBROUTINE FAST_DestroyServoDyn_Data( ServoDyn_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(ServoDyn_DataData%Input) ENDIF -IF (ALLOCATED(ServoDyn_DataData%Input_bak)) THEN -DO i1 = LBOUND(ServoDyn_DataData%Input_bak,1), UBOUND(ServoDyn_DataData%Input_bak,1) - CALL SrvD_DestroyInput( ServoDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(ServoDyn_DataData%Input_Saved)) THEN +DO i1 = LBOUND(ServoDyn_DataData%Input_Saved,1), UBOUND(ServoDyn_DataData%Input_Saved,1) + CALL SrvD_DestroyInput( ServoDyn_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(ServoDyn_DataData%Input_bak) + DEALLOCATE(ServoDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(ServoDyn_DataData%InputTimes)) THEN DEALLOCATE(ServoDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(ServoDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(ServoDyn_DataData%InputTimes_bak) +IF (ALLOCATED(ServoDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(ServoDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyServoDyn_Data @@ -22717,24 +22717,24 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL SrvD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL SrvD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -22745,10 +22745,10 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -23147,18 +23147,18 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL SrvD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL SrvD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -23203,18 +23203,18 @@ SUBROUTINE FAST_PackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -23775,20 +23775,20 @@ SUBROUTINE FAST_UnPackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -23822,7 +23822,7 @@ SUBROUTINE FAST_UnPackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SrvD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL SrvD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -23849,21 +23849,21 @@ SUBROUTINE FAST_UnPackServoDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -23932,18 +23932,18 @@ SUBROUTINE FAST_CopyAeroDyn14_Data( SrcAeroDyn14_DataData, DstAeroDyn14_DataData IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcAeroDyn14_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcAeroDyn14_DataData%Input_bak,1) - i1_u = UBOUND(SrcAeroDyn14_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstAeroDyn14_DataData%Input_bak)) THEN - ALLOCATE(DstAeroDyn14_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcAeroDyn14_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcAeroDyn14_DataData%Input_Saved,1) + i1_u = UBOUND(SrcAeroDyn14_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstAeroDyn14_DataData%Input_Saved)) THEN + ALLOCATE(DstAeroDyn14_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn14_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn14_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcAeroDyn14_DataData%Input_bak,1), UBOUND(SrcAeroDyn14_DataData%Input_bak,1) - CALL AD14_CopyInput( SrcAeroDyn14_DataData%Input_bak(i1), DstAeroDyn14_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcAeroDyn14_DataData%Input_Saved,1), UBOUND(SrcAeroDyn14_DataData%Input_Saved,1) + CALL AD14_CopyInput( SrcAeroDyn14_DataData%Input_Saved(i1), DstAeroDyn14_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -23960,17 +23960,17 @@ SUBROUTINE FAST_CopyAeroDyn14_Data( SrcAeroDyn14_DataData, DstAeroDyn14_DataData END IF DstAeroDyn14_DataData%InputTimes = SrcAeroDyn14_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcAeroDyn14_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcAeroDyn14_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcAeroDyn14_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstAeroDyn14_DataData%InputTimes_bak)) THEN - ALLOCATE(DstAeroDyn14_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcAeroDyn14_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcAeroDyn14_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcAeroDyn14_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstAeroDyn14_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstAeroDyn14_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn14_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn14_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstAeroDyn14_DataData%InputTimes_bak = SrcAeroDyn14_DataData%InputTimes_bak + DstAeroDyn14_DataData%InputTimes_Saved = SrcAeroDyn14_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyAeroDyn14_Data @@ -24026,18 +24026,18 @@ SUBROUTINE FAST_DestroyAeroDyn14_Data( AeroDyn14_DataData, ErrStat, ErrMsg, DEAL ENDDO DEALLOCATE(AeroDyn14_DataData%Input) ENDIF -IF (ALLOCATED(AeroDyn14_DataData%Input_bak)) THEN -DO i1 = LBOUND(AeroDyn14_DataData%Input_bak,1), UBOUND(AeroDyn14_DataData%Input_bak,1) - CALL AD14_DestroyInput( AeroDyn14_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(AeroDyn14_DataData%Input_Saved)) THEN +DO i1 = LBOUND(AeroDyn14_DataData%Input_Saved,1), UBOUND(AeroDyn14_DataData%Input_Saved,1) + CALL AD14_DestroyInput( AeroDyn14_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(AeroDyn14_DataData%Input_bak) + DEALLOCATE(AeroDyn14_DataData%Input_Saved) ENDIF IF (ALLOCATED(AeroDyn14_DataData%InputTimes)) THEN DEALLOCATE(AeroDyn14_DataData%InputTimes) ENDIF -IF (ALLOCATED(AeroDyn14_DataData%InputTimes_bak)) THEN - DEALLOCATE(AeroDyn14_DataData%InputTimes_bak) +IF (ALLOCATED(AeroDyn14_DataData%InputTimes_Saved)) THEN + DEALLOCATE(AeroDyn14_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyAeroDyn14_Data @@ -24244,24 +24244,24 @@ SUBROUTINE FAST_PackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL AD14_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL AD14_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -24272,10 +24272,10 @@ SUBROUTINE FAST_PackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -24577,18 +24577,18 @@ SUBROUTINE FAST_PackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL AD14_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL AD14_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -24633,18 +24633,18 @@ SUBROUTINE FAST_PackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -25069,20 +25069,20 @@ SUBROUTINE FAST_UnPackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -25116,7 +25116,7 @@ SUBROUTINE FAST_UnPackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AD14_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL AD14_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -25143,21 +25143,21 @@ SUBROUTINE FAST_UnPackAeroDyn14_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -25245,18 +25245,18 @@ SUBROUTINE FAST_CopyAeroDyn_Data( SrcAeroDyn_DataData, DstAeroDyn_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcAeroDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcAeroDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcAeroDyn_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstAeroDyn_DataData%Input_bak)) THEN - ALLOCATE(DstAeroDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcAeroDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcAeroDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcAeroDyn_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstAeroDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstAeroDyn_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcAeroDyn_DataData%Input_bak,1), UBOUND(SrcAeroDyn_DataData%Input_bak,1) - CALL AD_CopyInput( SrcAeroDyn_DataData%Input_bak(i1), DstAeroDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcAeroDyn_DataData%Input_Saved,1), UBOUND(SrcAeroDyn_DataData%Input_Saved,1) + CALL AD_CopyInput( SrcAeroDyn_DataData%Input_Saved(i1), DstAeroDyn_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -25273,17 +25273,17 @@ SUBROUTINE FAST_CopyAeroDyn_Data( SrcAeroDyn_DataData, DstAeroDyn_DataData, Ctrl END IF DstAeroDyn_DataData%InputTimes = SrcAeroDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcAeroDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcAeroDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcAeroDyn_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstAeroDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstAeroDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcAeroDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcAeroDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcAeroDyn_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstAeroDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstAeroDyn_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstAeroDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstAeroDyn_DataData%InputTimes_bak = SrcAeroDyn_DataData%InputTimes_bak + DstAeroDyn_DataData%InputTimes_Saved = SrcAeroDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyAeroDyn_Data @@ -25348,18 +25348,18 @@ SUBROUTINE FAST_DestroyAeroDyn_Data( AeroDyn_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(AeroDyn_DataData%Input) ENDIF -IF (ALLOCATED(AeroDyn_DataData%Input_bak)) THEN -DO i1 = LBOUND(AeroDyn_DataData%Input_bak,1), UBOUND(AeroDyn_DataData%Input_bak,1) - CALL AD_DestroyInput( AeroDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(AeroDyn_DataData%Input_Saved)) THEN +DO i1 = LBOUND(AeroDyn_DataData%Input_Saved,1), UBOUND(AeroDyn_DataData%Input_Saved,1) + CALL AD_DestroyInput( AeroDyn_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(AeroDyn_DataData%Input_bak) + DEALLOCATE(AeroDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(AeroDyn_DataData%InputTimes)) THEN DEALLOCATE(AeroDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(AeroDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(AeroDyn_DataData%InputTimes_bak) +IF (ALLOCATED(AeroDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(AeroDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyAeroDyn_Data @@ -25606,24 +25606,24 @@ SUBROUTINE FAST_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -25634,10 +25634,10 @@ SUBROUTINE FAST_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -26008,18 +26008,18 @@ SUBROUTINE FAST_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -26064,18 +26064,18 @@ SUBROUTINE FAST_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -26596,20 +26596,20 @@ SUBROUTINE FAST_UnPackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -26643,7 +26643,7 @@ SUBROUTINE FAST_UnPackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL AD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -26670,21 +26670,21 @@ SUBROUTINE FAST_UnPackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -27727,18 +27727,18 @@ SUBROUTINE FAST_CopyInflowWind_Data( SrcInflowWind_DataData, DstInflowWind_DataD IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcInflowWind_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcInflowWind_DataData%Input_bak,1) - i1_u = UBOUND(SrcInflowWind_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstInflowWind_DataData%Input_bak)) THEN - ALLOCATE(DstInflowWind_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInflowWind_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcInflowWind_DataData%Input_Saved,1) + i1_u = UBOUND(SrcInflowWind_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstInflowWind_DataData%Input_Saved)) THEN + ALLOCATE(DstInflowWind_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcInflowWind_DataData%Input_bak,1), UBOUND(SrcInflowWind_DataData%Input_bak,1) - CALL InflowWind_CopyInput( SrcInflowWind_DataData%Input_bak(i1), DstInflowWind_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcInflowWind_DataData%Input_Saved,1), UBOUND(SrcInflowWind_DataData%Input_Saved,1) + CALL InflowWind_CopyInput( SrcInflowWind_DataData%Input_Saved(i1), DstInflowWind_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -27755,17 +27755,17 @@ SUBROUTINE FAST_CopyInflowWind_Data( SrcInflowWind_DataData, DstInflowWind_DataD END IF DstInflowWind_DataData%InputTimes = SrcInflowWind_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcInflowWind_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcInflowWind_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcInflowWind_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstInflowWind_DataData%InputTimes_bak)) THEN - ALLOCATE(DstInflowWind_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInflowWind_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcInflowWind_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcInflowWind_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstInflowWind_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstInflowWind_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInflowWind_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInflowWind_DataData%InputTimes_bak = SrcInflowWind_DataData%InputTimes_bak + DstInflowWind_DataData%InputTimes_Saved = SrcInflowWind_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyInflowWind_Data @@ -27830,18 +27830,18 @@ SUBROUTINE FAST_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg, DE ENDDO DEALLOCATE(InflowWind_DataData%Input) ENDIF -IF (ALLOCATED(InflowWind_DataData%Input_bak)) THEN -DO i1 = LBOUND(InflowWind_DataData%Input_bak,1), UBOUND(InflowWind_DataData%Input_bak,1) - CALL InflowWind_DestroyInput( InflowWind_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(InflowWind_DataData%Input_Saved)) THEN +DO i1 = LBOUND(InflowWind_DataData%Input_Saved,1), UBOUND(InflowWind_DataData%Input_Saved,1) + CALL InflowWind_DestroyInput( InflowWind_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(InflowWind_DataData%Input_bak) + DEALLOCATE(InflowWind_DataData%Input_Saved) ENDIF IF (ALLOCATED(InflowWind_DataData%InputTimes)) THEN DEALLOCATE(InflowWind_DataData%InputTimes) ENDIF -IF (ALLOCATED(InflowWind_DataData%InputTimes_bak)) THEN - DEALLOCATE(InflowWind_DataData%InputTimes_bak) +IF (ALLOCATED(InflowWind_DataData%InputTimes_Saved)) THEN + DEALLOCATE(InflowWind_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyInflowWind_Data @@ -28088,24 +28088,24 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -28116,10 +28116,10 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -28490,18 +28490,18 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -28546,18 +28546,18 @@ SUBROUTINE FAST_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -29078,20 +29078,20 @@ SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -29125,7 +29125,7 @@ SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -29152,21 +29152,21 @@ SUBROUTINE FAST_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -30129,18 +30129,18 @@ SUBROUTINE FAST_CopySubDyn_Data( SrcSubDyn_DataData, DstSubDyn_DataData, CtrlCod IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcSubDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcSubDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcSubDyn_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstSubDyn_DataData%Input_bak)) THEN - ALLOCATE(DstSubDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcSubDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcSubDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcSubDyn_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstSubDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstSubDyn_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSubDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSubDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcSubDyn_DataData%Input_bak,1), UBOUND(SrcSubDyn_DataData%Input_bak,1) - CALL SD_CopyInput( SrcSubDyn_DataData%Input_bak(i1), DstSubDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcSubDyn_DataData%Input_Saved,1), UBOUND(SrcSubDyn_DataData%Input_Saved,1) + CALL SD_CopyInput( SrcSubDyn_DataData%Input_Saved(i1), DstSubDyn_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -30176,17 +30176,17 @@ SUBROUTINE FAST_CopySubDyn_Data( SrcSubDyn_DataData, DstSubDyn_DataData, CtrlCod END IF DstSubDyn_DataData%InputTimes = SrcSubDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcSubDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcSubDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcSubDyn_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstSubDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstSubDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcSubDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcSubDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcSubDyn_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstSubDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstSubDyn_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSubDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSubDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstSubDyn_DataData%InputTimes_bak = SrcSubDyn_DataData%InputTimes_bak + DstSubDyn_DataData%InputTimes_Saved = SrcSubDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopySubDyn_Data @@ -30242,12 +30242,12 @@ SUBROUTINE FAST_DestroySubDyn_Data( SubDyn_DataData, ErrStat, ErrMsg, DEALLOCATE ENDDO DEALLOCATE(SubDyn_DataData%Input) ENDIF -IF (ALLOCATED(SubDyn_DataData%Input_bak)) THEN -DO i1 = LBOUND(SubDyn_DataData%Input_bak,1), UBOUND(SubDyn_DataData%Input_bak,1) - CALL SD_DestroyInput( SubDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(SubDyn_DataData%Input_Saved)) THEN +DO i1 = LBOUND(SubDyn_DataData%Input_Saved,1), UBOUND(SubDyn_DataData%Input_Saved,1) + CALL SD_DestroyInput( SubDyn_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(SubDyn_DataData%Input_bak) + DEALLOCATE(SubDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(SubDyn_DataData%Output)) THEN DO i1 = LBOUND(SubDyn_DataData%Output,1), UBOUND(SubDyn_DataData%Output,1) @@ -30261,8 +30261,8 @@ SUBROUTINE FAST_DestroySubDyn_Data( SubDyn_DataData, ErrStat, ErrMsg, DEALLOCATE IF (ALLOCATED(SubDyn_DataData%InputTimes)) THEN DEALLOCATE(SubDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(SubDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(SubDyn_DataData%InputTimes_bak) +IF (ALLOCATED(SubDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(SubDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroySubDyn_Data @@ -30469,24 +30469,24 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL SD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL SD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -30537,10 +30537,10 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -30842,18 +30842,18 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL SD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL SD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -30967,18 +30967,18 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -31403,20 +31403,20 @@ SUBROUTINE FAST_UnPackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -31450,7 +31450,7 @@ SUBROUTINE FAST_UnPackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL SD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -31573,21 +31573,21 @@ SUBROUTINE FAST_UnPackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -31656,18 +31656,18 @@ SUBROUTINE FAST_CopyExtPtfm_Data( SrcExtPtfm_DataData, DstExtPtfm_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcExtPtfm_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcExtPtfm_DataData%Input_bak,1) - i1_u = UBOUND(SrcExtPtfm_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstExtPtfm_DataData%Input_bak)) THEN - ALLOCATE(DstExtPtfm_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcExtPtfm_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcExtPtfm_DataData%Input_Saved,1) + i1_u = UBOUND(SrcExtPtfm_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstExtPtfm_DataData%Input_Saved)) THEN + ALLOCATE(DstExtPtfm_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstExtPtfm_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstExtPtfm_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcExtPtfm_DataData%Input_bak,1), UBOUND(SrcExtPtfm_DataData%Input_bak,1) - CALL ExtPtfm_CopyInput( SrcExtPtfm_DataData%Input_bak(i1), DstExtPtfm_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcExtPtfm_DataData%Input_Saved,1), UBOUND(SrcExtPtfm_DataData%Input_Saved,1) + CALL ExtPtfm_CopyInput( SrcExtPtfm_DataData%Input_Saved(i1), DstExtPtfm_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -31684,17 +31684,17 @@ SUBROUTINE FAST_CopyExtPtfm_Data( SrcExtPtfm_DataData, DstExtPtfm_DataData, Ctrl END IF DstExtPtfm_DataData%InputTimes = SrcExtPtfm_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcExtPtfm_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcExtPtfm_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcExtPtfm_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstExtPtfm_DataData%InputTimes_bak)) THEN - ALLOCATE(DstExtPtfm_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcExtPtfm_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcExtPtfm_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcExtPtfm_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstExtPtfm_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstExtPtfm_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstExtPtfm_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstExtPtfm_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstExtPtfm_DataData%InputTimes_bak = SrcExtPtfm_DataData%InputTimes_bak + DstExtPtfm_DataData%InputTimes_Saved = SrcExtPtfm_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyExtPtfm_Data @@ -31750,18 +31750,18 @@ SUBROUTINE FAST_DestroyExtPtfm_Data( ExtPtfm_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(ExtPtfm_DataData%Input) ENDIF -IF (ALLOCATED(ExtPtfm_DataData%Input_bak)) THEN -DO i1 = LBOUND(ExtPtfm_DataData%Input_bak,1), UBOUND(ExtPtfm_DataData%Input_bak,1) - CALL ExtPtfm_DestroyInput( ExtPtfm_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(ExtPtfm_DataData%Input_Saved)) THEN +DO i1 = LBOUND(ExtPtfm_DataData%Input_Saved,1), UBOUND(ExtPtfm_DataData%Input_Saved,1) + CALL ExtPtfm_DestroyInput( ExtPtfm_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(ExtPtfm_DataData%Input_bak) + DEALLOCATE(ExtPtfm_DataData%Input_Saved) ENDIF IF (ALLOCATED(ExtPtfm_DataData%InputTimes)) THEN DEALLOCATE(ExtPtfm_DataData%InputTimes) ENDIF -IF (ALLOCATED(ExtPtfm_DataData%InputTimes_bak)) THEN - DEALLOCATE(ExtPtfm_DataData%InputTimes_bak) +IF (ALLOCATED(ExtPtfm_DataData%InputTimes_Saved)) THEN + DEALLOCATE(ExtPtfm_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyExtPtfm_Data @@ -31968,24 +31968,24 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -31996,10 +31996,10 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -32301,18 +32301,18 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL ExtPtfm_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -32357,18 +32357,18 @@ SUBROUTINE FAST_PackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -32793,20 +32793,20 @@ SUBROUTINE FAST_UnPackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -32840,7 +32840,7 @@ SUBROUTINE FAST_UnPackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL ExtPtfm_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL ExtPtfm_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -32867,21 +32867,21 @@ SUBROUTINE FAST_UnPackExtPtfm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -32950,18 +32950,18 @@ SUBROUTINE FAST_CopySeaState_Data( SrcSeaState_DataData, DstSeaState_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcSeaState_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcSeaState_DataData%Input_bak,1) - i1_u = UBOUND(SrcSeaState_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstSeaState_DataData%Input_bak)) THEN - ALLOCATE(DstSeaState_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcSeaState_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcSeaState_DataData%Input_Saved,1) + i1_u = UBOUND(SrcSeaState_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstSeaState_DataData%Input_Saved)) THEN + ALLOCATE(DstSeaState_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSeaState_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSeaState_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcSeaState_DataData%Input_bak,1), UBOUND(SrcSeaState_DataData%Input_bak,1) - CALL SeaSt_CopyInput( SrcSeaState_DataData%Input_bak(i1), DstSeaState_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcSeaState_DataData%Input_Saved,1), UBOUND(SrcSeaState_DataData%Input_Saved,1) + CALL SeaSt_CopyInput( SrcSeaState_DataData%Input_Saved(i1), DstSeaState_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -32997,17 +32997,17 @@ SUBROUTINE FAST_CopySeaState_Data( SrcSeaState_DataData, DstSeaState_DataData, C END IF DstSeaState_DataData%InputTimes = SrcSeaState_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcSeaState_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcSeaState_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcSeaState_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstSeaState_DataData%InputTimes_bak)) THEN - ALLOCATE(DstSeaState_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcSeaState_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcSeaState_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcSeaState_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstSeaState_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstSeaState_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSeaState_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSeaState_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstSeaState_DataData%InputTimes_bak = SrcSeaState_DataData%InputTimes_bak + DstSeaState_DataData%InputTimes_Saved = SrcSeaState_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopySeaState_Data @@ -33063,12 +33063,12 @@ SUBROUTINE FAST_DestroySeaState_Data( SeaState_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(SeaState_DataData%Input) ENDIF -IF (ALLOCATED(SeaState_DataData%Input_bak)) THEN -DO i1 = LBOUND(SeaState_DataData%Input_bak,1), UBOUND(SeaState_DataData%Input_bak,1) - CALL SeaSt_DestroyInput( SeaState_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(SeaState_DataData%Input_Saved)) THEN +DO i1 = LBOUND(SeaState_DataData%Input_Saved,1), UBOUND(SeaState_DataData%Input_Saved,1) + CALL SeaSt_DestroyInput( SeaState_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(SeaState_DataData%Input_bak) + DEALLOCATE(SeaState_DataData%Input_Saved) ENDIF IF (ALLOCATED(SeaState_DataData%Output)) THEN DO i1 = LBOUND(SeaState_DataData%Output,1), UBOUND(SeaState_DataData%Output,1) @@ -33082,8 +33082,8 @@ SUBROUTINE FAST_DestroySeaState_Data( SeaState_DataData, ErrStat, ErrMsg, DEALLO IF (ALLOCATED(SeaState_DataData%InputTimes)) THEN DEALLOCATE(SeaState_DataData%InputTimes) ENDIF -IF (ALLOCATED(SeaState_DataData%InputTimes_bak)) THEN - DEALLOCATE(SeaState_DataData%InputTimes_bak) +IF (ALLOCATED(SeaState_DataData%InputTimes_Saved)) THEN + DEALLOCATE(SeaState_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroySeaState_Data @@ -33290,24 +33290,24 @@ SUBROUTINE FAST_PackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL SeaSt_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL SeaSt_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -33358,10 +33358,10 @@ SUBROUTINE FAST_PackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -33663,18 +33663,18 @@ SUBROUTINE FAST_PackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL SeaSt_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL SeaSt_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -33788,18 +33788,18 @@ SUBROUTINE FAST_PackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -34224,20 +34224,20 @@ SUBROUTINE FAST_UnPackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -34271,7 +34271,7 @@ SUBROUTINE FAST_UnPackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SeaSt_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL SeaSt_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -34394,21 +34394,21 @@ SUBROUTINE FAST_UnPackSeaState_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -34496,18 +34496,18 @@ SUBROUTINE FAST_CopyHydroDyn_Data( SrcHydroDyn_DataData, DstHydroDyn_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcHydroDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcHydroDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcHydroDyn_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstHydroDyn_DataData%Input_bak)) THEN - ALLOCATE(DstHydroDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcHydroDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcHydroDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcHydroDyn_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstHydroDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstHydroDyn_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHydroDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHydroDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcHydroDyn_DataData%Input_bak,1), UBOUND(SrcHydroDyn_DataData%Input_bak,1) - CALL HydroDyn_CopyInput( SrcHydroDyn_DataData%Input_bak(i1), DstHydroDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcHydroDyn_DataData%Input_Saved,1), UBOUND(SrcHydroDyn_DataData%Input_Saved,1) + CALL HydroDyn_CopyInput( SrcHydroDyn_DataData%Input_Saved(i1), DstHydroDyn_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -34524,17 +34524,17 @@ SUBROUTINE FAST_CopyHydroDyn_Data( SrcHydroDyn_DataData, DstHydroDyn_DataData, C END IF DstHydroDyn_DataData%InputTimes = SrcHydroDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcHydroDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcHydroDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcHydroDyn_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstHydroDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstHydroDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcHydroDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcHydroDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcHydroDyn_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstHydroDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstHydroDyn_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHydroDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHydroDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstHydroDyn_DataData%InputTimes_bak = SrcHydroDyn_DataData%InputTimes_bak + DstHydroDyn_DataData%InputTimes_Saved = SrcHydroDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyHydroDyn_Data @@ -34599,18 +34599,18 @@ SUBROUTINE FAST_DestroyHydroDyn_Data( HydroDyn_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(HydroDyn_DataData%Input) ENDIF -IF (ALLOCATED(HydroDyn_DataData%Input_bak)) THEN -DO i1 = LBOUND(HydroDyn_DataData%Input_bak,1), UBOUND(HydroDyn_DataData%Input_bak,1) - CALL HydroDyn_DestroyInput( HydroDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(HydroDyn_DataData%Input_Saved)) THEN +DO i1 = LBOUND(HydroDyn_DataData%Input_Saved,1), UBOUND(HydroDyn_DataData%Input_Saved,1) + CALL HydroDyn_DestroyInput( HydroDyn_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(HydroDyn_DataData%Input_bak) + DEALLOCATE(HydroDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(HydroDyn_DataData%InputTimes)) THEN DEALLOCATE(HydroDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(HydroDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(HydroDyn_DataData%InputTimes_bak) +IF (ALLOCATED(HydroDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(HydroDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyHydroDyn_Data @@ -34857,24 +34857,24 @@ SUBROUTINE FAST_PackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL HydroDyn_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL HydroDyn_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -34885,10 +34885,10 @@ SUBROUTINE FAST_PackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -35259,18 +35259,18 @@ SUBROUTINE FAST_PackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL HydroDyn_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL HydroDyn_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -35315,18 +35315,18 @@ SUBROUTINE FAST_PackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -35847,20 +35847,20 @@ SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -35894,7 +35894,7 @@ SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL HydroDyn_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL HydroDyn_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -35921,21 +35921,21 @@ SUBROUTINE FAST_UnPackHydroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -36004,18 +36004,18 @@ SUBROUTINE FAST_CopyIceFloe_Data( SrcIceFloe_DataData, DstIceFloe_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcIceFloe_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcIceFloe_DataData%Input_bak,1) - i1_u = UBOUND(SrcIceFloe_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstIceFloe_DataData%Input_bak)) THEN - ALLOCATE(DstIceFloe_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcIceFloe_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcIceFloe_DataData%Input_Saved,1) + i1_u = UBOUND(SrcIceFloe_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstIceFloe_DataData%Input_Saved)) THEN + ALLOCATE(DstIceFloe_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceFloe_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceFloe_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcIceFloe_DataData%Input_bak,1), UBOUND(SrcIceFloe_DataData%Input_bak,1) - CALL IceFloe_CopyInput( SrcIceFloe_DataData%Input_bak(i1), DstIceFloe_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcIceFloe_DataData%Input_Saved,1), UBOUND(SrcIceFloe_DataData%Input_Saved,1) + CALL IceFloe_CopyInput( SrcIceFloe_DataData%Input_Saved(i1), DstIceFloe_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -36032,17 +36032,17 @@ SUBROUTINE FAST_CopyIceFloe_Data( SrcIceFloe_DataData, DstIceFloe_DataData, Ctrl END IF DstIceFloe_DataData%InputTimes = SrcIceFloe_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcIceFloe_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcIceFloe_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcIceFloe_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstIceFloe_DataData%InputTimes_bak)) THEN - ALLOCATE(DstIceFloe_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcIceFloe_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcIceFloe_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcIceFloe_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstIceFloe_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstIceFloe_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceFloe_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIceFloe_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstIceFloe_DataData%InputTimes_bak = SrcIceFloe_DataData%InputTimes_bak + DstIceFloe_DataData%InputTimes_Saved = SrcIceFloe_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyIceFloe_Data @@ -36098,18 +36098,18 @@ SUBROUTINE FAST_DestroyIceFloe_Data( IceFloe_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(IceFloe_DataData%Input) ENDIF -IF (ALLOCATED(IceFloe_DataData%Input_bak)) THEN -DO i1 = LBOUND(IceFloe_DataData%Input_bak,1), UBOUND(IceFloe_DataData%Input_bak,1) - CALL IceFloe_DestroyInput( IceFloe_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(IceFloe_DataData%Input_Saved)) THEN +DO i1 = LBOUND(IceFloe_DataData%Input_Saved,1), UBOUND(IceFloe_DataData%Input_Saved,1) + CALL IceFloe_DestroyInput( IceFloe_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(IceFloe_DataData%Input_bak) + DEALLOCATE(IceFloe_DataData%Input_Saved) ENDIF IF (ALLOCATED(IceFloe_DataData%InputTimes)) THEN DEALLOCATE(IceFloe_DataData%InputTimes) ENDIF -IF (ALLOCATED(IceFloe_DataData%InputTimes_bak)) THEN - DEALLOCATE(IceFloe_DataData%InputTimes_bak) +IF (ALLOCATED(IceFloe_DataData%InputTimes_Saved)) THEN + DEALLOCATE(IceFloe_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyIceFloe_Data @@ -36316,24 +36316,24 @@ SUBROUTINE FAST_PackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL IceFloe_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL IceFloe_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -36344,10 +36344,10 @@ SUBROUTINE FAST_PackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -36649,18 +36649,18 @@ SUBROUTINE FAST_PackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL IceFloe_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL IceFloe_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -36705,18 +36705,18 @@ SUBROUTINE FAST_PackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -37141,20 +37141,20 @@ SUBROUTINE FAST_UnPackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -37188,7 +37188,7 @@ SUBROUTINE FAST_UnPackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IceFloe_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL IceFloe_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -37215,21 +37215,21 @@ SUBROUTINE FAST_UnPackIceFloe_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -37315,18 +37315,18 @@ SUBROUTINE FAST_CopyMAP_Data( SrcMAP_DataData, DstMAP_DataData, CtrlCode, ErrSta IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcMAP_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcMAP_DataData%Input_bak,1) - i1_u = UBOUND(SrcMAP_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstMAP_DataData%Input_bak)) THEN - ALLOCATE(DstMAP_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMAP_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcMAP_DataData%Input_Saved,1) + i1_u = UBOUND(SrcMAP_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstMAP_DataData%Input_Saved)) THEN + ALLOCATE(DstMAP_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMAP_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMAP_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcMAP_DataData%Input_bak,1), UBOUND(SrcMAP_DataData%Input_bak,1) - CALL MAP_CopyInput( SrcMAP_DataData%Input_bak(i1), DstMAP_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcMAP_DataData%Input_Saved,1), UBOUND(SrcMAP_DataData%Input_Saved,1) + CALL MAP_CopyInput( SrcMAP_DataData%Input_Saved(i1), DstMAP_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -37343,17 +37343,17 @@ SUBROUTINE FAST_CopyMAP_Data( SrcMAP_DataData, DstMAP_DataData, CtrlCode, ErrSta END IF DstMAP_DataData%InputTimes = SrcMAP_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcMAP_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcMAP_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcMAP_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstMAP_DataData%InputTimes_bak)) THEN - ALLOCATE(DstMAP_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMAP_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcMAP_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcMAP_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstMAP_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstMAP_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMAP_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMAP_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMAP_DataData%InputTimes_bak = SrcMAP_DataData%InputTimes_bak + DstMAP_DataData%InputTimes_Saved = SrcMAP_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyMAP_Data @@ -37416,18 +37416,18 @@ SUBROUTINE FAST_DestroyMAP_Data( MAP_DataData, ErrStat, ErrMsg, DEALLOCATEpointe ENDDO DEALLOCATE(MAP_DataData%Input) ENDIF -IF (ALLOCATED(MAP_DataData%Input_bak)) THEN -DO i1 = LBOUND(MAP_DataData%Input_bak,1), UBOUND(MAP_DataData%Input_bak,1) - CALL MAP_DestroyInput( MAP_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(MAP_DataData%Input_Saved)) THEN +DO i1 = LBOUND(MAP_DataData%Input_Saved,1), UBOUND(MAP_DataData%Input_Saved,1) + CALL MAP_DestroyInput( MAP_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(MAP_DataData%Input_bak) + DEALLOCATE(MAP_DataData%Input_Saved) ENDIF IF (ALLOCATED(MAP_DataData%InputTimes)) THEN DEALLOCATE(MAP_DataData%InputTimes) ENDIF -IF (ALLOCATED(MAP_DataData%InputTimes_bak)) THEN - DEALLOCATE(MAP_DataData%InputTimes_bak) +IF (ALLOCATED(MAP_DataData%InputTimes_Saved)) THEN + DEALLOCATE(MAP_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyMAP_Data @@ -37672,24 +37672,24 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -37700,10 +37700,10 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -38072,18 +38072,18 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL MAP_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38128,18 +38128,18 @@ SUBROUTINE FAST_PackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -38656,20 +38656,20 @@ SUBROUTINE FAST_UnPackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -38703,7 +38703,7 @@ SUBROUTINE FAST_UnPackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MAP_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL MAP_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38730,21 +38730,21 @@ SUBROUTINE FAST_UnPackMAP_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -38813,18 +38813,18 @@ SUBROUTINE FAST_CopyFEAMooring_Data( SrcFEAMooring_DataData, DstFEAMooring_DataD IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcFEAMooring_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcFEAMooring_DataData%Input_bak,1) - i1_u = UBOUND(SrcFEAMooring_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstFEAMooring_DataData%Input_bak)) THEN - ALLOCATE(DstFEAMooring_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcFEAMooring_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcFEAMooring_DataData%Input_Saved,1) + i1_u = UBOUND(SrcFEAMooring_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstFEAMooring_DataData%Input_Saved)) THEN + ALLOCATE(DstFEAMooring_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEAMooring_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEAMooring_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcFEAMooring_DataData%Input_bak,1), UBOUND(SrcFEAMooring_DataData%Input_bak,1) - CALL FEAM_CopyInput( SrcFEAMooring_DataData%Input_bak(i1), DstFEAMooring_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcFEAMooring_DataData%Input_Saved,1), UBOUND(SrcFEAMooring_DataData%Input_Saved,1) + CALL FEAM_CopyInput( SrcFEAMooring_DataData%Input_Saved(i1), DstFEAMooring_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -38841,17 +38841,17 @@ SUBROUTINE FAST_CopyFEAMooring_Data( SrcFEAMooring_DataData, DstFEAMooring_DataD END IF DstFEAMooring_DataData%InputTimes = SrcFEAMooring_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcFEAMooring_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcFEAMooring_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcFEAMooring_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstFEAMooring_DataData%InputTimes_bak)) THEN - ALLOCATE(DstFEAMooring_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcFEAMooring_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcFEAMooring_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcFEAMooring_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstFEAMooring_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstFEAMooring_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEAMooring_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEAMooring_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstFEAMooring_DataData%InputTimes_bak = SrcFEAMooring_DataData%InputTimes_bak + DstFEAMooring_DataData%InputTimes_Saved = SrcFEAMooring_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyFEAMooring_Data @@ -38907,18 +38907,18 @@ SUBROUTINE FAST_DestroyFEAMooring_Data( FEAMooring_DataData, ErrStat, ErrMsg, DE ENDDO DEALLOCATE(FEAMooring_DataData%Input) ENDIF -IF (ALLOCATED(FEAMooring_DataData%Input_bak)) THEN -DO i1 = LBOUND(FEAMooring_DataData%Input_bak,1), UBOUND(FEAMooring_DataData%Input_bak,1) - CALL FEAM_DestroyInput( FEAMooring_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(FEAMooring_DataData%Input_Saved)) THEN +DO i1 = LBOUND(FEAMooring_DataData%Input_Saved,1), UBOUND(FEAMooring_DataData%Input_Saved,1) + CALL FEAM_DestroyInput( FEAMooring_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(FEAMooring_DataData%Input_bak) + DEALLOCATE(FEAMooring_DataData%Input_Saved) ENDIF IF (ALLOCATED(FEAMooring_DataData%InputTimes)) THEN DEALLOCATE(FEAMooring_DataData%InputTimes) ENDIF -IF (ALLOCATED(FEAMooring_DataData%InputTimes_bak)) THEN - DEALLOCATE(FEAMooring_DataData%InputTimes_bak) +IF (ALLOCATED(FEAMooring_DataData%InputTimes_Saved)) THEN + DEALLOCATE(FEAMooring_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyFEAMooring_Data @@ -39125,24 +39125,24 @@ SUBROUTINE FAST_PackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL FEAM_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL FEAM_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -39153,10 +39153,10 @@ SUBROUTINE FAST_PackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -39458,18 +39458,18 @@ SUBROUTINE FAST_PackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL FEAM_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL FEAM_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -39514,18 +39514,18 @@ SUBROUTINE FAST_PackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -39950,20 +39950,20 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -39997,7 +39997,7 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL FEAM_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL FEAM_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40024,21 +40024,21 @@ SUBROUTINE FAST_UnPackFEAMooring_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -40126,18 +40126,18 @@ SUBROUTINE FAST_CopyMoorDyn_Data( SrcMoorDyn_DataData, DstMoorDyn_DataData, Ctrl IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcMoorDyn_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcMoorDyn_DataData%Input_bak,1) - i1_u = UBOUND(SrcMoorDyn_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstMoorDyn_DataData%Input_bak)) THEN - ALLOCATE(DstMoorDyn_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMoorDyn_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcMoorDyn_DataData%Input_Saved,1) + i1_u = UBOUND(SrcMoorDyn_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstMoorDyn_DataData%Input_Saved)) THEN + ALLOCATE(DstMoorDyn_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMoorDyn_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMoorDyn_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcMoorDyn_DataData%Input_bak,1), UBOUND(SrcMoorDyn_DataData%Input_bak,1) - CALL MD_CopyInput( SrcMoorDyn_DataData%Input_bak(i1), DstMoorDyn_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcMoorDyn_DataData%Input_Saved,1), UBOUND(SrcMoorDyn_DataData%Input_Saved,1) + CALL MD_CopyInput( SrcMoorDyn_DataData%Input_Saved(i1), DstMoorDyn_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -40154,17 +40154,17 @@ SUBROUTINE FAST_CopyMoorDyn_Data( SrcMoorDyn_DataData, DstMoorDyn_DataData, Ctrl END IF DstMoorDyn_DataData%InputTimes = SrcMoorDyn_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcMoorDyn_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcMoorDyn_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcMoorDyn_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstMoorDyn_DataData%InputTimes_bak)) THEN - ALLOCATE(DstMoorDyn_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMoorDyn_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcMoorDyn_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcMoorDyn_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstMoorDyn_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstMoorDyn_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMoorDyn_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMoorDyn_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMoorDyn_DataData%InputTimes_bak = SrcMoorDyn_DataData%InputTimes_bak + DstMoorDyn_DataData%InputTimes_Saved = SrcMoorDyn_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyMoorDyn_Data @@ -40229,18 +40229,18 @@ SUBROUTINE FAST_DestroyMoorDyn_Data( MoorDyn_DataData, ErrStat, ErrMsg, DEALLOCA ENDDO DEALLOCATE(MoorDyn_DataData%Input) ENDIF -IF (ALLOCATED(MoorDyn_DataData%Input_bak)) THEN -DO i1 = LBOUND(MoorDyn_DataData%Input_bak,1), UBOUND(MoorDyn_DataData%Input_bak,1) - CALL MD_DestroyInput( MoorDyn_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(MoorDyn_DataData%Input_Saved)) THEN +DO i1 = LBOUND(MoorDyn_DataData%Input_Saved,1), UBOUND(MoorDyn_DataData%Input_Saved,1) + CALL MD_DestroyInput( MoorDyn_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(MoorDyn_DataData%Input_bak) + DEALLOCATE(MoorDyn_DataData%Input_Saved) ENDIF IF (ALLOCATED(MoorDyn_DataData%InputTimes)) THEN DEALLOCATE(MoorDyn_DataData%InputTimes) ENDIF -IF (ALLOCATED(MoorDyn_DataData%InputTimes_bak)) THEN - DEALLOCATE(MoorDyn_DataData%InputTimes_bak) +IF (ALLOCATED(MoorDyn_DataData%InputTimes_Saved)) THEN + DEALLOCATE(MoorDyn_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyMoorDyn_Data @@ -40487,24 +40487,24 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -40515,10 +40515,10 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -40889,18 +40889,18 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40945,18 +40945,18 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -41477,20 +41477,20 @@ SUBROUTINE FAST_UnPackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -41524,7 +41524,7 @@ SUBROUTINE FAST_UnPackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL MD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41551,21 +41551,21 @@ SUBROUTINE FAST_UnPackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -41634,18 +41634,18 @@ SUBROUTINE FAST_CopyOrcaFlex_Data( SrcOrcaFlex_DataData, DstOrcaFlex_DataData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcOrcaFlex_DataData%Input_bak)) THEN - i1_l = LBOUND(SrcOrcaFlex_DataData%Input_bak,1) - i1_u = UBOUND(SrcOrcaFlex_DataData%Input_bak,1) - IF (.NOT. ALLOCATED(DstOrcaFlex_DataData%Input_bak)) THEN - ALLOCATE(DstOrcaFlex_DataData%Input_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcOrcaFlex_DataData%Input_Saved)) THEN + i1_l = LBOUND(SrcOrcaFlex_DataData%Input_Saved,1) + i1_u = UBOUND(SrcOrcaFlex_DataData%Input_Saved,1) + IF (.NOT. ALLOCATED(DstOrcaFlex_DataData%Input_Saved)) THEN + ALLOCATE(DstOrcaFlex_DataData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOrcaFlex_DataData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOrcaFlex_DataData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcOrcaFlex_DataData%Input_bak,1), UBOUND(SrcOrcaFlex_DataData%Input_bak,1) - CALL Orca_CopyInput( SrcOrcaFlex_DataData%Input_bak(i1), DstOrcaFlex_DataData%Input_bak(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcOrcaFlex_DataData%Input_Saved,1), UBOUND(SrcOrcaFlex_DataData%Input_Saved,1) + CALL Orca_CopyInput( SrcOrcaFlex_DataData%Input_Saved(i1), DstOrcaFlex_DataData%Input_Saved(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO @@ -41662,17 +41662,17 @@ SUBROUTINE FAST_CopyOrcaFlex_Data( SrcOrcaFlex_DataData, DstOrcaFlex_DataData, C END IF DstOrcaFlex_DataData%InputTimes = SrcOrcaFlex_DataData%InputTimes ENDIF -IF (ALLOCATED(SrcOrcaFlex_DataData%InputTimes_bak)) THEN - i1_l = LBOUND(SrcOrcaFlex_DataData%InputTimes_bak,1) - i1_u = UBOUND(SrcOrcaFlex_DataData%InputTimes_bak,1) - IF (.NOT. ALLOCATED(DstOrcaFlex_DataData%InputTimes_bak)) THEN - ALLOCATE(DstOrcaFlex_DataData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcOrcaFlex_DataData%InputTimes_Saved)) THEN + i1_l = LBOUND(SrcOrcaFlex_DataData%InputTimes_Saved,1) + i1_u = UBOUND(SrcOrcaFlex_DataData%InputTimes_Saved,1) + IF (.NOT. ALLOCATED(DstOrcaFlex_DataData%InputTimes_Saved)) THEN + ALLOCATE(DstOrcaFlex_DataData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOrcaFlex_DataData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOrcaFlex_DataData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstOrcaFlex_DataData%InputTimes_bak = SrcOrcaFlex_DataData%InputTimes_bak + DstOrcaFlex_DataData%InputTimes_Saved = SrcOrcaFlex_DataData%InputTimes_Saved ENDIF END SUBROUTINE FAST_CopyOrcaFlex_Data @@ -41728,18 +41728,18 @@ SUBROUTINE FAST_DestroyOrcaFlex_Data( OrcaFlex_DataData, ErrStat, ErrMsg, DEALLO ENDDO DEALLOCATE(OrcaFlex_DataData%Input) ENDIF -IF (ALLOCATED(OrcaFlex_DataData%Input_bak)) THEN -DO i1 = LBOUND(OrcaFlex_DataData%Input_bak,1), UBOUND(OrcaFlex_DataData%Input_bak,1) - CALL Orca_DestroyInput( OrcaFlex_DataData%Input_bak(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) +IF (ALLOCATED(OrcaFlex_DataData%Input_Saved)) THEN +DO i1 = LBOUND(OrcaFlex_DataData%Input_Saved,1), UBOUND(OrcaFlex_DataData%Input_Saved,1) + CALL Orca_DestroyInput( OrcaFlex_DataData%Input_Saved(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(OrcaFlex_DataData%Input_bak) + DEALLOCATE(OrcaFlex_DataData%Input_Saved) ENDIF IF (ALLOCATED(OrcaFlex_DataData%InputTimes)) THEN DEALLOCATE(OrcaFlex_DataData%InputTimes) ENDIF -IF (ALLOCATED(OrcaFlex_DataData%InputTimes_bak)) THEN - DEALLOCATE(OrcaFlex_DataData%InputTimes_bak) +IF (ALLOCATED(OrcaFlex_DataData%InputTimes_Saved)) THEN + DEALLOCATE(OrcaFlex_DataData%InputTimes_Saved) ENDIF END SUBROUTINE FAST_DestroyOrcaFlex_Data @@ -41946,24 +41946,24 @@ SUBROUTINE FAST_PackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Input_bak allocated yes/no - IF ( ALLOCATED(InData%Input_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Input_bak upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - Int_BufSz = Int_BufSz + 3 ! Input_bak: size of buffers for each call to pack subtype - CALL Orca_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_bak + Int_BufSz = Int_BufSz + 1 ! Input_Saved allocated yes/no + IF ( ALLOCATED(InData%Input_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input_Saved upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + Int_BufSz = Int_BufSz + 3 ! Input_Saved: size of buffers for each call to pack subtype + CALL Orca_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Input_bak + IF(ALLOCATED(Re_Buf)) THEN ! Input_Saved Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Input_bak + IF(ALLOCATED(Db_Buf)) THEN ! Input_Saved Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Input_bak + IF(ALLOCATED(Int_Buf)) THEN ! Input_Saved Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -41974,10 +41974,10 @@ SUBROUTINE FAST_PackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes END IF - Int_BufSz = Int_BufSz + 1 ! InputTimes_bak allocated yes/no - IF ( ALLOCATED(InData%InputTimes_bak) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InputTimes_bak upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_bak) ! InputTimes_bak + Int_BufSz = Int_BufSz + 1 ! InputTimes_Saved allocated yes/no + IF ( ALLOCATED(InData%InputTimes_Saved) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes_Saved upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes_Saved) ! InputTimes_Saved END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -42279,18 +42279,18 @@ SUBROUTINE FAST_PackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Input_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%Input_Saved) ) 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%Input_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Input_bak,1), UBOUND(InData%Input_bak,1) - CALL Orca_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_bak(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_bak + DO i1 = LBOUND(InData%Input_Saved,1), UBOUND(InData%Input_Saved,1) + CALL Orca_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input_Saved(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42335,18 +42335,18 @@ SUBROUTINE FAST_PackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%InputTimes_bak) ) THEN + IF ( .NOT. ALLOCATED(InData%InputTimes_Saved) ) 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%InputTimes_bak,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_bak,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes_Saved,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes_Saved,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%InputTimes_bak,1), UBOUND(InData%InputTimes_bak,1) - DbKiBuf(Db_Xferred) = InData%InputTimes_bak(i1) + DO i1 = LBOUND(InData%InputTimes_Saved,1), UBOUND(InData%InputTimes_Saved,1) + DbKiBuf(Db_Xferred) = InData%InputTimes_Saved(i1) Db_Xferred = Db_Xferred + 1 END DO END IF @@ -42771,20 +42771,20 @@ SUBROUTINE FAST_UnPackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input_Saved 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%Input_bak)) DEALLOCATE(OutData%Input_bak) - ALLOCATE(OutData%Input_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Input_Saved)) DEALLOCATE(OutData%Input_Saved) + ALLOCATE(OutData%Input_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Input_bak,1), UBOUND(OutData%Input_bak,1) + DO i1 = LBOUND(OutData%Input_Saved,1), UBOUND(OutData%Input_Saved,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -42818,7 +42818,7 @@ SUBROUTINE FAST_UnPackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL Orca_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_bak(i1), ErrStat2, ErrMsg2 ) ! Input_bak + CALL Orca_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input_Saved(i1), ErrStat2, ErrMsg2 ) ! Input_Saved CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42845,21 +42845,21 @@ SUBROUTINE FAST_UnPackOrcaFlex_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_bak not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes_Saved 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%InputTimes_bak)) DEALLOCATE(OutData%InputTimes_bak) - ALLOCATE(OutData%InputTimes_bak(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%InputTimes_Saved)) DEALLOCATE(OutData%InputTimes_Saved) + ALLOCATE(OutData%InputTimes_Saved(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_bak.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes_Saved.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%InputTimes_bak,1), UBOUND(OutData%InputTimes_bak,1) - OutData%InputTimes_bak(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%InputTimes_Saved,1), UBOUND(OutData%InputTimes_Saved,1) + OutData%InputTimes_Saved(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF From 47ef53ed56e2a560c3836222f5c1bcc186d015af Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 11 Dec 2023 15:17:13 -0700 Subject: [PATCH 35/91] ExtLoads: true-up the r-test pointer (no changes) --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index 4d36d8101c..9bdec5a01b 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 4d36d8101cd7d6b3f7169c6d412251b8257f32f2 +Subproject commit 9bdec5a01b88ac825277ecb323f642c5b6a977d6 From d4dae7c8c0c5c76d1d08ed8f20bd489271c7022e Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 11 Dec 2023 15:25:13 -0700 Subject: [PATCH 36/91] ExtLoads: rename SS --> SubStep / SAVED SS is also used for steady-state solve. To avoid ambiguity changing as follows: - STATE_SS_PRED --> STATE_SAVED_PRED - STATE_SS_CURR --> STATE_SAVED_CURR - _SS routines --> _SubStep --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 6 +- modules/openfast-library/src/FAST_Library.f90 | 30 +- modules/openfast-library/src/FAST_Library.h | 6 +- modules/openfast-library/src/FAST_Mods.f90 | 4 +- modules/openfast-library/src/FAST_Subs.f90 | 758 +++++++++--------- 5 files changed, 402 insertions(+), 402 deletions(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index d9fd1cb20c..53f5b4a407 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -944,7 +944,7 @@ void fast::OpenFAST::solution0(bool writeFiles) { FAST_CFD_Solution0(&iTurb, &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); - FAST_CFD_InitIOarrays_SS(&iTurb, &ErrStat, ErrMsg); + FAST_CFD_InitIOarrays_SubStep(&iTurb, &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); } @@ -1177,7 +1177,7 @@ void fast::OpenFAST::prework() { if (nSubsteps_ > 1) { for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - FAST_CFD_Store_SS(&iTurb, &nt_global, &ErrStat, ErrMsg) ; + FAST_CFD_Store_SubStep(&iTurb, &nt_global, &ErrStat, ErrMsg) ; checkError(ErrStat, ErrMsg); } @@ -1203,7 +1203,7 @@ void fast::OpenFAST::update_states_driver_time_step(bool writeFiles) { if (!firstPass_) { for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - FAST_CFD_Reset_SS(&iTurb, &nSubsteps_, &ErrStat, ErrMsg); + FAST_CFD_Reset_SubStep(&iTurb, &nSubsteps_, &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); } } diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 0482eecf4e..2c8ce3a2a6 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -804,24 +804,24 @@ subroutine FAST_CFD_Solution0(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CF end subroutine FAST_CFD_Solution0 !================================================================================================================================== -subroutine FAST_CFD_InitIOarrays_SS(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_InitIOarrays_SS') -!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_InitIOarrays_SS +subroutine FAST_CFD_InitIOarrays_SubStep(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_InitIOarrays_SubStep') +!DEC$ ATTRIBUTES DLLEXPORT::FAST_CFD_InitIOarrays_SubStep IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT -!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_InitIOarrays_SS +!GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_InitIOarrays_SubStep #endif INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number INTEGER(C_INT), INTENT( OUT) :: ErrStat_c CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - call FAST_InitIOarrays_SS_T(t_initial, Turbine(iTurb), ErrStat, ErrMsg ) + call FAST_InitIOarrays_SubStep_T(t_initial, Turbine(iTurb), ErrStat, ErrMsg ) ! set values for return to ExternalInflow ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -end subroutine FAST_CFD_InitIOarrays_SS +end subroutine FAST_CFD_InitIOarrays_SubStep !================================================================================================================================== subroutine FAST_ExtInfw_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, numblades_c, numElementsPerBlade_c, numElementsTower_c, n_t_global_c, & ExtInfw_Input_from_FAST, ExtInfw_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtInfw_Restart') @@ -1242,18 +1242,18 @@ subroutine FAST_CFD_Step(iTurb, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Ste end subroutine FAST_CFD_Step !================================================================================================================================== -subroutine FAST_CFD_Reset_SS(iTurb, n_timesteps, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Reset_SS') +subroutine FAST_CFD_Reset_SubStep(iTurb, n_timesteps, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Reset_SubStep') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT - !DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Reset_SS - !GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Reset_SS + !DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Reset_SubStep + !GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Reset_SubStep #endif INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number INTEGER(C_INT), INTENT(IN ) :: n_timesteps ! Number of time steps to go back INTEGER(C_INT), INTENT( OUT) :: ErrStat_c CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - CALL FAST_Reset_SS_T(t_initial, n_t_global-n_timesteps, n_timesteps, Turbine(iTurb), ErrStat, ErrMsg ) + CALL FAST_Reset_SubStep_T(t_initial, n_t_global-n_timesteps, n_timesteps, Turbine(iTurb), ErrStat, ErrMsg ) if (iTurb .eq. (NumTurbines-1) ) then n_t_global = n_t_global - n_timesteps @@ -1264,26 +1264,26 @@ subroutine FAST_CFD_Reset_SS(iTurb, n_timesteps, ErrStat_c, ErrMsg_c) BIND (C, N ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -end subroutine FAST_CFD_Reset_SS +end subroutine FAST_CFD_Reset_SubStep !================================================================================================================================== -subroutine FAST_CFD_Store_SS(iTurb, n_t_global, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Store_SS') +subroutine FAST_CFD_Store_SubStep(iTurb, n_t_global, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_CFD_Store_SubStep') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT - !DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Store_SS - !GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Store_SS + !DEC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Store_SubStep + !GCC$ ATTRIBUTES DLLEXPORT :: FAST_CFD_Store_SubStep #endif INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number INTEGER(C_INT), INTENT(IN ) :: n_t_global !< loop counter INTEGER(C_INT), INTENT( OUT) :: ErrStat_c CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) - CALL FAST_Store_SS_T(t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) + CALL FAST_Store_SubStep_T(t_initial, n_t_global, Turbine(iTurb), ErrStat, ErrMsg ) ErrStat_c = ErrStat ErrMsg = TRIM(ErrMsg)//C_NULL_CHAR ErrMsg_c = TRANSFER( ErrMsg//C_NULL_CHAR, ErrMsg_c ) -end subroutine FAST_CFD_Store_SS +end subroutine FAST_CFD_Store_SubStep !================================================================================================================================== END MODULE FAST_Data diff --git a/modules/openfast-library/src/FAST_Library.h b/modules/openfast-library/src/FAST_Library.h index 51269339f0..5427cdbacf 100644 --- a/modules/openfast-library/src/FAST_Library.h +++ b/modules/openfast-library/src/FAST_Library.h @@ -30,14 +30,14 @@ EXTERNAL_ROUTINE void FAST_ExtInfw_Init(int * iTurb, double *TMax, const char *I EXTERNAL_ROUTINE void FAST_ExtLoads_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * n_t_global, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_ExtLoads_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, char *OutFileRoot, float * TurbinePosition, int *AbortErrLev, double * dtDriver, double * dt, int * NumBl, double * az_blend_mean, double * az_blend_delta, double * vel_mean, double * wind_dir, double * z_ref, double * shear_exp, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_Solution0(int * iTurb, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_CFD_InitIOarrays_SS(int * iTurb, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_InitIOarrays_SubStep(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_Prework(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_UpdateStates(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_AdvanceToNextTimeStep(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_WriteOutput(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_Step(int * iTurb, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_CFD_Reset_SS(int * iTurb, int * n_timesteps, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_CFD_Store_SS(int * iTurb, int * n_t_global, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_Reset_SubStep(int * iTurb, int * n_timesteps, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_CFD_Store_SubStep(int * iTurb, int * n_t_global, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_HubPosition(int * iTurb, float * absolute_position, float * rotation_veocity, double * orientation_dcm, int *ErrStat, char *ErrMsg); diff --git a/modules/openfast-library/src/FAST_Mods.f90 b/modules/openfast-library/src/FAST_Mods.f90 index 5d1ba46480..a09e8f43d5 100644 --- a/modules/openfast-library/src/FAST_Mods.f90 +++ b/modules/openfast-library/src/FAST_Mods.f90 @@ -37,8 +37,8 @@ MODULE FAST_ModTypes ! state array indexes INTEGER(IntKi), PARAMETER :: STATE_CURR = 1 !< index for "current" (t_global) states INTEGER(IntKi), PARAMETER :: STATE_PRED = 2 !< index for "predicted" (t_global_next) states - INTEGER(IntKi), PARAMETER :: STATE_SS_CURR = 3 - INTEGER(IntKi), PARAMETER :: STATE_SS_PRED = 4 + INTEGER(IntKi), PARAMETER :: STATE_SAVED_CURR = 3 + INTEGER(IntKi), PARAMETER :: STATE_SAVED_PRED = 4 ! VTK visualization INTEGER(IntKi), PARAMETER :: VTK_Unknown = -1 !< unknown option (will produce error) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index c130da47e4..8d34031ad5 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -5616,9 +5616,9 @@ SUBROUTINE FAST_InitIOarrays( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, A END SUBROUTINE FAST_InitIOarrays !---------------------------------------------------------------------------------------------------------------------------------- -!> Routine that calls FAST_InitIOarrays_SS for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!> Routine that calls FAST_InitIOarrays_SubStep for one instance of a Turbine data structure. This is a separate subroutine so that the FAST !! driver programs do not need to change or operate on the individual module level. -SUBROUTINE FAST_InitIOarrays_SS_T(t_initial, Turbine, ErrStat, ErrMsg ) +SUBROUTINE FAST_InitIOarrays_SubStep_T(t_initial, Turbine, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< start time of the simulation TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine @@ -5627,9 +5627,9 @@ SUBROUTINE FAST_InitIOarrays_SS_T(t_initial, Turbine, ErrStat, ErrMsg ) INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_InitIOarrays_SS_T' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_InitIOarrays_SubStep_T' - CALL FAST_InitIOarrays_SS(t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + CALL FAST_InitIOarrays_SubStep(t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, & Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, ErrStat2, ErrMsg2 ) @@ -5637,12 +5637,12 @@ SUBROUTINE FAST_InitIOarrays_SS_T(t_initial, Turbine, ErrStat, ErrMsg ) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) -END SUBROUTINE FAST_InitIOarrays_SS_T +END SUBROUTINE FAST_InitIOarrays_SubStep_T !---------------------------------------------------------------------------------------------------------------------------------- !> This routine initializes the input and output arrays stored for extrapolation when used in a sub-timestepping mode with an external driver program. They are initialized after the first input-output solve so that the first !! extrapolations are used with values from the solution, not just initial guesses. It also creates new copies of the state variables, which need to !! be stored for the predictor-corrector loop. -SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, HD, SD, ExtPtfm, & +SUBROUTINE FAST_InitIOarrays_SubStep( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< start time of the simulation @@ -5674,7 +5674,7 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD INTEGER(IntKi) :: i, j, k ! loop counters INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_InitIOarrays_SS' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_InitIOarrays_SubStep' ErrStat = ErrID_None @@ -5698,22 +5698,22 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL ED_CopyContState (ED%x( STATE_CURR), ED%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyContState (ED%x( STATE_CURR), ED%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyDiscState (ED%xd(STATE_CURR), ED%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyDiscState (ED%xd(STATE_CURR), ED%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyConstrState (ED%z( STATE_CURR), ED%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyConstrState (ED%z( STATE_CURR), ED%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyOtherState (ED%OtherSt( STATE_CURR), ED%OtherSt( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyOtherState (ED%OtherSt( STATE_CURR), ED%OtherSt( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (p_FAST%CompElast == Module_BD ) THEN @@ -5731,23 +5731,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL BD_CopyContState (BD%x( k,STATE_CURR), BD%x( k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyContState (BD%x( k,STATE_CURR), BD%x( k,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyDiscState (BD%xd(k,STATE_CURR), BD%xd(k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyDiscState (BD%xd(k,STATE_CURR), BD%xd(k,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyConstrState (BD%z( k,STATE_CURR), BD%z( k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyConstrState (BD%z( k,STATE_CURR), BD%z( k,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyOtherState (BD%OtherSt( k,STATE_CURR), BD%OtherSt( k,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_CURR), BD%OtherSt( k,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO ! nBeams @@ -5769,23 +5769,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL SrvD_CopyContState (SrvD%x( STATE_CURR), SrvD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyContState (SrvD%x( STATE_CURR), SrvD%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyDiscState (SrvD%xd(STATE_CURR), SrvD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_CURR), SrvD%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyConstrState (SrvD%z( STATE_CURR), SrvD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyConstrState (SrvD%z( STATE_CURR), SrvD%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyOtherState( SrvD%OtherSt(STATE_CURR), SrvD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyOtherState( SrvD%OtherSt(STATE_CURR), SrvD%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyOtherState( SrvD%OtherSt(STATE_PRED), SrvD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyOtherState( SrvD%OtherSt(STATE_PRED), SrvD%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL SrvD_CopyMisc( SrvD%m, SrvD%m_bak, MESH_NEWCOPY, Errstat2, ErrMsg2) @@ -5807,23 +5807,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL AD14_CopyContState (AD14%x( STATE_CURR), AD14%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyContState (AD14%x( STATE_CURR), AD14%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyDiscState (AD14%xd(STATE_CURR), AD14%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyDiscState (AD14%xd(STATE_CURR), AD14%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyConstrState (AD14%z( STATE_CURR), AD14%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyConstrState (AD14%z( STATE_CURR), AD14%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyOtherState( AD14%OtherSt(STATE_CURR), AD14%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyOtherState( AD14%OtherSt(STATE_CURR), AD14%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyOtherState( AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD14_CopyOtherState( AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN @@ -5839,23 +5839,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL AD_CopyContState(AD%x(STATE_CURR), AD%x(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyContState(AD%x(STATE_CURR), AD%x(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyDiscState(AD%xd(STATE_CURR), AD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyDiscState(AD%xd(STATE_CURR), AD%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyConstrState(AD%z(STATE_CURR), AD%z(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyConstrState(AD%z(STATE_CURR), AD%z(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyOtherState(AD%OtherSt(STATE_CURR), AD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyOtherState(AD%OtherSt(STATE_CURR), AD%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL AD_CopyContState(AD%x(STATE_PRED), AD%x(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyContState(AD%x(STATE_PRED), AD%x(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyDiscState(AD%xd(STATE_PRED), AD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyDiscState(AD%xd(STATE_PRED), AD%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyConstrState(AD%z(STATE_PRED), AD%z(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyConstrState(AD%z(STATE_PRED), AD%z(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyOtherState(AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL AD_CopyOtherState(AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompAero == Module_AD @@ -5876,23 +5876,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL InflowWind_CopyContState (IfW%x( STATE_CURR), IfW%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyContState (IfW%x( STATE_CURR), IfW%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyDiscState (IfW%xd(STATE_CURR), IfW%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_CURR), IfW%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyConstrState (IfW%z( STATE_CURR), IfW%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyConstrState (IfW%z( STATE_CURR), IfW%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyOtherState( IfW%OtherSt(STATE_CURR), IfW%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyOtherState( IfW%OtherSt(STATE_CURR), IfW%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyOtherState( IfW%OtherSt(STATE_PRED), IfW%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyOtherState( IfW%OtherSt(STATE_PRED), IfW%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompInflow == Module_IfW @@ -5911,23 +5911,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL HydroDyn_CopyContState (HD%x( STATE_CURR), HD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyContState (HD%x( STATE_CURR), HD%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyDiscState (HD%xd(STATE_CURR), HD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_CURR), HD%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyConstrState (HD%z( STATE_CURR), HD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyConstrState (HD%z( STATE_CURR), HD%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyOtherState( HD%OtherSt(STATE_CURR), HD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyOtherState( HD%OtherSt(STATE_CURR), HD%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyOtherState( HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyOtherState( HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF !CompHydro @@ -5947,23 +5947,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL SD_CopyContState (SD%x( STATE_CURR), SD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyContState (SD%x( STATE_CURR), SD%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyDiscState (SD%xd(STATE_CURR), SD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyDiscState (SD%xd(STATE_CURR), SD%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyConstrState (SD%z( STATE_CURR), SD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyConstrState (SD%z( STATE_CURR), SD%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyOtherState( SD%OtherSt(STATE_CURR), SD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyOtherState( SD%OtherSt(STATE_CURR), SD%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyOtherState( SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SD_CopyOtherState( SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSE IF (p_FAST%CompSub == Module_ExtPtfm ) THEN @@ -5979,23 +5979,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_CURR), ExtPtfm%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_CURR), ExtPtfm%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_CURR), ExtPtfm%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_CURR), ExtPtfm%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_CURR), ExtPtfm%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_CURR), ExtPtfm%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyOtherState( ExtPtfm%OtherSt(STATE_CURR), ExtPtfm%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyOtherState( ExtPtfm%OtherSt(STATE_CURR), ExtPtfm%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyOtherState( ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyOtherState( ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompSub @@ -6015,11 +6015,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL MAP_CopyContState (MAPp%x( STATE_CURR), MAPp%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MAP_CopyContState (MAPp%x( STATE_CURR), MAPp%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyDiscState (MAPp%xd(STATE_CURR), MAPp%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MAP_CopyDiscState (MAPp%xd(STATE_CURR), MAPp%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyConstrState (MAPp%z( STATE_CURR), MAPp%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MAP_CopyConstrState (MAPp%z( STATE_CURR), MAPp%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( p_FAST%n_substeps( MODULE_MAP ) > 1 ) THEN CALL MAP_CopyOtherState( MAPp%OtherSt, MAPp%OtherSt_old, MESH_NEWCOPY, Errstat2, ErrMsg2) @@ -6027,11 +6027,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END IF ! Initialize predicted states for j_pc loop: - CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( p_FAST%n_substeps( MODULE_MAP ) > 1 ) THEN CALL MAP_CopyOtherState( MAPp%OtherSt, MAPp%OtherSt_old, MESH_NEWCOPY, Errstat2, ErrMsg2) @@ -6052,23 +6052,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL MD_CopyContState (MD%x( STATE_CURR), MD%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyContState (MD%x( STATE_CURR), MD%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyDiscState (MD%xd(STATE_CURR), MD%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyDiscState (MD%xd(STATE_CURR), MD%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyConstrState (MD%z( STATE_CURR), MD%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyConstrState (MD%z( STATE_CURR), MD%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyOtherState( MD%OtherSt(STATE_CURR), MD%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyOtherState( MD%OtherSt(STATE_CURR), MD%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyOtherState( MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL MD_CopyOtherState( MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -6087,23 +6087,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL FEAM_CopyContState (FEAM%x( STATE_CURR), FEAM%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyContState (FEAM%x( STATE_CURR), FEAM%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyDiscState (FEAM%xd(STATE_CURR), FEAM%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_CURR), FEAM%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyConstrState (FEAM%z( STATE_CURR), FEAM%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyConstrState (FEAM%z( STATE_CURR), FEAM%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyOtherState( FEAM%OtherSt(STATE_CURR), FEAM%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyOtherState( FEAM%OtherSt(STATE_CURR), FEAM%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyOtherState( FEAM%OtherSt(STATE_PRED), FEAM%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyOtherState( FEAM%OtherSt(STATE_PRED), FEAM%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompMooring == Module_Orca) THEN @@ -6119,23 +6119,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL Orca_CopyContState (Orca%x( STATE_CURR), Orca%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyContState (Orca%x( STATE_CURR), Orca%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyDiscState (Orca%xd(STATE_CURR), Orca%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyDiscState (Orca%xd(STATE_CURR), Orca%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyConstrState (Orca%z( STATE_CURR), Orca%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyConstrState (Orca%z( STATE_CURR), Orca%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyOtherState( Orca%OtherSt(STATE_CURR), Orca%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyOtherState( Orca%OtherSt(STATE_CURR), Orca%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyOtherState( Orca%OtherSt(STATE_PRED), Orca%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL Orca_CopyOtherState( Orca%OtherSt(STATE_PRED), Orca%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompMooring @@ -6155,23 +6155,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL IceFloe_CopyContState (IceF%x( STATE_CURR), IceF%x( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyContState (IceF%x( STATE_CURR), IceF%x( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyDiscState (IceF%xd(STATE_CURR), IceF%xd(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_CURR), IceF%xd(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyConstrState (IceF%z( STATE_CURR), IceF%z( STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyConstrState (IceF%z( STATE_CURR), IceF%z( STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyOtherState( IceF%OtherSt(STATE_CURR), IceF%OtherSt(STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyOtherState( IceF%OtherSt(STATE_CURR), IceF%OtherSt(STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyOtherState( IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyOtherState( IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompIce == Module_IceD ) THEN @@ -6190,23 +6190,23 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END DO ! Initialize predicted states for j_pc loop: - CALL IceD_CopyContState (IceD%x( i,STATE_CURR), IceD%x( i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyContState (IceD%x( i,STATE_CURR), IceD%x( i,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyDiscState (IceD%xd(i,STATE_CURR), IceD%xd(i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_CURR), IceD%xd(i,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyConstrState (IceD%z( i,STATE_CURR), IceD%z( i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyConstrState (IceD%z( i,STATE_CURR), IceD%z( i,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyOtherState( IceD%OtherSt(i,STATE_CURR), IceD%OtherSt(i,STATE_SS_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyOtherState( IceD%OtherSt(i,STATE_CURR), IceD%OtherSt(i,STATE_SAVED_CURR), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Initialize predicted states for j_pc loop: - CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyOtherState( IceD%OtherSt(i,STATE_PRED), IceD%OtherSt(i,STATE_SS_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL IceD_CopyOtherState( IceD%OtherSt(i,STATE_PRED), IceD%OtherSt(i,STATE_SAVED_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2) CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO ! numIceLegs @@ -6214,11 +6214,11 @@ SUBROUTINE FAST_InitIOarrays_SS( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD END IF ! CompIce -END SUBROUTINE FAST_InitIOarrays_SS +END SUBROUTINE FAST_InitIOarrays_SubStep !---------------------------------------------------------------------------------------------------------------------------------- -!> Routine that calls FAST_Reset_SS for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!> Routine that calls FAST_Reset_SubStep for one instance of a Turbine data structure. This is a separate subroutine so that the FAST !! driver programs do not need to change or operate on the individual module level. -SUBROUTINE FAST_Reset_SS_T(t_initial, n_t_global, n_timesteps, Turbine, ErrStat, ErrMsg ) +SUBROUTINE FAST_Reset_SubStep_T(t_initial, n_t_global, n_timesteps, Turbine, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter @@ -6227,15 +6227,15 @@ SUBROUTINE FAST_Reset_SS_T(t_initial, n_t_global, n_timesteps, Turbine, ErrStat, INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - CALL FAST_Reset_SS(t_initial, n_t_global, n_timesteps, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + CALL FAST_Reset_SubStep(t_initial, n_t_global, n_timesteps, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) -END SUBROUTINE FAST_Reset_SS_T +END SUBROUTINE FAST_Reset_SubStep_T !---------------------------------------------------------------------------------------------------------------------------------- !> This routine resets the states, inputs and output data from n_t_global to n_t_global - 1 -SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & +SUBROUTINE FAST_Reset_SubStep(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) USE BladedInterface, ONLY: CallBladedDLL ! Hack for Bladed-style DLL @@ -6306,22 +6306,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! ElastoDyn: copy final predictions to actual states - CALL ED_CopyContState (ED%x( STATE_SS_PRED), ED%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyContState (ED%x( STATE_SAVED_PRED), ED%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyDiscState (ED%xd(STATE_SS_PRED), ED%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyDiscState (ED%xd(STATE_SAVED_PRED), ED%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyConstrState (ED%z( STATE_SS_PRED), ED%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyConstrState (ED%z( STATE_SAVED_PRED), ED%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyOtherState (ED%OtherSt( STATE_SS_PRED), ED%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyOtherState (ED%OtherSt( STATE_SAVED_PRED), ED%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyContState (ED%x( STATE_SS_CURR), ED%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyContState (ED%x( STATE_SAVED_CURR), ED%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyDiscState (ED%xd(STATE_SS_CURR), ED%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyDiscState (ED%xd(STATE_SAVED_CURR), ED%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyConstrState (ED%z( STATE_SS_CURR), ED%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyConstrState (ED%z( STATE_SAVED_CURR), ED%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyOtherState (ED%OtherSt( STATE_SS_CURR), ED%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyOtherState (ED%OtherSt( STATE_SAVED_CURR), ED%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -6339,22 +6339,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL BD_CopyContState (BD%x( k,STATE_SS_PRED), BD%x( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyContState (BD%x( k,STATE_SAVED_PRED), BD%x( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyDiscState (BD%xd(k,STATE_SS_PRED), BD%xd(k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyDiscState (BD%xd(k,STATE_SAVED_PRED), BD%xd(k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyConstrState (BD%z( k,STATE_SS_PRED), BD%z( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyConstrState (BD%z( k,STATE_SAVED_PRED), BD%z( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyOtherState (BD%OtherSt( k,STATE_SS_PRED), BD%OtherSt( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_SAVED_PRED), BD%OtherSt( k,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyContState (BD%x( k,STATE_SS_CURR), BD%x( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyContState (BD%x( k,STATE_SAVED_CURR), BD%x( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyDiscState (BD%xd(k,STATE_SS_CURR), BD%xd(k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyDiscState (BD%xd(k,STATE_SAVED_CURR), BD%xd(k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyConstrState (BD%z( k,STATE_SS_CURR), BD%z( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyConstrState (BD%z( k,STATE_SAVED_CURR), BD%z( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyOtherState (BD%OtherSt( k,STATE_SS_CURR), BD%OtherSt( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_SAVED_CURR), BD%OtherSt( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6386,22 +6386,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL SrvD_CopyContState (SrvD%x( STATE_SS_PRED), SrvD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyContState (SrvD%x( STATE_SAVED_PRED), SrvD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyDiscState (SrvD%xd(STATE_SS_PRED), SrvD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_SAVED_PRED), SrvD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyConstrState (SrvD%z( STATE_SS_PRED), SrvD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyConstrState (SrvD%z( STATE_SAVED_PRED), SrvD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_SS_PRED), SrvD%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_SAVED_PRED), SrvD%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyContState (SrvD%x( STATE_SS_CURR), SrvD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyContState (SrvD%x( STATE_SAVED_CURR), SrvD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyDiscState (SrvD%xd(STATE_SS_CURR), SrvD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_SAVED_CURR), SrvD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyConstrState (SrvD%z( STATE_SS_CURR), SrvD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyConstrState (SrvD%z( STATE_SAVED_CURR), SrvD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_SS_CURR), SrvD%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_SAVED_CURR), SrvD%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL SrvD_CopyMisc( SrvD%m_bak, SrvD%m, MESH_UPDATECOPY, Errstat2, ErrMsg2) @@ -6421,22 +6421,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL AD14_CopyContState (AD14%x( STATE_SS_PRED), AD14%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyContState (AD14%x( STATE_SAVED_PRED), AD14%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyDiscState (AD14%xd(STATE_SS_PRED), AD14%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyDiscState (AD14%xd(STATE_SAVED_PRED), AD14%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyConstrState (AD14%z( STATE_SS_PRED), AD14%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyConstrState (AD14%z( STATE_SAVED_PRED), AD14%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyOtherState (AD14%OtherSt(STATE_SS_PRED), AD14%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_SAVED_PRED), AD14%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyContState (AD14%x( STATE_SS_CURR), AD14%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyContState (AD14%x( STATE_SAVED_CURR), AD14%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyDiscState (AD14%xd(STATE_SS_CURR), AD14%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyDiscState (AD14%xd(STATE_SAVED_CURR), AD14%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyConstrState (AD14%z( STATE_SS_CURR), AD14%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyConstrState (AD14%z( STATE_SAVED_CURR), AD14%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyOtherState (AD14%OtherSt(STATE_SS_CURR), AD14%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_SAVED_CURR), AD14%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN @@ -6451,22 +6451,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL AD_CopyContState (AD%x( STATE_SS_PRED), AD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyContState (AD%x( STATE_SAVED_PRED), AD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyDiscState (AD%xd(STATE_SS_PRED), AD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyDiscState (AD%xd(STATE_SAVED_PRED), AD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyConstrState (AD%z( STATE_SS_PRED), AD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyConstrState (AD%z( STATE_SAVED_PRED), AD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyOtherState (AD%OtherSt(STATE_SS_PRED), AD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyOtherState (AD%OtherSt(STATE_SAVED_PRED), AD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyContState (AD%x( STATE_SS_CURR), AD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyContState (AD%x( STATE_SAVED_CURR), AD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyDiscState (AD%xd(STATE_SS_CURR), AD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyDiscState (AD%xd(STATE_SAVED_CURR), AD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyConstrState (AD%z( STATE_SS_CURR), AD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyConstrState (AD%z( STATE_SAVED_CURR), AD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyOtherState (AD%OtherSt(STATE_SS_CURR), AD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyOtherState (AD%OtherSt(STATE_SAVED_CURR), AD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompAero == Module_AD @@ -6484,22 +6484,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL InflowWind_CopyContState (IfW%x( STATE_SS_PRED), IfW%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyContState (IfW%x( STATE_SAVED_PRED), IfW%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyDiscState (IfW%xd(STATE_SS_PRED), IfW%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_SAVED_PRED), IfW%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyConstrState (IfW%z( STATE_SS_PRED), IfW%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyConstrState (IfW%z( STATE_SAVED_PRED), IfW%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_SS_PRED), IfW%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_SAVED_PRED), IfW%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyContState (IfW%x( STATE_SS_CURR), IfW%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyContState (IfW%x( STATE_SAVED_CURR), IfW%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyDiscState (IfW%xd(STATE_SS_CURR), IfW%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_SAVED_CURR), IfW%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyConstrState (IfW%z( STATE_SS_CURR), IfW%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyConstrState (IfW%z( STATE_SAVED_CURR), IfW%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_SS_CURR), IfW%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_SAVED_CURR), IfW%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompInflow == Module_IfW @@ -6517,22 +6517,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL HydroDyn_CopyContState (HD%x( STATE_SS_PRED), HD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyContState (HD%x( STATE_SAVED_PRED), HD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyDiscState (HD%xd(STATE_SS_PRED), HD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_SAVED_PRED), HD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyConstrState (HD%z( STATE_SS_PRED), HD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyConstrState (HD%z( STATE_SAVED_PRED), HD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_SS_PRED), HD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_SAVED_PRED), HD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyContState (HD%x( STATE_SS_CURR), HD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyContState (HD%x( STATE_SAVED_CURR), HD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyDiscState (HD%xd(STATE_SS_CURR), HD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_SAVED_CURR), HD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyConstrState (HD%z( STATE_SS_CURR), HD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyConstrState (HD%z( STATE_SAVED_CURR), HD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_SS_CURR), HD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_SAVED_CURR), HD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF !CompHydro @@ -6551,22 +6551,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL SD_CopyContState (SD%x( STATE_SS_PRED), SD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyContState (SD%x( STATE_SAVED_PRED), SD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyDiscState (SD%xd(STATE_SS_PRED), SD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyDiscState (SD%xd(STATE_SAVED_PRED), SD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyConstrState (SD%z( STATE_SS_PRED), SD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyConstrState (SD%z( STATE_SAVED_PRED), SD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyOtherState (SD%OtherSt(STATE_SS_PRED), SD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyOtherState (SD%OtherSt(STATE_SAVED_PRED), SD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyContState (SD%x( STATE_SS_CURR), SD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyContState (SD%x( STATE_SAVED_CURR), SD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyDiscState (SD%xd(STATE_SS_CURR), SD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyDiscState (SD%xd(STATE_SAVED_CURR), SD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyConstrState (SD%z( STATE_SS_CURR), SD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyConstrState (SD%z( STATE_SAVED_CURR), SD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyOtherState (SD%OtherSt(STATE_SS_CURR), SD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyOtherState (SD%OtherSt(STATE_SAVED_CURR), SD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSE IF (p_FAST%CompSub == Module_ExtPtfm ) THEN @@ -6581,22 +6581,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_SS_PRED), ExtPtfm%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_SAVED_PRED), ExtPtfm%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_SS_PRED), ExtPtfm%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_SAVED_PRED), ExtPtfm%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_SS_PRED), ExtPtfm%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_SAVED_PRED), ExtPtfm%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_SS_PRED), ExtPtfm%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_SAVED_PRED), ExtPtfm%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_SS_CURR), ExtPtfm%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_SAVED_CURR), ExtPtfm%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_SS_CURR), ExtPtfm%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_SAVED_CURR), ExtPtfm%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_SS_CURR), ExtPtfm%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_SAVED_CURR), ExtPtfm%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_SS_CURR), ExtPtfm%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_SAVED_CURR), ExtPtfm%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompSub @@ -6615,22 +6615,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL MAP_CopyContState (MAPp%x( STATE_SS_PRED), MAPp%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyContState (MAPp%x( STATE_SAVED_PRED), MAPp%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyDiscState (MAPp%xd(STATE_SS_PRED), MAPp%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyDiscState (MAPp%xd(STATE_SAVED_PRED), MAPp%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyConstrState (MAPp%z( STATE_SS_PRED), MAPp%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyConstrState (MAPp%z( STATE_SAVED_PRED), MAPp%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_SS_PRED), MAPp%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_SAVED_PRED), MAPp%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyContState (MAPp%x( STATE_SS_CURR), MAPp%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyContState (MAPp%x( STATE_SAVED_CURR), MAPp%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyDiscState (MAPp%xd(STATE_SS_CURR), MAPp%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyDiscState (MAPp%xd(STATE_SAVED_CURR), MAPp%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyConstrState (MAPp%z( STATE_SS_CURR), MAPp%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyConstrState (MAPp%z( STATE_SAVED_CURR), MAPp%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_SS_CURR), MAPp%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_SAVED_CURR), MAPp%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompMooring == Module_MD) THEN @@ -6646,22 +6646,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL MD_CopyContState (MD%x( STATE_SS_PRED), MD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyContState (MD%x( STATE_SAVED_PRED), MD%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyDiscState (MD%xd(STATE_SS_PRED), MD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyDiscState (MD%xd(STATE_SAVED_PRED), MD%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyConstrState (MD%z( STATE_SS_PRED), MD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyConstrState (MD%z( STATE_SAVED_PRED), MD%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyOtherState (MD%OtherSt(STATE_SS_PRED), MD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyOtherState (MD%OtherSt(STATE_SAVED_PRED), MD%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyContState (MD%x( STATE_SS_CURR), MD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyContState (MD%x( STATE_SAVED_CURR), MD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyDiscState (MD%xd(STATE_SS_CURR), MD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyDiscState (MD%xd(STATE_SAVED_CURR), MD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyConstrState (MD%z( STATE_SS_CURR), MD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyConstrState (MD%z( STATE_SAVED_CURR), MD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyOtherState (MD%OtherSt(STATE_SS_CURR), MD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyOtherState (MD%OtherSt(STATE_SAVED_CURR), MD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN @@ -6677,22 +6677,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL FEAM_CopyContState (FEAM%x( STATE_SS_PRED), FEAM%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyContState (FEAM%x( STATE_SAVED_PRED), FEAM%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyDiscState (FEAM%xd(STATE_SS_PRED), FEAM%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_SAVED_PRED), FEAM%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyConstrState (FEAM%z( STATE_SS_PRED), FEAM%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyConstrState (FEAM%z( STATE_SAVED_PRED), FEAM%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_SS_PRED), FEAM%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_SAVED_PRED), FEAM%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyContState (FEAM%x( STATE_SS_CURR), FEAM%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyContState (FEAM%x( STATE_SAVED_CURR), FEAM%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyDiscState (FEAM%xd(STATE_SS_CURR), FEAM%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_SAVED_CURR), FEAM%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyConstrState (FEAM%z( STATE_SS_CURR), FEAM%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyConstrState (FEAM%z( STATE_SAVED_CURR), FEAM%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_SS_CURR), FEAM%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_SAVED_CURR), FEAM%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompMooring == Module_Orca) THEN @@ -6707,22 +6707,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL Orca_CopyContState (Orca%x( STATE_SS_PRED), Orca%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyContState (Orca%x( STATE_SAVED_PRED), Orca%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyDiscState (Orca%xd(STATE_SS_PRED), Orca%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyDiscState (Orca%xd(STATE_SAVED_PRED), Orca%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyConstrState (Orca%z( STATE_SS_PRED), Orca%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyConstrState (Orca%z( STATE_SAVED_PRED), Orca%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyOtherState (Orca%OtherSt( STATE_SS_PRED), Orca%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_SAVED_PRED), Orca%OtherSt( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyContState (Orca%x( STATE_SS_CURR), Orca%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyContState (Orca%x( STATE_SAVED_CURR), Orca%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyDiscState (Orca%xd(STATE_SS_CURR), Orca%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyDiscState (Orca%xd(STATE_SAVED_CURR), Orca%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyConstrState (Orca%z( STATE_SS_CURR), Orca%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyConstrState (Orca%z( STATE_SAVED_CURR), Orca%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyOtherState (Orca%OtherSt( STATE_SS_CURR), Orca%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_SAVED_CURR), Orca%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompMooring @@ -6741,22 +6741,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL IceFloe_CopyContState (IceF%x( STATE_SS_PRED), IceF%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyContState (IceF%x( STATE_SAVED_PRED), IceF%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyDiscState (IceF%xd(STATE_SS_PRED), IceF%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_SAVED_PRED), IceF%xd(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyConstrState (IceF%z( STATE_SS_PRED), IceF%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyConstrState (IceF%z( STATE_SAVED_PRED), IceF%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_SS_PRED), IceF%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_SAVED_PRED), IceF%OtherSt(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyContState (IceF%x( STATE_SS_CURR), IceF%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyContState (IceF%x( STATE_SAVED_CURR), IceF%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyDiscState (IceF%xd(STATE_SS_CURR), IceF%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_SAVED_CURR), IceF%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyConstrState (IceF%z( STATE_SS_CURR), IceF%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyConstrState (IceF%z( STATE_SAVED_CURR), IceF%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_SS_CURR), IceF%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_SAVED_CURR), IceF%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompIce == Module_IceD ) THEN @@ -6774,22 +6774,22 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL IceD_CopyContState (IceD%x( i,STATE_SS_PRED), IceD%x( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyContState (IceD%x( i,STATE_SAVED_PRED), IceD%x( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyDiscState (IceD%xd(i,STATE_SS_PRED), IceD%xd(i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_SAVED_PRED), IceD%xd(i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyConstrState (IceD%z( i,STATE_SS_PRED), IceD%z( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyConstrState (IceD%z( i,STATE_SAVED_PRED), IceD%z( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_SS_PRED), IceD%OtherSt( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_SAVED_PRED), IceD%OtherSt( i,STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyContState (IceD%x( i,STATE_SS_CURR), IceD%x( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyContState (IceD%x( i,STATE_SAVED_CURR), IceD%x( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyDiscState (IceD%xd(i,STATE_SS_CURR), IceD%xd(i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_SAVED_CURR), IceD%xd(i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyConstrState (IceD%z( i,STATE_SS_CURR), IceD%z( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyConstrState (IceD%z( i,STATE_SAVED_CURR), IceD%z( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_SS_CURR), IceD%OtherSt( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_SAVED_CURR), IceD%OtherSt( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO ! numIceLegs @@ -6804,11 +6804,11 @@ SUBROUTINE FAST_Reset_SS(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST, m_F m_FAST%t_global = t_global ! y_FAST%n_Out = y_FAST%n_Out - n_timesteps -END SUBROUTINE FAST_Reset_SS +END SUBROUTINE FAST_Reset_SubStep !---------------------------------------------------------------------------------------------------------------------------------- -!> Routine that calls FAST_Store_SS for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!> Routine that calls FAST_Store_SubStep for one instance of a Turbine data structure. This is a separate subroutine so that the FAST !! driver programs do not need to change or operate on the individual module level. -SUBROUTINE FAST_Store_SS_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) +SUBROUTINE FAST_Store_SubStep_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter @@ -6816,15 +6816,15 @@ SUBROUTINE FAST_Store_SS_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - CALL FAST_Store_SS(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + CALL FAST_Store_SubStep(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) -END SUBROUTINE FAST_Store_SS_T +END SUBROUTINE FAST_Store_SubStep_T !---------------------------------------------------------------------------------------------------------------------------------- !> This routine resets the states, inputs and output data from n_t_global to n_t_global - 1 -SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & +SUBROUTINE FAST_Store_SubStep(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) USE BladedInterface, ONLY: CallBladedDLL ! Hack for Bladed-style DLL @@ -6868,7 +6868,7 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Solution' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Store_SubStep' ErrStat = ErrID_None @@ -6894,22 +6894,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ! ElastoDyn: copy final predictions to actual states - CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyContState (ED%x( STATE_CURR), ED%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyContState (ED%x( STATE_CURR), ED%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyDiscState (ED%xd(STATE_CURR), ED%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyDiscState (ED%xd(STATE_CURR), ED%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyConstrState (ED%z( STATE_CURR), ED%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyConstrState (ED%z( STATE_CURR), ED%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyOtherState (ED%OtherSt( STATE_CURR), ED%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ED_CopyOtherState (ED%OtherSt( STATE_CURR), ED%OtherSt( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (p_FAST%CompElast == Module_BD ) THEN @@ -6926,22 +6926,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyContState (BD%x( k,STATE_CURR), BD%x( k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyContState (BD%x( k,STATE_CURR), BD%x( k,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyDiscState (BD%xd(k,STATE_CURR), BD%xd(k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyDiscState (BD%xd(k,STATE_CURR), BD%xd(k,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyConstrState (BD%z( k,STATE_CURR), BD%z( k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyConstrState (BD%z( k,STATE_CURR), BD%z( k,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyOtherState (BD%OtherSt( k,STATE_CURR), BD%OtherSt( k,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL BD_CopyOtherState (BD%OtherSt( k,STATE_CURR), BD%OtherSt( k,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO @@ -6959,22 +6959,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_PRED), SrvD%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_PRED), SrvD%OtherSt( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyContState (SrvD%x( STATE_CURR), SrvD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyContState (SrvD%x( STATE_CURR), SrvD%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyDiscState (SrvD%xd(STATE_CURR), SrvD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyDiscState (SrvD%xd(STATE_CURR), SrvD%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyConstrState (SrvD%z( STATE_CURR), SrvD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyConstrState (SrvD%z( STATE_CURR), SrvD%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_CURR), SrvD%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_CURR), SrvD%OtherSt( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL SrvD_CopyMisc( SrvD%m, SrvD%m_bak, MESH_UPDATECOPY, Errstat2, ErrMsg2) @@ -6994,22 +6994,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyOtherState (AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyContState (AD14%x( STATE_CURR), AD14%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyContState (AD14%x( STATE_CURR), AD14%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyDiscState (AD14%xd(STATE_CURR), AD14%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyDiscState (AD14%xd(STATE_CURR), AD14%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyConstrState (AD14%z( STATE_CURR), AD14%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyConstrState (AD14%z( STATE_CURR), AD14%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyOtherState (AD14%OtherSt(STATE_CURR), AD14%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD14_CopyOtherState (AD14%OtherSt(STATE_CURR), AD14%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN @@ -7024,22 +7024,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL AD_CopyContState (AD%x( STATE_PRED), AD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyContState (AD%x( STATE_PRED), AD%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyDiscState (AD%xd(STATE_PRED), AD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyDiscState (AD%xd(STATE_PRED), AD%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyConstrState (AD%z( STATE_PRED), AD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyConstrState (AD%z( STATE_PRED), AD%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyOtherState (AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyOtherState (AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyContState (AD%x( STATE_CURR), AD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyContState (AD%x( STATE_CURR), AD%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyDiscState (AD%xd(STATE_CURR), AD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyDiscState (AD%xd(STATE_CURR), AD%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyConstrState (AD%z( STATE_CURR), AD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyConstrState (AD%z( STATE_CURR), AD%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyOtherState (AD%OtherSt(STATE_CURR), AD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL AD_CopyOtherState (AD%OtherSt(STATE_CURR), AD%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompAero == Module_AD @@ -7057,22 +7057,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_PRED), IfW%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_PRED), IfW%OtherSt( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyContState (IfW%x( STATE_CURR), IfW%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyContState (IfW%x( STATE_CURR), IfW%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyDiscState (IfW%xd(STATE_CURR), IfW%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyDiscState (IfW%xd(STATE_CURR), IfW%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyConstrState (IfW%z( STATE_CURR), IfW%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyConstrState (IfW%z( STATE_CURR), IfW%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_CURR), IfW%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_CURR), IfW%OtherSt( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompInflow == Module_IfW @@ -7090,22 +7090,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyContState (HD%x( STATE_CURR), HD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyContState (HD%x( STATE_CURR), HD%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyDiscState (HD%xd(STATE_CURR), HD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyDiscState (HD%xd(STATE_CURR), HD%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyConstrState (HD%z( STATE_CURR), HD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyConstrState (HD%z( STATE_CURR), HD%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_CURR), HD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_CURR), HD%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF !CompHydro @@ -7124,22 +7124,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyOtherState (SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyOtherState (SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyContState (SD%x( STATE_CURR), SD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyContState (SD%x( STATE_CURR), SD%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyDiscState (SD%xd(STATE_CURR), SD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyDiscState (SD%xd(STATE_CURR), SD%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyConstrState (SD%z( STATE_CURR), SD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyConstrState (SD%z( STATE_CURR), SD%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyOtherState (SD%OtherSt(STATE_CURR), SD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SD_CopyOtherState (SD%OtherSt(STATE_CURR), SD%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSE IF (p_FAST%CompSub == Module_ExtPtfm ) THEN @@ -7154,22 +7154,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_CURR), ExtPtfm%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_CURR), ExtPtfm%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_CURR), ExtPtfm%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_CURR), ExtPtfm%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_CURR), ExtPtfm%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_CURR), ExtPtfm%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_CURR), ExtPtfm%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_CURR), ExtPtfm%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompSub @@ -7188,22 +7188,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_PRED), MAPp%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_PRED), MAPp%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyContState (MAPp%x( STATE_CURR), MAPp%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyContState (MAPp%x( STATE_CURR), MAPp%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyDiscState (MAPp%xd(STATE_CURR), MAPp%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyDiscState (MAPp%xd(STATE_CURR), MAPp%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyConstrState (MAPp%z( STATE_CURR), MAPp%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MAP_CopyConstrState (MAPp%z( STATE_CURR), MAPp%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_CURR), MAPp%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_CURR), MAPp%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompMooring == Module_MD) THEN @@ -7219,22 +7219,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyOtherState (MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyOtherState (MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyContState (MD%x( STATE_CURR), MD%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyContState (MD%x( STATE_CURR), MD%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyDiscState (MD%xd(STATE_CURR), MD%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyDiscState (MD%xd(STATE_CURR), MD%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyConstrState (MD%z( STATE_CURR), MD%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyConstrState (MD%z( STATE_CURR), MD%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyOtherState (MD%OtherSt(STATE_CURR), MD%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL MD_CopyOtherState (MD%OtherSt(STATE_CURR), MD%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN @@ -7250,22 +7250,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_PRED), FEAM%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_PRED), FEAM%OtherSt( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyContState (FEAM%x( STATE_CURR), FEAM%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyContState (FEAM%x( STATE_CURR), FEAM%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyDiscState (FEAM%xd(STATE_CURR), FEAM%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyDiscState (FEAM%xd(STATE_CURR), FEAM%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyConstrState (FEAM%z( STATE_CURR), FEAM%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyConstrState (FEAM%z( STATE_CURR), FEAM%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_CURR), FEAM%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_CURR), FEAM%OtherSt( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompMooring == Module_Orca) THEN @@ -7280,22 +7280,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyOtherState (Orca%OtherSt( STATE_PRED), Orca%OtherSt( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_PRED), Orca%OtherSt( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyContState (Orca%x( STATE_CURR), Orca%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyContState (Orca%x( STATE_CURR), Orca%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyDiscState (Orca%xd(STATE_CURR), Orca%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyDiscState (Orca%xd(STATE_CURR), Orca%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyConstrState (Orca%z( STATE_CURR), Orca%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyConstrState (Orca%z( STATE_CURR), Orca%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyOtherState (Orca%OtherSt( STATE_CURR), Orca%OtherSt( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL Orca_CopyOtherState (Orca%OtherSt( STATE_CURR), Orca%OtherSt( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF ! CompMooring @@ -7314,22 +7314,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyContState (IceF%x( STATE_CURR), IceF%x( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyContState (IceF%x( STATE_CURR), IceF%x( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyDiscState (IceF%xd(STATE_CURR), IceF%xd(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyDiscState (IceF%xd(STATE_CURR), IceF%xd(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyConstrState (IceF%z( STATE_CURR), IceF%z( STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyConstrState (IceF%z( STATE_CURR), IceF%z( STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_CURR), IceF%OtherSt(STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_CURR), IceF%OtherSt(STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF (p_FAST%CompIce == Module_IceD ) THEN @@ -7347,22 +7347,22 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_PRED), IceD%OtherSt( i,STATE_SS_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_PRED), IceD%OtherSt( i,STATE_SAVED_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyContState (IceD%x( i,STATE_CURR), IceD%x( i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyContState (IceD%x( i,STATE_CURR), IceD%x( i,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyDiscState (IceD%xd(i,STATE_CURR), IceD%xd(i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyDiscState (IceD%xd(i,STATE_CURR), IceD%xd(i,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyConstrState (IceD%z( i,STATE_CURR), IceD%z( i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyConstrState (IceD%z( i,STATE_CURR), IceD%z( i,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_CURR), IceD%OtherSt( i,STATE_SS_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_CURR), IceD%OtherSt( i,STATE_SAVED_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO ! numIceLegs @@ -7382,7 +7382,7 @@ SUBROUTINE FAST_Store_SS(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, end if end if -END SUBROUTINE FAST_Store_SS +END SUBROUTINE FAST_Store_SubStep !---------------------------------------------------------------------------------------------------------------------------------- !> Routine that calls FAST_Prework for one instance of a Turbine data structure. This is a separate subroutine so that the FAST !! driver programs do not need to change or operate on the individual module level. From 875a38d747c0a5ce2c28abfba6e62d23df1c5e04 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 11 Dec 2023 17:15:05 -0700 Subject: [PATCH 37/91] ExtLoads: move FAST_Solution and new routines FAST_Solution now calls - FAST_Prework - FAST_UpdateStates - FAST_AdvanceToNextTimeStep - FAST_WriteOutput revised the interfaces on the above to make them the same as FAST_Solution. Also imported newer stuff from FAST_Solution to these routines --- modules/openfast-library/src/FAST_Subs.f90 | 663 +++++++-------------- 1 file changed, 214 insertions(+), 449 deletions(-) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 8d34031ad5..7e5a6ffb64 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -6254,7 +6254,7 @@ SUBROUTINE FAST_Reset_SubStep(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data - TYPE(ExternalInflow_Data), INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data @@ -6280,7 +6280,7 @@ SUBROUTINE FAST_Reset_SubStep(t_initial, n_t_global, n_timesteps, p_FAST, y_FAST INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Solution' + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Reset_SubStep' ErrStat = ErrID_None @@ -7383,6 +7383,121 @@ SUBROUTINE FAST_Store_SubStep(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, end if END SUBROUTINE FAST_Store_SubStep +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine that calls FAST_Solution for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!! driver programs do not need to change or operate on the individual module level. +SUBROUTINE FAST_Solution_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CALL FAST_Solution(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + +END SUBROUTINE FAST_Solution_T +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine takes data from n_t_global and gets values at n_t_global + 1 +SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & + MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) + + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code + TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables + + TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data + TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< Supercontroller Exchange data + TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + REAL(DbKi) :: t_global_next ! next simulation time (m_FAST%t_global + p_FAST%dt) + INTEGER(IntKi) :: n_t_global_next ! n_t_global + 1 + INTEGER(IntKi) :: j_pc ! predictor-corrector loop counter + INTEGER(IntKi) :: NumCorrections ! number of corrections for this time step + INTEGER(IntKi), parameter :: MaxCorrections = 20 ! maximum number of corrections allowed + LOGICAL :: WriteThisStep ! Whether WriteOutput values will be printed + + INTEGER(IntKi) :: I, k ! generic loop counters + + !REAL(ReKi) :: ControlInputGuess ! value of controller inputs + + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Solution' + + + ErrStat = ErrID_None + ErrMsg = "" + + n_t_global_next = n_t_global+1 + t_global_next = t_initial + n_t_global_next*p_FAST%DT ! = m_FAST%t_global + p_FAST%dt + + y_FAST%WriteThisStep = NeedWriteOutput(n_t_global_next, t_global_next, p_FAST) + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 1.a: set some variables and Extrapolate Inputs + + call FAST_Prework(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 1.b: Advance states (yield state and constraint values at t_global_next) + !! ## Step 1.c: Input-Output Solve + !! ## Step 2: Correct (continue in loop) + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + call FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + !! ## Step 3: Save all final variables (advance to next time) and reset global time + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + call FAST_AdvanceToNextTimeStep(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + !---------------------------------------------------------------------------------------- + !! Write outputs + !---------------------------------------------------------------------------------------- + call FAST_WriteOutput(m_FAST%t_global, n_t_global_next, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + +END SUBROUTINE FAST_Solution + !---------------------------------------------------------------------------------------------------------------------------------- !> Routine that calls FAST_Prework for one instance of a Turbine data structure. This is a separate subroutine so that the FAST !! driver programs do not need to change or operate on the individual module level. @@ -7395,15 +7510,15 @@ SUBROUTINE FAST_Prework_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None CALL FAST_Prework(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, & - Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) END SUBROUTINE FAST_Prework_T !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine does the prep work to advance the time step from n_t_global to n_t_global + 1 -SUBROUTINE FAST_Prework(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, & - ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) +!> This routine does thde prep work to advance the time step from n_t_global to n_t_global + 1 +SUBROUTINE FAST_Prework(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter @@ -7420,6 +7535,8 @@ SUBROUTINE FAST_Prework(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, S TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< Supercontroller Exchange data + TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data @@ -7468,6 +7585,11 @@ SUBROUTINE FAST_Prework(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, S ! the previous step before we extrapolate these inputs: IF ( p_FAST%CompServo == Module_SrvD ) CALL SrvD_SetExternalInputs( p_FAST, m_FAST, SrvD%Input(1) ) + IF ( p_FAST%UseSC ) THEN + CALL SC_DX_SetOutputs(p_FAST, SrvD%Input(1), SC_DX, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END IF + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !! ## Step 1.a: Extrapolate Inputs !! @@ -7481,7 +7603,7 @@ SUBROUTINE FAST_Prework(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, S END SUBROUTINE FAST_Prework !---------------------------------------------------------------------------------------------------------------------------------- !---------------------------------------------------------------------------------------------------------------------------------- -!> Routine that calls FAST_PredictStates for one instance of a Turbine data structure. This is a separate subroutine so that the FAST +!> Routine that calls FAST_UpdateStates for one instance of a Turbine data structure. This is a separate subroutine so that the FAST !! driver programs do not need to change or operate on the individual module level. SUBROUTINE FAST_UpdateStates_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) @@ -7492,15 +7614,15 @@ SUBROUTINE FAST_UpdateStates_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None CALL FAST_UpdateStates(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, & - Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) END SUBROUTINE FAST_UpdateStates_T !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine takes data from n_t_global and predicts the states and output at n_t_global+1 -SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, & - ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) +!> This routine takes data from n_t_global and predicts the states and output at n_t_global+1 +SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter @@ -7517,6 +7639,8 @@ SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< Supercontroller Exchange data + TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data @@ -7554,8 +7678,6 @@ SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, t_global_next = t_initial + (n_t_global+1)*p_FAST%DT ! = m_FAST%t_global + p_FAST%dt n_t_global_next = n_t_global+1 - y_FAST%WriteThisStep = NeedWriteOutput(n_t_global_next, t_global_next, p_FAST) - ! set number of corrections to be used for this time step: IF ( p_FAST%CompElast == Module_BD ) THEN ! BD accelerations have fewer spikes with these corrections on the first several time steps if (n_t_global > 2) then ! this 2 should probably be related to p_FAST%InterpOrder @@ -7570,14 +7692,17 @@ SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, END IF !! predictor-corrector loop: - DO j_pc = 0, NumCorrections + j_pc = 0 + do while (j_pc <= NumCorrections) WriteThisStep = y_FAST%WriteThisStep .AND. j_pc==NumCorrections + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !! ## Step 1.b: Advance states (yield state and constraint values at t_global_next) !! !! STATE_CURR values of x, xd, z, and OtherSt contain values at m_FAST%t_global; !! STATE_PRED values contain values at t_global_next. !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + CALL FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -7586,18 +7711,49 @@ SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !! ## Step 1.c: Input-Output Solve !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! save predicted inputs for comparison with corrected value later + !IF (p_FAST%CheckHSSBrTrqC) THEN + ! ControlInputGuess = ED%Input(1)%HSSBrTrqC + !END IF CALL CalcOutputs_And_SolveForInputs( n_t_global, t_global_next, STATE_PRED, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & - p_FAST, m_FAST, y_FAST%WriteThisStep, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) + p_FAST, m_FAST, WriteThisStep, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !! ## Step 2: Correct (continue in loop) !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + j_pc = j_pc + 1 + + ! ! Check if the predicted inputs were significantly different than the corrected inputs + ! ! (values before and after CalcOutputs_And_SolveForInputs) + !if (j_pc > NumCorrections) then + ! + ! !if (p_FAST%CheckHSSBrTrqC) then + ! ! if ( abs(ControlInputGuess - ED%Input(1)%HSSBrTrqC) > 50.0_ReKi ) then ! I randomly picked 50 N-m + ! ! NumCorrections = min(p_FAST%NumCrctn + 1, MaxCorrections) + ! ! ! print *, 'correction:', t_global_next, NumCorrections + ! ! cycle + ! ! end if + ! !end if + ! + ! ! check pitch position input to structural code (not implemented, yet) + !end if enddo ! j_pc + if (p_FAST%UseSC ) then + call SC_DX_SetInputs(p_FAST, SrvD%y, SC_DX, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end if + + if ( P_FAST%CompSeaSt == Module_SeaSt .and. y_FAST%WriteThisStep) then + ! note: SeaState has no inputs and only calculates WriteOutputs, so we don't need to call CalcOutput unless we are writing to the file + call SeaSt_CalcOutput( t_global_next, SeaSt%u, SeaSt%p, SeaSt%x(1), SeaSt%xd(1), SeaSt%z(1), SeaSt%OtherSt(1), SeaSt%y, SeaSt%m, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end if + END SUBROUTINE FAST_UpdateStates !---------------------------------------------------------------------------------------------------------------------------------- @@ -7612,15 +7768,15 @@ SUBROUTINE FAST_AdvanceToNextTimeStep_T(t_initial, n_t_global, Turbine, ErrStat, CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None CALL FAST_AdvanceToNextTimeStep(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & - Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) END SUBROUTINE FAST_AdvanceToNextTimeStep_T !---------------------------------------------------------------------------------------------------------------------------------- !> This routine advances the time step from n_t_global to n_t_global + 1 and does all the relvant copying of data -SUBROUTINE FAST_AdvanceToNextTimeStep(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, HD, SD, ExtPtfm, & - MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) +SUBROUTINE FAST_AdvanceToNextTimeStep(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter @@ -7634,8 +7790,11 @@ SUBROUTINE FAST_AdvanceToNextTimeStep(t_initial, n_t_global, p_FAST, y_FAST, m_F TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data - TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data + TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< Supercontroller Exchange data + TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data @@ -7750,6 +7909,7 @@ SUBROUTINE FAST_AdvanceToNextTimeStep(t_initial, n_t_global, p_FAST, y_FAST, m_F CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF + ! SeaState has no states ! HydroDyn: copy final predictions to actual states IF ( p_FAST%CompHydro == Module_HD ) THEN @@ -7848,6 +8008,7 @@ SUBROUTINE FAST_AdvanceToNextTimeStep(t_initial, n_t_global, p_FAST, y_FAST, m_F END DO END IF + !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !! We've advanced everything to the next time step: !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -7869,42 +8030,44 @@ SUBROUTINE FAST_WriteOutput_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None CALL FAST_WriteOutput(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%IfW, Turbine%ExtInfw, & - Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, & - Turbine%Orca, Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) + Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & + Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & + Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) END SUBROUTINE FAST_WriteOutput_T !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine advances the time step from n_t_global to n_t_global + 1 and does all the relvant copying of data -SUBROUTINE FAST_WriteOutput(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & - MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) +!> This routine writes the outputs at this timestep +SUBROUTINE FAST_WriteOutput(t_global, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) - REAL(DbKi), INTENT(IN ) :: t_initial !< initial time + REAL(DbKi), INTENT(IN ) :: t_global !< initial time INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables - TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data - TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data - TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data - TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data - TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data - TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data - TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data - TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data - TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data - TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data - TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data - TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data - TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data - TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module - TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data - TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data - TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + TYPE(ElastoDyn_Data), INTENT(IN ) :: ED !< ElastoDyn data + TYPE(BeamDyn_Data), INTENT(IN ) :: BD !< BeamDyn data + TYPE(ServoDyn_Data), INTENT(IN ) :: SrvD !< ServoDyn data + TYPE(AeroDyn14_Data), INTENT(IN ) :: AD14 !< AeroDyn14 data + TYPE(AeroDyn_Data), INTENT(IN ) :: AD !< AeroDyn data + TYPE(ExtLoads_Data), INTENT(IN ) :: ExtLd !< External loads data + TYPE(InflowWind_Data), INTENT(IN ) :: IfW !< InflowWind data + TYPE(ExternalInflow_Data),INTENT(IN ) :: ExtInfw !< ExternalInflow data + TYPE(SCDataEx_Data), INTENT(IN ) :: SC_DX !< Supercontroller Exchange data + TYPE(SeaState_Data), INTENT(IN ) :: SeaSt !< SeaState data + TYPE(HydroDyn_Data), INTENT(IN ) :: HD !< HydroDyn data + TYPE(SubDyn_Data), INTENT(IN ) :: SD !< SubDyn data + TYPE(ExtPtfm_Data), INTENT(IN ) :: ExtPtfm !< ExtPtfm_MCKF data + TYPE(MAP_Data), INTENT(IN ) :: MAPp !< MAP data + TYPE(FEAMooring_Data), INTENT(IN ) :: FEAM !< FEAMooring data + TYPE(MoorDyn_Data), INTENT(IN ) :: MD !< Data for the MoorDyn module + TYPE(OrcaFlex_Data), INTENT(IN ) :: Orca !< OrcaFlex interface data + TYPE(IceFloe_Data), INTENT(IN ) :: IceF !< IceFloe data + TYPE(IceDyn_Data), INTENT(IN ) :: IceD !< All the IceDyn data used in time-step loop - TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + TYPE(FAST_ModuleMapType), INTENT(IN ) :: MeshMapData !< Data for mapping between modules INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -7920,11 +8083,11 @@ SUBROUTINE FAST_WriteOutput(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, B ErrStat = ErrID_None ErrMsg = "" + !---------------------------------------------------------------------------------------- !! Check to see if we should output data this time step: - !---------------------------------------------------------------------------------------- - - CALL WriteOutputToFile(n_t_global, m_FAST%t_global, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & + !---------------------------------------------------------------------------------------- + CALL WriteOutputToFile(n_t_global, t_global, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -7933,411 +8096,13 @@ SUBROUTINE FAST_WriteOutput(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, B !---------------------------------------------------------------------------------------- IF (p_FAST%WrSttsTime) then - IF ( MOD( n_t_global + 1, p_FAST%n_SttsTime ) == 0 ) THEN - - if (.not. Cmpl4SFun) then + IF ( MOD( n_t_global, p_FAST%n_SttsTime ) == 0 ) THEN CALL SimStatus( m_FAST%TiLstPrn, m_FAST%PrevClockTime, m_FAST%t_global, p_FAST%TMax, p_FAST%TDesc ) - end if - ENDIF ENDIF END SUBROUTINE FAST_WriteOutput -!---------------------------------------------------------------------------------------------------------------------------------- -!> Routine that calls FAST_Solution for one instance of a Turbine data structure. This is a separate subroutine so that the FAST -!! driver programs do not need to change or operate on the individual module level. -SUBROUTINE FAST_Solution_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) - REAL(DbKi), INTENT(IN ) :: t_initial !< initial time - INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter - TYPE(FAST_TurbineType), INTENT(INOUT) :: Turbine !< all data for one instance of a turbine - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - CALL FAST_Solution(t_initial, n_t_global, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & - Turbine%ED, Turbine%BD, Turbine%SrvD, Turbine%AD14, Turbine%AD, Turbine%ExtLd, Turbine%IfW, Turbine%ExtInfw, Turbine%SC_DX, & - Turbine%SeaSt, Turbine%HD, Turbine%SD, Turbine%ExtPtfm, Turbine%MAP, Turbine%FEAM, Turbine%MD, Turbine%Orca, & - Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrStat, ErrMsg ) - -END SUBROUTINE FAST_Solution_T -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine takes data from n_t_global and gets values at n_t_global + 1 -SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, SeaSt, HD, SD, ExtPtfm, & - MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) - - REAL(DbKi), INTENT(IN ) :: t_initial !< initial time - INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter - - TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code - TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code - TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables - - TYPE(ElastoDyn_Data), INTENT(INOUT) :: ED !< ElastoDyn data - TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BeamDyn data - TYPE(ServoDyn_Data), INTENT(INOUT) :: SrvD !< ServoDyn data - TYPE(AeroDyn14_Data), INTENT(INOUT) :: AD14 !< AeroDyn14 data - TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data - TYPE(ExtLoads_Data), INTENT(INOUT) :: ExtLd !< External loads data - TYPE(InflowWind_Data), INTENT(INOUT) :: IfW !< InflowWind data - TYPE(ExternalInflow_Data),INTENT(INOUT) :: ExtInfw !< ExternalInflow data - TYPE(SCDataEx_Data), INTENT(INOUT) :: SC_DX !< Supercontroller Exchange data - TYPE(SeaState_Data), INTENT(INOUT) :: SeaSt !< SeaState data - TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HydroDyn data - TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SubDyn data - TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm !< ExtPtfm_MCKF data - TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data - TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAM !< FEAMooring data - TYPE(MoorDyn_Data), INTENT(INOUT) :: MD !< Data for the MoorDyn module - TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data - TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data - TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop - - TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - ! local variables - REAL(DbKi) :: t_global_next ! next simulation time (m_FAST%t_global + p_FAST%dt) - INTEGER(IntKi) :: n_t_global_next ! n_t_global + 1 - INTEGER(IntKi) :: j_pc ! predictor-corrector loop counter - INTEGER(IntKi) :: NumCorrections ! number of corrections for this time step - INTEGER(IntKi), parameter :: MaxCorrections = 20 ! maximum number of corrections allowed - LOGICAL :: WriteThisStep ! Whether WriteOutput values will be printed - - INTEGER(IntKi) :: I, k ! generic loop counters - - !REAL(ReKi) :: ControlInputGuess ! value of controller inputs - - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_Solution' - - - ErrStat = ErrID_None - ErrMsg = "" - - n_t_global_next = n_t_global+1 - t_global_next = t_initial + n_t_global_next*p_FAST%DT ! = m_FAST%t_global + p_FAST%dt - - y_FAST%WriteThisStep = NeedWriteOutput(n_t_global_next, t_global_next, p_FAST) - - !! determine if the Jacobian should be calculated this time - IF ( m_FAST%calcJacobian ) THEN ! this was true (possibly at initialization), so we'll advance the time for the next calculation of the Jacobian - - if (p_FAST%CompMooring == Module_Orca .and. n_t_global < 5) then - m_FAST%NextJacCalcTime = m_FAST%t_global + p_FAST%DT ! the jacobian calculated with OrcaFlex at t=0 is incorrect, but is okay on the 2nd step (it's not okay for OrcaFlex version 10, so I increased this to 5) - else - m_FAST%NextJacCalcTime = m_FAST%t_global + p_FAST%DT_UJac - end if - - END IF - - ! set number of corrections to be used for this time step: - IF ( p_FAST%CompElast == Module_BD ) THEN ! BD accelerations have fewer spikes with these corrections on the first several time steps - if (n_t_global > 2) then ! this 2 should probably be related to p_FAST%InterpOrder - NumCorrections = p_FAST%NumCrctn - elseif (n_t_global == 0) then - NumCorrections = max(p_FAST%NumCrctn,16) - else - NumCorrections = max(p_FAST%NumCrctn,1) - end if - ELSE - NumCorrections = p_FAST%NumCrctn - END IF - - ! the ServoDyn inputs from Simulink are for t, not t+dt, so we're going to overwrite the inputs from - ! the previous step before we extrapolate these inputs: - IF ( p_FAST%CompServo == Module_SrvD ) CALL SrvD_SetExternalInputs( p_FAST, m_FAST, SrvD%Input(1) ) - - IF ( p_FAST%UseSC ) THEN - CALL SC_DX_SetOutputs(p_FAST, SrvD%Input(1), SC_DX, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - !! ## Step 1.a: Extrapolate Inputs - !! - !! gives predicted values at t+dt - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - CALL FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, HD, SD, ExtPtfm, & - MAPp, FEAM, MD, Orca, IceF, IceD, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - !! predictor-corrector loop: - j_pc = 0 - do while (j_pc <= NumCorrections) - WriteThisStep = y_FAST%WriteThisStep .AND. j_pc==NumCorrections - - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - !! ## Step 1.b: Advance states (yield state and constraint values at t_global_next) - !! - !! STATE_CURR values of x, xd, z, and OtherSt contain values at m_FAST%t_global; - !! STATE_PRED values contain values at t_global_next. - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - CALL FAST_AdvanceStates( t_initial, n_t_global, p_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, & - MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - !! ## Step 1.c: Input-Output Solve - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! save predicted inputs for comparison with corrected value later - !IF (p_FAST%CheckHSSBrTrqC) THEN - ! ControlInputGuess = ED%Input(1)%HSSBrTrqC - !END IF - - CALL CalcOutputs_And_SolveForInputs( n_t_global, t_global_next, STATE_PRED, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & - p_FAST, m_FAST, WriteThisStep, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - !! ## Step 2: Correct (continue in loop) - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - j_pc = j_pc + 1 - - ! ! Check if the predicted inputs were significantly different than the corrected inputs - ! ! (values before and after CalcOutputs_And_SolveForInputs) - !if (j_pc > NumCorrections) then - ! - ! !if (p_FAST%CheckHSSBrTrqC) then - ! ! if ( abs(ControlInputGuess - ED%Input(1)%HSSBrTrqC) > 50.0_ReKi ) then ! I randomly picked 50 N-m - ! ! NumCorrections = min(p_FAST%NumCrctn + 1, MaxCorrections) - ! ! ! print *, 'correction:', t_global_next, NumCorrections - ! ! cycle - ! ! end if - ! !end if - ! - ! ! check pitch position input to structural code (not implemented, yet) - !end if - - enddo ! j_pc - - if (p_FAST%UseSC ) then - call SC_DX_SetInputs(p_FAST, SrvD%y, SC_DX, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - end if - - if ( P_FAST%CompSeaSt == Module_SeaSt .and. y_FAST%WriteThisStep) then - ! note: SeaState has no inputs and only calculates WriteOutputs, so we don't need to call CalcOutput unless we are writing to the file - call SeaSt_CalcOutput( t_global_next, SeaSt%u, SeaSt%p, SeaSt%x(1), SeaSt%xd(1), SeaSt%z(1), SeaSt%OtherSt(1), SeaSt%y, SeaSt%m, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - end if - - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - !! ## Step 3: Save all final variables (advance to next time) - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - !---------------------------------------------------------------------------------------- - !! copy the final predicted states from step t_global_next to actual states for that step - !---------------------------------------------------------------------------------------- - - ! ElastoDyn: copy final predictions to actual states - CALL ED_CopyContState (ED%x( STATE_PRED), ED%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyDiscState (ED%xd(STATE_PRED), ED%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyConstrState (ED%z( STATE_PRED), ED%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ED_CopyOtherState (ED%OtherSt( STATE_PRED), ED%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - ! BeamDyn: copy final predictions to actual states - IF ( p_FAST%CompElast == Module_BD ) THEN - DO k=1,p_FAST%nBeams - CALL BD_CopyContState (BD%x( k,STATE_PRED), BD%x( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyDiscState (BD%xd(k,STATE_PRED), BD%xd(k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyConstrState (BD%z( k,STATE_PRED), BD%z( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL BD_CopyOtherState (BD%OtherSt( k,STATE_PRED), BD%OtherSt( k,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END DO - END IF - - - ! AeroDyn: copy final predictions to actual states; copy current outputs to next - IF ( p_FAST%CompAero == Module_AD14 ) THEN - CALL AD14_CopyContState (AD14%x( STATE_PRED), AD14%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyDiscState (AD14%xd(STATE_PRED), AD14%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyConstrState (AD14%z( STATE_PRED), AD14%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD14_CopyOtherState (AD14%OtherSt(STATE_PRED), AD14%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF ( (p_FAST%CompAero == Module_AD) .or. (p_FAST%CompAero == Module_ExtLd) ) THEN - CALL AD_CopyContState (AD%x( STATE_PRED), AD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyDiscState (AD%xd(STATE_PRED), AD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyConstrState (AD%z( STATE_PRED), AD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AD_CopyOtherState (AD%OtherSt(STATE_PRED), AD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - - ! InflowWind: copy final predictions to actual states; copy current outputs to next - IF ( p_FAST%CompInflow == Module_IfW ) THEN - CALL InflowWind_CopyContState (IfW%x( STATE_PRED), IfW%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyDiscState (IfW%xd(STATE_PRED), IfW%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyConstrState (IfW%z( STATE_PRED), IfW%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL InflowWind_CopyOtherState (IfW%OtherSt( STATE_PRED), IfW%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - - ! ServoDyn: copy final predictions to actual states; copy current outputs to next - IF ( p_FAST%CompServo == Module_SrvD ) THEN - CALL SrvD_CopyContState (SrvD%x( STATE_PRED), SrvD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyDiscState (SrvD%xd(STATE_PRED), SrvD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyConstrState (SrvD%z( STATE_PRED), SrvD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SrvD_CopyOtherState (SrvD%OtherSt( STATE_PRED), SrvD%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - ! SeaState has no states - - ! HydroDyn: copy final predictions to actual states - IF ( p_FAST%CompHydro == Module_HD ) THEN - CALL HydroDyn_CopyContState (HD%x( STATE_PRED), HD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyDiscState (HD%xd(STATE_PRED), HD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyConstrState (HD%z( STATE_PRED), HD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL HydroDyn_CopyOtherState (HD%OtherSt(STATE_PRED), HD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - - ! SubDyn: copy final predictions to actual states - IF ( p_FAST%CompSub == Module_SD ) THEN - CALL SD_CopyContState (SD%x( STATE_PRED), SD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyDiscState (SD%xd(STATE_PRED), SD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyConstrState (SD%z( STATE_PRED), SD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL SD_CopyOtherState (SD%OtherSt(STATE_PRED), SD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN - CALL ExtPtfm_CopyContState (ExtPtfm%x( STATE_PRED), ExtPtfm%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyDiscState (ExtPtfm%xd(STATE_PRED), ExtPtfm%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyConstrState (ExtPtfm%z( STATE_PRED), ExtPtfm%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ExtPtfm_CopyOtherState (ExtPtfm%OtherSt(STATE_PRED), ExtPtfm%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - - ! MAP: copy final predictions to actual states - IF (p_FAST%CompMooring == Module_MAP) THEN - CALL MAP_CopyContState (MAPp%x( STATE_PRED), MAPp%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyDiscState (MAPp%xd(STATE_PRED), MAPp%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MAP_CopyConstrState (MAPp%z( STATE_PRED), MAPp%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - !CALL MAP_CopyOtherState (MAPp%OtherSt(STATE_PRED), MAPp%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF (p_FAST%CompMooring == Module_MD) THEN - CALL MD_CopyContState (MD%x( STATE_PRED), MD%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyDiscState (MD%xd(STATE_PRED), MD%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyConstrState (MD%z( STATE_PRED), MD%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL MD_CopyOtherState (MD%OtherSt(STATE_PRED), MD%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN - CALL FEAM_CopyContState (FEAM%x( STATE_PRED), FEAM%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyDiscState (FEAM%xd(STATE_PRED), FEAM%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyConstrState (FEAM%z( STATE_PRED), FEAM%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL FEAM_CopyOtherState (FEAM%OtherSt( STATE_PRED), FEAM%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF (p_FAST%CompMooring == Module_Orca) THEN - CALL Orca_CopyContState (Orca%x( STATE_PRED), Orca%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyDiscState (Orca%xd(STATE_PRED), Orca%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyConstrState (Orca%z( STATE_PRED), Orca%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Orca_CopyOtherState (Orca%OtherSt( STATE_PRED), Orca%OtherSt( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - ! IceFloe: copy final predictions to actual states - IF ( p_FAST%CompIce == Module_IceF ) THEN - CALL IceFloe_CopyContState (IceF%x( STATE_PRED), IceF%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyDiscState (IceF%xd(STATE_PRED), IceF%xd(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyConstrState (IceF%z( STATE_PRED), IceF%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceFloe_CopyOtherState (IceF%OtherSt(STATE_PRED), IceF%OtherSt(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF ( p_FAST%CompIce == Module_IceD ) THEN - DO i=1,p_FAST%numIceLegs - CALL IceD_CopyContState (IceD%x( i,STATE_PRED), IceD%x( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyDiscState (IceD%xd(i,STATE_PRED), IceD%xd(i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyConstrState (IceD%z( i,STATE_PRED), IceD%z( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL IceD_CopyOtherState (IceD%OtherSt( i,STATE_PRED), IceD%OtherSt( i,STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END DO - END IF - - - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - !! We've advanced everything to the next time step: - !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - !! update the global time - - m_FAST%t_global = t_global_next - - - !---------------------------------------------------------------------------------------- - !! Check to see if we should output data this time step: - !---------------------------------------------------------------------------------------- - CALL WriteOutputToFile(n_t_global_next, t_global_next, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & - SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - !---------------------------------------------------------------------------------------- - !! Display simulation status every SttsTime-seconds (i.e., n_SttsTime steps): - !---------------------------------------------------------------------------------------- - - IF (p_FAST%WrSttsTime) then - IF ( MOD( n_t_global_next, p_FAST%n_SttsTime ) == 0 ) THEN - CALL SimStatus( m_FAST%TiLstPrn, m_FAST%PrevClockTime, m_FAST%t_global, p_FAST%TMax, p_FAST%TDesc ) - - ENDIF - ENDIF - -END SUBROUTINE FAST_Solution !---------------------------------------------------------------------------------------------------------------------------------- ! ROUTINES TO OUTPUT WRITE DATA TO FILE AT EACH REQUSTED TIME STEP !---------------------------------------------------------------------------------------------------------------------------------- From ac88936ad91cb372e661af4c2de24c24f3675cb9 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 12 Dec 2023 10:06:53 -0700 Subject: [PATCH 38/91] ExtLoads: remove InitOut%QPtN from BeamDyn (old change shouldn't have been included) --- modules/beamdyn/src/BeamDyn.f90 | 6 --- modules/beamdyn/src/BeamDyn_Types.f90 | 54 ------------------------ modules/beamdyn/src/Registry_BeamDyn.txt | 1 - 3 files changed, 61 deletions(-) diff --git a/modules/beamdyn/src/BeamDyn.f90 b/modules/beamdyn/src/BeamDyn.f90 index 89b63318f8..8909ca8b7d 100644 --- a/modules/beamdyn/src/BeamDyn.f90 +++ b/modules/beamdyn/src/BeamDyn.f90 @@ -824,12 +824,6 @@ subroutine SetInitOut(p, InitOut, ErrStat, ErrMsg) InitOut%Ver = BeamDyn_Ver - call AllocAry(InitOut%QPtN, p%nqp, 'InitOut%QPtN', ErrStat2,ErrMsg2) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if(ErrStat >= AbortErrLev) return - - InitOut%QPtN = (p%QPtN + 1.0)*0.5 - ! Set the info in WriteOutputHdr and WriteOutputUnt for BldNd sections. CALL BldNdOuts_InitOut( InitOut, p, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) diff --git a/modules/beamdyn/src/BeamDyn_Types.f90 b/modules/beamdyn/src/BeamDyn_Types.f90 index 1de281c9c1..5ef2e000ff 100644 --- a/modules/beamdyn/src/BeamDyn_Types.f90 +++ b/modules/beamdyn/src/BeamDyn_Types.f90 @@ -63,7 +63,6 @@ MODULE BeamDyn_Types TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: kp_coordinate !< Key point coordinates array [-] INTEGER(IntKi) :: kp_total !< Total number of key points [-] - REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: QPtN !< Quadrature (QuadPt) point locations in natural frame [-1, 1] [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_y !< Names of the outputs used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_x !< Names of the continuous states used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_u !< Names of the inputs used in linearization [-] @@ -686,18 +685,6 @@ SUBROUTINE BD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er DstInitOutputData%kp_coordinate = SrcInitOutputData%kp_coordinate ENDIF DstInitOutputData%kp_total = SrcInitOutputData%kp_total -IF (ALLOCATED(SrcInitOutputData%QPtN)) THEN - i1_l = LBOUND(SrcInitOutputData%QPtN,1) - i1_u = UBOUND(SrcInitOutputData%QPtN,1) - IF (.NOT. ALLOCATED(DstInitOutputData%QPtN)) THEN - ALLOCATE(DstInitOutputData%QPtN(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%QPtN.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitOutputData%QPtN = SrcInitOutputData%QPtN -ENDIF IF (ALLOCATED(SrcInitOutputData%LinNames_y)) THEN i1_l = LBOUND(SrcInitOutputData%LinNames_y,1) i1_u = UBOUND(SrcInitOutputData%LinNames_y,1) @@ -828,9 +815,6 @@ SUBROUTINE BD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpoin IF (ALLOCATED(InitOutputData%kp_coordinate)) THEN DEALLOCATE(InitOutputData%kp_coordinate) ENDIF -IF (ALLOCATED(InitOutputData%QPtN)) THEN - DEALLOCATE(InitOutputData%QPtN) -ENDIF IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) ENDIF @@ -926,11 +910,6 @@ SUBROUTINE BD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_BufSz = Db_BufSz + SIZE(InData%kp_coordinate) ! kp_coordinate END IF Int_BufSz = Int_BufSz + 1 ! kp_total - Int_BufSz = Int_BufSz + 1 ! QPtN allocated yes/no - IF ( ALLOCATED(InData%QPtN) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! QPtN upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%QPtN) ! QPtN - END IF Int_BufSz = Int_BufSz + 1 ! LinNames_y allocated yes/no IF ( ALLOCATED(InData%LinNames_y) ) THEN Int_BufSz = Int_BufSz + 2*1 ! LinNames_y upper/lower bounds for each dimension @@ -1082,21 +1061,6 @@ SUBROUTINE BD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs END IF IntKiBuf(Int_Xferred) = InData%kp_total Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%QPtN) ) 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%QPtN,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%QPtN,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%QPtN,1), UBOUND(InData%QPtN,1) - DbKiBuf(Db_Xferred) = InData%QPtN(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF IF ( .NOT. ALLOCATED(InData%LinNames_y) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1358,24 +1322,6 @@ SUBROUTINE BD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er END IF OutData%kp_total = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! QPtN 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%QPtN)) DEALLOCATE(OutData%QPtN) - ALLOCATE(OutData%QPtN(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%QPtN.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%QPtN,1), UBOUND(OutData%QPtN,1) - OutData%QPtN(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinNames_y not allocated Int_Xferred = Int_Xferred + 1 ELSE diff --git a/modules/beamdyn/src/Registry_BeamDyn.txt b/modules/beamdyn/src/Registry_BeamDyn.txt index 02af619393..d6b10e5fac 100644 --- a/modules/beamdyn/src/Registry_BeamDyn.txt +++ b/modules/beamdyn/src/Registry_BeamDyn.txt @@ -44,7 +44,6 @@ typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - typedef ^ InitOutputType R8Ki kp_coordinate {:}{:} - - "Key point coordinates array" - typedef ^ InitOutputType IntKi kp_total - - - "Total number of key points" - -typedef ^ InitOutputType R8Ki QPtN {:} - - "Quadrature (QuadPt) point locations in natural frame [-1, 1]" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - #typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_z {:} - - "Names of the constraint states used in linearization" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_x {:} - - "Names of the continuous states used in linearization" - From d35e2e36221f81688ab52fc9943128e0d96321d6 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 12 Dec 2023 10:21:12 -0700 Subject: [PATCH 39/91] BD: remove kp_total and kp_coordinate from InitOut --- modules/beamdyn/src/BeamDyn.f90 | 3 - modules/beamdyn/src/BeamDyn_Types.f90 | 75 ------------------------ modules/beamdyn/src/Registry_BeamDyn.txt | 2 - 3 files changed, 80 deletions(-) diff --git a/modules/beamdyn/src/BeamDyn.f90 b/modules/beamdyn/src/BeamDyn.f90 index 8909ca8b7d..35f1c75d86 100644 --- a/modules/beamdyn/src/BeamDyn.f90 +++ b/modules/beamdyn/src/BeamDyn.f90 @@ -247,9 +247,6 @@ SUBROUTINE BD_Init( InitInp, u, p, x, xd, z, OtherState, y, MiscVar, Interval, I z%DummyConstrState = 0.0_BDKi - ! copy data for BeamDyn driver: - call move_alloc ( InputFileData%kp_coordinate, InitOut%kp_coordinate) - InitOut%kp_total = InputFileData%kp_total !............................................................................................ ! Initialize Jacobian: diff --git a/modules/beamdyn/src/BeamDyn_Types.f90 b/modules/beamdyn/src/BeamDyn_Types.f90 index 5ef2e000ff..d098a848e6 100644 --- a/modules/beamdyn/src/BeamDyn_Types.f90 +++ b/modules/beamdyn/src/BeamDyn_Types.f90 @@ -61,8 +61,6 @@ MODULE BeamDyn_Types CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Names of the output-to-file channels [-] CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of the output-to-file channels [-] TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] - REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: kp_coordinate !< Key point coordinates array [-] - INTEGER(IntKi) :: kp_total !< Total number of key points [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_y !< Names of the outputs used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_x !< Names of the continuous states used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_u !< Names of the inputs used in linearization [-] @@ -636,7 +634,6 @@ SUBROUTINE BD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er ! 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 = 'BD_CopyInitOutput' @@ -670,21 +667,6 @@ SUBROUTINE BD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcInitOutputData%kp_coordinate)) THEN - i1_l = LBOUND(SrcInitOutputData%kp_coordinate,1) - i1_u = UBOUND(SrcInitOutputData%kp_coordinate,1) - i2_l = LBOUND(SrcInitOutputData%kp_coordinate,2) - i2_u = UBOUND(SrcInitOutputData%kp_coordinate,2) - IF (.NOT. ALLOCATED(DstInitOutputData%kp_coordinate)) THEN - ALLOCATE(DstInitOutputData%kp_coordinate(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%kp_coordinate.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitOutputData%kp_coordinate = SrcInitOutputData%kp_coordinate -ENDIF - DstInitOutputData%kp_total = SrcInitOutputData%kp_total IF (ALLOCATED(SrcInitOutputData%LinNames_y)) THEN i1_l = LBOUND(SrcInitOutputData%LinNames_y,1) i1_u = UBOUND(SrcInitOutputData%LinNames_y,1) @@ -812,9 +794,6 @@ SUBROUTINE BD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpoin ENDIF CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) -IF (ALLOCATED(InitOutputData%kp_coordinate)) THEN - DEALLOCATE(InitOutputData%kp_coordinate) -ENDIF IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) ENDIF @@ -904,12 +883,6 @@ SUBROUTINE BD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1 ! kp_coordinate allocated yes/no - IF ( ALLOCATED(InData%kp_coordinate) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! kp_coordinate upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%kp_coordinate) ! kp_coordinate - END IF - Int_BufSz = Int_BufSz + 1 ! kp_total Int_BufSz = Int_BufSz + 1 ! LinNames_y allocated yes/no IF ( ALLOCATED(InData%LinNames_y) ) THEN Int_BufSz = Int_BufSz + 2*1 ! LinNames_y upper/lower bounds for each dimension @@ -1039,28 +1012,6 @@ SUBROUTINE BD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%kp_coordinate) ) 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%kp_coordinate,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%kp_coordinate,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%kp_coordinate,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%kp_coordinate,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%kp_coordinate,2), UBOUND(InData%kp_coordinate,2) - DO i1 = LBOUND(InData%kp_coordinate,1), UBOUND(InData%kp_coordinate,1) - DbKiBuf(Db_Xferred) = InData%kp_coordinate(i1,i2) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - END IF - IntKiBuf(Int_Xferred) = InData%kp_total - Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%LinNames_y) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1203,7 +1154,6 @@ SUBROUTINE BD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er 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 = 'BD_UnPackInitOutput' @@ -1297,31 +1247,6 @@ SUBROUTINE BD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er 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 ! kp_coordinate 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%kp_coordinate)) DEALLOCATE(OutData%kp_coordinate) - ALLOCATE(OutData%kp_coordinate(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%kp_coordinate.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%kp_coordinate,2), UBOUND(OutData%kp_coordinate,2) - DO i1 = LBOUND(OutData%kp_coordinate,1), UBOUND(OutData%kp_coordinate,1) - OutData%kp_coordinate(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - END IF - OutData%kp_total = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinNames_y not allocated Int_Xferred = Int_Xferred + 1 ELSE diff --git a/modules/beamdyn/src/Registry_BeamDyn.txt b/modules/beamdyn/src/Registry_BeamDyn.txt index d6b10e5fac..db3b1d169e 100644 --- a/modules/beamdyn/src/Registry_BeamDyn.txt +++ b/modules/beamdyn/src/Registry_BeamDyn.txt @@ -42,8 +42,6 @@ typedef ^ InitInputType LOGICAL CompAeroMaps - .FALSE. - "fl typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output-to-file channels" - typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - -typedef ^ InitOutputType R8Ki kp_coordinate {:}{:} - - "Key point coordinates array" - -typedef ^ InitOutputType IntKi kp_total - - - "Total number of key points" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - #typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_z {:} - - "Names of the constraint states used in linearization" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_x {:} - - "Names of the continuous states used in linearization" - From 22f2c74758f70af6871792703aba5ace3f99be72 Mon Sep 17 00:00:00 2001 From: Philip Sakievich Date: Tue, 1 Aug 2023 21:14:14 -0600 Subject: [PATCH 40/91] Add hub and nacelle ref orient --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 53f5b4a407..2fb7c97ec4 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -2964,6 +2964,8 @@ void fast::OpenFAST::get_ref_positions_from_openfast(int iTurb) { for (int i=0; i < 3; i++) { brFSIData[iTurb][fast::STATE_NP1].hub_ref_pos[i] = extld_i_f_FAST[iTurb].hubRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; brFSIData[iTurb][fast::STATE_NP1].nac_ref_pos[i] = extld_i_f_FAST[iTurb].nacRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; + brFSIData[iTurb][fast::STATE_NP1].hub_ref_pos[i+3] = extld_i_f_FAST[iTurb].hubRefPos[i+3]; + brFSIData[iTurb][fast::STATE_NP1].nac_ref_pos[i+3] = extld_i_f_FAST[iTurb].nacRefPos[i+3]; } int nBlades = turbineData[iTurb].numBlades; From c83011ea0faeafb53b2cc16015fbd16b8b244e80 Mon Sep 17 00:00:00 2001 From: Philip Sakievich Date: Wed, 2 Aug 2023 10:41:45 -0600 Subject: [PATCH 41/91] Add netcdf output for hub/nac --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 2fb7c97ec4..61855b3646 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -603,6 +603,17 @@ void fast::OpenFAST::prepareOutputFile(int iTurbLoc) { param_count_dim.data(), tmpArray.data()); } } + + ierr = nc_put_var_double(ncid, ncOutVarIDs_["nac_ref_pos"], + &brFSIData[iTurbLoc][3].nac_ref_pos[0]); + ierr = nc_put_var_double(ncid, ncOutVarIDs_["nac_ref_orient"], + &brFSIData[iTurbLoc][3].nac_ref_pos[3]); + + ierr = nc_put_var_double(ncid, ncOutVarIDs_["hub_ref_pos"], + &brFSIData[iTurbLoc][3].hub_ref_pos[0]); + ierr = nc_put_var_double(ncid, ncOutVarIDs_["hub_ref_orient"], + &brFSIData[iTurbLoc][3].hub_ref_pos[3]); + } ierr = nc_close(ncid); From 8ff6282791c1e35d2c6485425b02eb03922ade2b Mon Sep 17 00:00:00 2001 From: psakiev Date: Thu, 3 Aug 2023 08:29:05 -0600 Subject: [PATCH 42/91] Make netcdf output parallel consistent --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 61855b3646..b0e24e0baa 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -282,7 +282,7 @@ void fast::OpenFAST::prepareOutputFile(int iTurbLoc) { //Create the file - this will destory any file std::stringstream defloads_fstream; defloads_fstream << "turb_" ; - defloads_fstream << std::setfill('0') << std::setw(2) << iTurbLoc; + defloads_fstream << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; defloads_fstream << "_output.nc"; std::string defloads_filename = defloads_fstream.str(); int ierr = nc_create(defloads_filename.c_str(), NC_CLOBBER, &ncid); From 6f0b5a2b6a3547314245acdcd3a5916d90890183 Mon Sep 17 00:00:00 2001 From: psakiev Date: Thu, 3 Aug 2023 23:07:32 -0600 Subject: [PATCH 43/91] Set file to operate on TurbID --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index b0e24e0baa..cedac6163c 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -58,7 +58,7 @@ void fast::OpenFAST::findRestartFile(int iTurbLoc) { //Find the file and open it in read only mode std::stringstream rstfile_ss; rstfile_ss << "turb_" ; - rstfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; + rstfile_ss << std::setfill('0') << std::setw(2) << turbineData[iTurbLoc].TurbID; rstfile_ss << "_rst.nc"; std::string rst_filename = rstfile_ss.str(); int ierr = nc_open(rst_filename.c_str(), NC_NOWRITE, &ncid); @@ -120,7 +120,7 @@ void fast::OpenFAST::prepareRestartFile(int iTurbLoc) { //This will destroy any existing file std::stringstream rstfile_ss; rstfile_ss << "turb_" ; - rstfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; + rstfile_ss << std::setfill('0') << std::setw(2) << turbineData[iTurbLoc].TurbID; rstfile_ss << "_rst.nc"; std::string rst_filename = rstfile_ss.str(); int ierr = nc_create(rst_filename.c_str(), NC_CLOBBER, &ncid); @@ -246,7 +246,7 @@ void fast::OpenFAST::findOutputFile(int iTurbLoc) { //Find the file and open it in read only mode std::stringstream outfile_ss; outfile_ss << "turb_" ; - outfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; + outfile_ss << std::setfill('0') << std::setw(2) << turbineData[iTurbLoc].TurbID; outfile_ss << "_output.nc"; std::string out_filename = outfile_ss.str(); int ierr = nc_open(out_filename.c_str(), NC_NOWRITE, &ncid); @@ -282,7 +282,7 @@ void fast::OpenFAST::prepareOutputFile(int iTurbLoc) { //Create the file - this will destory any file std::stringstream defloads_fstream; defloads_fstream << "turb_" ; - defloads_fstream << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurbLoc]; + defloads_fstream << std::setfill('0') << std::setw(2) << turbineData[iTurbLoc].TurbID; defloads_fstream << "_output.nc"; std::string defloads_filename = defloads_fstream.str(); int ierr = nc_create(defloads_filename.c_str(), NC_CLOBBER, &ncid); @@ -2232,7 +2232,7 @@ int fast::OpenFAST::openVelocityDataFile(int iTurb) { int ncid; std::stringstream velfile_fstream; velfile_fstream << "turb_" ; - velfile_fstream << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurb]; + velfile_fstream << std::setfill('0') << std::setw(2) << turbineData[iTurb].TurbID; velfile_fstream << "_veldata.nc"; std::string velfile_filename = velfile_fstream.str(); int ierr = nc_open(velfile_filename.c_str(), NC_WRITE, &ncid); @@ -2247,7 +2247,7 @@ void fast::OpenFAST::prepareVelocityDataFile(int iTurb) { int ncid; std::stringstream velfile_fstream; velfile_fstream << "turb_" ; - velfile_fstream << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurb]; + velfile_fstream << std::setfill('0') << std::setw(2) << turbineData[iTurb].TurbID; velfile_fstream << "_veldata.nc"; std::string velfile_filename = velfile_fstream.str(); int ierr = nc_create(velfile_filename.c_str(), NC_CLOBBER, &ncid); @@ -2280,7 +2280,7 @@ void fast::OpenFAST::writeVelocityData(int iTurb, int n_t_global, int nlinIter) //Find the file and open it in append mode std::stringstream velfile_ss; velfile_ss << "turb_" ; - velfile_ss << std::setfill('0') << std::setw(2) << turbineMapProcToGlob[iTurb]; + velfile_ss << std::setfill('0') << std::setw(2) << turbineData[iTurb].TurbID; velfile_ss << "_veldata.nc"; std::string vel_filename = velfile_ss.str(); int ierr = nc_open(vel_filename.c_str(), NC_WRITE, &ncid); @@ -2597,7 +2597,7 @@ void fast::OpenFAST::writeOutputFile(int iTurbLoc, int n_t_global) { //Open the file in append mode std::stringstream outfile_ss; outfile_ss << "turb_" ; - outfile_ss << std::setfill('0') << std::setw(2) << iTurbLoc; + outfile_ss << std::setfill('0') << std::setw(2) << turbineData[iTurbLoc].TurbID; outfile_ss << "_output.nc"; std::string defloads_filename = outfile_ss.str(); int ierr = nc_open(defloads_filename.c_str(), NC_WRITE, &ncid); From 104ab10ba762ea5c7fa12eaecb81176427c3c9ec Mon Sep 17 00:00:00 2001 From: Jon Rood Date: Wed, 20 Sep 2023 12:22:01 -0600 Subject: [PATCH 44/91] Check if restart frequency is > 0 to avoid dividing by 0. --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index cedac6163c..851657a414 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -1349,7 +1349,7 @@ void fast::OpenFAST::advance_to_next_driver_time_step(bool writeFiles) { if (writeFiles) { for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { int tStepRatio = dtDriver/dtFAST; - if ( (((nt_global - ntStart) % (restartFreq_*tStepRatio)) == 0 ) && (nt_global != ntStart) ) { + if ( (restartFreq_*tStepRatio > 0) && (((nt_global - ntStart) % (restartFreq_*tStepRatio)) == 0 ) && (nt_global != ntStart) ) { turbineData[iTurb].FASTRestartFileName = " "; // if blank, it will use FAST convention .nt_global FAST_CreateCheckpoint(&iTurb, turbineData[iTurb].FASTRestartFileName.data(), &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); From 1cf828bede7711b3902ad47852607d8ca7e374bc Mon Sep 17 00:00:00 2001 From: psakiev Date: Thu, 26 Oct 2023 08:28:25 -0600 Subject: [PATCH 45/91] Fix precision errors based on integer conversion --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 851657a414..e8e3e066da 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -1508,8 +1508,11 @@ void fast::OpenFAST::step(bool writeFiles) { } if (writeFiles) { + // provide an epsilon that is small relative to dtFast to help with integer conversion + const double eps = dtFast*1e-6; for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - int tStepRatio = dtDriver/dtFAST; + // ensure that the ratio is robust to integer conversion by making sure it will always truncate down + int tStepRatio = static_cast((dtDriver+eps)/dtFAST); if ( (((nt_global - ntStart) % (restartFreq_ * tStepRatio)) == 0 ) && (nt_global != ntStart) ) { turbineData[iTurb].FASTRestartFileName = " "; // if blank, it will use FAST convention .nt_global FAST_CreateCheckpoint(&iTurb, turbineData[iTurb].FASTRestartFileName.data(), &ErrStat, ErrMsg); From b277768d5cd867cd562a31e1a07d2c871c107c86 Mon Sep 17 00:00:00 2001 From: psakiev Date: Thu, 26 Oct 2023 14:41:45 -0600 Subject: [PATCH 46/91] Fix typo, and then replace other ratio computations --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index e8e3e066da..ab495294b4 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -15,6 +15,14 @@ inline void check_nc_error(int code, std::string msg) { int fast::OpenFAST::AbortErrLev = ErrID_Fatal; // abort error level; compare with NWTC Library +int time_step_ratio(double fastDt, double driverDt, double epsFactor=1e-6) +{ + // ensure that the ratio is robust to integer conversion by making sure it will always truncate down + // provide an epsilon that is small relative to dtFast to help with integer conversion + const double eps = driverDt*epsFactor; + return static_cast((driverDt*eps)/fastDt); +} + //Constructor fast::fastInputs::fastInputs(): nTurbinesGlob(0), @@ -1348,7 +1356,7 @@ void fast::OpenFAST::advance_to_next_driver_time_step(bool writeFiles) { if (writeFiles) { for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - int tStepRatio = dtDriver/dtFAST; + int tStepRatio = time_step_ratio(dtFAST, dtDriver); if ( (restartFreq_*tStepRatio > 0) && (((nt_global - ntStart) % (restartFreq_*tStepRatio)) == 0 ) && (nt_global != ntStart) ) { turbineData[iTurb].FASTRestartFileName = " "; // if blank, it will use FAST convention .nt_global FAST_CreateCheckpoint(&iTurb, turbineData[iTurb].FASTRestartFileName.data(), &ErrStat, ErrMsg); @@ -1508,11 +1516,8 @@ void fast::OpenFAST::step(bool writeFiles) { } if (writeFiles) { - // provide an epsilon that is small relative to dtFast to help with integer conversion - const double eps = dtFast*1e-6; + int tStepRatio = time_step_ratio(dtFAST, dtFAST); for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - // ensure that the ratio is robust to integer conversion by making sure it will always truncate down - int tStepRatio = static_cast((dtDriver+eps)/dtFAST); if ( (((nt_global - ntStart) % (restartFreq_ * tStepRatio)) == 0 ) && (nt_global != ntStart) ) { turbineData[iTurb].FASTRestartFileName = " "; // if blank, it will use FAST convention .nt_global FAST_CreateCheckpoint(&iTurb, turbineData[iTurb].FASTRestartFileName.data(), &ErrStat, ErrMsg); @@ -1582,7 +1587,7 @@ int fast::OpenFAST::checkAndSetSubsteps() { } } if (dtFAST > 0) { - int tStepRatio = dtDriver/dtFAST; + int tStepRatio = time_step_ratio(dtFAST, dtDriver); if (std::abs(dtDriver - tStepRatio * dtFAST) < 0.001) {// TODO: Fix arbitrary number 0.001 nSubsteps_ = tStepRatio; return 1; @@ -2607,7 +2612,7 @@ void fast::OpenFAST::writeOutputFile(int iTurbLoc, int n_t_global) { check_nc_error(ierr, "nc_open"); size_t count1=1; - int tStepRatio = dtDriver/dtFAST; + int tStepRatio = time_step_ratio(dtFAST, dtDriver); size_t n_tsteps = n_t_global/tStepRatio/outputFreq_ - 1; double curTime = n_t_global * dtFAST; ierr = nc_put_vara_double(ncid, ncOutVarIDs_["time"], &n_tsteps, &count1, &curTime); @@ -2902,7 +2907,7 @@ void fast::OpenFAST::writeRestartFile(int iTurbLoc, int n_t_global) { check_nc_error(ierr, "nc_open"); size_t count1=1; - int tStepRatio = dtDriver/dtFAST; + int tStepRatio = time_step_ratio(dtFAST, dtDriver); size_t n_tsteps = n_t_global/tStepRatio/restartFreq_ - 1; double curTime = n_t_global * dtFAST; ierr = nc_put_vara_double(ncid, ncRstVarIDs_["time"], &n_tsteps, &count1, &curTime); From 20e0b7d39723483d3569c53db555b29881ae09ff Mon Sep 17 00:00:00 2001 From: psakiev Date: Thu, 26 Oct 2023 14:55:13 -0600 Subject: [PATCH 47/91] Sigh, more typos --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index ab495294b4..9903741357 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -19,7 +19,7 @@ int time_step_ratio(double fastDt, double driverDt, double epsFactor=1e-6) { // ensure that the ratio is robust to integer conversion by making sure it will always truncate down // provide an epsilon that is small relative to dtFast to help with integer conversion - const double eps = driverDt*epsFactor; + const double eps = fastDt*epsFactor; return static_cast((driverDt*eps)/fastDt); } @@ -1516,7 +1516,7 @@ void fast::OpenFAST::step(bool writeFiles) { } if (writeFiles) { - int tStepRatio = time_step_ratio(dtFAST, dtFAST); + int tStepRatio = time_step_ratio(dtFAST, dtDriver); for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { if ( (((nt_global - ntStart) % (restartFreq_ * tStepRatio)) == 0 ) && (nt_global != ntStart) ) { turbineData[iTurb].FASTRestartFileName = " "; // if blank, it will use FAST convention .nt_global From b0184a24c0c857f2e7322becb49c5eb0ae1fb265 Mon Sep 17 00:00:00 2001 From: psakiev Date: Thu, 26 Oct 2023 20:58:46 -0600 Subject: [PATCH 48/91] One more typo --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 9903741357..58e2549a54 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -20,7 +20,7 @@ int time_step_ratio(double fastDt, double driverDt, double epsFactor=1e-6) // ensure that the ratio is robust to integer conversion by making sure it will always truncate down // provide an epsilon that is small relative to dtFast to help with integer conversion const double eps = fastDt*epsFactor; - return static_cast((driverDt*eps)/fastDt); + return static_cast((driverDt+eps)/fastDt); } //Constructor From 554c4ce80ae5e5edc520d0b34025cecf0ad82a46 Mon Sep 17 00:00:00 2001 From: Ganesh Vijayakumar Date: Thu, 14 Dec 2023 18:16:27 -0700 Subject: [PATCH 49/91] Fix WriteOutput time written --- modules/openfast-library/src/FAST_Subs.f90 | 500 ++++++++++----------- 1 file changed, 250 insertions(+), 250 deletions(-) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 7e5a6ffb64..3042f91ca3 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -27,7 +27,7 @@ MODULE FAST_Subs USE VersionInfo IMPLICIT NONE - + CONTAINS !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! INITIALIZATION ROUTINES @@ -42,11 +42,11 @@ SUBROUTINE FAST_InitializeAll_T( t_initial, TurbID, Turbine, ErrStat, ErrMsg, In CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None CHARACTER(*), OPTIONAL,INTENT(IN ) :: InFile !< A CHARACTER string containing the name of the primary FAST input file (if not present, we'll get it from the command line) TYPE(FAST_ExternInitType),OPTIONAL,INTENT(IN ) :: ExternInitData !< Initialization input data from an external source (Simulink) - + LOGICAL, PARAMETER :: CompAeroMaps = .false. Turbine%TurbID = TurbID - - + + IF (PRESENT(InFile)) THEN IF (PRESENT(ExternInitData)) THEN CALL FAST_InitializeAll( t_initial, Turbine%p_FAST, Turbine%y_FAST, Turbine%m_FAST, & @@ -103,7 +103,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules LOGICAL, INTENT(IN ) :: CompAeroMaps !< Determines if simplifications are made to produce aero maps (not time-marching) - + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None CHARACTER(*), OPTIONAL, INTENT(IN ) :: InFile !< A CHARACTER string containing the name of the primary FAST input file (if not present, we'll get it from the command line) @@ -124,11 +124,11 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, INTEGER(IntKi) :: k ! blade loop counter INTEGER(IntKi) :: nNodes ! temp var for ExtInfw coupling logical :: CallStart - + REAL(R8Ki) :: theta(3) ! angles for hub orientation matrix for aeromaps - + INTEGER(IntKi) :: NumBl - + CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'FAST_InitializeAll' @@ -137,7 +137,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, !.......... ErrStat = ErrID_None ErrMsg = "" - + p_FAST%CompAeroMaps = CompAeroMaps y_FAST%UnSum = -1 ! set the summary file unit to -1 to indicate it's not open @@ -151,7 +151,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, y_FAST%VTK_count = 0 ! first VTK file has 0 as output y_FAST%n_Out = 0 ! set the number of ouptut channels to 0 to indicate there's nothing to write to the binary file p_FAST%ModuleInitialized = .FALSE. ! (array initialization) no modules are initialized - + ! Get the current time CALL DATE_AND_TIME ( Values=m_FAST%StrtTime ) ! Let's time the whole simulation CALL CPU_TIME ( m_FAST%UsrTime1 ) ! Initial time (this zeros the start time when used as a MATLAB function) @@ -296,11 +296,11 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - + NumBl = Init%OutData_ED%NumBl p_FAST%GearBox_index = Init%OutData_ED%GearBox_index - - + + if (p_FAST%CalcSteady) then if ( EqualRealNos(Init%OutData_ED%RotSpeed, 0.0_ReKi) ) then p_FAST%TrimCase = TrimCase_none @@ -362,7 +362,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_BD%Linearize = p_FAST%Linearize Init%InData_BD%CompAeroMaps = p_FAST%CompAeroMaps Init%InData_BD%gravity = (/ 0.0_ReKi, 0.0_ReKi, -p_FAST%Gravity /) ! "Gravitational acceleration" m/s^2 - + ! now initialize BeamDyn for all beams dt_BD = p_FAST%dt_module( MODULE_BD ) @@ -413,7 +413,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (p_FAST%CompAeroMaps .and. BD%p(k)%BldMotionNodeLoc /= BD_MESH_FE) call SetErrStat(ErrID_Fatal, "BeamDyn aero maps must have outputs at FE nodes.", ErrStat, ErrMsg, RoutineName ) if (ErrStat>=AbortErrLev) exit !exit this loop so we don't get p_FAST%nBeams of the same errors - + if (size(y_FAST%Lin%Modules(MODULE_BD)%Instance) >= k) then ! for aero maps, we only use the first instance: if (allocated(Init%OutData_BD(k)%LinNames_y)) call move_alloc(Init%OutData_BD(k)%LinNames_y, y_FAST%Lin%Modules(MODULE_BD)%Instance(k)%Names_y ) if (allocated(Init%OutData_BD(k)%LinNames_x)) call move_alloc(Init%OutData_BD(k)%LinNames_x, y_FAST%Lin%Modules(MODULE_BD)%Instance(k)%Names_x ) @@ -423,17 +423,17 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (allocated(Init%OutData_BD(k)%RotFrame_u)) call move_alloc(Init%OutData_BD(k)%RotFrame_u, y_FAST%Lin%Modules(MODULE_BD)%Instance(k)%RotFrame_u ) if (allocated(Init%OutData_BD(k)%IsLoad_u )) call move_alloc(Init%OutData_BD(k)%IsLoad_u , y_FAST%Lin%Modules(MODULE_BD)%Instance(k)%IsLoad_u ) if (allocated(Init%OutData_BD(k)%DerivOrder_x)) call move_alloc(Init%OutData_BD(k)%DerivOrder_x, y_FAST%Lin%Modules(MODULE_BD)%Instance(k)%DerivOrder_x ) - + if (allocated(Init%OutData_BD(k)%WriteOutputHdr)) y_FAST%Lin%Modules(MODULE_BD)%Instance(k)%NumOutputs = size(Init%OutData_BD(k)%WriteOutputHdr) end if - + END DO - + IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN END IF - + END IF @@ -490,16 +490,16 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, END IF ELSEIF ( (p_FAST%CompAero == Module_AD) .OR. (p_FAST%CompAero == Module_ExtLd) ) THEN - - allocate(Init%InData_AD%rotors(1), stat=ErrStat2) + + allocate(Init%InData_AD%rotors(1), stat=ErrStat2) if (ErrStat2 /= 0 ) then call SetErrStat( ErrID_Fatal, 'Allocating rotors', errStat, errMsg, RoutineName ) call Cleanup() return end if - + Init%InData_AD%rotors(1)%NumBlades = NumBl - + if (p_FAST%CompAeroMaps) then CALL AllocAry( MeshMapData%HubOrient, 3, 3, Init%InData_AD%rotors(1)%NumBlades, 'Hub orientation matrix', ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -507,15 +507,15 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - + theta = 0.0_R8Ki do k=1,Init%InData_AD%rotors(1)%NumBlades theta(1) = TwoPi_R8 * (k-1) / Init%InData_AD%rotors(1)%NumBlades MeshMapData%HubOrient(:,:,k) = EulerConstruct( theta ) end do end if - - + + ! set initialization data for AD CALL AllocAry( Init%InData_AD%rotors(1)%BladeRootPosition, 3, Init%InData_AD%rotors(1)%NumBlades, 'Init%InData_AD%rotors(1)%BladeRootPosition', errStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -526,7 +526,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, RETURN END IF - Init%InData_AD%Gravity = p_FAST%Gravity + Init%InData_AD%Gravity = p_FAST%Gravity Init%InData_AD%Linearize = p_FAST%Linearize Init%InData_AD%CompAeroMaps = p_FAST%CompAeroMaps Init%InData_AD%rotors(1)%RotSpeed = p_FAST%RotSpeedInit ! used only for aeromaps @@ -544,20 +544,20 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_AD%defPvap = p_FAST%Pvap Init%InData_AD%WtrDpth = p_FAST%WtrDpth Init%InData_AD%MSL2SWL = p_FAST%MSL2SWL - - + + Init%InData_AD%rotors(1)%HubPosition = ED%y%HubPtMotion%Position(:,1) Init%InData_AD%rotors(1)%HubOrientation = ED%y%HubPtMotion%RefOrientation(:,:,1) Init%InData_AD%rotors(1)%NacellePosition = ED%y%NacelleMotion%Position(:,1) Init%InData_AD%rotors(1)%NacelleOrientation = ED%y%NacelleMotion%RefOrientation(:,:,1) ! Note: not passing tailfin position and orientation at init Init%InData_AD%rotors(1)%AeroProjMod = APM_BEM_NoSweepPitchTwist - + do k=1,NumBl Init%InData_AD%rotors(1)%BladeRootPosition(:,k) = ED%y%BladeRootMotion(k)%Position(:,1) Init%InData_AD%rotors(1)%BladeRootOrientation(:,:,k) = ED%y%BladeRootMotion(k)%RefOrientation(:,:,1) end do - + CALL AD_Init( Init%InData_AD, AD%Input(1), AD%p, AD%x(STATE_CURR), AD%xd(STATE_CURR), AD%z(STATE_CURR), & AD%OtherSt(STATE_CURR), AD%y, AD%m, p_FAST%dt_module( MODULE_AD ), Init%OutData_AD, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -585,10 +585,10 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN - END IF - + END IF + AirDens = Init%OutData_AD%rotors(1)%AirDens - + ELSE AirDens = 0.0_ReKi END IF ! CompAero @@ -665,12 +665,12 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) - if ( p_FAST%CompElast == Module_BD ) then + if ( p_FAST%CompElast == Module_BD ) then Init%InData_IfW%RadAvg = TwoNorm(BD%y(1)%BldMotion%Position(:,1) - BD%y(1)%BldMotion%Position(:,BD%y(1)%BldMotion%Nnodes)) else Init%InData_IfW%RadAvg = Init%OutData_ED%BladeLength end if - + IF ( PRESENT(ExternInitData) ) THEN Init%InData_IfW%Use4Dext = ExternInitData%FarmIntegration @@ -709,7 +709,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - + IF ( p_FAST%CompServo == Module_SrvD ) THEN !assign the number of gates to ServD if (allocated(IfW%y%lidar%LidSpeed)) then ! make sure we have the array allocated before setting it CALL AllocAry(Init%InData_SrvD%LidSpeed, size(IfW%y%lidar%LidSpeed), 'Init%InData_SrvD%LidSpeed', errStat2, ErrMsg2) @@ -736,7 +736,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_SrvD%NumPulseGate = IfW%p%lidar%NumPulseGate Init%InData_SrvD%PulseSpacing = IfW%p%lidar%PulseSpacing END IF - + ELSEIF ( p_FAST%CompInflow == Module_ExtInfw ) THEN @@ -866,27 +866,27 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_SeaSt%hasIce = p_FAST%CompIce /= Module_None Init%InData_SeaSt%InputFile = p_FAST%SeaStFile Init%InData_SeaSt%OutRootName = TRIM(p_FAST%OutFileRoot)//'.'//TRIM(y_FAST%Module_Abrev(Module_SeaSt)) - + ! these values support wave field handling Init%InData_SeaSt%WaveFieldMod = p_FAST%WaveFieldMod Init%InData_SeaSt%PtfmLocationX = p_FAST%TurbinePos(1) Init%InData_SeaSt%PtfmLocationY = p_FAST%TurbinePos(2) - + Init%InData_SeaSt%TMax = p_FAST%TMax - + CALL SeaSt_Init( Init%InData_SeaSt, SeaSt%Input(1), SeaSt%p, SeaSt%x(STATE_CURR), SeaSt%xd(STATE_CURR), SeaSt%z(STATE_CURR), & SeaSt%OtherSt(STATE_CURR), SeaSt%y, SeaSt%m, p_FAST%dt_module( MODULE_SeaSt ), Init%OutData_SeaSt, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + p_FAST%ModuleInitialized(Module_SeaSt) = .TRUE. CALL SetModuleSubstepTime(Module_SeaSt, p_FAST, y_FAST, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN - END IF - + END IF + ! Need to set up other module's InitInput data here because we will also need to clean up SeaState data and would rather not defer that cleanup if ( p_FAST%CompHydro == Module_HD ) then Init%InData_HD%NStepWave = Init%OutData_SeaSt%NStepWave @@ -895,45 +895,45 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_HD%WaveMod = Init%OutData_SeaSt%WaveMod Init%InData_HD%WaveStMod = Init%OutData_SeaSt%WaveStMod Init%InData_HD%WaveDirMod = Init%OutData_SeaSt%WaveDirMod - Init%InData_HD%WvLowCOff = Init%OutData_SeaSt%WvLowCOff - Init%InData_HD%WvHiCOff = Init%OutData_SeaSt%WvHiCOff + Init%InData_HD%WvLowCOff = Init%OutData_SeaSt%WvLowCOff + Init%InData_HD%WvHiCOff = Init%OutData_SeaSt%WvHiCOff Init%InData_HD%WvLowCOffD = Init%OutData_SeaSt%WvLowCOffD - Init%InData_HD%WvHiCOffD = Init%OutData_SeaSt%WvHiCOffD + Init%InData_HD%WvHiCOffD = Init%OutData_SeaSt%WvHiCOffD Init%InData_HD%WvLowCOffS = Init%OutData_SeaSt%WvLowCOffS - Init%InData_HD%WvHiCOffS = Init%OutData_SeaSt%WvHiCOffS + Init%InData_HD%WvHiCOffS = Init%OutData_SeaSt%WvHiCOffS Init%InData_HD%InvalidWithSSExctn = Init%OutData_SeaSt%InvalidWithSSExctn - - Init%InData_HD%WaveDirMin = Init%OutData_SeaSt%WaveDirMin - Init%InData_HD%WaveDirMax = Init%OutData_SeaSt%WaveDirMax - Init%InData_HD%WaveDir = Init%OutData_SeaSt%WaveDir + + Init%InData_HD%WaveDirMin = Init%OutData_SeaSt%WaveDirMin + Init%InData_HD%WaveDirMax = Init%OutData_SeaSt%WaveDirMax + Init%InData_HD%WaveDir = Init%OutData_SeaSt%WaveDir Init%InData_HD%WaveMultiDir = Init%OutData_SeaSt%WaveMultiDir - Init%InData_HD%WaveDOmega = Init%OutData_SeaSt%WaveDOmega + Init%InData_HD%WaveDOmega = Init%OutData_SeaSt%WaveDOmega Init%InData_HD%MCFD = Init%OutData_SeaSt%MCFD - - CALL MOVE_ALLOC( Init%OutData_SeaSt%WaveElev0, Init%InData_HD%WaveElev0 ) - Init%InData_HD%WaveTime => Init%OutData_SeaSt%WaveTime - Init%InData_HD%WaveDynP => Init%OutData_SeaSt%WaveDynP - Init%InData_HD%WaveAcc => Init%OutData_SeaSt%WaveAcc - Init%InData_HD%WaveVel => Init%OutData_SeaSt%WaveVel - Init%InData_HD%PWaveDynP0 => Init%OutData_SeaSt%PWaveDynP0 - Init%InData_HD%PWaveAcc0 => Init%OutData_SeaSt%PWaveAcc0 - Init%InData_HD%PWaveVel0 => Init%OutData_SeaSt%PWaveVel0 + + CALL MOVE_ALLOC( Init%OutData_SeaSt%WaveElev0, Init%InData_HD%WaveElev0 ) + Init%InData_HD%WaveTime => Init%OutData_SeaSt%WaveTime + Init%InData_HD%WaveDynP => Init%OutData_SeaSt%WaveDynP + Init%InData_HD%WaveAcc => Init%OutData_SeaSt%WaveAcc + Init%InData_HD%WaveVel => Init%OutData_SeaSt%WaveVel + Init%InData_HD%PWaveDynP0 => Init%OutData_SeaSt%PWaveDynP0 + Init%InData_HD%PWaveAcc0 => Init%OutData_SeaSt%PWaveAcc0 + Init%InData_HD%PWaveVel0 => Init%OutData_SeaSt%PWaveVel0 Init%InData_HD%WaveElevC0 => Init%OutData_SeaSt%WaveElevC0 CALL MOVE_ALLOC( Init%OutData_SeaSt%WaveElevC, Init%InData_HD%WaveElevC ) Init%InData_HD%WaveDirArr => Init%OutData_SeaSt%WaveDirArr Init%InData_HD%WaveElev1 => Init%OutData_SeaSt%WaveElev1 Init%InData_HD%WaveElev2 => Init%OutData_SeaSt%WaveElev2 - + Init%InData_HD%WaveAccMCF => Init%OutData_SeaSt%WaveAccMCF Init%InData_HD%PWaveAccMCF0 => Init%OutData_SeaSt%PWaveAccMCF0 - + call SeaSt_Interp_CopyParam(Init%OutData_SeaSt%SeaSt_Interp_p, Init%InData_HD%SeaSt_Interp_p, MESH_NEWCOPY, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + end if - + end if - + ! ........................ ! initialize HydroDyn ! ........................ @@ -1034,16 +1034,16 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ELSE Init%InData_SD%WtrDpth = 0.0_ReKi END IF - + Init%InData_SD%Linearize = p_FAST%Linearize - Init%InData_SD%g = p_FAST%Gravity - !Ini%tInData_SD%UseInputFile = .TRUE. + Init%InData_SD%g = p_FAST%Gravity + !Ini%tInData_SD%UseInputFile = .TRUE. Init%InData_SD%SDInputFile = p_FAST%SubFile Init%InData_SD%RootName = p_FAST%OutFileRoot Init%InData_SD%TP_RefPoint = ED%y%PlatformPtMesh%Position(:,1) ! "Interface point" where loads will be transferred to Init%InData_SD%SubRotateZ = 0.0 ! Used by driver to rotate structure around z - - + + CALL SD_Init( Init%InData_SD, SD%Input(1), SD%p, SD%x(STATE_CURR), SD%xd(STATE_CURR), SD%z(STATE_CURR), & SD%OtherSt(STATE_CURR), SD%y, SD%m, p_FAST%dt_module( MODULE_SD ), Init%OutData_SD, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -1066,7 +1066,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (allocated(Init%OutData_SD%WriteOutputHdr)) y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%NumOutputs = size(Init%OutData_SD%WriteOutputHdr) if (allocated(Init%OutData_SD%DerivOrder_x)) call move_alloc(Init%OutData_SD%DerivOrder_x,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%DerivOrder_x) end if - + IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN @@ -1169,7 +1169,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL WrScr(NewLine) !bjj: I'm printing two blank lines here because MAP seems to be writing over the last line on the screen. -! Init%InData_MAP%rootname = p_FAST%OutFileRoot ! Output file name +! Init%InData_MAP%rootname = p_FAST%OutFileRoot ! Output file name Init%InData_MAP%gravity = p_FAST%Gravity ! This need to be according to g from driver Init%InData_MAP%sea_density = Init%OutData_SeaSt%WtrDens ! This needs to be set according to seawater density in SeaState Init%InData_MAP%depth = Init%OutData_SeaSt%WtrDpth ! This need to be set according to the water depth in SeaState @@ -1208,7 +1208,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! initialize MoorDyn ! ........................ ELSEIF (p_FAST%CompMooring == Module_MD) THEN - + ! some new allocations needed with version that's compatible with farm-level use ALLOCATE( Init%InData_MD%PtfmInit(6,1), Init%InData_MD%TurbineRefPos(3,1), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1238,7 +1238,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, p_FAST%ModuleInitialized(Module_MD) = .TRUE. CALL SetModuleSubstepTime(Module_MD, p_FAST, y_FAST, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + allocate( y_FAST%Lin%Modules(MODULE_MD)%Instance(1), stat=ErrStat2) if (ErrStat2 /= 0 ) then call SetErrStat(ErrID_Fatal, "Error allocating Lin%Modules(MD).", ErrStat, ErrMsg, RoutineName ) @@ -1253,7 +1253,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (allocated(Init%OutData_MD%WriteOutputHdr)) y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%NumOutputs = size(Init%OutData_MD%WriteOutputHdr) if (allocated(Init%OutData_MD%DerivOrder_x)) call move_alloc(Init%OutData_MD%DerivOrder_x,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%DerivOrder_x) end if - + IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN @@ -1267,7 +1267,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_FEAM%RootName = TRIM(p_FAST%OutFileRoot)//'.'//TRIM(y_FAST%Module_Abrev(Module_FEAM)) Init%InData_FEAM%PtfmInit = Init%OutData_ED%PlatformPos !ED%x(STATE_CURR)%QT(1:6) ! initial position of the platform !bjj: this should come from Init%OutData_ED, not x_ED - Init%InData_FEAM%NStepWave = 1 ! an arbitrary number > 0 (to set the size of the wave data, which currently contains all zero values) + Init%InData_FEAM%NStepWave = 1 ! an arbitrary number > 0 (to set the size of the wave data, which currently contains all zero values) Init%InData_FEAM%gravity = p_FAST%Gravity ! This need to be according to g from driver Init%InData_FEAM%WtrDens = Init%OutData_SeaSt%WtrDens ! This needs to be set according to seawater density in SeaState ! Init%InData_FEAM%depth = Init%OutData_SeaSt%WtrDpth ! This need to be set according to the water depth in SeaState @@ -1374,7 +1374,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_IceF%simLength = p_FAST%TMax !bjj: IceFloe stores this as single-precision (ReKi) TMax is DbKi Init%InData_IceF%MSL2SWL = Init%OutData_SeaSt%MSL2SWL Init%InData_IceF%gravity = p_FAST%Gravity - + CALL IceFloe_Init( Init%InData_IceF, IceF%Input(1), IceF%p, IceF%x(STATE_CURR), IceF%xd(STATE_CURR), IceF%z(STATE_CURR), & IceF%OtherSt(STATE_CURR), IceF%y, IceF%m, p_FAST%dt_module( MODULE_IceF ), Init%OutData_IceF, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -1393,7 +1393,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ELSEIF ( p_FAST%CompIce == Module_IceD ) THEN Init%InData_IceD%InputFile = p_FAST%IceFile - Init%InData_IceD%RootName = TRIM(p_FAST%OutFileRoot)//'.'//TRIM(y_FAST%Module_Abrev(Module_IceD))//'1' + Init%InData_IceD%RootName = TRIM(p_FAST%OutFileRoot)//'.'//TRIM(y_FAST%Module_Abrev(Module_IceD))//'1' Init%InData_IceD%MSL2SWL = Init%OutData_SeaSt%MSL2SWL Init%InData_IceD%WtrDens = Init%OutData_SeaSt%WtrDens Init%InData_IceD%gravity = p_FAST%Gravity @@ -1441,7 +1441,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! ........................ - ! initialize ServoDyn + ! initialize ServoDyn ! ........................ ALLOCATE( SrvD%Input( p_FAST%InterpOrder+1 ), SrvD%InputTimes( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1449,7 +1449,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - + ALLOCATE( SrvD%Input_Saved( p_FAST%InterpOrder+1 ), SrvD%InputTimes_Saved( p_FAST%InterpOrder+1 ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating SrvD%Input_Saved and SrvD%InputTimes_Saved.",ErrStat,ErrMsg,RoutineName) @@ -1502,7 +1502,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_SrvD%BladeRootOrient(:,:,k) = ED%y%BladeRootMotion(k)%Orientation(:,:,1) enddo - + IF ( PRESENT(ExternInitData) ) THEN Init%InData_SrvD%NumSC2CtrlGlob = ExternInitData%NumSC2CtrlGlob IF ( (Init%InData_SrvD%NumSC2CtrlGlob > 0) ) THEN @@ -1512,7 +1512,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - + do i=1,Init%InData_SrvD%NumSC2CtrlGlob Init%InData_SrvD%fromSCGlob(i) = ExternInitData%fromSCGlob(i) end do @@ -1526,7 +1526,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - + do i=1,Init%InData_SrvD%NumSC2Ctrl Init%InData_SrvD%fromSC(i) = ExternInitData%fromSC(i) end do @@ -1538,12 +1538,12 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_SrvD%NumSC2CtrlGlob = 0 Init%InData_SrvD%NumSC2Ctrl = 0 Init%InData_SrvD%NumCtrl2SC = 0 - END IF + END IF ! Set cable controls inputs (if requested by other modules) -- There is probably a nicer way to do this, but this will work for now. call SetSrvDCableControls() - - + + CALL AllocAry(Init%InData_SrvD%BlPitchInit, Init%OutData_ED%NumBl, 'BlPitchInit', ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -1564,7 +1564,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) !! initialize SrvD%y%ElecPwr and SrvD%y%GenTq because they are one timestep different (used as input for the next step)? - + allocate( y_FAST%Lin%Modules(MODULE_SrvD)%Instance(1), stat=ErrStat2) if (ErrStat2 /= 0 ) then call SetErrStat(ErrID_Fatal, "Error allocating Lin%Modules(SrvD).", ErrStat, ErrMsg, RoutineName ) @@ -1580,32 +1580,32 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (allocated(Init%OutData_SrvD%WriteOutputHdr)) y_FAST%Lin%Modules(MODULE_SrvD)%Instance(1)%NumOutputs = size(Init%OutData_SrvD%WriteOutputHdr) end if - + IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN END IF - + ! ........................ ! some checks for AeroDyn and ElastoDyn inputs with the high-speed shaft brake hack in ElastoDyn: ! (DO NOT COPY THIS CODE!) - ! ........................ + ! ........................ ! bjj: this is a hack to get high-speed shaft braking in FAST v8 - + IF ( Init%OutData_SrvD%UseHSSBrake ) THEN IF ( p_FAST%CompAero == Module_AD14 ) THEN IF ( AD14%p%DYNINFL ) THEN CALL SetErrStat(ErrID_Fatal,'AeroDyn v14 "DYNINFL" InfModel is invalid for models with high-speed shaft braking.',ErrStat,ErrMsg,RoutineName) END IF END IF - + IF ( ED%p%method == Method_RK4 ) THEN ! bjj: should be using ElastoDyn's Method_ABM4 Method_AB4 parameters CALL SetErrStat(ErrID_Fatal,'ElastoDyn must use the AB4 or ABM4 integration method to implement high-speed shaft braking.',ErrStat,ErrMsg,RoutineName) ENDIF END IF ! Init%OutData_SrvD%UseHSSBrake - - + + END IF @@ -1638,19 +1638,19 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! Initialize for linearization or computing aero maps: ! ------------------------------------------------------------------------- if ( p_FAST%Linearize .or. p_FAST%CompAeroMaps) then - ! NOTE: In the following call, we use Init%OutData_AD%BladeProps(1)%NumBlNds as the number of aero nodes on EACH blade, which + ! NOTE: In the following call, we use Init%OutData_AD%BladeProps(1)%NumBlNds as the number of aero nodes on EACH blade, which ! is consistent with the current AD implementation, but if AD changes this, then it must be handled here, too! if (p_FAST%CompAero == MODULE_AD) then - call Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, Init%OutData_AD%rotors(1)%BladeProps(1)%NumBlNds, ErrStat2, ErrMsg2) + call Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, Init%OutData_AD%rotors(1)%BladeProps(1)%NumBlNds, ErrStat2, ErrMsg2) else - call Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, -1, ErrStat2, ErrMsg2) - endif + call Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, -1, ErrStat2, ErrMsg2) + endif call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) then call Cleanup() return end if - + if (p_FAST%CompAeroMaps) then p_FAST%SizeJac_Opt1(1) = y_FAST%Lin%Glue%SizeLin(LIN_ContSTATE_COL) + y_FAST%Lin%Glue%SizeLin(LIN_INPUT_COL) p_FAST%TolerSquared = p_FAST%TolerSquared * (p_FAST%SizeJac_Opt1(1)**2) ! do this calculation here so we don't have to keep dividing by the size of the array later @@ -1733,7 +1733,7 @@ SUBROUTINE Cleanup() !............................................................................................................................... ! We assume that all initializion data points to parameter data, so we just nullify the pointers instead of deallocate ! data that they point to: - CALL FAST_DestroyInitData( Init, ErrStat2, ErrMsg2, DEALLOCATEpointers=.false. ) + CALL FAST_DestroyInitData( Init, ErrStat2, ErrMsg2, DEALLOCATEpointers=.false. ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) END SUBROUTINE Cleanup @@ -1843,12 +1843,12 @@ SUBROUTINE FAST_ProgStart(ThisProgVer) TYPE(ProgDesc) :: NewProgVer !< program name/date/version description - + NewProgVer = ThisProgVer if (LEN_TRIM(ProgName)>0) then ! add this for steady-state solver NewProgVer%Name = ProgName end if - + ! ... Initialize NWTC Library ! sets the pi constants, open console for output, etc... @@ -1964,7 +1964,7 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, !............................................................................................................................... y_FAST%Module_Ver( Module_Glue ) = FAST_Ver - + DO i=2,NumModules y_FAST%Module_Ver(i)%Date = 'unknown date' y_FAST%Module_Ver(i)%Ver = 'unknown version' @@ -1987,7 +1987,7 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, y_FAST%Module_Ver( Module_Orca )%Name = 'OrcaFlexInterface' y_FAST%Module_Ver( Module_IceF )%Name = 'IceFloe' y_FAST%Module_Ver( Module_IceD )%Name = 'IceDyn' - + y_FAST%Module_Abrev( Module_Glue ) = 'FAST' y_FAST%Module_Abrev( Module_IfW ) = 'IfW' y_FAST%Module_Abrev( Module_ExtInfw) = 'ExtInfw' @@ -2007,7 +2007,7 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, y_FAST%Module_Abrev( Module_Orca ) = 'Orca' y_FAST%Module_Abrev( Module_IceF ) = 'IceF' y_FAST%Module_Abrev( Module_IceD ) = 'IceD' - + p%n_substeps = 1 ! number of substeps for between modules and global/FAST time p%BD_OutputSibling = .false. @@ -2070,8 +2070,8 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, end if p%OutFmt_t = 'F'//trim(num2lstr( p%TChanLen ))//'.4' ! 'F10.4' end if - - + + !............................................................................................................................... ! Do some error checking on the inputs (validation): !............................................................................................................................... @@ -2128,11 +2128,11 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) IF (p%tolerSquared < EPSILON(p%tolerSquared)) THEN CALL SetErrStat( ErrID_Fatal, 'Toler must be larger than sqrt(epsilon).', ErrStat, ErrMsg, RoutineName ) END IF - + IF (p%KMax < 1) THEN CALL SetErrStat( ErrID_Fatal, 'MaxIter must be at least 1.', ErrStat, ErrMsg, RoutineName ) END IF - + ! Check that InputFileData%OutFmt is a valid format specifier and will fit over the column headings CALL ChkRealFmtStr( p%OutFmt, 'OutFmt', p%FmtWidth, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -2159,12 +2159,12 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) IF (p%CompSub == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompSub must be 0 (None), 1 (SubDyn), or 2 (ExtPtfm_MCKF).', ErrStat, ErrMsg, RoutineName ) IF (p%CompMooring == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompMooring must be 0 (None), 1 (MAP), 2 (FEAMooring), 3 (MoorDyn), or 4 (OrcaFlex).', ErrStat, ErrMsg, RoutineName ) IF (p%CompIce == Module_Unknown) CALL SetErrStat( ErrID_Fatal, 'CompIce must be 0 (None) or 1 (IceFloe).', ErrStat, ErrMsg, RoutineName ) - + ! NOTE: If future modules consume SeaState data, then their checks should be added to this routine. 12/1/21 GJH if (p%CompHydro == Module_HD .and. p%CompSeaSt == Module_None) then CALL SetErrStat( ErrID_Fatal, 'SeaState must be used when HydroDyn is used. Set CompSeaSt = 1 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) end if - + IF (p%CompHydro /= Module_HD) THEN IF (p%CompMooring == Module_MAP) THEN CALL SetErrStat( ErrID_Fatal, 'HydroDyn must be used when MAP is used. Set CompHydro > 0 or CompMooring = 0 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) @@ -2177,7 +2177,7 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) IF (p%CompMooring == Module_Orca) CALL SetErrStat( ErrID_Fatal, 'HydroDyn cannot be used if OrcaFlex is used. Set CompHydro = 0 or CompMooring < 4 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) IF (p%CompSub == Module_ExtPtfm) CALL SetErrStat( ErrID_Fatal, 'HydroDyn cannot be used if ExtPtfm_MCKF is used. Set CompHydro = 0 or CompSub < 2 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) END IF - + IF (p%CompMooring == Module_Orca .and. p%CompSub /= Module_None) CALL SetErrStat( ErrID_Fatal, 'SubDyn and ExtPtfm cannot be used if OrcaFlex is used. Set CompSub = 0 or CompMooring < 4 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) @@ -2192,7 +2192,7 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) IF (p%CompElast == Module_BD .and. p%CompAero == Module_AD14 ) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used when BeamDyn is used. Change CompAero or CompElast in the FAST input file.', ErrStat, ErrMsg, RoutineName ) if (p%CompInflow == MODULE_ExtInfw .and. p%CompAero == Module_AD14 ) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used when ExternalInflow is used. Change CompAero or CompInflow in the FAST input file.', ErrStat, ErrMsg, RoutineName ) if ((p%CompAero == Module_ExtLd) .and. (p%CompInflow /= Module_NONE) ) call SetErrStat(ErrID_Fatal, 'Inflow module cannot be used when ExtLoads is used. Change CompAero or CompInflow in the OpenFAST input file.', ErrStat, ErrMsg, RoutineName) - + IF (p%MHK /= MHK_None .and. p%MHK /= MHK_FixedBottom .and. p%MHK /= MHK_Floating) CALL SetErrStat( ErrID_Fatal, 'MHK switch is invalid. Set MHK to 0, 1, or 2 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) IF (p%MHK /= MHK_None .and. p%CompAero == Module_AD14) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used with an MHK turbine. Change CompAero or MHK in the FAST input file.', ErrStat, ErrMsg, RoutineName ) @@ -2296,13 +2296,13 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) CALL SetErrStat( ErrID_Fatal, 'RotSpeed must be positive for the steady-state solver.', ErrStat, ErrMsg, RoutineName ) end if end do - + do i=1,p%NumSSCases if (p%WS_TSR(i) < EPSILON(p%WS_TSR(1))) then CALL SetErrStat( ErrID_Fatal, 'WindSpeed and TSR must be positive numbers for the steady-state solver.', ErrStat, ErrMsg, RoutineName ) ! at least, they can't be zero! end if end do - + end if end if @@ -2377,7 +2377,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) y_FAST%Module_Ver( Module_SeaSt ) = Init%OutData_SeaSt%Ver y_FAST%FileDescLines(2) = TRIM(y_FAST%FileDescLines(2) ) //'; '//TRIM(GetNVD(y_FAST%Module_Ver( Module_SeaSt ))) END IF - + IF ( p_FAST%CompHydro == Module_HD ) THEN y_FAST%Module_Ver( Module_HD ) = Init%OutData_HD%Ver y_FAST%FileDescLines(2) = TRIM(y_FAST%FileDescLines(2) ) //'; '//TRIM(GetNVD(y_FAST%Module_Ver( Module_HD ))) @@ -2417,7 +2417,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) ! Set the number of output columns from each module !...................................................... y_FAST%numOuts = 0 ! Inintialize entire array - + IF ( ALLOCATED( Init%OutData_IfW%WriteOutputHdr ) ) y_FAST%numOuts(Module_IfW) = SIZE(Init%OutData_IfW%WriteOutputHdr) IF ( ALLOCATED( Init%OutData_ExtInfw%WriteOutputHdr ) ) y_FAST%numOuts(Module_ExtInfw) = SIZE(Init%OutData_ExtInfw%WriteOutputHdr) IF ( ALLOCATED( Init%OutData_ED%WriteOutputHdr ) ) y_FAST%numOuts(Module_ED) = SIZE(Init%OutData_ED%WriteOutputHdr) @@ -2426,7 +2426,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) end do !ad14 doesn't have outputs: y_FAST%numOuts(Module_AD14) = 0 - + IF ( ALLOCATED( Init%OutData_AD%rotors)) then IF ( ALLOCATED( Init%OutData_AD%rotors(1)%WriteOutputHdr)) y_FAST%numOuts(Module_AD) = SIZE(Init%OutData_AD%rotors(1)%WriteOutputHdr) ENDIF @@ -2451,7 +2451,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) y_FAST%numOuts(Module_Glue) = 1 ! time end if - + NumOuts = SUM( y_FAST%numOuts ) CALL AllocAry( y_FAST%ChannelNames,NumOuts, 'ChannelNames', ErrStat, ErrMsg ) @@ -2459,7 +2459,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) CALL AllocAry( y_FAST%ChannelUnits,NumOuts, 'ChannelUnits', ErrStat, ErrMsg ) IF ( ErrStat /= ErrID_None ) RETURN - ! Glue outputs: + ! Glue outputs: if (p_FAST%CompAeroMaps) then y_FAST%ChannelNames(1) = 'Case' y_FAST%ChannelUnits(1) = '(-)' @@ -2469,25 +2469,25 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) y_FAST%ChannelNames(SS_Indx_TSR+1) = 'TSR' y_FAST%ChannelUnits(SS_Indx_TSR+1) = '(-)' - + y_FAST%ChannelNames(SS_Indx_RotSpeed+1) = 'RotorSpeed' y_FAST%ChannelUnits(SS_Indx_RotSpeed+1) = '(RPM)' - + y_FAST%ChannelNames(SS_Indx_Err+1) = 'AvgError' y_FAST%ChannelUnits(SS_Indx_Err+1) = '(-)' - + y_FAST%ChannelNames(SS_Indx_Iter+1) = 'Iterations' y_FAST%ChannelUnits(SS_Indx_Iter+1) = '(-)' - + y_FAST%ChannelNames(SS_Indx_WS+1) = 'WindSpeed' y_FAST%ChannelUnits(SS_Indx_WS+1) = '(m/s)' - + else y_FAST%ChannelNames(1) = 'Time' y_FAST%ChannelUnits(1) = '(s)' end if - + indxNext = y_FAST%numOuts(Module_Glue) + 1 DO i=1,y_FAST%numOuts(Module_ExtInfw) !ExternalInflow @@ -2540,7 +2540,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) y_FAST%ChannelUnits(indxNext) = Init%OutData_SeaSt%WriteOutputUnt(i) indxNext = indxNext + 1 END DO - + DO i=1,y_FAST%numOuts(Module_HD) !HydroDyn y_FAST%ChannelNames(indxNext) = Init%OutData_HD%WriteOutputHdr(i) y_FAST%ChannelUnits(indxNext) = Init%OutData_HD%WriteOutputUnt(i) @@ -3099,13 +3099,13 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS ELSE p%CompIce = Module_Unknown END IF - + ! MHK - MHK turbine type (switch) {0=Not an MHK turbine; 1=Fixed MHK turbine; 2=Floating MHK turbine}: CALL ReadVar( UnIn, InputFile, p%MHK, "MHK", "MHK turbine type (switch) {0=Not an MHK turbine; 1=Fixed MHK turbine; 2=Floating MHK turbine}", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if !---------------------- ENVIRONMENTAL CONDITIONS -------------------------------- @@ -3113,15 +3113,15 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN - end if - + RETURN + end if + ! Gravity - Gravitational acceleration (m/s^2): CALL ReadVar( UnIn, InputFile, p%Gravity, "Gravity", "Gravitational acceleration (m/s^2)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! AirDens - Air density (kg/m^3): @@ -3129,7 +3129,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! WtrDens - Water density (kg/m^3): @@ -3137,7 +3137,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! KinVisc - Kinematic viscosity of working fluid (m^2/s): @@ -3145,7 +3145,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! SpdSound - Speed of sound in working fluid (m/s): @@ -3153,7 +3153,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! Patm - Atmospheric pressure (Pa): @@ -3161,7 +3161,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! Pvap - Vapour pressure of working fluid (Pa): @@ -3169,7 +3169,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! WtrDpth - Water depth (m): @@ -3177,7 +3177,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! MSL2SWL - Offset between still-water level and mean sea level (m): @@ -3185,7 +3185,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if !---------------------- INPUT FILES --------------------------------------------- @@ -3528,7 +3528,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS call SetErrStat(ErrID_Info, "Setting NLinTimes to 2 to avoid problem with CalcSteady with only one time.", ErrStat,ErrMsg,RoutineName) p%NLinTimes = 2 end if - + ! LinInputs - Include inputs in linearization (switch) {0=none; 1=standard; 2=all module inputs (debug)} CALL ReadVar( UnIn, InputFile, p%LinInputs, "LinInputs", "Include inputs in linearization (switch) {0=none; 1=standard; 2=all module inputs (debug)}", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3680,7 +3680,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) INTEGER(IntKi) :: I ! loop counter INTEGER(IntKi) :: UnIn ! Unit number for reading file INTEGER(IntKi) :: UnEc ! I/O unit for echo file. If > 0, file is open for writing. - + REAL(ReKi) :: TmpAry(3) ! temporary array to read in columns of case table INTEGER(IntKi) :: ErrStat2 ! Temporary Error status @@ -3690,13 +3690,13 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) CHARACTER(1024) :: FstFile ! Name of the primary ENFAST model file CHARACTER(*), PARAMETER :: RoutineName = 'FAST_ReadSteadyStateFile' - + ! Initialize some variables: UnEc = -1 Echo = .FALSE. ! Don't echo until we've read the "Echo" flag CALL GetPath( InputFile, PriPath ) ! Input files will be relative to the path where the primary input file is located. - + ! Get an available unit number for the file. @@ -3710,7 +3710,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if @@ -3726,14 +3726,14 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if CALL ReadStr( UnIn, InputFile, p%FTitle, 'FTitle', 'File Header: File Description (line 2)', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if !---------------------- ENFAST MODEL FILE -------------------------------------- @@ -3741,22 +3741,22 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if CALL ReadVar( UnIn, InputFile, FstFile, "FstFile", "Name of the primary ENFAST model file (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if - + !---------------------- STEADY-STATE SIMULATION CONTROL -------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Simulation Control', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if @@ -3765,7 +3765,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if @@ -3779,7 +3779,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if IF ( UnEc > 0 ) WRITE (UnEc,'(/,A,/)') 'Data from '//TRIM(FAST_Ver%Name)//' primary steady-state input file "'//TRIM( InputFile )//'":' @@ -3788,7 +3788,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) IF (ErrStat2 /= 0_IntKi ) THEN CALL SetErrStat( ErrID_Fatal, 'Error rewinding file "'//TRIM(InputFile)//'".',ErrStat,ErrMsg,RoutineName) call cleanup() - RETURN + RETURN END IF END DO @@ -3800,7 +3800,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) ! ------------------------------------------------------------- ! READ FROM THE PRIMARY OPENFAST (TIME-DOMAIN) INPUT FILE ! do this before reading the rest of the variables in this - ! steady-state input file so that we don't accidentally + ! steady-state input file so that we don't accidentally ! overwrite them. ! ------------------------------------------------------------- IF ( PathIsRelative( FstFile ) ) FstFile = TRIM(PriPath)//TRIM(FstFile) @@ -3810,7 +3810,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) call cleanup() RETURN end if - + !-------------------------------------------- ! Overwrite values for parameters that we do not ! want to read from the input file: @@ -3837,7 +3837,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) if (p%CompElast == Module_BD) then CALL SetErrStat( ErrID_Warn, "AeroMaps with BeamDyn have not been verified.", ErrStat, ErrMsg, RoutineName) end if - + p%DT_Out = p%DT p%n_DT_Out = 1 ! output every step (i.e., every case) p%TStart = 0.0_DbKi @@ -3848,17 +3848,17 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) p%NLinTimes = 1 p%LinInputs = LIN_ALL p%LinOutputs = LIN_ALL - + p%LinOutMod = .TRUE. ! if debugging, this will allow us to output linearization files (see parameter "output_debugging" in FAST_SS_Solver.f90); otherwise this doesn't do anything p%LinOutJac = .TRUE. ! if debugging, this will allow us to output linearization files (see parameter "output_debugging" in FAST_SS_Solver.f90); otherwise this doesn't do anything p%WrVTK = VTK_None p%VTK_Type = VTK_None p%n_VTKTime = 1 m_FAST%Lin%FoundSteady = .false. - p%LinInterpOrder = p%InterpOrder ! 1 ! always use linear (or constant) interpolation on rotor + p%LinInterpOrder = p%InterpOrder ! 1 ! always use linear (or constant) interpolation on rotor !-------------------------------------------- - - + + ! Toler - Convergence tolerance for nonlinear solve residual equation [>0] (-) CALL ReadVar( UnIn, InputFile, p%tolerSquared, "Toler", "Convergence tolerance for nonlinear solve residual equation (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3867,8 +3867,8 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) RETURN end if p%tolerSquared = p%tolerSquared ** 2 - - + + ! MaxIter - Maximum number of iteration steps for nonlinear solve [>0] (-) CALL ReadVar( UnIn, InputFile, p%KMax, "MaxIter", "Maximum number of iteration steps for nonlinear solve (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3876,8 +3876,8 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) call cleanup() RETURN end if - - + + ! N_UJac - Number of iteration steps to recalculate Jacobian (-) [1=every iteration step, 2=every other step] CALL ReadVar( UnIn, InputFile, p%N_UJac, "N_SSJac", "Number of iteration steps to recalculate steady-state Jacobian (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3885,23 +3885,23 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) call cleanup() RETURN end if - - + + ! UJacSclFact - Scaling factor used in Jacobians (-) CALL ReadVar( UnIn, InputFile, p%UJacSclFact, "SSJacSclFact", "Scaling factor used in steady-state Jacobians (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if - - + + !---------------------- CASES ----------------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Steady-State Cases', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() - RETURN + RETURN end if ! WindSpeedOrTSR - Choice of swept parameter (switch) { 1:wind speed; 2: TSR }: @@ -3925,7 +3925,7 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) call cleanup() RETURN end if - + ! TSR - List of TSRs (-) [>0] call AllocAry( p%RotSpeed, p%NumSSCases, 'RotSpeed', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call AllocAry( p%WS_TSR, p%NumSSCases, 'WS_TSR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3934,19 +3934,19 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) call cleanup() RETURN end if - + ! Case table header: CALL ReadCom( UnIn, InputFile, 'Section Header: Steady-State Case Column Names', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - + CALL ReadCom( UnIn, InputFile, 'Section Header: Steady-State Case Column Units', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() RETURN end if - - + + ! Case table: do i=1,p%NumSSCases CALL ReadAry( UnIn, InputFile, TmpAry, size(TmpAry), "TmpAry", "List of cases (-) [>0]", ErrStat2, ErrMsg2, UnEc) @@ -3955,16 +3955,16 @@ SUBROUTINE FAST_ReadSteadyStateFile( InputFile, p, m_FAST, ErrStat, ErrMsg ) call cleanup() RETURN end if - + p%RotSpeed(i) = TmpAry(1) * RPM2RPS p%WS_TSR( i) = TmpAry(2) p%Pitch( i) = TmpAry(3) * D2R end do - + !---------------------- END OF FILE ----------------------------------------- p%TMax = p%NumSSCases p%RotSpeedInit = p%RotSpeed(1) - + call cleanup() RETURN @@ -4178,7 +4178,7 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_S IF ( p_FAST%CompAero == Module_AD ) THEN ! These meshes may have airfoil data associated with nodes... IF (ALLOCATED(InitOutData_AD%rotors(1)%BladeShape)) THEN - do k=1,NumBl + do k=1,NumBl call move_alloc( InitOutData_AD%rotors(1)%BladeShape(k)%AirfoilCoords, p_FAST%VTK_Surface%BladeShape(k)%AirfoilCoords ) end do ELSE @@ -4186,11 +4186,11 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_S call WrScr('Using generic blade surfaces for AeroDyn (S809 airfoil, assumed chord, twist, AC). ') rootNode = 1 - - DO K=1,NumBl + + DO K=1,NumBl tipNode = AD%Input(1)%rotors(1)%BladeMotion(K)%NNodes cylNode = min(3,AD%Input(1)%rotors(1)%BladeMotion(K)%Nnodes) - + call SetVTKDefaultBladeParams(AD%Input(1)%rotors(1)%BladeMotion(K), p_FAST%VTK_Surface%BladeShape(K), tipNode, rootNode, cylNode, 1, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4241,7 +4241,7 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_S !....................... ! morison surfaces !....................... - + IF ( HD%y%Morison%VisMesh%Committed ) THEN call move_alloc(InitOutData_HD%Morison%MorisonVisRad, p_FAST%VTK_Surface%MorisonVisRad) END IF @@ -4325,7 +4325,7 @@ SUBROUTINE SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, i bladeLengthFract = 0.22*bladeLength bladeLengthFract2 = bladeLength-bladeLengthFract != 0.78*bladeLength - + ! Circle, square or rectangle, constant chord if (iShape>1) then chord = bladeLength*0.04 ! chord set to 4% of blade length @@ -4336,8 +4336,8 @@ SUBROUTINE SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, i x = yc(j) y = xc(j) - 0.5 ! x,y coordinates for cylinder - BladeShape%AirfoilCoords(1,j,i) = chord*x - BladeShape%AirfoilCoords(2,j,i) = chord*y + BladeShape%AirfoilCoords(1,j,i) = chord*x + BladeShape%AirfoilCoords(2,j,i) = chord*y END DO enddo return ! We exit this routine @@ -5117,9 +5117,9 @@ SUBROUTINE FAST_Solution0(p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, if ( P_FAST%CompSeaSt == Module_SeaSt .and. y_FAST%WriteThisStep) then ! note: SeaState has no inputs and only calculates WriteOutputs, so we don't need to call CalcOutput unless we are writing to the file call SeaSt_CalcOutput( t_initial, SeaSt%u, SeaSt%p, SeaSt%x(1), SeaSt%xd(1), SeaSt%z(1), SeaSt%OtherSt(1), SeaSt%y, SeaSt%m, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) end if - + CALL CalcOutputs_And_SolveForInputs( n_t_global, t_initial, STATE_CURR, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & p_FAST, m_FAST, y_FAST%WriteThisStep, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) @@ -7457,7 +7457,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, ErrStat = ErrID_None ErrMsg = "" - + n_t_global_next = n_t_global+1 t_global_next = t_initial + n_t_global_next*p_FAST%DT ! = m_FAST%t_global + p_FAST%dt @@ -7491,7 +7491,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, !---------------------------------------------------------------------------------------- !! Write outputs - !---------------------------------------------------------------------------------------- + !---------------------------------------------------------------------------------------- call FAST_WriteOutput(m_FAST%t_global, n_t_global_next, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -7747,11 +7747,11 @@ SUBROUTINE FAST_UpdateStates(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, call SC_DX_SetInputs(p_FAST, SrvD%y, SC_DX, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) end if - + if ( P_FAST%CompSeaSt == Module_SeaSt .and. y_FAST%WriteThisStep) then ! note: SeaState has no inputs and only calculates WriteOutputs, so we don't need to call CalcOutput unless we are writing to the file call SeaSt_CalcOutput( t_global_next, SeaSt%u, SeaSt%p, SeaSt%x(1), SeaSt%xd(1), SeaSt%z(1), SeaSt%OtherSt(1), SeaSt%y, SeaSt%m, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) end if END SUBROUTINE FAST_UpdateStates @@ -8036,7 +8036,7 @@ SUBROUTINE FAST_WriteOutput_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) END SUBROUTINE FAST_WriteOutput_T !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine writes the outputs at this timestep +!> This routine writes the outputs at this timestep SUBROUTINE FAST_WriteOutput(t_global, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) @@ -8086,8 +8086,8 @@ SUBROUTINE FAST_WriteOutput(t_global, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD !---------------------------------------------------------------------------------------- !! Check to see if we should output data this time step: - !---------------------------------------------------------------------------------------- - CALL WriteOutputToFile(n_t_global, t_global, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & + !---------------------------------------------------------------------------------------- + CALL WriteOutputToFile(n_t_global, m_FAST%t_global, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -8223,9 +8223,9 @@ SUBROUTINE WrOutputLine( t, p_FAST, y_FAST, IfWOutput, ExtInfwOutput, EDOutput, ErrStat = ErrID_None ErrMsg = '' - + CALL FillOutputAry(p_FAST, y_FAST, IfWOutput, ExtInfwOutput, EDOutput, y_AD, SrvDOutput, SeaStOutput, HDOutput, SDOutput, ExtPtfmOutput, & - MAPOutput, FEAMOutput, MDOutput, OrcaOutput, IceFOutput, y_IceD, y_BD, OutputAry) + MAPOutput, FEAMOutput, MDOutput, OrcaOutput, IceFOutput, y_IceD, y_BD, OutputAry) IF (p_FAST%WrTxtOutFile) THEN @@ -8327,7 +8327,7 @@ SUBROUTINE FillOutputAry(p_FAST, y_FAST, IfWOutput, ExtInfwOutput, EDOutput, y_A indxLast = 0 indxNext = 1 - + IF (y_FAST%numOuts(Module_Glue) > 1) THEN ! if we output more than just the time channel.... indxLast = indxNext + SIZE(y_FAST%DriverWriteOutput) - 1 OutputAry(indxNext:indxLast) = y_FAST%DriverWriteOutput @@ -8365,9 +8365,9 @@ SUBROUTINE FillOutputAry(p_FAST, y_FAST, IfWOutput, ExtInfwOutput, EDOutput, y_A OutputAry(indxNext:indxLast) = y_AD%Rotors(i)%WriteOutput indxNext = IndxLast + 1 endif - end do - END IF - + end do + END IF + IF ( y_FAST%numOuts(Module_SrvD) > 0 ) THEN indxLast = indxNext + SIZE(SrvDOutput) - 1 OutputAry(indxNext:indxLast) = SrvDOutput @@ -8379,7 +8379,7 @@ SUBROUTINE FillOutputAry(p_FAST, y_FAST, IfWOutput, ExtInfwOutput, EDOutput, y_A OutputAry(indxNext:indxLast) = SeaStOutput indxNext = IndxLast + 1 END IF - + IF ( y_FAST%numOuts(Module_HD) > 0 ) THEN indxLast = indxNext + SIZE(HDOutput) - 1 OutputAry(indxNext:indxLast) = HDOutput @@ -8619,28 +8619,28 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, ExtInfw enddo ENDIF end if - - -! AeroDyn - IF ( p_FAST%CompAero == Module_AD .and. allocated(AD%Input)) THEN + + +! AeroDyn + IF ( p_FAST%CompAero == Module_AD .and. allocated(AD%Input)) THEN if (allocated(AD%Input(1)%rotors) .and. allocated(AD%y%rotors) ) then if (allocated(AD%Input(1)%rotors(1)%BladeRootMotion)) then - - DO K=1,NumBl + + DO K=1,NumBl call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeRootMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_BladeRootMotion'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) !call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_BladeMotion'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) END DO call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%HubMotion, trim(p_FAST%VTK_OutFileRoot)//'.AD_HubMotion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) !call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%TowerMotion, trim(p_FAST%VTK_OutFileRoot)//'.AD_TowerMotion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) - + IF (allocated(AD%y%rotors(1)%BladeLoad)) then - DO K=1,NumBl + DO K=1,NumBl call MeshWrVTK(p_FAST%TurbinePos, AD%y%rotors(1)%BladeLoad(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_Blade'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, AD%Input(1)%rotors(1)%BladeMotion(k) ) END DO END IF call MeshWrVTK(p_FAST%TurbinePos, AD%y%rotors(1)%TowerLoad, trim(p_FAST%VTK_OutFileRoot)//'.AD_Tower', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, AD%Input(1)%rotors(1)%TowerMotion ) - + end if end if @@ -8656,9 +8656,9 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, ExtInfw end if end if END IF - -! HydroDyn - IF ( p_FAST%CompHydro == Module_HD .and. allocated(HD%Input)) THEN + +! HydroDyn + IF ( p_FAST%CompHydro == Module_HD .and. allocated(HD%Input)) THEN call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%PRPMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_PRP', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) call MeshWrVTK(p_FAST%TurbinePos, HD%y%WamitMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_WAMIT', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%WAMITMesh ) call MeshWrVTK(p_FAST%TurbinePos, HD%y%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_MorisonPt', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Morison%Mesh ) @@ -8783,7 +8783,7 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, ExtIn ! Blades IF ( p_FAST%CompAero == Module_AD .and. ALLOCATED(AD%Input) ) THEN ! These meshes may have airfoil data associated with nodes... if (allocated(AD%Input(1)%rotors) .and. allocated(AD%y%rotors)) then - DO K=1,NumBl + DO K=1,NumBl call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_Blade'//trim(num2lstr(k)), & y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=AD%y%rotors(1)%BladeLoad(K) ) END DO @@ -8826,7 +8826,7 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, ExtIn ! END IF IF ( p_FAST%CompHydro == Module_HD .and. ALLOCATED(HD%Input)) THEN - call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%WAMITMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_WAMIT', y_FAST%VTK_count, & + call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%WAMITMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_WAMIT', y_FAST%VTK_count, & p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%y%WAMITMesh ) call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_MorisonPt', y_FAST%VTK_count, & p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%y%Morison%Mesh ) @@ -8924,7 +8924,7 @@ SUBROUTINE WrVTK_Surfaces(t_global, p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, ED%y%TowerLn2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.TowerSurface', & y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, p_FAST%VTK_Surface%NumSectors, p_FAST%VTK_Surface%TowerRad ) end if - + ! Blades IF ( p_FAST%CompAero == Module_AD .and. allocated(AD%Input)) THEN ! These meshes may have airfoil data associated with nodes... if (allocated(AD%Input(1)%rotors) .and. allocated(AD%y%rotors)) then @@ -8961,10 +8961,10 @@ SUBROUTINE WrVTK_Surfaces(t_global, p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW ! Substructure ! call MeshWrVTK(p_FAST%TurbinePos, ED%y%PlatformPtMesh, trim(p_FAST%VTK_OutFileRoot)//'.ED_PlatformPtMesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) ! IF ( p_FAST%CompSub == Module_SD ) THEN -! call MeshWrVTK(p_FAST%TurbinePos, SD%Input(1)%TPMesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_TPMesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) -! call MeshWrVTK(p_FAST%TurbinePos, SD%y%y2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y2Mesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) -! call MeshWrVTK(p_FAST%TurbinePos, SD%y%y3Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y3Mesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) -! END IF +! call MeshWrVTK(p_FAST%TurbinePos, SD%Input(1)%TPMesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_TPMesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) +! call MeshWrVTK(p_FAST%TurbinePos, SD%y%y2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y2Mesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) +! call MeshWrVTK(p_FAST%TurbinePos, SD%y%y3Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y3Mesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) +! END IF ! HydroDyn @@ -8973,13 +8973,13 @@ SUBROUTINE WrVTK_Surfaces(t_global, p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, p_FAST%VTK_Surface%NumSectors, & p_FAST%VTK_Surface%MorisonVisRad ) END IF - - -! Mooring Lines? + + +! Mooring Lines? ! IF ( p_FAST%CompMooring == Module_MAP ) THEN ! call MeshWrVTK(p_FAST%TurbinePos, MAPp%Input(1)%PtFairDisplacement, trim(p_FAST%VTK_OutFileRoot)//'.MAP_PtFair_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) if ( p_FAST%CompMooring == Module_MD ) THEN - !call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%CoupledKinematics, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) + !call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%CoupledKinematics, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) if (allocated(MD%y%VisLinesMesh)) then do l=1,size(MD%y%VisLinesMesh) if (MD%y%VisLinesMesh(l)%Committed) then ! No orientation data, so surface representation not possible @@ -9216,13 +9216,13 @@ SUBROUTINE WriteInputMeshesToFile(u_ED, u_AD, u_SD, u_HD, u_MAP, u_BD, FileName, END DO ! Add how many AD blade meshes there are: - NumBl = SIZE(u_AD%rotors(1)%BladeMotion,1) ! Note that NumBl is B4Ki + NumBl = SIZE(u_AD%rotors(1)%BladeMotion,1) ! Note that NumBl is B4Ki WRITE( unOut, IOSTAT=ErrStat ) NumBl DO K_local = 1,NumBl CALL MeshWrBin( unOut, u_AD%rotors(1)%BladeMotion(k_local), ErrStat, ErrMsg ) - END DO - + END DO + ! Close the file CLOSE(unOut) @@ -9465,7 +9465,7 @@ SUBROUTINE ExitThisProgram_T( Turbine, ErrLevel_in, StopTheProgram, ErrLocMsg, S LOGICAL :: SkipRunTimes INTEGER(IntKi) :: ErrStat CHARACTER(ErrMsgLen) :: ErrMsg - + IF (PRESENT(SkipRunTimeMsg)) THEN SkipRunTimes = SkipRunTimeMsg ELSE @@ -9488,10 +9488,10 @@ SUBROUTINE ExitThisProgram_T( Turbine, ErrLevel_in, StopTheProgram, ErrLocMsg, S Turbine%IceF, Turbine%IceD, Turbine%MeshMapData, ErrLevel_in, StopTheProgram, SkipRunTimeMsg=SkipRunTimes ) END IF - - + + CALL FAST_DestroyTurbineType( Turbine, ErrStat, ErrMsg) ! just in case we missed some data in ExitThisProgram() - + END SUBROUTINE ExitThisProgram_T !---------------------------------------------------------------------------------------------------------------------------------- @@ -9587,8 +9587,8 @@ SUBROUTINE ExitThisProgram( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, CLOSE(y_FAST%UnSum) y_FAST%UnSum = -1 END IF - - + + SimMsg = TRIM(FAST_Ver%Name)//' encountered an error '//TRIM(SimMsg)//'.'//NewLine//' Simulation error level: '//TRIM(GetErrStr(ErrorLevel)) if (StopTheProgram) then CALL ProgAbort( trim(SimMsg), TrapErrors=.FALSE., TimeWait=3._ReKi ) ! wait 3 seconds (in case they double-clicked and got an error) @@ -9733,8 +9733,8 @@ SUBROUTINE FAST_EndMods( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, HD ErrStat = ErrID_None ErrMsg = "" - - + + IF ( p_FAST%ModuleInitialized(Module_ED) ) THEN CALL ED_End( ED%Input(1), ED%p, ED%x(STATE_CURR), ED%xd(STATE_CURR), ED%z(STATE_CURR), ED%OtherSt(STATE_CURR), & ED%y, ED%m, ErrStat2, ErrMsg2 ) @@ -9822,13 +9822,13 @@ SUBROUTINE FAST_EndMods( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, HD END IF - + ! Write output to file (do this after ending modules so that we have more memory to use if needed) CALL FAST_EndOutput( p_FAST, y_FAST, m_FAST, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - - + + END SUBROUTINE FAST_EndMods !---------------------------------------------------------------------------------------------------------------------------------- !> This routine calls the destroy routines for each module. (It is basically a duplicate of FAST_DestroyTurbineType().) @@ -10137,8 +10137,8 @@ SUBROUTINE FAST_CreateCheckpoint_T(t_initial, n_t_global, NumTurbines, Turbine, Turbine%SrvD%m%dll_data%SimStatus = Turbine%SrvD%m%dll_data%avrSWAP( 1) end if END IF - - + + call cleanup() contains @@ -10341,10 +10341,10 @@ SUBROUTINE FAST_RestoreFromCheckpoint_T(t_initial, n_t_global, NumTurbines, Turb ! deal with sibling meshes here: ! (ignoring for now; they are not going to be siblings on restart) - + Turbine%HD%p%PointsToSeaState = .false. ! since the pointers aren't pointing to the same data as SeaState after restart, set this to avoid memory leaks and deallocation problems - + ! deal with files that were open: IF (Turbine%p_FAST%WrTxtOutFile) THEN CALL OpenFunkFileAppend ( Turbine%y_FAST%UnOu, TRIM(Turbine%p_FAST%OutFileRoot)//'.out', ErrStat2, ErrMsg2) @@ -10500,7 +10500,7 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, ModeNo = p_FAST%VTK_modes%VTKModes(iMode) if (ModeNo>iModeMax) then call WrScr(' Skipping mode '//trim(num2lstr(ModeNo))//', maximum number of modes reached ('//trim(num2lstr(iModeMax))//'). Exiting.') - exit; + exit; endif call GetTimeConstants(p_FAST%VTK_modes%DampedFreq_Hz(ModeNo), p_FAST%VTK_fps, p_FAST%VTK_modes%VTKLinTim, nt, dt, p_FAST%VTK_tWidth ) write(sInfo, '(A,I4,A,F12.4,A,I4,A,I0)') 'Mode',ModeNo,', Freq=', p_FAST%VTK_modes%DampedFreq_Hz(ModeNo),'Hz, NLinTimes=',NLinTimes,', nt=',nt @@ -10614,7 +10614,7 @@ SUBROUTINE GetTimeConstants(DampedFreq_Hz, VTK_fps, VTKLinTim, nt, dt, VTK_tWidt else ! All simulation will use VTK_fps cycle_time = 1.0_DbKi / DampedFreq_Hz - nt = NINT(VTK_fps) + nt = NINT(VTK_fps) endif dt = cycle_time / nt From be10599741c6771ae327a82788dd631470cf92c9 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 15 Dec 2023 14:36:29 -0700 Subject: [PATCH 50/91] cpp interface: update documentation (doxygenclass not working) --- docs/conf.py | 9 ++++++- docs/source/dev/cppapi/README.txt | 3 +++ docs/source/dev/cppapi/api.rst | 3 ++- .../dev/cppapi/bibliography.bib} | 26 +++++++++---------- docs/source/dev/cppapi/index.rst | 11 +++++--- docs/source/dev/cppapi/zrefs.rst | 8 ++++++ docs/source/zrefs.rst | 6 ----- 7 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 docs/source/dev/cppapi/README.txt rename docs/{_static/references.bib => source/dev/cppapi/bibliography.bib} (91%) create mode 100644 docs/source/dev/cppapi/zrefs.rst delete mode 100644 docs/source/zrefs.rst diff --git a/docs/conf.py b/docs/conf.py index 85c5e70a2b..b220b9666b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -66,6 +66,7 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): 'sphinxcontrib.doxylink', 'sphinxcontrib.bibtex', 'sphinxcontrib.mermaid', +# 'breathe', ] bibtex_bibfiles = [ 'source/user/aerodyn-aeroacoustics/references.bib', @@ -76,7 +77,8 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): 'source/user/fast.farm/bibliography.bib', 'source/user/hydrodyn/references.bib', 'source/user/servodyn-stc/StC_Refs.bib', - 'source/user/subdyn/references_SD.bib' + 'source/user/subdyn/references_SD.bib', + 'source/dev/cppapi/bibliography.bib' ] autodoc_default_flags = [ @@ -89,6 +91,11 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): mathjax_path = 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML' +## Breathe Configuration -- for cpp interface +#breathe_projects = {"cppapi": "source/dev/cppapi"} +#breathe_default_project = "cppapi" + + # FIXME: Naively assuming build directory one level up locally, and two up on readthedocs if useDoxygen: if readTheDocs: diff --git a/docs/source/dev/cppapi/README.txt b/docs/source/dev/cppapi/README.txt new file mode 100644 index 0000000000..bb8b3a62a2 --- /dev/null +++ b/docs/source/dev/cppapi/README.txt @@ -0,0 +1,3 @@ +2023.12.15 ADP + +We don't currently run doxygen on RTD due to some configuration issues. So the doxygen content for the cpp was manually run and stored (really not ideal and should be fixed). diff --git a/docs/source/dev/cppapi/api.rst b/docs/source/dev/cppapi/api.rst index 063d97d035..96fdff067b 100644 --- a/docs/source/dev/cppapi/api.rst +++ b/docs/source/dev/cppapi/api.rst @@ -4,7 +4,8 @@ C++ API Documentation OpenFAST -------- -.. doxygenclass:: fast::OpenFAST +.. + .. doxygenclass:: fast::OpenFAST :members: :protected-members: :undoc-members: diff --git a/docs/_static/references.bib b/docs/source/dev/cppapi/bibliography.bib similarity index 91% rename from docs/_static/references.bib rename to docs/source/dev/cppapi/bibliography.bib index 34192e55d0..266ce94238 100644 --- a/docs/_static/references.bib +++ b/docs/source/dev/cppapi/bibliography.bib @@ -6,7 +6,7 @@ %% Saved with string encoding Unicode (UTF-8) -@inbook{churchfield2012, +@inbook{cpp-churchfield2012, Annote = {doi:10.2514/6.2012-537}, Author = {Churchfield, Matthew and Lee, Sang and Moriarty, Patrick and Martinez, Luis and Leonardi, Stefano and Vijayakumar, Ganesh and Brasseur, James}, Booktitle = {50th AIAA Aerospace Sciences Meeting including the New Horizons Forum and Aerospace Exposition}, @@ -20,7 +20,7 @@ @inbook{churchfield2012 Year = {2012}} -@techreport{beamdynManual, +@techreport{cpp-beamdynManual, Author = {Wang, Q and Jonkman, Jason and Sprague, Michael A, and Jonkman, Bonnie}, Date-Added = {2016-12-07 23:35:57 +0000}, Date-Modified = {2016-12-07 23:37:15 +0000}, @@ -29,7 +29,7 @@ @techreport{beamdynManual Title = {BeamDyn User's Guide and Theory Manual}, Year = {2016}} -@article{martinez2016, +@article{cpp-martinez2016, Author = {Luis A. Martinez-Tossas and Matthew J. Churchfield and Charles Meneveau}, Journal = {Journal of Physics: Conference Series}, Number = {8}, @@ -39,21 +39,21 @@ @article{martinez2016 Volume = {753}, Year = {2016}} -@techreport{fastProgrammersHandbook, +@techreport{cpp-fastProgrammersHandbook, Author = {B.J. Jonkman and J. Michalakes and J.M. Jonkman and M.L. Buhl and Jr. and A. Platt and and M.A. Sprague}, Institution = {National Renewable Energy Laboratory}, Month = {July}, Title = {NWTC Programmer's Handbook: A Guide for Software Development Within the FAST Computer-Aided Engineering Tool}, Year = {2013}} -@techreport{aerodynV15Manual, +@techreport{cpp-aerodynV15Manual, Author = {J.M. Jonkman}, Institution = {National Renewable Energy Laboratory}, Month = {April}, Title = {AeroDyn v15 User's Guide and Theory Manual}, Year = {2016}} -@techreport{naluDoc, +@techreport{cpp-naluDoc, Address = {https://github.com/spdomin/NaluDoc}, Author = {Stefan Domino}, Institution = {Sandia National Laboratories Unclassified Unlimited Release (UUR)}, @@ -61,7 +61,7 @@ @techreport{naluDoc Title = {Sierra Low Mach Module: Nalu Theory Manual 1.0}, Year = {2015}} -@techreport{fastv8AlgorithmsExamples, +@techreport{cpp-fastv8AlgorithmsExamples, Author = {Michael A. Sprague and Jason M. Jonkman and Bonnie J. Jonkman}, Institution = {National Renewable Energy Laboratory}, Month = {January}, @@ -69,7 +69,7 @@ @techreport{fastv8AlgorithmsExamples Title = {FAST Modular Framework for Wind Turbine Simulation: New Algorithms and Numerical Examples}, Year = {2015}} -@techreport{fastv8ModFramework, +@techreport{cpp-fastv8ModFramework, Author = {Jason M. Jonkman}, Date-Added = {2016-07-21 19:25:11 +0000}, Date-Modified = {2016-07-21 19:26:24 +0000}, @@ -79,7 +79,7 @@ @techreport{fastv8ModFramework Title = {The New Modularization Framework for the FAST Wind Turbine CAE Tool}, Year = {2013}} -@techreport{fastv8, +@techreport{cpp-fastv8, Author = {Jason M. Jonkman and Bonnie J. Jonkman}, Date-Added = {2016-07-21 19:15:10 +0000}, Date-Modified = {2016-07-21 19:28:31 +0000}, @@ -88,7 +88,7 @@ @techreport{fastv8 Title = {FAST v8: Changelog}, Year = {2016}} -@techreport{fastv7, +@techreport{cpp-fastv7, Author = {Jason M. Jonkman and Marshall L. Buhl Jr.}, Date-Added = {2016-07-21 18:11:47 +0000}, Date-Modified = {2016-07-21 18:13:07 +0000}, @@ -98,7 +98,7 @@ @techreport{fastv7 Title = {FAST User's Guide}, Year = {2005}} -@techreport{fleming2013, +@techreport{cpp-fleming2013, Author = {Paul Fleming and Sang Lee and Matthew J. Churchfield and Andrew Scholbrock and John Michalakes and Kathryn Johnson and and Patrick Moriarty}, Date-Added = {2016-07-21 18:05:29 +0000}, Date-Modified = {2016-07-21 19:30:03 +0000}, @@ -108,14 +108,14 @@ @techreport{fleming2013 Title = {The SOWFA Super-Controller: A High-Fidelity Tool for Evaluating Wind Plant Control Approaches}, Year = {2013}} -@misc{MPI-3.1, +@misc{cpp-MPI-3.1, Author = {MPI Forum}, Month = {June}, Note = {available at: http://www.mpi-forum.org (Jun. 2015)}, Title = {MPI: A Message-Passing Interface Standard. Version 3.1}, Year = {2015}} -@misc{hdf5, +@misc{cpp-hdf5, Author = {The HDF Group}, Note = {http://www.hdfgroup.org/HDF5/}, Title = {Hierarchical Data Format, version 5}, diff --git a/docs/source/dev/cppapi/index.rst b/docs/source/dev/cppapi/index.rst index 916f5c0f14..b6f6c49fa1 100644 --- a/docs/source/dev/cppapi/index.rst +++ b/docs/source/dev/cppapi/index.rst @@ -14,7 +14,8 @@ The C++ API is defined and implemented in the :class:`~fast::OpenFAST` class. An All inputs to the OpenFAST class are expected through an object of the :class:`fast::fastInputs`. -.. doxygenclass:: fast::fastInputs +.. + .. doxygenclass:: fast::fastInputs :members: :private-members: :protected-members: @@ -22,7 +23,8 @@ All inputs to the OpenFAST class are expected through an object of the :class:`f The object of :class:`~fast::fastInputs` class is expected hold a struct vector of type :class:`~fast::turbineDataType` and size of the number of turbines in the simulation. -.. doxygenstruct:: fast::turbineDataType +.. + .. doxygenstruct:: fast::turbineDataType :members: :private-members: @@ -30,7 +32,7 @@ The object of :class:`~fast::fastInputs` class is expected hold a struct vector Use of C++ API for Actuator Line Simulations -------------------------------------------- -The C++ API was developed mainly to integrate OpenFAST with Computational Fluid Dynamics (CFD) solvers for Fluid-Structure Interaction (FSI) applications. The workhorse FSI algorithm for wind energy applications today is the Actuator Line algorithm :cite:`churchfield2012`. The Actuator Line algorithm represents the effect of a turbine on a flow field as a series of point forces at **actuator points** along aerodynamic surfaces. The use of Blade Element Momentum theory in AeroDyn is modified to interface OpenFAST with CFD solvers for actuator line simulations. The CFD solver becomes the inflow module for OpenFAST that provides velocity information near the turbine. The calculation of the induction factors is turned off in OpenFAST and AeroDyn simply uses look up tables and an optional dynamic stall model to calculate the loads on the turbine based on the inflow field information received from the CFD solver. The induction model should be turned off in OpenFAST by selecting :samp:`WakeMod=0` in the AeroDyn input file. OpenFAST lumps the line forces along the blades and tower into a series of point forces for the actuator line algorithm. :numref:`actuatorline-viz` illustrates the transfer of information between OpenFAST and a CFD solver for actuator line applications. +The C++ API was developed mainly to integrate OpenFAST with Computational Fluid Dynamics (CFD) solvers for Fluid-Structure Interaction (FSI) applications. The workhorse FSI algorithm for wind energy applications today is the Actuator Line algorithm :cite:`cpp-churchfield2012`. The Actuator Line algorithm represents the effect of a turbine on a flow field as a series of point forces at **actuator points** along aerodynamic surfaces. The use of Blade Element Momentum theory in AeroDyn is modified to interface OpenFAST with CFD solvers for actuator line simulations. The CFD solver becomes the inflow module for OpenFAST that provides velocity information near the turbine. The calculation of the induction factors is turned off in OpenFAST and AeroDyn simply uses look up tables and an optional dynamic stall model to calculate the loads on the turbine based on the inflow field information received from the CFD solver. The induction model should be turned off in OpenFAST by selecting :samp:`WakeMod=0` in the AeroDyn input file. OpenFAST lumps the line forces along the blades and tower into a series of point forces for the actuator line algorithm. :numref:`actuatorline-viz` illustrates the transfer of information between OpenFAST and a CFD solver for actuator line applications. .. _actuatorline-viz: @@ -51,7 +53,7 @@ The CFD solver is expected to be the *driver program* for actuator line FSI simu A conventional serial staggered FSI scheme that can be constructed through the C++ API for actuator line applications. -OpenFAST uses different spatial meshes for the various modules :cite:`fastv8ModFramework`. We define the actuator points to be along the mesh defined in the structural model (ElastoDyn/BeamDyn) of the turbine. The user defines the required number of actuator points along each blade and the tower through the input parameters :samp:`numForcePtsBlade` and :samp:`numForcePtsTower` for each turbine. The number of actuator points have to be the same on all blades. The C++ API uses OpenFAST to create the requested number of actuator points through linear interpolation of the nodes in the structural model. The mesh mapping algorithm in OpenFAST :cite:`fastv8AlgorithmsExamples` is used to transfer deflections from the structural model and loads from AeroDyn to the actuator points. To distinguish the *actuator points* from the Aerodyn points, the OpenFAST C++ uses the term :samp:`forceNodes` for the actuator points and :samp:`velNodes` (velocity nodes) for the Aerodyn points. The following piece of code illustrates how one can use the C++ API to implement a strongly coupled FSI scheme with "outer" iterations for actuator line applications. This sample piece of code sets the velocity at the :samp:`velNodes` and access the coordinates and the lumped forces at the :samp:`forceNodes`. +OpenFAST uses different spatial meshes for the various modules :cite:`cpp-fastv8ModFramework`. We define the actuator points to be along the mesh defined in the structural model (ElastoDyn/BeamDyn) of the turbine. The user defines the required number of actuator points along each blade and the tower through the input parameters :samp:`numForcePtsBlade` and :samp:`numForcePtsTower` for each turbine. The number of actuator points have to be the same on all blades. The C++ API uses OpenFAST to create the requested number of actuator points through linear interpolation of the nodes in the structural model. The mesh mapping algorithm in OpenFAST :cite:`cpp-fastv8AlgorithmsExamples` is used to transfer deflections from the structural model and loads from AeroDyn to the actuator points. To distinguish the *actuator points* from the Aerodyn points, the OpenFAST C++ uses the term :samp:`forceNodes` for the actuator points and :samp:`velNodes` (velocity nodes) for the Aerodyn points. The following piece of code illustrates how one can use the C++ API to implement a strongly coupled FSI scheme with "outer" iterations for actuator line applications. This sample piece of code sets the velocity at the :samp:`velNodes` and access the coordinates and the lumped forces at the :samp:`forceNodes`. .. code-block:: c++ @@ -96,6 +98,7 @@ OpenFAST uses different spatial meshes for the various modules :cite:`fastv8ModF :maxdepth: 1 api.rst + zrefs.rst Implementation diff --git a/docs/source/dev/cppapi/zrefs.rst b/docs/source/dev/cppapi/zrefs.rst new file mode 100644 index 0000000000..3e5b907356 --- /dev/null +++ b/docs/source/dev/cppapi/zrefs.rst @@ -0,0 +1,8 @@ +.. only:: html + + References + ---------- + +.. bibliography:: bibliography.bib + :labelprefix: cpp- + diff --git a/docs/source/zrefs.rst b/docs/source/zrefs.rst deleted file mode 100644 index 0bacbc412e..0000000000 --- a/docs/source/zrefs.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. only:: html - - References - ---------- - -.. bibliography:: ../_static/references.bib From 111c3b3d74499b7b785fc9b532502836c39b1478 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 15 Dec 2023 14:58:34 -0700 Subject: [PATCH 51/91] cpp docs: convert pdf images to png --- .../files/actuatorLine_illustrationViz.png | Bin 0 -> 81706 bytes .../dev/cppapi/files/css_actuatorline.png | Bin 0 -> 10902 bytes docs/source/dev/cppapi/index.rst | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 docs/source/dev/cppapi/files/actuatorLine_illustrationViz.png create mode 100644 docs/source/dev/cppapi/files/css_actuatorline.png diff --git a/docs/source/dev/cppapi/files/actuatorLine_illustrationViz.png b/docs/source/dev/cppapi/files/actuatorLine_illustrationViz.png new file mode 100644 index 0000000000000000000000000000000000000000..3efc1e2598f89afd25d083a65edc394f6732a8d8 GIT binary patch literal 81706 zcmYJa1y~gA`vyvPH%PN|Er>`70!u8-(xEg`N-8N`OS5$6Qqqmm9U_8+gfuAKEqI3S z_dn+hv$NN=%goOEzE9lu{X7HL(oiDAqr*c%K_P@HLtrQ<=o~00sCGD5z$b;bN7%p{ zvz0PT9R(5zn9{Oqcm_j3KSx%>$R|d@9FnsE=M3n=FN9rTq?MFY@rV|yV2nX zHSu}SyE^1~uJUu=qr>)_>X*%uKd=h5w+;|JrQvZnz7MI)`Q8{j;QosXK`ZRNKm`m!HVyBQzV81vW-J2-RF4pn6UX|O zpR4KTN)}Y@m-yUCk-`@KdE52Q?1z z9j;AAJ27)yU;Ej7ZF*s3+I}vRi*0Wn@yG6yXgr6}`K><~2IB$4 zdjGp+@QId>W$&=E|M%7aBiyLLiFzxN8RG$0C`+|>^I56lTexx8wbK2z$-K?ntT@wH znQL7I4;$G_Zkyu&`{iKEzv^u?sN9UoA1-9;G4*yonUAuItf-hcm#2F`8P+HneqXRW zWi_}Qwxm@MPj?x?FOpTf!J?bXTx8r@Y?0#l&int*U_R4^k{ZVo7TSreO}Fh)IhZbP z6l*~O{45&I1$40%CFq+DMX&JFQ!)78oIr5n?odHvSb8C`2K&hA#+Ze1b?YKD%*du%!$02 zCURHVS+f!DjLs}>WCh(_(;?W%5|;c#&a-t=8rj9|RNQ6|e_j|o6-H3_T8@tYZ!Gyt z3z1N9as(_&|Jz+5C~rwtGp=};ghIg$@%3DzJO*kYAxDim-q&N2M{A&;TcD_d2T>l( ziBUtyOR=#L{I}_l@AemG6E7pls%NVv=KiFeYan58JC+H*(7bvrgs? zOMKxKj`s+yZf|5q+loG95kZi>uruD3`s~1jsdUt{BQcev?QDyTZ$?iQncLb zXs3w=Cn%rtwG$n*tQ$E&P!!<>j$yb+3mn#~NO_5n@WTJvx_O$UEK`9%pplWiYG+m= z6Jj48f*4w6eAE*LKW=Iq6ar_yEZ_oMXwVQZmcg{0fHrTV3I~-d za+h015Q#e@=K`{!yM$14bCV=;aj|6JVE=Q&UX=e|xGF60iyZMvM7VK)kW;4R;yq)e z6ygU^L^f9#iTNq87%kA4H5M{WdwpVnP9D5ny1oSl3@{ivBfqr%5XaDqDl4I0MqLXWxlUKiO@m0*aG>M~R6k2GiqS5~Xwn3_8 z<1Qes_5Llqk~S@>8FKWn=|?o{Hc5eHAPJ^UZv4|xGa5K-$J$_=mX!3%yxcSJKNGMx zwfGAk31tHzS=ca*f^%iL^bSl+`#nu&M2)Rm=p&nBROc+Nc z)2mp7lXjzg(Pl^D4adDneHMh&e{s|L)c;@JX5xP6-h=3#5f_MBp=Vf%w;y2J>KV2-6Q|jFi*6m!Su^qyedN zvqmqzv=+8);z9p1^L|7gYR^!Q{2M^7kZarz(AKw**2oJ}mL4b|YOGhB+}$9y#N;Mb z=fQtFc{^MCU%S%P#ExD+I_Qn%T=lD;jrK`pPCrW2e>OR$S>~B`1^m3C>eIz4NS-R{ zx}ISDrnOH=;Sek}qAc{~4`Y{MR&_!@xUVauWaTUv5+Rir*QkK1#h9$wsGiIzqw{)| z2@yHW&dR~_ZBNd-40fk0G;_uF5;e1kAExc^RJ_Q{X(B{{JB5*2e>P%Deq(W(D&MJM z4_nQMv-FE`A*~sBwVPmhIcv;_3tUKp@3;?S=qtLX1Iq^efn=r-Wk|I77*T&i~ zGVK|C-ae#_FWb<3(9s;jj2~yuq++!boX#9}Fb)03Y9(=k-F7KV#%mA88G_3=dLbrU zO}EFGuMO6aQ1V0{*M-+uME&X4bKOBtX)tQ~mlSUd>NN*dqy5TniXD@gbo8;%u|pEk z-^4gZSev=gF|4VwrkyX?wv){r=OUwzcXvE7?gI@pyF$LC@#)@6lGy(gk@HEgFgH*4 zI`)$K+3L#n;b@r<Qy_hir<+%y$1C5yY3S>&|4+wWxoB zzZmUoS?*pIk3@$^F-0sr`y?wYRmGKz*? z62N`q*}S%gg}%0x#xe-g(3H?DEG&FqUM51Zb9PoTF?oVwK9PP5i7QKB)_u zdnv*}>Y1DquN<0K96jkT-pCo2tdVmh6*b4Pk*g(qH${TVY?62^p=u+08}Vx4k0!Rn z@!uXK_lBNZ{%b)&a*G2^`6 zSh(Ml%-C8E z8SWcA=zVCU>67>3PY;s`42nH^E*@n44p%(aZfcwd^6u}6q}mSt1&ulMFqm{D3Y~Wz z1Vl@=+@oK9+;evQZSa6EIG~P7_v(24HAnJ! z2#wHVn&dEbsrv|3;kFjS8EH*Obh^iHttkZ8!pUvc^K@AinBR#hqxRx6Rwj92qGGa3 z;a~^GKQF~#7P-MB4bC{=#wD*l#m!-x`AC5O0^|4&Fye z;vo1r)O=x@JB4zih2h&t1sr^B)iXemu9a?EcILkNTtCC)y@ za{Ckw0;BVGO`vY_um@YOvqcOdzAd9CcWZkQ2#f>O*uTP-i!waf)?s~#-^YBXaSohpW*!I z3^=n+r}+Ne`*mhdo$3*%&w6pjWC+JD(>)P^*N4aHYi0<6_$=EK`#kc3Jlrkvw`4pi z*1jX4ol+2FKPGRTn~X4&AZS>H5ArWTjZ8LqdF&=d8COG;mDQleMfNnlhIi2FH>h5VeB*4H|Hxyl7RuYTSu_* zuG16ZwZz3ai(h%peL+XgLrj+p-7WqXce)+ZH4tL~Dcwq=1}p{!23Gg#O%|)O?eVtP z5Wq#bgD)>XI4w5w+bD`s3W2}JcRh@X`mKf#ul8Uwjg}q#`4c#|H-0_0aT19WeLSEg zJsg{^rq4eT$_f%EAsRTP-_{D@3kRp$#e`<0TmG~xOIF1}EHREDqWDVePIFJiP4U;lzUx$lRcdYd&o}bxBD*Sa zGoqk|;U%G?1cI~%ies#-V8m_mti0B8?XBo^O(*3|@Z)mQGzOEP0omz=?VLj!qEP7Zhd)cibd&0H3%0Q4a0*ev`c%wI=9 zQDwB-NmcOV`)+$e(FX;b#3#zE>$-!q$^GiBUPP;2fn+2qvg8GYI0+owQ~o1$?EN9i zxFL~T!wJMJLbBUlB#AU!$uRA_71jRSB4;7!;c(v7%SCID6W7-kZa5JVBy(PyEnPI zx_agv$1~7~)`T3Wi5D0Hkb|fbQ=6Mbot9b?NmE<{r7dBX#ny#(P&}u4Wb&1~jwhlc zZ#H%$vM1R*|SVCJjmGjVHGO3B5=)5PX!HLwu=`dAl{vT z;s=g(3Dy+(cWNrA@(+jJ`w5TKBLRP%nA>WSORm7YM^XLu9=dknQ|Ej2ZhxT(|L*c2 zWWcg#uIu5w)b(lzayb%;d(c&#l$cB*-(Q%35M}|*6O9%6*ke?I>`CvkLC@GQC|0N5 zt5BJqJU9Ius5}yJyei1dTs{F=GLWMvBO4(}))7C5YOL{y54)cc;Wnzt@KxMJ>yv&fA;qJ zW~&yzPfZC6xcf*k@|ktgcioITAAgr8E+{F%%KP{C_vFF?4_Xy8MsTI%~NGznccC_Z0-^~Bj#*1@O12yFS0SQ8?bMf}JMk34d5F83n9ab;iw`^`d z(n!+OrVzB4d^QflLY9wo2)vx1T-epcq>)CR9n@EEGv;!4&=SA+S1FFZ$JzhviPLgB ztx3x}1tle=QG?p5Dt?>Ofdt8EICP#IK_AA~Cw+Xi4G!nbpjaP>ZP%t>Cy#$ z&V(FGBX^ilIA;P;M3CBRD8VAAq=}@mzU;Be!Ihv9sG?+fvqC*~p;dE2K=~o{NOkM? z&vTji6WPkIK06gd7GijsS&R-xm+#_gd1)z|l@$nKkN*8( z|7XzbtiB@5E%da;aXtwl<;Q|I@6oOd{bp+d>F8MZ!V87e#o`5NlOrnhc||tUtjt^>Sy7Bl4COQybw$V!%%bBZBTHSr3It;`lXOQa<2}!vo<|vZ%05CXHq9(2 z7rqO%Wze?6e<_-$a$7Ml624D~uzS5ZtXn=vY< zU!R}-CfRXKo4NKB&I4mJ34-K_#tNF6o^8?Rfw&(NN+Lz7CcETjAEu@vO!!c{WmH+U z&`6$DUZ9?ov~cQq7CkJ&yJB^N1w2D$&kw_Zl-;i$%d|W&5HX4qJ&JuNp+g%zYkd)8 znc1K|q%b%c?Qy|pt4vV)n+SbyM*$Fa9P8}IKzQ*UOhaH;Z_V9#I%kGCw8g|-XQ+%w z2Ex9`^XHF=V54Fy!)|ywUG4Ek_PCI#AcF>e+6X86P;Lua?Oo0d8UaTRb~}M{CMX#p z)Xd&!l!*9#;k8}dT?7m%Wa+-LXOufi-W zt$<1TS!abU#i*%b1v}J)BzZH_(5M9U^z=;M0o>!!av0+|-z1fG|1_Le5=(Y~Jt9;F z$q(khn7&S{Vr{(PdXXW*-ZpAz2Sa=kgbM(UKdHqAQu)XXj#eQf4YE(w#h2?r?iDYP z1)a4`gH+WZ%&g4za~W1x+dHy%iHt!2L0_a7Se&IA0>vs{>suPIXI!9N38tYNv^LuLGaN$ zEc(KO6TPcxf?}c~0SkUaUO-TP9BT91#nd#TMQcbVuomjj`Mac;h8=wYTa$`V$m$gf z+(7|pYY4xxG$Y1oWVcV^<6-8Nt54i#JLfOZl`~F&DhGOf5fOqSNO#U$f}k0Vd>7(E zrK=4tX2O0*WR6WfOPt=k+&j)qgM#l*d4sgelkiCuo8o10^p=*+4{~T9(ot5q**FNy zBXF^>asZ(2o#YK8N`2~G*w$tQ(Gqp~8CYe~B1|p_dc=E}cFEBtASH_^6_s-bWr{|& z@&`AK9W*xtE1PLWHg#k4)rN2*LwSG#hw;eg)*Z?`5EmMn9C;oK9d`W!N#yP(F0P)} zZcT|1Rq2+N#Db>CW}#z2eXPj8HsvH2o>;->qOuN0DYxXZUmfhTXmYM)VjhF^24R7b zjx_VgQGjrry$T{9U=HSwh5|%{X6F@Y3z6D^m#*q<9QfQLN`ogND|FN_*2z#Vc1B%R zmf$NXOx8r4$R3<;b}Gs4+<7GBGLb(q@JUE1G9TzUnJigZ&shp+ZB2x2bSnw9r$dz^ z;q-0!^>6hS>_e+B>F9WQF3OBU{FpCWCi%=@C6%Fy#)VWns_&#vR)T8rCn9m>;Uv)m z$GgiNE^Rr6t>&all$3zx9Ax1qgxlqBVq#MFW`c2lx#NlBY-LZ9rnC_W+H+EEDNA7^ zVDc{jsn3Mlzt*Wes$U$t8#BzROPfSROY2+1NQ`4xoJh z{(bs$XH@-4OLpY9&6z=V^gf~LQ5|%8sPt3+Ln-1NOQY)?*@U0SPM`cr}=tJ zNzX&RCgqK&Uh<@J4VBRz4^`c?q8@|j*s`? zbpG^NFuorm`8yIbY@TNCtem= zhVXy}M73`OF2`@OBj}Xv?jr;)HgA|GjU6B%PykaASh%?0a5UgP_r-SEnWAhz8QeS8 z)hj3{AXQBj=&R7HDl0D!>*+=W3#&;J5D{5g_dhR>#3dmnt9AeVE!pZXFeDZJsn&wp ze(Q=PM0?t6G#Emt5#gN{ECY2=dk-Vy6fkXPSVQTxn9UYHp4JE%aS9u;jCEAyf|DnQ zp83G6(3I6%V8J+%QHH#%&xR0}DGt)p!%Cv8iA{_W1>C^~sfRXdDp6Ig-*@MV9QjbM zg_ljjM`E#=d~km3?jG+yomihP*P%HlVx`(7#S0Sxi(y0$5GZLfRlnNnJ+T@(9$JwJ z^FG_Qc)v&YHLHu{{riiUVz3&Wn$z6X{^Oz`*i~z-hT?QBM@QmL#;gi)2ReF27bZKj ztd$#XQuEcuM_$>!V?V1RP*>&I)t9JaVMiPK(A%?9p=_^mU0f16XhvZvL;7;PSb%Vk z7eqn3KpylLemm{k^Q6ieGE1*E{c>@ON9(z|TdHK)VHBVGd4gmWT@3^ih;zu`A3Ko6 zk5>f;op;|C7o(F(HP*J$%myD?RtArUaV&#`FhW=e2#9*DMS5);3V+)Q#xY7pjYi># zh>mwJG_{z|pHd!sRhSEBsC0m^u*UO~gQ+Vjp#|SQEKJVN!@qs|=9;l5xpG7FEk_dj z(@fO+z1g*8-y?>VfmD<*77pasKh>^>^{yUiS*2WYhlpyQ@fO%7NOhAx@rDW`?l7Yu zkeg){H|;uGWG+gw^$d5tS0~5}8k}$pMHEabLCRsU8nDtN_0k5{#yx}A9b|O*AAhfLUaQh!6Yn@l^*jLN$#NpxL$FnBRMPI%= z@x9#d*&0hDB?u#dD+;Zj_1TGZuhkaa`4DU5Nra7#;sLS-@sGXT+7Ac(c1{k#T^y!Gf?DB+tvXlO=M55W2v_8Y0>7K3+9% zme{~hB(dOyLh2=|@ztBioXg}ok`sm*1j@tFtK2MZ5DAvw(yqRWpuI!7KE87`x)|4J&I5vOn*_hkk?DUrK5k8POQ!tm<)%(msG)s@oPl1&bQlx!; ze!jXp!)w^-H<0|TqZ{lGfN}44Pq)V%gGQ`-Tbcu&5E2q1sXlT2pRNjM2!P(w%xy81 zA|sT+=g*Ew{gFQB*NigU*q7arpL-`TG#Mlbl1Jl&Mh@42jQB*?&~SPux!zq~^f)xJ zDWd9NxU}*9pd&9XvWNHnPt2Q_t+n^QwOf2lOb+iZjn>mskAy zUW}>D!u(xUpOz*nW<};gl3vUO<%ff#OT%xh*S;5&x(0LRGrRg~S)#A3bDP|@@G4E) z(1Ko~q}79TCQcRZptaU%MzFXNoo`bUyzF78NiFkI$xJXaHmUxZWg8q_5W5GY`>KuA2_xUD$K zk<|lUp&NcZ67x55#F~Y@A~tGMht)uz3&v_vGZV_|{*3^}di*5OIZ5<{>=q6hQRN%7 zGB?M;vO*D30b7;eyNytAv*Vih*FF7W`kJ)LnC#`E?5n+=hHP}REtN<-#948|_=STa zp0eWR9+zGDJV#$LI+Ehew`^2o_eJjObZoU+Lw*{X<8|Y?XNF&?eja?_Gi)WPs@em0 zR1-b5{Tlk~-O##1bgkDUtKUhqS@-ZT&LxvrAa!m4YUxDwVA)E%Azyf%InF)$Yr`sA zz#7)3kg7i$ek-Wui8A0*3G^ZbrQQNQK6e)2Obbu3gonVkTOj1cIXLj%0%v5a8Uu-$Fl-2MA3h=lbv3nwOSz3an0NvTFoKc~!v zk#23}Ie`K;ceS2c20)f50Yx%*8cwbH$4Zz~8Fy08ROHQ7rPa2qid#%K`zb?WrVD$0 z%TN;sZXRh6FbAt2zN~o|1j2~gyF+=U?YChKIoLW8rgA^LmC3?-(Q8xdAR9LPYDb36 z7F+LHEOXqE?)EuKd&U%!d;4Vz3MH^Tikk#7o6}KcT=|`sI6W)(_j4}m{kZKnvnF2m z7ju)pei0T4Jv==;Q(8NV?*)PckQsJ7x{sI!faqz_A`=3{SF6c&_H;>4#?0T%z`ElB zCe$56`}DYn*dOKN$B&PfIoWlrS=*iY^ryp{{9zJhFqnl#j3_%OKjejhH&PWvnX{Q=!#^uLu(s4vsU}t&ZNSy{A5G-5~nAW%d^{jzKaUU}x=rPkF`Mw+SrkxVT~+brB^- zqMtA|O3^>wqqlmLlXE2DQc|Ya*=IzU%&vq#hSZitZ3BY{^(@gfd8S(u0H((=$;7?z zU6^z&Mt?Q;Ina(GQJF$s-jy)6?_Jp9f!h4_9XhIEB~?24T7>gbYh1uxOF&OJ;n4s# zlUHOIyDb+zhKyF7A;oha9~FL5dDMcubTt(6>c2z0g=X;FDy~K|_90Qk$3Xe&9LPOTN)0Q!bvV5znX(-Ry`zEUBn(GnT^Xu=OHDT zTWtWlQu@g@hn+XyzF2ye_7`O8B z)Y*<3R~pvg>CHT=op&Zf-2Z~P4?RN;Mw{4(n~%nc@P;iJ#nC` zFGA@r%?YM?Q@Zw6dFT&|zJ$5xQva4G_xJZ+t344~1_oxkZ>`f;m6@DNw$p0A*ErV8 zF$ra$6c?BIvv2I|S3@t+u2YH^BJWj%)mxe4dfA0h*$P|as<72#Q$%M@?-WspP~L>j z?_&t1lSxn@s3J8f0iNj#|^^H@Jw!w-nJM6@0dj2%<9bF6AnO)|^Vp`?TSwMLXQo^w1*y+)@&k=*X@C&|IV?$=KhKqP)#)-LD-a4N)xpoOh?ma2oA+-Ar~k`*Z+j+Yi2)${1$z^ z|GO(NHT5P*8bQ`~ZOQXX6Of^k7P>HKJehzd7?miGkhG~#)rEx3NrPi?HnOySk?7I$ z=o6{i+dGRoW6}-OFG&$!3MGEU4ssJnx@UefdUN`5T~`4@Sw?5mWq0HG>LAt)Clt>6$cj3$zRcSu-J>xhm-uWa7{`ov3b1 z0s>fQpT*w~S4lKQIl(?A^QfWlxg*NUVkaoy%3R&ihO)>{K`4@jnG!Agh=^yl zs0PgppHi>Ar+}ENCgNJp;@@fUeE&WoHaG_Prg8LR+WX~@78aN;ws!F#@w@aGR#_3MtP4qvl@ zFGroxNt~L!dkmpHb`WN8_)BwwP!d1}YBeRg{_AhL_c{FeWk+~Lg+rxb8=f8`adk#a zq@tB;K&m0Zq@fz9W`shY~+WREf#f&(@~C*fMaK8rzJE)>wP-ut0T(opH43f0%>w zkv0NoJzzd6UV0+x>;BeI7-}7qi~>&uI$Ep>(J1EC`JUUqr5+FqSB`Q)2}5@gAlfxn zFY>Tg^gyt@u=;H|ilj6a5%{dOX|2{)yZ|;Lj56+kL>D%`6R)1=)^c*8k1%r26bg8d z%a#maT+_lyhCx{Uul@W;4Jl8!><6+D+CA+ zM-pj+t*C_)Uu2N1V0idF>p$K&HZYwSK={ORh+1C}{d`O1@#<)xdzGYp+2Z{CvS82W zx%BLi^t?8-4V%X-H%V`TTGRaXayOR3NqauDyheG_i^~6!| z?|$#)zs8wDAdDtve=A2uDHzw2QYr8X(yBu%UJsfQ^I#}QFj6My%k@WRS$2gG*o05` zZ$G_0FO?1hGVlJ!3q8}%9<+BW{!iH0*iZ^-0Ih)rzpzH|aPwV@36N+Xxo%$s5x{9J z78>n=Bpi=aO?xCrkL)N2o3R_6SPG?UCI0O9#Kz5Uvu+arcq}hJM#5vMcrC7&L{ga; zMf6H4{H1rCd{j?M)IZ6-eM|U~`w_3;MQp50q7+UxQVrONSSngE^d@pq@f+inj$y`; z&`bEy0NQK>TgF&akSu2jUimLT^#mGBBDc4#6#=}no` z&1wd*N!5lco1XZeT=j}_|Mnc86P7nX%k+t$5NE+ywLdKvg{p%iw~jT!94oPFb)>htt_{K7@4Qr za~d(jDt!R>6A<~ho~&c;FJAHNe~{c3X?e^lhOI876`vey9cFkcjhpcL`ufB^ZWDaV zlZ?MiTXZcyBLip_4@F&o2uj?BxoF0!$Ab3S2TMhr7bwBGSsllBN*j~ZypfR*v0BD#YU^-(WD>s)iO(uUyET)FK|&g zR14fDc~x!fk;#{S%|x*7GU%wlbUBa?Hg4{3Xnki2eJV}+QpY5mu6gg!*8($PUcj-&bFg5u%f z=pT`48Xwk>YksojOvTLgr++JHoXE@my^BWy^k?VCyX0d*)M*h8o#5n{r+7Oih0~fN zIJsQsBZ}eHB2u~=MOHjIzt0Fmro@DV(w%A-a&Z44Fo=gE%P0bLbKLS%tv^s_e!xX0 zK0Q$x3p*!wOZim-Iy-5v^iH2*HroEaoBf)PiFoJwv)WMOQniHo(0OKzO{2k&60NQJ zO+$yJ&|ykpa18k)N(L(S2H&;Jq6Y^#01vj8&J$j6T_cK7y9 z9a(j1o+)v&GF$-XlJ`Tdx2Kwf9`EAq9 zNe~GynYA2TqtJk$O87)njT?qWF*8(5pbV83ruwz^s%WFlc7+Tn6v?qdb|aoN9r!YJ zClW{FvMIEW<$S3Xw_yfP1vQC1)aT1n*ICs~A(kBs4p);ckSb{sc_s)KcE_Mx_>wep zU1CJ1{QETTymXT~5BzUvi5ab=W=c(xrPoR_idNWbcW&-_4$bN77LZd3oDVu;&UlyK zjP0h~h}gg@vcnBwv5rA4bGsqnyc70W?g6&}$a7)Qtk=+m;Q6~t3v(A5%6HTnITDx= zeQ~?HbYC-m#3-ny78Z1(sz0>_7-R3j2LNHF7&bYu%N2m-3Ydu)Btjnn0H9vG-i)$` zl1sAyxQaQnf4qub^!$=={WkWAn1_o@uJt|uqwE(UN{rqF zRgSY7qnyhG13}-_5?qpwI-v*zP^l^cK-cto4DTj<#QMgKCLR(MmTmB!o}rUH^EPtD z@d}faE$86H-9!4gEzP*?`4w@mUA_4`)fZFq8dK8jClk5=B3KK4${57i$a!Le#EsJ8 zK@OW1qBn-d+UXOJgjqdhuZXaifqIMsu9Ps4D*Mzui- zzkV4hlepMV@M!>ux*uy7E4{2%_G;%VA7|TmdtAx$Q5dp4_LGXooj8jeuym2gIldVZ z?!{3m5;`X)cwBR$FN8CCl&xMTX#UrIN9&VA(lG#_qyF%vW7^~!7?qi|j{L8$H_+vZ zlAw|e%FDv(l$?WVewIiX`#!+ZwNp7s{w6C5a$h2Px^h3gnt=ZT|goF!S6Q|Q}$jAdD zN0fKNlF9uLUdlNuO$hRrOtPfSnof~^-h=7$vhI~hqlvt3>x7ubd1bFqabrpx%e0iA z#S|g^Z_pIgXjDR6#9{!=J6q~K9?+>E=6_Bj@ZmMa#2NP)l^o7j4)U*5z$^-+lWQC* z7U5o8T$GjPguid8RC=%X%yv9CiCN55X&tyk=Yzio{b9HJ#EXc|&exCCt`mA0({;|^ zZcCv)+t>&qtb$h84(eoBtEq;reyatzKWBj(i4)#SLr>rP$B<;r1@hsQZ38Y~nE>J% zpzdm={iNSizkf_X3*;_I|Jx*{qNexH0ELePFI>oKTg~t9MqYYtNubQ_Wc=}zs^FSV z-YvzWs^GVyYL;1FjKM{1+1to&G^owSVcf_Le-0eV1I}1DaM4(pIZ#kFH*ug6yne=x z2oTThFfMb=3wYX_Lu3i(7G9`Qb7dg*ZT7^;2Glm{rFr0AWwj6EhE#23qDE{cK<}D^`9zV(FH{Sv^v4QOE zwsdiKs#JkjM5SZ6K&g^00I2uu{`C=+?o!F^KbS2)|2wOt>UFc zEr_!S26_Np>o_UzFO8$ILC6MC2?T4}^uvTjhs#+cl&1C+tFXblF}ovZIiCiT=Pa zAw?>vIYhw5F^G2S{Xx2`d^u2Dpm-~ z#l20#JgiNf(f^Od^}Rm<5y9%}TA!HLDl?GvBdeXUK6|%M!aQRPUVJ{Xw`1$kvWw=Z1h9B2d*Di%=H#o+3+PQ=?htaY8b!1 z1xr{v|4bpwW-l%FxOj7>yl!$zYH`|_^#l7N{C1=<$eNG6^osl8?FcyT&p`)VFyLkk zoQ1=~%L{g#bxQwgTWREr@8IY#DeNpQ76){-p|W5Awg&7CwiAOzfRG93fZwvkLmXed z^4i)mZ~-Xkqe>@6HjwWrhSaW09|vc|l$E)xO>K<ezQy~&Yf z3dMEh?s*v?qo{Pxs=fk|otpdzfQ6W35b#9M*R@w>OjVui4jY>}Td&?m@!i)eZm3*a zS*M4L#A;Hsq=5D<*WI;ZVy?kd^Z+n67cp5auYks;NM~`@fBpdhRbz<5d6n!~&wPz9 zUc%~28hY@7L?6P+&b^LarImze)0jjx_)up#9<~1tsnja<2``dRwsgri9EyHLe~y?? zH0?*re_7UbJBhN;r+RwCD_R}jJZk=f?xn5S$3!o%YdlGaWlp)aC(N{Vt89VBnbz|R zwwo_fA|f$$-9JM?945_9J=^11b*>wO0J9b4(qc@4AM?IqCa*?QGdRD9tazVkLTMv= z^5(+TWK-J(i%9*)9tPVF3|y6Ptnk%;JEk1aLI}i6<#Zv*qr)(SOmIS^58qS2={lYVQTIIO+60#}jdWlWq2*Q!kCY=20cPu=c3X0K%RGTjkHSJmbHiXoO zfSk?u>N5eSW={ADQ}-XcB~MT_yU@nz%sW8o$Og(4L=l8k(U<~hPu#afta^GC?ChN6 z0GSFf#U59Bsg#ssUHx@H66N#CRRYuW18w4fyh7Q2Jr(^}#mLD?11c4;xZRGAAz(Tn z*{?rv+ct1lBe%W1A{4cB4uS@p6wmfKFhXRnm4;T&;#p}3qD6i{L;Fb2iM@pWFesX> zxQqG!#bEq+uI+am6k#r!rP{GYU_-Fu>}t9Zfop%!0Cd#>Rb@?kB~Nh*p&m;rwGx6O zpWm~;I_+Wygekp=KS?nH><5{%!2)9MJ#+pmBwC;;`sir;3!=^35~)j3}vbp(4D<3Mi9vB9^!z=Xlg-L z3cQUl>enwP#u@1!+x;U7)<_A6(V0Pvy=f$XqMY63Lh9Ug&w;ZB;PNn)c>i}C`z2?)RrZ}q2Vy+{bcgoO8pA_FMs-vk~LzuB2$Pk-j9zk7xp zGpKW3*=xO8zOokUe+uRbqGGeX7c(Di+D?|Tlj-wd<|OSH$y+`4hOewJ7I>4QJ!Z8Rg3q24#(UT?t8cL>EL^?jspZ?k)0!TGImQ9w%2O>Y6MEQ)`X;i5M2TRnS)VcpA zK1pKwCq~K9T2X-}kcJ+z%n}oa)qO@G#Wdj39}fsu1d43g8c$3$uz`s!(X1J)oL6r> z>b!HE=(y@Jk71HD)!=jzH7RdNwdiHhu@auF1)fd;I<_QFT!Lhy&`6TjZ&N93+hM@b z<-l8EV@e|YD{g~UnriW9W#5#9>3=^+KNn}LJ{@nzV299Xh%K}Jz?6R-&6PA*Ad*M*Y%I6E^vX6dYs=O?4QzLUS+6TW!vZ0Yqg0;od+^$nnuD7vT) zNUERaK3j;=o=ingglvdC^3dH(<4U71L{tr!GtZiUY?P)$7XzH5#YOPt7ZyNQEy^1t z1A$JF0v4w5h>rl_s$HxqtMJ$e`<>Sl`{dU(P@xT3SglNl5)i~(gW>W1KHMPnVOb~2#LDAm7;_wObH0fo%b!yh@E;?CgGmMQpYOz{H>YSXaJZ1~!g(ucbLEZ4~b58c2oe38KKaJz3`!LqJvy_nhJAIb2k`1%`nepoatn5Wp$5n!PMJ0Mhi|M?RI<>&QJ zE1;u0V&Zq-e8U^p-D&Rql`bX#3l48g<2`KRaQ+YzI2$%%UaB zzVM>Z0fd86QPB@4f(;;jC@2wqL@kTBd4j+cWwJa+x*~*y*CQsLHFkl5b(&<>hW41(Efp>Ds@Wa6v|jlY&{q2pq4W!^k!)L zhE&v@zLaI>(?(5I<{F5ci0Ce3vW>=^?53%3EJ26!^(Na+W`h2zL%touL(0D&L0YMV zWa0nJu9Ho_edYb7`7K%XwN8TGC)S36j13%It;?~b#juf-Uw^t#>lMK|IT}V9zqWM| zQlg&=qj9(Mzs5xuKybq3u3P^7>ss%<@f5OBB(K!R-`#rxlmv;B=3|=nX8RoK@(b#4 zIg+?HMqB}H7cjr?fcY_9ci*jD#Rvbkf`ejS(@S{ZqzSz0MUJHbjck@4fQqRKvTjVb zc$Q^Rm%ipEj*4=BA98$$UXEi*c=3ZIYtYI=Byf#Xrgseo&^|2d(uXfs-nA6jEK8A~ zg%(kK@%%^i`&-@+P~clV(M|EmqUE4LuvF`Gt&p!m6X*5@Qu$4eH}Z5>wZEUmUd2neyb>}&7QNgjOE2xmv}P1P1>O|xC%~@7vqiNEu~Fj zNl9AYgImZk(-T>B?}a#@qXAe9=&K{h8pn$xX)e<_2*Jfe_X{_S^L(^G?RnIZjer;L%JJLTBIAKq(mC-I^Vt5=lI8ZguVCLbB;O2JI{W!pU{w_ZG?h)`Fn2m z@87?B%Ebe?IZ*ms@;e{6=zXNa!hAvX-EY&>W4sYGV;=r(M?y9fT}0iyS@?7#-iI8h zW)&ye?JIFN7kh6iV+C7ze?L2<)$e~( zSdcI@atxX)+u$**RLcD3w64bJMqZ9-M)_#WuZowQE#IZ;^Ev#nEOB>DtwGInt`i?Iv4Od7fI!ug{Zy#gh&HL(0l;I#i zs)~@I@!YuCJNtCvL)L4C@+y@>hDH+{`V!2tY=je#l<9?t*X{ zA{T#8T&_f~Hgi9&27ms1pyfo{ZzU}v=FAeHMu#i;B;j9Cq9wzlhl-9~i7AMiyqO!v z07_oh58j+}y{~?V%RrJBLJS&gEOy69sB+*WvJC0c%kTdhLDLkWa{4MpRHyQRl}OJ5 zDhXvx;*%T_KW3OUDHjwwD#i=CNGnk{2(RkOj5M@zG)=xQjOIwGyHJ177t|4 z_4j#qT~x?Tw)gACi!w_|w>91r-8&O+z4l-IOaUE2rL_wod*ei3*4{-Cfv_Kz}z3gkb42 zs~8(Rfw=xA`*}%}Ui+FZv@dh;WiycnS)@8%pKBd%(14k9{r=`XXtS72ags)2d2|in zPA0joiQ_X=+&z?-;VmW2*ihnlHevDAzA#^Ej#TQIcyfq=ef-b41bnn%~w36YCr(9}NKX^`TD5d12K+Ymwx!TWi z%WyEfTi6-%C2y@ow!Re};d-{=CRAtE3lHhJy*$K;9^@jQXo=7+Q!4;7%{LRdgPFW< zpulfebtp#@MT88dN<5in&BmaJ80eKomPC=1esBYhA)_u=Owf`S))B`bA(X0rkyHIZ z4-RFy`=ZkuIhVap9zbD!LE^gNwf6};u{4694w2;|#z*9(w!SkScTL@ni#)bWLXX;b zos=%(eXl$;<-^9v^hHfh-Z!5QsgK00Nl;S2@~7Bzs`5pagv?9CVp-xqRxhg549}7~ z>Qq?@jcK=t4ED?NDq@Vyfk?d5 zn=NYpkMI8Vo2{EQ8E(dhF+pQxT`m_tfR0a}&E}Wm%U=$<;4_~20s+i=dY*eM2ZDb` z%ZaETzh}W?HL@E=KRV?#MRHsmR@xUj?B8?@J0H%Xv8womN42>A*f{J2G@c-rh=9ny zd6OaNk%5-HUX36AO*zv+u@4ztwLXQ95yGR=zImK{JdKAks^I;uK)&5ohoe|Nd88U@ z23dHrK$A2=Lw8J}BFc;+4P=!TbA&^2rRcV$<>e{{1-+QhVfItRP^l2iyQ-(xZ_AZm zSct2f&W;RWGwHww9xARZpdXZ{JP+U6TucQ2d;CC{I|!0rR)!2752wyc!Z-@iD1^H! zOS4Jzh6M}+`Q8isqCoB#q@m3p=W?{5yI`~71y|q1^HDHI$O{)+GzzHj4~5Ei*u{WXxvNY^WLRjclVqb+U}<2 zs`{*}*lFs}yr+LX5?Jn|#WF{_!IEd`V*Ur~bGz=1E=OFl_r}k$9t~1~Piit2A{_4S zfm&$E`#cU`TV57zjo=VtB4w}>3LL!zzu(w6j*L?4bEBj)KN}DL3K<;TFYKvzl2L7K zLXe)AQil60b^jm*x)8wzQm)MlO9wWlbNYf58uCapGiMZuoKs+UG&14f2)~f zY|Y2q*E;xYk@h|6e3^BBlSAvvt!4+_R6JMymFZ;Ol7tMXl5!YoJUHMshs7Vc!Tc?_ zXgIF#ZQbVm%>}HZoRXyU5u=0*sMetL)@_xoyZt)rL+9+T27Sxbh691!KJy@xDdT+BaRA{Q6u`LW~Vo;O6MV17CgP5R)^VT zoa@G0&dC{x1kqgJ)p~52%>FFz$~>kty37{%wenD0&@eD@AU9 zheHO6oS(tN$o#58zLsg!e@ZdP1c%UTen!_xrU^k^WboXM}9}C`D5!Xl5qL z=!S-dTJ@wD~E6yG0Qt5loqAQfETL5Oh)S*ep%y>1mY^ z>9S7(C#OuBR*J>!?M=xOz4Wk{IPHi_adXt(u=LF_il3oET=xFi@}WUmd~VR*0Vkva zU6lCaSv(aY=v)N6kAQxQJT@%-AatY)xO6VSuXV=3K$5O#4l+lhxp}S1lM5F=(R?0;NjAB>90PJ-rQ=Qd z)k%Fp8cO?9!`<0c23WL2`mYNs%sEK$N)X9O6#~;n3_gp|7^t*vAIz+p@O(gXOeEQR zopK{efNWGQso+BxqsTi%OOr%hrGCJ`1QC;ciNdro?Tc8Cwp2D&Zsu1}6Hd1m;e6~W z>A&NnL^qhwUQTMP#Am16SeRg$O2&Y&|2A_bq_rVii5&?cm;qdOqjq=95Gc8zH$D-k z5#q$~Dd>>Fg@zA=$jQrZEhgwAYUcL!kl>Q6d;&6+^RHvBER0%%D%i#S)BWTN?1cpu zZd^!V7VErukN8;R0s%jN&i!h?YP$9c-P>?(;{rj6!U=!Scp7#2kU(ldoXgGKy%1P0 z)WvSBDw=Jk%{FaS&c||00$R}=hhEt};XXf~4iYthmWtsESD@oyg+qxifq2np`?b%k z-s+#?&I_Cj8~QP=6YT~xm0lj#7zNcPL~k6LO2upkRMpPyO{>T^3fA5_cwt)n-I^H+3_-B`5hf@I+wi2!8VsB-4f(Ms1R_8yx3v*YG1Mm;orx4` z?jtc>8g#YhPl-Ye%5435H^HxtcS=)bFysgLe))lvD}hN(dgwC_cqKIzv@+l9apbHH zk)vozaM+&~*1LxmniRf|0jL83vY=^j>QBfYd-oqn_-)tv?&K=a7 zzv`{g-Ty3)_Q4YolSU}Id~Z?WF%h$86=uqCAt2!U~$)39+pA?I<9^H4V>VTw*{AGo)NjI~3 z?^4cb_QFgZ6^uUxUnd1<-^YFV zFLv1_mL5(93uU9h7{S0jvx%gXBT0tN&QL+3#|06LB|(?OylJd*^s5emB0gNOoe0&S zdfn=gXRLqUc;?jbL3xZkOB#ulpDrZ-b3KpwW(vugQt^w#(N{_C2l*9e)0Div>PeQ? zX_0SUF)(ko={U8%mYz#~z4YOSXmq$|_41$3(;6YJW3#M7G6gCa+Hk>k zC?Gktesve+m*)oWOb&c@DHmG15#8DWjXWd60e9py!y&0Y1D z2b+u-aEAdam-)d3C|=+Oy78WdpMJsTmQf+XLa7`^Es%zVnEr5KXK>si!WRM92SlRx zg4^i$Ah5Rwe3dPQ$JG1}%ba zQe&`n07j5J=0b+L(1pNaIjE{kq$aWu!KaTcx(t8HmN=&uw0#5L>yol?LOU2p7IEMl z6>ta%E~>A~RHkXOXrlQe#KN!G)*^&ZDTJ@1s86<%tJLE@>gW2~U|?iPqToEwfjROo z59bjeuptI;N&-^Eo9oA`Ze&P4U#>U{X)HDP;G-cxkdVSbf^2F=IHKVsXSf~wloz|j z0TG)t???=7{OJ%##kq?BC4DjzPj}L0VJ&I0#Wn{snwyGAsg>C>m4-W%z8i`fL1%kX z4hT2c9y3a=N9*Y9k(KP!zwd;mx02>4ReRbO(G};Ql0IT&;3GP zCpN2Ib=ch7eh}8uG&aVBfK&w=C#v)UkV!0@C$lle36LZ65TYu$?Evr#2;EqeVnzq- z8MsVN7D)upVuoIQ4GFYmA)VO&Kz+tn-QJEI$jZ;<^uqyeYEn)Ox1SDe`#ecujLtB{ zEzvvf%E6GJ$=$G7Iq#p0-(S~GZAJ>$`M6qp;C;?eVOXC33I}A3bWYRW!Dv`r^1F2* zzHXh^Vu~0Hd~^LDZ*=n7+V(TV9KG)m;DDJnC@f4Mk~(DlHkM+!V<8ySdu04Zwcf}$ z(Q>t(qgvpf{B`_KCc_*6Vf%mEPID?j8T8)=;`1#wQ)kt72XJV*9e zaO_ohu2Qv_H4{x8UYZin+j3*igpWR?_=)JIpO_L}JeU)6g4xV{-qVFYWB}XBuUq`` zlgH^gNYnlehGMO(7<+DgZw5^{NVNxD5OG*~dLl9u;oMzOs$6oD#DWNPVO<@?%8Do` zVIcwb;OJjj34OR*>&yDtq+e%2kj7?=)UW_9h?yCbIF@d-VKzx=J>B1!%T?2HiN(nkH zJkoN(iBghR+PMzp$#_(hLAXwwmzVt7`!XlC4 zwzSj^A+^rE@N7o4RF^kDgijEmj9mUt9{%Ctq7RJFACRm`zW6vK$N=8P?Y$%zSnBBL zZ1e;MgORt(m9a-EIF&FUbOx(<@{v~1aByc<8@ET5mX-#MHvyy%Fu!o&RpUy8WvEE< zR@dVzC9iMs#u{2xV@T1yK#t}w@WH@GH0mqhq1~>*5LAq1;yJ;sd5v$N{BxX@IW@;$ zkpVqX@k<7|hK)8A8UH7y1m>ON=Xr-CSSvTd#f>fwoFoi{K-7yOU_D)aKT&8mr1I-I z7SKYrRzLoML+Op$`KGC@jSxJAqSv>O8(5Gd(Ll$dxGOM91cPdPbtHT5&WSUoZK>5* z9OXp;VPx@VCf&YQ8DRI!9UiGAYWnbjih(!iQDXBvsdAf6^j#3*cA+esOcs8G+({fdU>q3_P?DXVe#pLdzd$IP`jVVd8;up}tfKBR4a$ zt+KLd2zT@(KPSoynzug~`q~hssU-yPrA(h7W*_<~$z@8u!-s#*ddn%Vwn@tb@>DT} z3@ioyb_^Sd@5A(zlFNzFqsL~*H0|dO8ETG6IHA@LlPwlBP`XlTb7CjpOc(mMLPdNH_8ZN?MJ6>`a&0#kj1QdRx;Q2ySFM@0`u!}#8 zPMCeo=qc%vMgba!(T~PtA4_e#cdJK%W%ckt2;+BJ9cY-iN9Anp4hfAWw7fjf{ZG?* zdDmj~!^Ug`ImGI%+@_$4t)!py($Z3 z?P^ylA=wGjLY{ovKT;~6sqYdDWjLPqL(csez#Ltzj9V;#D*EGB#K^vf1bSSO_g^x- zD^4mLXk=60S9CDz8wxeiI!eyaX&JU`HSpEMAmLmlrW?_HcgiDfHOpX2c*|#KxEm$L zsb356Sau07cd)WT^nctl?Hf%l1DQuK4uprWh+ft%9@#oN4vuH?uDiB^8&A1Y1}Usk zAs1)!ANgpG^}_S51{h25SK9|x@c%}F!iIW?Sv`G-@#5#oRiC$KIo5P#i>QheBbCb} zUh>dgmDM3c?Na)?u@X#dLm!5Xbu9Rouf^IbC;<=wC0 zQ<(MzVkrG#nB|p~1E9>@aBnx~BF@M|?Jo|<$xJ5&^Xq4jUtl~2B2k~bCp5gFO3b3S z*B+WjT)kP@dw7Y_+mq_L!iBFa3u#*|g1-bKW9)Z0+j$ zV4G{Yx8}o~b9=FZ&JKJWFKvEg86N>uqmWoWON#t1siYy^`E?I+&3K-=lU;;e5u8N8o<%ZjE9YYG1R zc3W+QkzkrH{kcfTj$Ou5UDd{av!tXg70bFej+of37bGE^ovC(~-+k4eoScL#beoQ@ zZMVMPJN;(*h#O7#qyP4@xxj8{JjI_9paAH)(7^U4`U(zA9LxYsF(t z*4X&@>fP!UkCv7klQ<>bD|`WeML~fsbyt}}O$@9%oG!QL55B(THEu$K1Xwb0ip0cM z_eBuH!9-W}(!kqx{^!Uv(%^{UZP81d)MU5nMS>Rw_|`M7h3P`o-{O!%wMqgYgHyTS zPO%#PxOzbWgFA{$Y&FfBNONtpU=6&W1O2gl9Qh!Kw7P6=XX>;r?Z}v#Qle}CKPC~a zn0Q;wRsPn9=Il=$%hBl_{jUy!tM5(8Kp}#M6_OB?GYaEW0LzsK5I{;yaDx%I&a3ze z&eK(x%wOeSOfoH*xY?xAY0S1DB~L|ov9p)gP=>Y_()3ShJ)VA9+b}p|?uOS?yqc*o zfcyJa&$WHE&FY(EGT78(0jzF^PL%+sXP;>*Um|sUJLndBh5q}3cP-sgYQ9Ztqx4^1U_+q0TwV?GmuBbka*r7>YD})!kAxx>B)ws zM-t@A%8d_UL4FMnCOjGJX*A!_C3^W~wYQlG3JZrbO@uX>RZK8t7j#gRbTK2|1&+mx zbJh274T3?Lm9IRIwRL^Ylk;SN^X*UPl?li=jAw8M%dT5w&_yiG4EYB|{L$zIzHWeE z90sfdn%4iFv>A4 z$=Jtq(AAjhi=j5XIsJ7QwJC+O>jK%^}Y%3=C ztvE)1YEw^HcGUP?aNcakyW-knBIb)mTK6VK`zyntsP;Y{C5EDn*(9<}Zew7ep&){B zf}Hj7t}zGE_^!&uFFg~lXX+x40u)}`)RpgyVLl_E4wRUnAxKM7x%sF+8BG4|Ht@sG zK%F0ucsCFt%8qYYcqIRFCflmhQ20|~D=@O-kdpM91%&%sA-*RowZnaN61Pjl!~dRc z?o5ZbYmcZj1D8IE5AIJLyuCVFr-kgk)~N0@UUXX058^CaDJ6M$l2QzqTIl5eQJyAV zQ3Op7I4%%-Di<0+$Si8Rh0i-{+B}*zo*%EB2V|cFb6uUA4~nBYq>jaa7L~L zK+pIgP-x$%m1kL@e@ZP31-RDLIs46QB!!;VN2)S1seGI ze2*l$kf44-tRG{dqgI5cIgml@cF9cQmg?g&(f2>B`c=1;SKy{+3KVhBRw)QJ%F}RT z#9niY97%KGBf<49cyMffZ^p{6-(>dLZO9t}$0AbMOo=oaxI5r9RplxlS2`?*u>kJZ z?#KH+4WSfd?ol*%VkW}bCJMB0^C(a6s~Agro7ccN_A^zvjtw_>(BY>WJ@2B`N8CL5 zAgN1?ivvXhf=DI8q{7sE{E(ax+wK(A^w}ofoqIi|c8bxqK{^>qIK_B%{5vi#e3*I( zQoK5qrj52ZFl|}W0Ce48f&=sdIUr6}Ik&IC2AeT*v?3Jo)y|(WFm}Q`p&T10+3V~j zwe(4GN-*ZqO1p>UM6PIw34Ab;3e+NrwRAGQb~&?&STlJRo z0EVX}*cuVWGYC6$mp{xKuM5QOFqvogP(@_B;AEmfl+)M}kJI=z&Vk>{1TGlq_tP#* zGb0DykF(D4f9g>Vk%V^UIh!wbREWrK4~dzPZ*)E_rP^p?YgdNmZ_BC87R(hZzy7^` zE)>d&li2uGNrmE^o_ch^c>14;WuHbIkVI`7T4yc5w+t1LoQQv)hZqC(>B}}wXrI}L z$n>AZCUkJ7jEC667nH~A@O>&9i~Vgy)G`adja+4z0&n-4sU%{6rdBv7BCJS|;yrKw zWvTt&_RcTC5-Y97b__dK@oy1jqyN#(oY1vP`wUSq)1|TfTd6!zN;rCm1O!d8k!-!u zWGD$djkJZ;6567sP;WOfF~f7Fl5w4Ab1hoCu|XX8;6Q|7mwhM4tQ*z?z8;SCP#?q5ST&T-qU$o(fY+9Kd0oCGK<55oeMT z$W}#0VS{s{&gJ3ugG>>QN_LuP(niCCSadM*zoM#RF*f~L;t!XXD)0NaZm6zV7*K&#mH5M#w-6j-%S$#WfCLPO_s-~{PDEBMhevz zgHfWz*;1Z6{ae(oh1PG z1ob0q3OQ@R`#VI;f~Np$15fcMjnvOK#Sj}q($>iS{l2>XvPp5=p7Uqlg;X%zl5nel z55WhQ_Dg4i;QcpTbU{p|v+;I_ARcFAPF8dNgo}yx zio^(85@&+50e3WaFj5I;R@p#ahe{_(Mqi6TTA_Gr6bHAW8zq&R+3M!&-x0!T(v^Ysj(H<}d%VK5140%L2?vM!XTO~w!_0$XZWlDp? zEyvUrGaj7CImM`s%=ETMy^g%f@aUMLw%nL=nHgF?L7pNaB?hlCQc78WEF9+1*aVa% z>oV(e#Mf%}eDC1yh>2YX08mJo9Uk0B)V1eoS*|z`5z63|ci{^TU{Zh#xTBfe^Y2n%t0C(#OqQkXoP|^v`uNP zoU>BmH1kHnZm&-u6=fphoKBWiGVzdBU1OliI(M2ilhm3T+IFFL&`~z$`?@hMwPH@= zoN;s|9Wlx8?KG2&5A9fy%3mjV7#}w>ti@mPzL$xB3orK^C0rT?ScQod0I2g;ljK~& zE>f}eT1SQOHKu5XGzVFW7LU03>xJJ&W4lI0aN=*@j0ddj2Tf20Fq0fB%XwCm%E&07 z{Rw1KZ;Np7Lt|lJgMVLiEzHtzg6kM4Wie)D7`0`;$%}Lw1#vke`#Gmz)p4}Fh~wMubX`nJs1== z!~jtcY!H9CzxdtihiUI*5D(*K?YMHwdxR;XE8)Efv??A#WZtmk)~|Ybe=y(O`yU9B zK{_|1m^2ynd{9JkK!w)j6qv{XICIk=C1{WN_7=(IJs*%wW5|q+TdW6Z7AVymi|N+- z&C;YhDrY>UW)kt$WyTO4`2;6e1vb8HFbL??oQU$UQ^J1C-eg-OCU%yA$lbOvX8N{(S%#cdAEGPa8i-p)1%>RWk^0S zL6T^Tp$@)A*!BBnz=Nu>J5b!icqJvS$P&${O`59}-AH?IJoi4U{3grlt*Ss={^vsY zySPuXF}Rhcbt)CYm}GA2lt!V{$@qaZRLW41TKuvw#9pE7YbcPMA*%<$GHM`9(4m z$?NHP>ak|!XzpkT4qli=5HyI>XCpf5QY;S}3=Tc-&xS!74%CSZ0FdPlyh(CO#0;EP zekWeJ@_Qx9pm79?6j+-=FrGnoS+}5~d6`n!witZ1x{CJ0EaDAK z+F|-NmC%~9LS)kWuexQ&v$Y2E%CE#3=9$wZOQAd=^e=LgFe3YF3L_T#kju!dyOARb z7t(Zssm?AH?1XrBMn8)NCMb;9s%t&c*aaoEVhbr|E&8z@aceSL0upSBbE^^fTt|0b zqXSq{+?EnME`sz_V$8s^V*hrjUML_91g<^)^C%&VFOUF4o-rxm9xjTJKlVvDZ_)RQ zY)Wm0Y?>I9c#aCF;@VQFXm#Qen4n0V9GC`JhdRM&k|qs>g!C$Ma8(S=EMAIn<;8)c zE${k7>4U`VvYYv+3pOA z3&0q_X*D6{EYzt+IHRU7gM!0_Yu!e1fvKr}c9R<)MfOIQj0mgWQ_DPG&z^>kF(m-n ztC@rwFo{^Vk-$Jgw}Zj?vaMkAtfbT^C?OyUS#t2AAVx85S)b%y>eJcC8v}L6fWCX4 z4Zl|tO-heUQi6>&rZ1PPVjP&^r3VicUfWcR$Xbgfm%R~_VII@ z=3->TbkKHT-~QYzOvK^ZjxYWhqP4!*#BuE-)>v)w>4gP-{{Y;_87X;dn}Hl zvJ5`OiB9|yZgN*5#fy011r8k;Jib~X5f=i?pa5zZ(tgs02asuuag?D89at3V1koz| zy_!N6S{(dpts|NawsSFb33EBDtbzskfY^cDX=~U>3{qq1?P^7<+KJS1rC~A&sZy$z zNwSCe`==R_QW2hpm=BRijF%Ww4Q*{qiV3Rr331`sqrBU9WA>(WYI}vgO2QRoua$?= zl-Zc6tT!X9gA541ul)H!hAJYa04fE|wD#qu}!eDjVCfIfcJ73nv5gUC1|us~G| zTA48k6;7dW7(xG*z-E_|48|#1(fW*6Cm1x zQ9_taEzcE;8ccIe%Lv)=`g@6OcKY`jFj%{pc7-9uvnI02*bb%oNf%qmq+l8CaAkbw z2e3qI@{o$($y)eTjSI=PxS_2(SGsjPf>9KzF|{U zgj%pDZezw~;p{k$RROK23(!ILdW1K3@I_GjJ#pDRde5VGfBD=}Zoyi2YFm#yQP9EO;&*g4RO z{*gdS%$+DbmBM8G`IF{U>2C%`g|Osjz$?qL^6p5~4S$L_9&+03tQA+N&PirTeB+qFo*lws)BBP~_`#(GqdCz{|wLq47o zZQdb?64+}dp{%T2A!}|%OayX8q~TZ;K!F0k4521Rp(e(R*#M{mKubc;ji&~HOG0I6 ziarLdUNv~UzW@fcA9!aaAdF>XaN!drX( z6k`oNCQxBuZOLJvdOg58+BI_gJeBOVIkvS*Nkkv2;ZH`R(J4`a0)s)eib+EvyH7}r zKAD4ibWT4;LS06Q!mU1gkanD6AnP*5%Ae2_V)I! zbMBRb_9exs>Dacr?)>|kux%t5sF8a}h04p?n%;;BjW0EKZZ&h!8%X6D{U?ImcX4*w zn}U2j5Isbfhxf=Z>Rx!&=e-}TXUE8dJomD6Y*AJtMP4X(S-C5ME(jjQv~Y;Tax6ai zv68R*T9&Eiv{0~fXyZ>xM@kmXP5Obp!H^Z$xnjnI0&tTiUS8N>)^3m^;)R5aO)&(F z0o)=y@F$Zfuq+N4y7>zGA@C2Jjjj5EIGCr?Qm1~0vlswEhXIi|)tdxE@c*2U=_RRM zlva+|6b&zE1YhlQ?`yK9J1R9^zN%vUOgVTQ>1sUGXn0sZs{JdN2pl}Ip;L`!)EIII za@EG6%%n;>V|Ge1PJcxs7!A<*zK%M@*S{r+_<5&r=*yfTeAp|P?T{dc_!HuY*<^3} zS7IyU#%I2Go5=s2tw}(bAbM0S15%g(I8$J8+&p$dbQK2eia`rACQ_!77MBMhzngD) zTbJ{ugJe#BK<6UkD^1H`B!J!gEq1r{J5@-)`B@Ib<%cHEtL1hej-U2ktzoBsiv)}` zlaCLM%TKFU8(&NxSink#iu9p;glCKlS=l@mT7CmE-?AF1O4uU{x9+V44zkSF1#}Xb zO4}tj}4d=qm;N4VvB95m<$SbxJ(szlKM@?{%Zc9EOLq` z+hvpJC*Rc{)gaeU`VZ&m=_znV0_16Cpu}pvogyZV3L@jL25H>f;lrBFsI6i3_30f} zeJ+17HeE6-54Zf%QoFp=dy>a>e952CY zuuLm35Dwzgh0}4lo9%hv(LUwdNj4n!3GrDiI4vI>Ke z-Zll4;j6VjCm`SeA*tu{ZEemI#vW$>j!4!~dK>p+JrA(eEsqzQV8gSSTonixcuNn+ z#G`7q;@}CoQcp&O^l1Vkq#OdywXniH^QCCUb)`n zmVCbAS9UX}>KCR=3T+V8Ho{utu)jEa;JG|uqILStlk!hj8 z>|gl7QG(Dh9Ah6UWTH*5hWl!}C0qvmX0qOCtAaVvz$wil$|phhm4^wr|_cO(0M z9}SedJlK!3cgLl-9MaT-zy*-R1`mMG4X)qi0H@2paXU!QMjWt|{k6EMF98&?7MCrC zA9>vYAl21x(Nx&hMwmvDH2DH>8}wq3H@(R71-p2qdDk%s;*=30Im$_6ht$oq)WH7P04gY;Y- zS|87763MCZ*JU`NXUb~-#yxF#I7_YsgaN2-5j@S)&mo^vPh^o))OEuEG5enN0>l@YF4MS1 z0(Q8~nINv?mWk?!3q17nW9PfSm9?0@qa-?M6FWw@sWf$M@}M<+y;ZF%Kk^Yg%04pW z`vAMY%%A~Upk?IPIx~HQe>0H-kJ6jjaI!u&$5Cm}iAI=BP@sX>Yeo#XRnZ{dR8Uuk zLwPeIfBHL|BJjHnUOeM1{u2-Ae+j#;R-OjBAMU!hGT-C^Jl`N}7ZO0h#>75zIlOHW zaJ`12P+t%6cg2BSg%)7&4EEE7f%jp7bAsGb(7k+S9LonmM2rM_+J!MR8L6S~nWEWS zT|S{gI8$m8SC{_)4%3dS7Xu9*414X)&4wo->Lz~ zxxt`k=%<}0ev}}f18@!GdNn3P7o3fj(o3QOEl-XRL`TPyelT}}ZR~?h{JU`}^dH>_d&D)hwvDZIt|82A;) zrhJcCOg#4qmR;_uJnyRbosSm@e71}7`u-g+O@WX!;69rJzbiP*Kyun~EcgagQRGv$ z0Ac1AA_WJ`l*#knTw{1LW+D7iI3;|3(Cy-`XQ)phR?p=j92?R-EA8Xj4?|b_%Y@?QmYZ>oYw+rQ4=8}PEtSDBsa4qi!D(fmhOb|{T%Vf5 ztcKJzI5{dZW3ZX7cqnwyD$APlHzW0unQ5J&(- zQASc{wvdbKw;UaAFE6m?bYI_0Os=gV0|p@f>LRwfHN9??A&6+A+#(~n?2Hj~0Gt~n z;NXD8=h)u#TNdIO*eL1=*xDQJtzd!+GQUjtFe5PVaVJi7fm7UL&6gkP_Ri(8Pgb8z z*I5n$V4MOEKEIVIGGG4P6}FoOQg!qBVBQISz#RS^CY(U1iPLi0OF^8;;Mzu_PiBOG zdKM{Mj_ddHp~+K}pWpLPktt;cmg0rV2xcup3;Ga62--A2-FX?euZO>!F9s^*}g zf_p8q%DMvim@raYP6idtdaDlOC1^+u&G6xmQ~BN<2~#U;_R6D8qfNg__q zGmyNAMH3oaVjQCjzaRf?J~HVrQf*KyiDN4KnM(d`Y?9vYgPa5&PGxfM7889w-vudX zVWsQL8w>y;{=X0mhlY~Ng$;JsQ|Hrwlivd?BD`OY;2qY#u7AMVFch2ZdD-L(X#6zZ z-tT}{0S;m_ZY$+_pBVDqa`<(}E*3FW>POgm5&>(U+ zEk?ci5E+d$BI;4wZ00;&#!Dj<#h<^8S*&CfP3XDK`!p258)*4xzgPGqXK=#rAFt=< z&!?9){?7xnXWs#L)^I%KFhHaN-+88PXaO77%a>u|4`+3|Ib5g3G{bCIe5 zCqFk9#X$fdZG2AscG|x7ND9b}z*=&4&xCqB3ZA=K^L`}QvNJHBELlBQ#FkTG5CQa} zP-zbj{um^9pnKQVQ4_1~UZ=+;IB1|r1q?Qjo-U3ypvYNf@UI|f8`GEfLZm8wjWaYM z)-{B(Q771HZ~s(FzK>vPCdm_>g@&r2^WCCbPcSE?d~P&Ma?q^jvsb{sl3S#0K7_4w zpg#N4ezNK9LDbgP24cXkDvjHb)XMOlKM$Y!>E6wx^LgobXmd~*mNz(BxS)BwSAN1% zOaC&fY?jdnTVavwc~2zp@gD}w1~e{DAXGyj=Hp2xS-u1nRE7&5o|+t(7jS(3yw4-B zlNS;eo?2e6RJTl$f8?bW^a7{{@FLy)I^MtF@q?NeZ7Z$m%h`4f<#1KAspL|ac<`vz z*ko>P2jd_zSWI*i2-SHtm)~#!qCdg^MU_$bKjR7A-}*S$IVVzz$oG2Qg@*oS7bh`1L%;Zg z>*(9h**Q=RIU(Yq=iq8&@Vqgc`O+8@!a5; z83iq6EkF!i&*8;edX7XFY)}IN2x6>iEUY{0+h7{PZB+yYw#e@L=%-LX=m!yvh#^H> zJkb#!XoRlIhpA`=r1WadSywpL#oI7Wb zN6im98WxpPUJU_qDFHsDJ-r}h|Qc3C?k!njb1v6l*<9}x~T#?M^ysdytu0{mPH)kQ^ z>$Rslf6JTmohV;aaF_(OI6smDOFDzH8E8*KLD&FvGbbP%7`=W&td=7bo12>rfUnPT zuo&SjfmTBeXcqr%*oB1*0bnbN0ef_VYX>|}9}d&uAe1_VcNhr#?=ux)bS9O7(?AJ;(uw~n3deIPngF!A}ne)DGP z^(#26Akb0G{+zWX<@M5t9kLMc`OC*)+8OBVjG_ES6`3BXSMsH*MmYsM&EbG?KD(As zhSrN|X<6Elxa=)2y-&6~dl5A+-zpiw!D&njMT|z)le|LWR^W-8y`EmdKl$ROqhyWI zBXeareWhrE)r4t@7)nh9n1X;w(Jc=a!vNkAQs>z^Whwzd%i)hDbDnJOH$TXobG&<0 z+E)U%7}db~u$h*<)sLEb!#O)7QRqs{K#+)Mq^P+XH`f6f>Be*N zo)f<(KC#osyQ$SjTn^K&ka*us-ty0%)h-?XZ!a9cJi!WTu!nRIP}`K<9T~`oxy>hI zL9iB7A3?obQX5>QWMEfN)#mWD(nd(~PKa4=r5r{)(v<%N!%y~XCyL5s*$1 zkrDv~$)QV1K|(^5aD#{lBHf6BDBYoSN=klfp7%Qrf9@?fbKTdy)|sD!ae!E3M8t>9 zr5J>q{(_VMfkQDmZaOsB^<+;2&ZsB0rk2mzPZuZ=A%LET=pK_eZ<%;QbmDe$%G1py z*i^LOnwLzP`Cn&ph0%uL_|DSnW#{g1bTFuege$Wm49p~D2Erh6pL{212N(EW^pLRN z^y-9Ifw_A5E_$f1_u&9OzdLt{2p<*|iEv}ZM~Z$jjHRW!Fp@CW&j`unVdCjs`!C@c zP&Kq9jH3eg!Ydl+J2*n78IKBmW+h;O6P=#Iqr9uVQlfoN|3l%k>*soDT+BE2=k;9j zH{RMfXM7Y~a*i*&OP|Wk+2726;%D(r%3_O@nCz&hM`trVqoAH&0m_DoJ~ZGyy)lNf zsGC%`Xj=TnUoN^4>-_{1n8iZowBKk)TqV>gGgzk12)T-NJi~+YQ|N{dPSAHyYSgeevf(0ueDAZ#jD4r=4K1%P+L)YS~U#~u5Yg5mj?$A;mMLmChWoM zNvZ3);y+7M-Cnc+74nXUW@nQjRR*n&{3fetAmS)CWEfFHUP5*8wCTO&QtBuCyQ)v0 zGC_ntPLGe}chb(k>BIa;VyAERs<%q;qG`P^X87MvR6$%{+X_=_#PS5MBm0VnApiY* zhSzT0YQOAa+((_&3xzYE_qkb#t(e=C=4;$TJ$Ex(lY*Ks%Z0Ys0Oai)CX_cw!9}tK zX^Bq20u2gm`|8R0%6FJ03XND#5n*4;?*Q|Xm`EIs@UFMsH61}HkhRRk7>XdwqwqRx zz1*v@_XJ`uQ`z)#Y{_5@JJyuO|3jI^OWx~TsL*9x&nI@1CK|*3B^B<2`j94umD#6w zF{DiGQTrc=cO9(#s&?!mw83kD?6baH@R`vI`((sbfjt#gw=oR zZL0dPHTB*I95Bsm1&62?-$r6)=~2rt>eD8rO=)!{-W&*@Svg+H%juvcR0jwWZ3cjF?XV?I0UaE z*k}(^!1Y}co9GpYyj)--4#Jx+E7NFg4d=i{ykgVgk-@F$iXh*CPmpHV`Cmy*h`WNR-CG=t?W7LgYx#loyM7=oKq`m9RxB{wo`7_oyzc zsS!W?`=n`gb5rlP2f<>_+&MQoj|HHSvv0Dt*Wn%0OQ;H0jJW5)K^tUrJY4?fSCUJY zXk0&<@rg5p=UruaMD-UkIL>Mh%y5`Jzc7JQwcSUAmPEut&-=3t?a?XrvQ(5goeKqh z(mR#k2ZGZn9z(Cg-Yq+b1>LMwni?Yz?4$o96>0D1Oq>65Eml)C7NyGCnKG2hX84tZ zI;lNFyQs^AS%D>i>?XyVa0RHd3Q`*`v&`m^c`SNwcR&63G-c4T^ zS}qT(yjOpy0Od9B-9xTd@n6>r#6jh+h(dYl>A{oW%l%g!AYSEb@VdclFp6yOJ-pgu zxeA9WG;}vGpnPbcr8|kig+RBOg+TDmNBpU}P$Kky69?fSt&p4Ld6NiYCKI6Uq{BmO zDb8-EyB#M17}c-CFK;lD0saD&&A901TWGF_TU6`+JR-**KK{HEe|O_BB3YeCuDsxH zr`5yHjZCqZQRPvex!fOck*E{k)%2B^xgK`#4DQ3#=OE$B+KFG>2Vxip+N5s3RfXDB z+Mn2uF)4+Rn7T3uY*FMc6$FZPB2#*=5o!%hj3ja0q;B`DgK`TY873iGlIZDMwI4eZ zqNpjE!evv6ydqv(3&~}Ct)G}u{dMPWgnLBCM`sjL?|v?USEw+oDSQ?89mFh=_$TCy zM6K>M9P|VoW|laHggeT@JU9v?we!TdCr>$m4~IQl_R6`|gPBSHQgsO-GQ!wT}k;7mi7sP7mbHzt3GV zfvG6-$$i?dv>C>JevI8qEhjh)RRIe#4_AD)?$F$>v>*+LVi?jUW@X&|ykZ-?Zt|-0 z#OQ82&jVqTu(7C7TKeW&j%pAz#Pt zu1NF0@1gA#Rn5`xE7^;L0Zjv@f$7IR4@v4Xs&6Kqi(OxL_Ge8u;*r?vH&Iz;`74=N;~p#q2o`!VE01!cuIsf95YWYmilz#-)b z=?Sp<7kX~lR-#ifpobg1`vRm3H!=s<*W7DcTYU;*wFvU0y_f}_*V8$tb#m6y{%hSi zb~^S7O<=iN?V%;YRZ#{=*bMrvrW-<-+{FI+068wdz01IY5pW1>BGNfKzG z51ib55AW?ajlG_^ zhW9S%*?X@ma!A0D_p&2;@rxibTuq`|t)p5&t5ja|{=<+_&D)(1d9pfqcgkJ=9jXai zrZT9eyw!BIN?uZL=7>@+%pJ{vkJ`uorjfIA)_DE!L>w5G?SX-V<}Z-yVgVn5n;*D{ zW*Zi~$H4*zbmN(f;z4hWA;6K|bdbvgF$LWqM2@r&Abi^qJ_x#di_h-Yz)cH5br4Pk z$z#{l=;k51F>o=?ZgIX1tNw8fO^kf9n#HJ zx@aK!@Lb$=z)kPIUa+Fa9P?Nf=TmDCe3~>1p;KvWvAL)d7NlGLk@#<)3nwNgV-Dfv+k~CyIhJ!`QH$jf%9xLAtoP5*^MVN}YJ` zXa1^&)Kg_ePMjb5rlvi^&dJXi2*G5LH=X9qh|lWpzfvE#ovu!|AY+&xVa$x;jNmqW z6rrYUvb3u}W*8>U8JqgmR@||j6-pZ6R6lKMf=Q1EhdTZ<``L!vTD1Jc(==X{C4zV|-lLJr-q5N*{F8ST6rn9>uu zHB~3RFGN6WcQ!fJJo@mj;nDNNtW~?;*zDZUQc%!BmI0#_L3l*#(q2JBIo~B!Sb2_E zmlB`)A9l{XM>)?>SQ4qB;rNqXlDth97qol-+UOEjS!g@M0%*5AxCwNZ_y_pKu_^w( zwryXCy3j6vw9HI&s=I935*d5WKXu8wRW^CE$3kbWV6&>deZjl%Qzbb}*oZI?X?{Pz z9pBWqc;GK%?J1M%DPt{!Qezt)mTX<~bsAPGlB?|VP}w@r9QPoF9SiDrh9$qLN>FG@ zP~6^JseBjl{hAxLK*=rf?G~yba#}fj)~TM&DjZv;49g zJ>iXk`R;AVv6aH!iLm#=IZor@5k_DWw7h+*4=Ki*84CinHsi3V`4ZHVqfNEwE6HAj zCtm%}UZ6eY%Rm}Bu*-oGBJ#UyRG%}nB)~8H-~q$D|6PiR(a}-U*YCJ)KL4#C3`C8G zM<>t>=u*i<;uKJZw>efX{w_-g+89*%w5vN^5SL`)>Y@ulK_|m+6>$(Jp;vQPX#crh z5PNH9;@1+c8O%t4<{^27$Py?fjijaUA#e<4Jq# zP3NReaF%M$5D> zi0J3aghOH6Vk+5#PH^Qz8Uo}jU7qq=`D~7hLNUzn=qM`{@d8M`-XHSYbwNN|g3uJq zeM3J#AO@AL*q;OiDf5z5bYUuL+KWx?*1Wo6gsPD?AZrl?0{QXcR5VSHZ9R8&VdBTA z7z;9iLMRunFt0*QnPKD`g9Du6)!Fol_uit0Q493lLHAk0SO3j%wo`!@Z8kz5o*y7* z0eaQBZwR>_2@~vAW3#jQsT^FEwxzKaP!H4^&~j#jj`D#En>ttM`m%&HRE!ow-Wz}y zoq^0OPy9Gszx8g*e*#HA*qZERAhu9R;)y}8vh5g=^8 zmKIf7dDQAI6|p3P-7!Q=zE5D0NhfQet1mWI;kx#%dY!gJHe*csyQ;yl znW3(cnK()KP~h*XH`xyXk@YS<27_@o zMk`11475moHgfrX)=zt^jC%0;*a2Mj&?$D*ctD}Y%>m9Y@Vg*s89G*!t~Ac~QbIe? zR|A+A-{$rQY>ubKN1JIAlaek@&0R{_hCXG1qYA-qFhCX;HZ%9X5bT~_o;W$D`DE|e zAN<{kyExzx><2K?o7{;s?(W3qDU~(vi;Htk6l3LvV5!8@Xongr@&qFpn@pH*QOGEk zTe8NgE)~B_()E1P{)+1$pP?ufgxR&UOrDAE5Tsf_3acRx3JZ@E_%PeH-d#g> z8f4eYQOT3`Wx=c=3AHgVMYYFH!#h1DEmuso!I!eun~kXSw*&TTFuQ0^Cj?ACmR9`N zXHfL%)2HDgz9MLMg~-UZ&`T`^hq5mBwvqc|NKy^&;~N3!r*XU`R0*1BFaHW(QAm4E zE8o3)cXnV$7h*SHG`hYEm%|)BHd^H7eR(bm7F{f`-Kq9Z%bqOK9HvsT>i-155w~hg z-lc;`+)*qlE^cfi3Wz``poZb$@G$8fC9NeVX@{|K5q%cFyeN4z(XvS==d6~t9)eXw zDq0OB<-u!?=p4|k1|hMyUVXic${am)A)GB8p-xU)CD{*AD<0ic32g7TUbWeMt{g`V zo3>pJTB+n_TUJ!KyDu=U#(Z~8p(Oo+mD?6JZ-GD|0g>FThEnLp(gV}*F#CcQ8mSy6 z(icQS+ElaQiZJEm%p@C%;H%=7m)~~~p+^#9izsYHbu2)!sS1zG8=mVN+$IbL7ux~j z7gIA(FfO#|j|XcIGqg(xSbo5^X3uKBx@ft=gA&N-J~wbMb9qQHxPE_00tv`3C)XfH zty!irc?G;=`Ai1pAQDbdzjMIzHr;U zx;D=g`IfWbkl_1gq;MnbLpK^b1WnBbE+zShCd6wNpFox$3T>={8J7&MDUiB^cPuF1 z-{AZ9AU`RIK`9Xw#Y6wGJpiXQkca<2bW)!;!dT7`LMG`bDFy%DO+aZ#d=eB9UHC_f zfaI{iy)nPz>tsFj*~5-+Z0(b~ zH<0-n8^(av!s7anC2mM{rxv~gHO{h*I@boT+{Y?fJJnU5`Ch*+n@aj$C|t1J&1q3t zfqeF71Lg=i$22liu5T*erJVf5T>)8j`M*{R)cU$RRC;3|k&hK!y-Bp`rB=w&%2^uP{%C#Q1sK=T3oBdCF8 zYJ?=u4vrKB;|%YSF4eRw8H!HS%46%#zSsC~S6*ICo^6ZB#>;QjHC*4?{c+c#H!C7^Eiy7adB3mT128llYOq@v@8su9#P@EL#Et1K28g{1viLUnzZ9s%!DpX9#RU7 zkJOhYOxcH-tr$=B=~DRbOvE%;5a-!2#iDRH7awKi>apdObXzq$jx@v@|M8_${troM zhy8lk>!u6cPnu@jhU2iH?B|-O%dIN}$svy|iC}Edvi*MpTib1-Gy7P>i&^V3zQ6II zew-B_({}2Tk92b`#*e#rz5o7znzN+}%muT7`+{&JuneVzmX;`GE>D*B`V2xSXso?M zG`4Q$vg%NP%XxRRX3!CiI#BX=eeACk!A-cBVWQs!YQ4Q5kz}mteNZXOb+X#y*#joZ zdTf_?G(AbCbbepqJjZV7AC0a0RbhwB;c)s8V3S=52AyZOD?6c@*gAcH6ryXx;4_rh zm4^k+d*;y?8m#G1Q`0W_<>u+$4f%6MX#Y&PaTHkf7SS5t{KrSKhEa}SUf1SMxA=76 z2Mz^F>EL->>ksF~lFZf^Xg4;xy4S4Yw!`82h*{2EuGY9dh-QFt(MWG?Wf{hZcSwNX z*pwJe>n(KR`fz6#Q~TLP`^YJi!tmKmIRe|-5Vj^OVmh~c_lpqS-J0a282b$=ZJnK* zN04?@R6Qh>3o0gtbnEPOiu8HrCf$1SR2OZ#16J;cupb&LYQb}o%BCcy8rKLl2A&6B ziw8Nf7L8ao@#Wg9OY)$A9o465Sh#pv-tfjK_*`=B(WArq-)RZx6m&H#Ao*gdLjLpz zo-D)^8WQUAPEJ7s^{fI6d<$8hXJn4XHL`Bpm4eUBqE`07+$GfzyV6 zeB+&r@1dKA?9L$$^FVx%Jtx!qcdrAKGrS--DS(Og^#KsD{^(2vn^O zTXesD(Ma(Va@B|1s9Gr=Hr9eWADaI&pJGECZOMmK?-3*>L41&6@?M-y?#JKiPHNw` zD=wZ<^*jwE(AKFXAdpXXZ)mvIf$7$H@rr%si2ZlPZG_83OW)k7FSeQtV>h%+CSIH! zFTrugMZh6<^7HHT=5L1P$lYazsl83{(6;+ic5R83qz5d_${@XU9OCicT15zW+b}H@lWM{Ep$k(=ggy=NDeenLCmD1YR85C;!ZH{nvS6nkDKHR>WYr z+|?5Cnr(cU_GFE@VSJni0aq*Z(YZGM{mPH9FBRpDk7&7=N`V1$*6>d`7o7I_{r{iM z4NLE1nmeDPl>X1U;j-n$q`jWm!av(3$7 z#L+HEd-g{_T}53hNFH*YSarlG;)0)a2vvrcS>=yB74a!8?h!4dXBg@?Dkaw7*GlE! z@#eVRdj5DO@N{Bjujl$@gr)cw?`68T^2aHdc9(cbA8k8cqnJ{>d>xTpKb7$b!tg{@ zEW(VPHoANcRG+(m{E%U3$w|AD;m6Qy{MG3m88S(|z)<5+Q;u#VQu+Bc7^xv@UBgI3 zwoJ}ICeRIY;wc5}is)N8$FqSPFpAqW^~x~*bOBB&!luq z_h9Iy$@#y*P#i?#emfBaFMCYywlVm?#6$f~)s)9iy6s(%{fwZ<2B}5LjSs>9d^>(j z@g5Nrl>5qF1(oKl2s5WFaj^WuU);kzA2SFkf8fOf+NDT!_VB(q9nS05z1whTSZ%|$ zMwe2QlHqNMF6e$?<4@Oo(k1K&bm=d?i1T4C?mxsIWWHm{=qIMAA$jo0MI;pBvuj-c zSz})e#|65*kRr2r$M-@=R`ljA{F3sQ&jovnF3WV}iOUFlad@57Fj=V+7Tfm+JLiA! zQ0(ENRN2`b3O5kRPV+e zU6vnFLMr+9lh&gWRFaf(} zMko~x{F7my%e9VuACQuNIi@=0j1uP;RrI<;bwRx)J&% zfl4<}BzR%_gcsdM4Ay+~318g^VhFwHw@cM~OP-7xnjVk+G^*K~mdF;)nyt66*Td5B z>4EV463Z3#tk1F~P7B5|4=FeWpqh23Lyb%^cIA^tS0Y^=+WqP}D2w~T+LwS+ryc!+ z5I9YibC9~_*>d6EvE3oO0JD$iz+uP*uJJ*;>B&}-I(z-v8;D4)LELZI#X%y~okTaM zzR(~*fTXB!G4^&>I&`1FZ;1vKuV{`9|KxF0m6K|^=!))2T`?!!P?AR?cRkmB}S z`?o21p4g)4p@-&bhlY&8ken1rSuPyh$)`8Jl|?=vaEZfrsT8~=RvD3`7C^H}JBSKX z6_2Q+ZC%lH<)+_!h9)5=YUGDTCXz4C$Q*;&Bi}49pC9)+?QgtkcIoF2+D!Xd?C5T@ z&hLWSzM$@Hi`;h6mnZpKJBB&Q9Rp9!^ZrKMwiU6uAjRc@Jo6)$rBddfYZ8}-b~~`v z&@_Dc0>&ww>vn)LQ*;s8SymecyYws4u+d4Y6 z)ThzgA3xPDyiV6w)zXSdI=F+y@PU?zDT-4EejF`>Nn}5CrzR#PIr#cgAka^1!|5fs+?hzkyid zcfWP|^ayqm^svMj1phV3l5UZ>-_t;ATkD=#@w;r)$RpE=WQZEY#KpBep%kmnW63z~M)eOPW)P##BMeY7c{#%?Ps zDH(BL@r8({rj}?+5OeyD7%mOA?{`BiuR|ggebLHqb81Q(YP_pfUaISuyiF$*Qp^jUYqbX9**W1QpM|W6GfG$ zrJBkS@$z%z>C^p8yTCh5)xQgW1AD5-rCGZuY;yrNPk0^ta+<*oQ>!0F4$JLbkXkqZo45v%BRLN)$tS7>Oiz zT1uy-W6~0!Zwrr%*@H1*K1;U8e(i&cMS~x&`Cd69Kj_FZc!B6XoH)syX2KP_U484& zi$iXj)^{kim~_Sdu862 z-Nl3{1aH_h2g|~{!4pX}^VIj&bRFx)ZL_$zs)$;4Q6KGh zMsaaPJTl()EQ^Pa5cuswa3rJy6U_|*#v2|#UUZC$6U-;*5b`UFE4X>9GdDm;#gL0L zddfa6y$C^FMj-lqY+O%#|7DimVp)r48%$Eq^Bb^XW*pMHV`?V#!t%)sS5IxWyFZtT zp;THCPi#m47V1)M`{{KG?U_r09}RLh^>;-xBV$+V8ot2e=s(CmDCc8Jf^JD^et)#@ z_TZknTweG54_4zciJxo42v){q_@nysbs&@uWerJUmH81CvD&vqFgJqb;iRKDg*{JS z&4`EldO8w2Vj$W7W1XZLQoZ*>q91o;TpTA4kF#alh`CKtK+}eejO(`O`p%;$Q5l)o zwl)=oqwyu}w&TnD;d`yPxTnh>A&pi@vDj^AIb$_}zh4 zh_Dw^!RP*+ONX*? zeJ9w>2PKmkS?>V^>Ld%<#ZuU9jfC3+T?&A$(pvU5H!)jW4tzc=?Km{Hrp6-!&CQAs z9z&iZ^`IS8!`1F1<-CQ@aL4FHhlE@#yEm#@k}V`)c)oLI3UW2*&$p_a zPysBjJ2?qBWPOW16XB|aYBbvb?VIypV?w@PO{?-9tl@ zvC+{_5|iJie#bQ<@?~f8+~|Cs{jw8kCMh*kHiH;u;t1FZZuGEUG?RsC7EcE9lo|~3 zH=9rY2|{v;+zmKZ(1*bS7^^tIAym>hdE!qQ0w(XhEd+?^>}Xp9*h7682T@S(rXbi# zD=Io>Z+roFewa3AqMlU3!UDOVg#-PB2X%%qP#I7nfmD5_fA^X0TNPd;Vce?QeU%`q z8h8Ag_zexN1r_&k5fN5iXGn^;ZpXLRXg>%nmAv>=2*q<~G&!wL2c4IP{_yi}d`TU7 ztxIw!8p}3hXl5cEpB}3Tr6NT#e=->Q(_oFkx^0)lBDbFt?GzfsS4NEb3b1*QV!=`S5y1uZG!YD|vd*|KMTqF6IWn9vB zUV_eDX6~ZTG*WcEYEy>ypT?+@|4^7^R0zZuyyb&m6q}mLhVO`7?M8Ju+j_>zWkP%H z5yQI)8iFE3+xL?^Bo8VAm-A76$xUU|(m{#jG6EP9MMW`mzQP(Sy%&C5g<_2z|2thn zODmJO&=#^eGZO=KpO9$^v%_VWvsjd$W@eFg8fqa`w1e^qce;uURfOs_q>8e($xTLP zI;;|^2<0C?3{$$*vF^O2XNy*M{z!}*C;P>yeOmywCEBRz9NJG21 zuqB#TVL%L(YEJh@!OwEsTG>&(dsiNm#i`ny-v3-)MBrmDcwwgVrhg_H4_pSpvw=dpTPRjF~^z`g(FaOv!20EG2j{d9gJ3Kl<&y}z?H?e7y zNs7roYVyVSH4t>W`XMtD9WI*~HoG#CV>R1O9U-$Zkd*m+l_2^fs$qD@25ZBmbV1Hw zZnBK;wmVX6H0gc*TS9Bo2&Y-%mo)9aF<*b@rj-%Dd`S<`fr@~vk0>(9(fz9N zbFr(`HzAZVJ`s{*+bgoSm$g(NoNpjaFhG$U6-K2m;qLlWRyP_ZgT+^uYb-G2M8oRH zLx{tsEXCpA=fN0ux*-l-bb$)Vad8AoTcMncfJbWFd|3R1If0Ec9&SAjEH#;6XC&fT zrn8|gTRdii+$3u}`-cgEqs<#(&V2t(6dQ6Xg6OPiCTetkV)=_`L#dHvZP z(&Rf~toZe-MG5djP*tHzIpZLrMnGkGox|cd&PmtBv6HhiZQblqYFav_@}t2<(EJdS zkT{^fvQHj#@Jh2a>HfP2UA2!_+Fs=E+Z8`AY6)^RZxw&>ir`7P+v7~G?FYy+pr@g= zJ}XO)JyTZ=*>M!p@LrjjR7dgGcnHZOq5aSAc$9gFDJV$#12SWg-?M2%C5wMirI%-| zeQWgm!0B{6i$%-KtZ_W;^kZV^b}PLyOX|+!7eQybN#vF(d>#Fg;w7;jLCo#HQD=?p zM$Y;+gsApOg{KEDzJi-~#y@IG3^x3+nu85hvPi5aqX+HdJF0oLu)Dw^;}?h^G~1em zoR3&=C&Jo=cXqs^cK;?NKp_ck5~#{#sgIu|ic3C|#|1_n$!oCoi;=R>wa@Ry@<~23 zQ)TCmU;e6)I5gw~5(0-{_BcOHvqN{c(w^K2@gK93#Fo!RMYB7@u`Xo9WD+A|aG!m5 z9U7+9lFI4+MDwc0DResV?yJZ2XhpJZUVEH6{%`cJOOY`m+1i%QzK zjCgWV{{6!-PsVkn2;hAiFS~Q#z(~QZgot1*DEUnA=ui|Mz1T?^i2Z;eil-ziH@CC5 z7vDDYfxLg?AvfBRJTcK_)+iIqk*&8_*K#3Pl=@!Rqij8RG3^gOBv3rg>`{fe1_a;G zEot0%dAb3Ag}MZF7X$i*_Kx(7j1h9%S>bg4{_uIB5?&e5gcs9t_N7G)vT8%lmspn2 zHI0Z7+_C}J70b3m0%xb9O1FCn`Yw)(ch9e}a%bz&o2I7r>5exAuwWM{T1XXluwEfB zCtmzG@9Y!_p-D6#jA%2Zuc2m&fyP~qpd;ni5-W-pbvIN7G(^t2C*8dqUk4$3uMaXmdiw6a+JBE>f*G5!`I`B=R0IM7-Ul5EHJ+~X)6z4x!g>MN zOBE1-SPR;;#T>=>QR*W<^2&`-L)AW+ZoMDMn{kw>u+wd<*elEVG}s-6N4nkz4Tki- ztX3$YDl_d4d_%wn2m+Ec2J)~~o?mmWu|%xrj083^=P^Aftx5^!EB~?(7pLP~Ly=Y{ zLC>(1H8c?p`%Xc18Nu7UPgL;gRb|T!xQybOvWDU5g7o*KdY=rz#Fo6L(wWg+KYM-l-om~ttRB-!4-W1^r0lRScCgI&h zf`gsAB=ZE#O{B~<6UM1yt#53oNG=_hIXW$(U?U7Zo0{tu4n4dN2iyL*(ne-E>+|Zi zBJSP%f208DRY0?Z=ry{V5T1Ma@6{Du%h}A1ch@!Z`2@RjN3+B~krlp~lLMSyg{p_O z*6X*#mtOSs5xh2`d})z8f3jq1o}O$Jbulnwlti>Vlg+^EFxYfjL}jU?IyW1s>?99o z_;hwQhH~Y*m|TC^lRvLj%U!c-n&O838^NiR^3r*}*PY|FaPaGSSOjaHK0CjWofoIV zt9FHI!>_7*?z?mYT7wegS!WE!MHG~5R2U=qcDiLc|MjQ1-!A0rOwmX+@4b~=772pG z^A4r+8>ML@(DaP>t>N(X^>2mVWuWyj7-M6tJCch;ZXWZre zKDEzTL`DWP9Jy-nzR2+VfV!bh3a69Dw1A3f($|e2!&F)V)Lpy1Jfw##nqt|b_#_(a zXJV;fAc7kGm?^jrrvn#I$NIXh$d40tgw%w28SrD}JQr${Rk$I0w< za>b%J>OH!;Ed0B((XsL{QR7E-oXkPNM+B?=;B1pNSGt>9X-w(F6eGXlB zoztIZV!Qa3W;_80hjS00Pe?eJ0SBA~?0D0}Y9HwFB~OaG>y#KnlY^QJMRXC5Tdef+ zU9A}o|2QWfX$DI7*+vtyTl|cKY|MlU)z@Ev`lXwo$8X}x^^no&xu+Fe4rrqajyy2E9-?1N}OyyRFaqdXbx#35it>7lru1zSPAHuIY@7EnAN*^J_u6|Kj9ECFDv!Bxz{Stzy^U?W&v!D&PrI#`oWvesEs( z7=)XEu0mt`(9BHIQi@d=RFW+2$!&rj%G8Ls%;+kW%~_1@W32>q-q;6Q*DgI?I+TV@ zbtdvZt015L|5!9lOeoFw7iIXMbUJ3R(h|!E2|EcHd#d()>*a;py?f|7CU1yOTM&Qs z@48>WApco_Y6^Q*&wq6E^zBge;eBy9Rt$A}?95FO6}}j?B?FR~Hn{1mF5eHGEmh?t z35*f}@dfhYIv9>b-5%Wc@#+{1ETg0wx|AvNG3qK5s)@S(?d`UhMZzvAyE5+kPgp;BBlqfv1FP}KadWNoMtqN(&t=mXOA}LaXvAgc=tqkTQJf3-Y z^K&fYwN_BA?sYDOsw*(}04Np?Db``e26~(%Kg9szOLV1S?c$1AEpTmBlj|35Nrcl+ifF5xfxVtc7)D_z zluArVVc;w&WV@~s-?IT-KrHN(Mf~Mh{i(ZBA%j}`?$}m z>Z#D(Tu|>VCnqPPvj7QW2+uLo&-8v~m2m`+G+|<%nGjXPa{^X|#Gvhe)cyxst>9B( zBg8~|y5OVPD$=j_roR=+PuhWXKWJon~5gUKEIzvP&8?$l}PM*5yR5y*H%(b2EhU7Dq|bUuGK zT4!(!7(i3l(z?U)k7X$e(0PWmJ}US%nCUuD+&DUK#e3a8F=rTe78%7BAuuB<2c%FM zgsrsA~3WW&_#=@td}IK0gv(SWnomY2tjz#!SP)Sn@u;L?*nLp60PKB7S_ z#pAXrce>ty9*c^j-{pGT2^?xp zZtfm@ebWgXmYKn&L>m>zu_jd+Y|-^k)vWmUeDr)5ykqg!cAbPNauZKDWEo9J*8J$x z)6;1gUbSv`ZDSW)K6e$PTY43&O=Y&G!-G;U!Whz~{ZIr=?vV&urW^#0247yAcT0J5 z=67edJ~3>SFjgdzy+Cv*?9=TL|Np8*NyCxfy>G<9ipmqeetT?wGg&U-UEOEv5Eujp zjXkP;xR}lfAUUB+`JHj#krxn2mx2OZ~qWx+S}BuP!J*HJvD+A1d?a z4R`n=a;6Hs^{fsK1X`gtAt`7Fw3WwS<`(ALBGEBGkZ=PJ@v}@$>%ay1ioY{>rhnVJ zH71~BX7rt<$%oayzpNc8>{sk~Ccc82jx*VqkT*x=_5l0PIQj^&-8PSDXb5Yr#7gPo z($^_l*!RbI5~M#Z^#-B*{{EO^qJf@cpdW>rT1T&|i$vahOjgDV8NIk$-mT+o*yRgf z#&T?Y{P5!i)X2AnW-k~j@i;gJD9FcjUicBneocX`@_aW&N!iztxT^6WLRSo5<)H}& z#K0HDYJN|@Etek76CXYHU$xJO#y!3~9A!2gF({qX>|kXDX4S^#0g#nEjH=pHB$1D! z%A;r1zK|ips4LW;RuUAxsY;=DQCwl3S(B$q()1aSU73gD-&yuH-&jhzC`7r;z4Mjc zo9ci$IM8haHbEGOz330?a<1_kvuB~3GpVt0FcReX55opm(1 zIoPNORP3p>ji{VISc14dWqz&Y5(lm)#o5PuUC1sZxI>19f3HaAI6Vn_8B*|eL)aJa zCSafyfoe*&yIOWYw0?s4dT7iUkf5Mo z^o@ACG~)}qdiMfq={!Z)l;MIS*U@sT`1*4}k|orbx3=QHaXQhBsK?lN=K0z4?%w|4=vLP9QE;a$6AZ-w8(~QU&2- z(#DECF|p64S;YDzOheEW_4(GZ;!QQ}zc*czi>{JPr~$X^=uiV(H>}8zQD&IzPguiR z34JQUbc#$BADDAF`8)7}HgRJ7P^8EUTZdd8ynV+5l)0$VI2i_Aw5ix)F(LQqt`z}T>L z?`eavUm^b&=8rLsobT+M<+uk$JhaDNgWEIXH9^w0L0i`Ztn2a3?VgehD6Uvnu6KzF zg2JY<`P7{;XtTP0qw5g zhAjn|WK=Y-kzsqw<0Pr!ScV@gdtZuU8{Wxs?o6{x^mG0?!%d24MY})-=MH84{67^I zDniMU5Z~Vjq_Im=}aHnSstjzx2HeXFGQ2g$MaW~@~SRI zJB!8Pv5cd(rtCBxKBNRnI;T84_xoZy(SU~D*?&wdEImZRjj>?)VR-cDk@nr6Cl@g$qW#A23x|V|&cvOvEzVFR{wCT0V`srVry7jx5gx?~_2Zku>xz4KB3@*gDrg zO}*H1=Qs}{Qi!Pzamf83_{|)IU}@R z`&B3C#=-9he*~>Q&BOT73Hw{M=Zu`W71hik3Fgk`+tOhNK3I#0P5Th)t%;TTo$Kp2 z)jIjuC=d4&E#mM*TU-Jd<*Gd;X0+q_xkp{B*Zgq38b4DyY9F%x3JokxREc`Ce0)82 z38SJZ1xd}OISoeRBIWQ?>IvdkY2-n!Z4?xPUU+x;B~!Fmo>FPy;tmZ{p+PRdH@|-| z!;M!3?%}*u6M{bSiAarB--Z^}qRe+CclMrQv&h{*4-}uyQ6=e!@~!lAqizTu65M?K~W# zFoFK)-|A`3g3Pz*bEK~@TK;|aN<6&93E#zCsR6ltfp-=@bd#UY7RnNePwD~|AQkD$ z(LRVhTZmPV?=MEoQ~O?vR()Z(D_|8JdeRfxxj9k0BK5hp_8LgP+aX~dEiD7Z^%6XG zJx~P>0fxp_|Khdv-Vn$5(3e)7glN#Vp1FlOI#R5eQe+@*-HOoFvp)MPI(trJ1aY?ydTHU=EK3^nJYjM=jb68*^?iPo2qS5Bg;F}AjKOVX&?b=la#Kw>-n+XJgEHvd9vyTARr%p z`-k@ol%Hu!jK97Dl#-Vmk36RPQR9zQ&q3S8Xl@rFjsdAOh|>1KjSNn6ma69@ygM05D#CwV()r8<;mN|Psb?Pdbq z@apv7E$AZ(-ozdQe5coPAKJ9gUkQ3IUK-M3scky{kIAgkaiM`tST(b3(!`ibPcKoG zD$H4qNCjEGt9FM_EdU|+m{ol$K(6dA`HI|Ves;sK5xXNBS0$=*)*tTmuAN2%9x1b` zS|i4-q@-sqIB6NGoSdvwWigyAO<#T$aCUMZuy%So`*Mp@k#w-G+)@PU>M}ut7+}+fd9BLaM06KQHXM(O$>7HL!1`pLw#*!z`797Fijf^wvwFL%Uf^Oxnrx-@yGd)KRe0T*Ns zOJ{Q}WP^%l0-#He*5gh>-~GXhl&@Mph!4EWo}+yGLJ$HtfP|P!k-R@Te|fee{YP}p zyK>-~{bDJKeqeP~1m6e{Lfx+Fs@R>PZ|1Z^6qlun0I-ap=V1&s(e z7nb5-AOnQwO;n*2!-@CW&k}S~a?HX48xm9D?3*1R$v;MhFj?z#hMFG8KJB8i>^|w_ zxvPwZpziQZz2?H@b$HF0T#aB%{QVS-vt8i1;5%9*Jt~TI^SsC3<@kc? z&uvP6zZx%-xBDj{QE5wt&N%V&+t1}_$$9M)nd5#LUGr*iSZI&>Unod-j{L|R9$`o1 zZB9l_9!^!HhTo?;(DB8xkq>EOcW^irm>ync^f|wOcpRcE9`XuYx1L|NI09i$OloLo z4~gMO#ZSI*WPzTcMr?~dz`U?IRcD?MfT_ow4rMgL57`~=@@hP7I=jOk?|2q4GyBHV z6VxuwmS!8ecg3{t`737_J9E(u#p-IRv5`-_b548=J>j6~P|6Q=;D4UqOw3Zhp!qG^ zBuMTI#!|jAg|*k|yMKhMdTtzt5Vf5Cse1ot<2Im!!50j3t)0I)g&KGB%#t2wkiiY6 z<>gh?XEJ8=SFS+&Q6*u}g)aB?!d}bHB64D`U&tur`bLw2+O2DK&M)a-j6}EU)b{iA zjAv!JdepIr=9!qNwMB^CDKNws^mt5A)l^N1N&fyIQM|nA8CTTRu>p?9w%}ot*=GbB zC;N5Yp((*(tLG`S0^y_g_=0senpb2a!kMaATj z-QF>S*iln1y$fgMRSIBd_V)G&w9_=HZWXcvdcaJW!Y|a4i?>IF=AZ%6qYDjL=LLeh z>Fkt5CyEkSsKR8IC?0%}T>D*^GbL#fli4)%yUgsQ-oW(4QLo;8O|51Z=YIHiE zvkx$D0Lt>)t-PAT|MUxYbiJ^Sc>a9!Wyo3ZFl&n3(NHW7QF2$y)l^HN5OqiB)$!GQ z6pgL2R8H58JhJ)I<2l1$zdH&0Ny951nlWWK!i;!P$lcnw{khGi)hzGr$>#Lh z*5@rtcA-}umW%AXKG(Taq_S_^xM4_zvqVX`x|W?{VWVf|NN9w7mg$23ob`o?$+&fV zQm|s&TXVAr=QBnWJ2}3pHrMM6`f|n+R`zDir4Ik7;v;mzoczwYIWeiR*e7+G*wN)Nv>?^Y17NYZ>4_=!_%{w~Lb!62lPE-2wvAB{9Sd-HmjEbVx`uLwAF8gM_q54c*-#9fBf)V8DC% z{?>cfV$Fho=5pgX=j^lh=XtJSIiv|wnS5wCfB@+;fV6XuKTPwE`u^%wPr_r9x@;A) zR}X{#0Mpx}=c(pG%?|($pqQs505%*;Al*>z(Za@;&3~!Fm7kteST=76L`FlkFt6PY zxoOrF3p?~etB&^sm>HOT)eK0vg7)lgS_j{*@nd6Iz@L=#+pw`rMKJp@yVnJTntv&d zEDtMTLeCPfA+6(9UFooUWxe3=@V9)3RcK|pQ@yGEM3oX{Eu(_XZZ}z!zilX@Lj4o8Ep|@w#r!VK{@-!9|v!j@yPYSCah-BTq_sabJS@95=X|@*S`})c(&uea! zHJ360*6%S;G1RjW1Gr1_OEq$F43jS(cR3p^Z~%CWyk1DsOOC34__fni#O90_7`*Q<#pyK$ zXOv%LV=$YuypToHVf{;}=!V>L4?KAOngh{^&&Ee&CIT17U!_!|(oL1p_b>tL@K0eut}emvpcHs88gb2#d7E6ciMsbntGs zIAyxuALhP!3}{qOGCk9X1*bMKge(+}J^5bbMh*xn`fu(d`&}lz0*Lzas18=~CHd0r zSUA(N#<7HV9T4-isl{`okKSkHHJ z!x;E`C;6z2e_x>!mP@f7!HuMk(Evu!0bKslo2^lWlrB{2PFlxV2>l5RO*i7Q3v7s&=IHSUZ0G+J22# z?+?LzyR|gFi0Rc#4BZ2FU!1QHSQrGotr%G9J$vnuTovxjidY%~fiFdVN2et1k0EZK zZn9^NF=c-Hj7R7^Wlz2l?R@5*gfyYhBmsg0QGl7)uzbaL2ZR!{ltBg#t|QUI_l_W9rWn?1nz^W|QZ z(9+Ku50HmAl;78y#sqHxVI06rZUtm&{Li{TsT`e`)3I7Lp6PD+xDM51uBmkE;MB2< z>Ny)B>t8vHXa3I>4Ql7W!dknO_yy4BItSFkwB6p%rpNYDWMAB{J>F8sBz^x_!H$Vb z<;qgZax;X@0_tbLj_I1M1mT9u@@~pO%SGIdvDb`p0C_>q5*VZaks4^40?-C;XpR*< zwbAOhCxJ+#QrV(;{9Y>bBMe;I=(|zIc<9ZaN_3sQ=V(ez-8Z|iVC~WMH?!w2CZK+z z=%4}46S%x?TRE^Rr*pY%cmgK|46VQ}wCUB^S#gr-mLp(k8>S5)dGWcOG}ELBEt9Kf z;qW}Z#A~OgyRWFmCkRkLhpZAMqqZNu5c-{zWj4HfxNllfYWet)yr2zG)@W7~%Dlj- zD03k>sW}Vw5~*u+HQGt?lH-Y#nc7lv61av1vQTIN!4;I51lAZZjS7;TS;*=wx@S6; zx`9M+I+C9}L}3|iQ{E~9>jq%f)$mQa$6Xb>@AkIzlqMR@l*YwgMPSGLfe0@#E?g_- z=0@-9`a7lEsJo6aMFo%dwj8*bIc{!g*g2*rOA#`TakPcYr0pZM?4S3$V(rUaIzR6M5Wj&T*>mBh@zv^%4V82b$*$ zqLyzddzR5c*?kIG(RO`h@5a*YE#NokYS~UcnRYR^1*s__PqY@wt3lFkm!&r3pPhKZ zHcMIVm2l2>DH8r27+bUnIyk%!)qfp86~+#X;(LN!sXwIP2aMzgO-1yUBZoYG60<`u!L??N@smSmW!0`W>!f$=TfxAKk1H&xqxeHe(-$|T7pGo|!YECG z1MKvophX^*Qk!uaEp;?QAd;h!@6yx|bmRmHIYTM`x%07r|CeDLcW9W+1b@a*WVL`K zywiXrJ{~{8KTS(11w(TJvyw^UwZi%KcA_TJslPU)!JMgw7UO^bRU3C&hc1Y3+t5 zVYGAuqT?kFo8_$gaHy89i zVl=J6Pw5SrRRQaf+(1d8&L%_y28>BSRRR28MCokWK!>lykdVUW64H1aRK+Jzs3=ul zLx*8mMpE8_+{RKiI-R&~Rug@it|Lu&u&T?hm%2bd@(@73nx;>O$t05kd!B$#7tnoQ zeA;Y7Pj1l%b${&&$l1!o?(8<=}!T%j;x|rJyj(Cn69A0FU>8 z;kF-0ygO*=162z9NusG1zTZ)`PlJ5LeXL8{zSBNm0j$Qeqw}e)=|Aw$OuqR;Q7|(A z$4W)ROHgI3RRRRRTiW(aC-Wd2kDy$z1m6DUVK!Y@)*l#0+U`i7smKA+3Q*PJ+J4{A za}P7zy1z3Fsn-yNDxR#dwjM=r(ewn`d?mMq%Fmhp_ zXh4nt0y)cHo9D3E(A9RiCn*;oNN}|Lw$=UUa8wgLAaUOM%MQ%$+?EWFfE9bon%osW zU}Nw);nz0e&wj*&g8&y2unE9u_B!2w0dP_Ro2VhxO)R5LqfS{;_e&Y90)j*Cj{%WS zp40MHR(olT(bUu}QPoft$0-?IO>|BLM=b}S;kL2++(1kDNwqNnAB+pGaMoaR=JRQ_ zjWCsXPsDRn*0Xs6QS|MNJJDAmHK1hH{;YIgYddoSqb>$l-s2rjVERQbjc z1*28zt_MTr5BpJhZbU!5n{Y6jEcxMz&~Iwo?6xYK;kzo$as=WdIcL~{S(KQB95wZ# zG%zUvOr)U1;mgmz>Hx)}fQ)Ll?a%KxX=flI`0$3%=kC~*ICflL5N zRj3hWV>k72b&lle>sCJ9fPrtIaU>J}UxQ-wWP5DJS!WfJn2#i0-!HaWYqf|ZC+Vrv zvVKfjM=)@hSoUk$KuTt-F`&UFeCZmCZ#1qyd3G$g>uhqO&;B?!tT72C zd&(?Yn;ak|+~-WwtENUSGuH3l+yGFGH5ly+QmH?A+_`Z$6X_LdXzhyB$QDNths|f^ zBbHlxV(htM0M;0=pKj}>Cpo8i`|_J0H79mRG^cT(2k4|St`_P&5WuB&RgrLz*X@zL z@R9vWLNgXa{?*Y%n5f9uBc+jW%kL!_jjseVR6#7C!|5I1$QJPV>NlRoihVfpy@|^z zP{INCs}gn}K#X%Arg;c^IVDn39*+FK-2Ug(uzo#bQ{OgAS&#ZR}^KCK` zW;QsCHzCp!tt?aMms+_^Fe$iA$?*oQps=Om_^f!Q_YF_(R4=C{Jsf%J_QOH>O0e!Q z-K*Jn%YX$F%a%mG_qkXoeKm3+6}z)k`%Tren){>5^1<>m<|ream|Wi%1Oy3M7NaSt z4c4Pj(v!0YVlu1E%+EX2s%8U7Yj8?wCm(A>VOJLw5CFz+Kdr7QPg9-#i4@p!qAkm! z5afu`Bsn2yFRcHk_XDnL$$coCkDqefY_U99=_GY25Br3Tc+I%0TOUZZBB6!x zdXLBD{pUkfjNXAHU7`UL26|>iyfAzB6&6N+lZVsNft2z`$aiEN4HlLnx8>z7@gt%V z$e9cWF2-Ln1Jd^=|0}lve7fGQt!o}NrE1Iyy4O>x<)qa>D@Ps^j!Xvy(QeO1m#*|H zllDSLMXyUns#xZzDQ``yJoT{hwZuR-Z)3V3(No!v_@$X2nO||ZGchl;VJIp;cZ@co ztWvmV&@rQ#Sjyv>1Yxu*t6*z2vPQ@{eut!|X_T`38geOE%yWi0)3*Nf>>A5Jq%|C5 ztJ9Mk?(XbVntFMATYM>&_d7hPaPcSUy}iW%NVty#Rg<9W#k?e7oTrdNK=CU*b+sI| zZt0ab%n+S7)Ox)%88Qk2vZ=plb6sHU?(__Ir)yLBw&t0=Sx`iH8WM|PwC(a**r$!J z#bLY@hRr!Egc zf&;oNw$#6>p5X`TKidGeLOAXx0Lb~&?a9XTd0zzpRdPQj`70uqo2v+1|4RMS^hV(D z%9pZ6;x(0TKFK7`K@RL*EPHZ7m{1kGe9H-*OIpOIZaVALUYOTurAY9+4o^)suXj>3dX!xM43)17qWA~L(W{fnkAxC5g0eA2Knh^$wV8)AijZvOD*-(NC|lM za^w~5*j&4><;p)=dw|i=!vURBPj|P{&5gPaTUw=jey9VoS05v$FIdV?=KUgd0Yim$ z^nmKrnD@w`LJWs*Oq?4PHE*GP!KqmwLiY=Qz%}D%Y{aNl=2`i?QbsUUT92sHG;#JYFBPw>HEajjjg&Qj!B9%vmv+ zc0w%oW276OwX^5^2tBz@h3L*A+56Az*kqfPpcsaP(++BoMG}lz8O(9zpjZ|LHJ9J7 zG5$Lbf&@#AU<5QI-gC8#Rl9$wG;NQ&2{knWDQ{w#|7Ifq@lf@A(0qgNw<#G!>$rJ_SyCR?3NmxrNHI~W!XT_gK+B8*L6gW zqrz)G49r5_^%B<1zOMS~9<)q$tkl4f{zN$V{XKg~mWo9cbf=2U(MfB9GTl8$dGX^q z!8|jA1^CBG3b__oyV>?cF+sur8{1obTy-5`vaHwA zfEoo~VT5-<72v`+MM(eDi=>_9dkpreCxhP96Ins&i^MpAP|2^JBS%r$hB(#U`hyZ#&b5trkDtr^;JXZ`1nRy@8|1Ru-*+N^LhbZhs5e_2#tut5)7s zc%Q!aGbsKwY@F?+(0>hRXR}-CXyfu4MH&-zVc^&U%h*=Sv8uuE1NTvf{2>Q!#~%mK$H{IGH8VyI;a z&M}>zCX!6zD{INhC1YvlfzC(;RcikMgCJ0WB zM!KonQOPK)2|q=|inZ-Alg@sSWMMU8vRx-r>G`Bk)fH zgOB6=Lg^tI&+qh{eccjH4aZ%@{F+i?+nshCrVAVHYLf+s(86?HV^>DG{9QSHA%s__ zV?oY*3RMFw(w$o+yPZ`}b{C@XbFq+MXu~GiANUm+T9Ev?9&-2bRh*7s|-NmK+~K z?7_soQ3?*^O=u%V-@%5naoaR-_+rb8nw$d#g|O;1BCNTQ?tVAm(0Tgzmv3i@lBJfJ zacT~~GRMkNDR~t_`Q;#(Jds(yy?c}`2lyk zo@~S??T^Iyr>dBiva9V6wBisptaZfh(pjD|&DO+~L=37j?&^I&k?k)a4o~Y`&x#<$ zN#%%%lLemY?!=AT$^$d)s}&mT_tD^D#jwP|qsRMMiKp_g;AE3JqRE*iZK)-XgRT*v zMLb*`*{aWc`FyzU^2d-(2Vs;8!o8Qe3nJ`i_f;Lw!=g#CF%=xC`(^HoH&=Zu2`~Q> z%H1fuBqBue*V%cs0Y(GODAn<-Hh7=^_32hZ?mlvqAfn}j9-}Y}oAYhFZipnNtzEEFff5PG<+f;hZemZn$%>L~J1RTG(s zqt;7ftCV90yptJtOez*n^?JI7D$R&2jJ@RQjnwk*%Z3+xE?%nwy@p|7e<6j`-);6U zY!qZRg-^{+jno{}_T?Vj7>R$27R@-rH`r2180{VDN5)RQ_0Sa9>QX?CCj$Y&m;;Wq zW%-rr91ocz|EmIyY4EJH#IB4e&om83Eu3F{gDDC0?y50ii!5#lX&SMm$lCe?H~VVi z7zGs)Ia$kp0>ogHxSvQh1p{v$l-9O;p(;d)DGZTOgK`_gouXLwJc&r$^GkG6)_i5R zsX`rW<~&ZKpa+{IPK{kjxicbGR+H=3P;5w_ib*ZK>$YfxqG1ISQj2w1=kY=T2Mjws zOJ^XfWLM@{_i6D@s(25guwoZgnBcqjq*>;O--1q7DXBRc>_%NAJl04{<9?X3fowla z{pZO^uDu@RZdDkPN4+54ZBV*96^*LVm?v;G6@!_nL!i3ao`@)B=khB%1_grg`Re+2 zM&<>qfCVUGwhNs?^VQb~WX_O34i+$J6zom+su1@8rxpu$$gjzz(L{dztUPIe_VGyH zQ7gv&duWBDp!4!vUMb5Gf9F2L7e@u#T3$v(g+2;HrL=1G5UH^}289Vkt7@<}5`$AA zgP&9y%A0eY_Xs^*IJ6!2o8x|j`If#-^pSvLPx`u^E~_Zzy_y_4xnTWv!}ptkxgdq8 z_vgChwY7@}XqXvfTo9QADwbM9t6-&WiA+u=5)fDbfWrC#?9|jY;aAgA50V9Hyfq$+ zX;fS<9mj&)Se#Wq4QUD{*m$FUm4(Gg44FYTC$phg3`(rptbpFU6-bE%2bM5_=1IPfflUx$;rQmZt6~7SZKfQM&yzZT2shP7@dDN9+tgCVVsE z49XZ2Y<_m4uoD&eL4v12sQ7$g@LHZyW^I-7x~mEx%>OL6-2`N*E=)v_A98%dgoiUb zo+T=Tdc;D#2<(a+pRJ>6;#oX=mVDgEoss;2CA{fH3}|09k`e?7Kf)gf)Rog#Zo8k9 zvI@SzegkD+0ByD8#V#PtaM%?bEf?RpkG(Y0K1%_U7j$@qp~>`KbVny8vy(*1GB7N# ztp>ZV@NRdqXuLJO?`d+^CEXQ9Tbx?r_O#g6-R?ICm4Bu=G%A^XtX|Yy4J~@ zd3r{}4HI)kCnmQP&T~G*(CJLGIch<$&-1mlb@$zrQ~|K;#QQX988!Z5V(=h6U0e>C zU@AfLCe$^@P26soaogo%oqWT=&#z&>m41Be`mVnOgVcI&7PtOkVLs&FBFw}#=T}Wm z_AJBPEvX*ll|0(#w$tBLQCj)H+Xw=SfWc_eKkG7w`ZQ?)<=c&*?6uWaq?xE zbtrIbTvS|ddKMDaDn#mK7nI*JIi(${vVjdvdM`EK^pX@IIO>2?B`Nx$bf_%v8BwFz zArsTmN3A5_T!>_oBzLn$aHTOYU1dpgCE@N+m0vPJ3ty`Zez(YI{QS+zZ>4tv=5m0L z{&fFuw4uz)R0$9vPNn=cr<;Bg_EY;5{(W#rsB!7n73KET`A1XVsGOk+W#ufVC}oO* zc5)9!Y%~(itWWM7ak!bP=}&8aMra;*q-3G6YV}`?(ztMkh1EHk3O{vV@UQ-JKIA?T z3Xc_Lu$cds1XcvOOzF{K(~f8r)@g>6R(YJbs~GSXwVhiNqV>v9?sDT;%ws5T8!W8zGG)&zRK~Etg zRlXFip_tlV!I4dTD&{Mx4G|D`2Ik)ih881;$pU10-0iyadM59YPZmg|0rkpb_S3oO z22BMYW_p2024`N{v6bDGXSqDsbYS0hQEkWwO+ysaFP(=5zU*#)lpxESYuM`W;=r*fW$8R6vr@Kfv=<<)(TqkY-6!YewZy)=#Yl6yov1_%Km`alfoeTW0B$WDVou~F9XKvz;Zn!N-?{f zg|UxD&6pilarwc8yjsxnX8~KKIc1w5GzCk`BsD$D;)2)+WtGQ~i!&iasE}Hl@Q#I5 zP)%)Y&1|OVne!X4`KQ6PT!X7XH=^wkVfEZ-9;Y;4@+aS7WR$$1(1bLDQG{;(IOPVR z`TXj~zdmGY)yBc)@ApDP(HwLGI2RM00HsOd!{2kU#nJZ}+5=j;9T0ZpriVnG^=u9b zi9GlF^iYIXFh81Km3bpGGaC^@90tTCF=u_Y>ZSG+`%|_5of`gC56eG6;$bh@NSzK? zY196~4;_t@F{d}X+Gu-OM}j^*2P?IV-$?)DtTRf^ZoQ_$i17E#SALlsmltb37@x(i z2ju)18J3jx%LOXDXB59xJC^lCPS+(bKiN{#_$XL7b)cNsPbJKZ(_t8puw31z$i;>> z`YH!-6(YRIQdIDFiO51*4*>(1JYWj#AGu|QgcjCx6ESE?11^%|TV^pMDn4ET+>qiH z4gzQfFTWTnTFekca)^y}5$g%wEPV!BN_Mkqt0G70Fyg;g4NI}=OJY`<^)EWN0ViE? zP9ML;INWbF)$)SRK?Y2|$}chfPk$);khd$gqF*H#Ic+)`7pD@Qp=w0#!{NJJ+?w+q zrA&$nU$uyRlF92WsoqWvy14SxHVT)Cu7mSS_nFvBb@r#NPGVgb9Vz#VV-Brf$Zd={ zL_k0&hS)OTjenTqVPQ!lFb)(M`eVmfD|;{MRcA^IO~7aer16y&6p22>S_YcPGDBuT z#6)l447sC>X3s*UOR%FM00%5dHC|57I%F=-3xkWVF^MGS4~8c`jDgc*^n&iOl3-y) z<34~>9os9EM)%N}-7GGDm?BS;_;XT*+BC?U0^T{|E?7pe%SuYa@{o)v z4#L*}W=6iZMU&!E^Uy|6v|76a-_rQL{W%0k71Q@{-A8mUq=be7Ay2E%*a zgEU8=FHmBVfLNn~DMZ>zpZJDO3=c*sosn#B4-mVsAxec!5lQq`&R*m(Tt!9o_}-eR z2tP?yHdbCI1u6m>36yH`;B9k8Y7}hUIQ6}%g(=-S9?AE_#E$~RSh(23)nS%UWrKcw zmHC@peue3xJk<(EiSB`lB+6f~onxSY(0)q223%{vIGI^o66Uao8vys$~ z4L+`=p}<&bFJN?T0qApma45<(XQF}zkB3&umjfy>G`yar5rl&~S`sl6_d|Ed(q?U= znVPYQ<)^>A^4`m@syZLEsi8Q6%6eQ{;QSN49Sr{p8@Nv*O*Nl>3 z^3wDSX3wIyh#$cd5>-`IkuMR%0Dh&wkub6(u2PFSl~Y-bvuy5QDf3nL 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 Date: Fri, 15 Dec 2023 15:02:52 -0700 Subject: [PATCH 52/91] cpp docs: update note about doxygenclass and doxygenstruct being disabled Also move references inline --- docs/source/dev/cppapi/README.txt | 5 +++++ docs/source/dev/cppapi/api.rst | 3 +++ docs/source/dev/cppapi/index.rst | 13 ++++++++++++- docs/source/dev/cppapi/zrefs.rst | 8 -------- 4 files changed, 20 insertions(+), 9 deletions(-) delete mode 100644 docs/source/dev/cppapi/zrefs.rst diff --git a/docs/source/dev/cppapi/README.txt b/docs/source/dev/cppapi/README.txt index bb8b3a62a2..c623c166fb 100644 --- a/docs/source/dev/cppapi/README.txt +++ b/docs/source/dev/cppapi/README.txt @@ -1,3 +1,8 @@ 2023.12.15 ADP We don't currently run doxygen on RTD due to some configuration issues. So the doxygen content for the cpp was manually run and stored (really not ideal and should be fixed). + +doxygenclass and doygenstruct are commented out in the following places. When doxygen is working, turn these back on. +api.rst:8: .. doxygenclass:: fast::OpenFAST +index.rst:18: .. doxygenclass:: fast::fastInputs +index.rst:27: .. doxygenstruct:: fast::turbineDataType diff --git a/docs/source/dev/cppapi/api.rst b/docs/source/dev/cppapi/api.rst index 96fdff067b..c1313d08e5 100644 --- a/docs/source/dev/cppapi/api.rst +++ b/docs/source/dev/cppapi/api.rst @@ -4,6 +4,9 @@ C++ API Documentation OpenFAST -------- + +FIXME: **doxygenclass** is needed to render the class structure + .. .. doxygenclass:: fast::OpenFAST :members: diff --git a/docs/source/dev/cppapi/index.rst b/docs/source/dev/cppapi/index.rst index 2b6ba46af4..85d7d6e698 100644 --- a/docs/source/dev/cppapi/index.rst +++ b/docs/source/dev/cppapi/index.rst @@ -14,6 +14,8 @@ The C++ API is defined and implemented in the :class:`~fast::OpenFAST` class. An All inputs to the OpenFAST class are expected through an object of the :class:`fast::fastInputs`. +FIXME: **doxygenclass** is needed to render the :class:`fast::fastInputs` class structure + .. .. doxygenclass:: fast::fastInputs :members: @@ -23,6 +25,8 @@ All inputs to the OpenFAST class are expected through an object of the :class:`f The object of :class:`~fast::fastInputs` class is expected hold a struct vector of type :class:`~fast::turbineDataType` and size of the number of turbines in the simulation. +FIXME: **doxygenstruct** is needed to render the :class:`fast::turbineDataType` class structure + .. .. doxygenstruct:: fast::turbineDataType :members: @@ -98,7 +102,6 @@ OpenFAST uses different spatial meshes for the various modules :cite:`cpp-fastv8 :maxdepth: 1 api.rst - zrefs.rst Implementation @@ -206,3 +209,11 @@ The test for the implementation of the mapping procedure is as follows. OpenFAST :width: 100% Variation of torque using different number of actuator force nodes in `OpenFAST` for the same number of velocity nodes. + + + +References +---------- + +.. bibliography:: bibliography.bib + :labelprefix: cpp- diff --git a/docs/source/dev/cppapi/zrefs.rst b/docs/source/dev/cppapi/zrefs.rst deleted file mode 100644 index 3e5b907356..0000000000 --- a/docs/source/dev/cppapi/zrefs.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. only:: html - - References - ---------- - -.. bibliography:: bibliography.bib - :labelprefix: cpp- - From 2f7bd6f7df1f1404adf57b5f18ecdb25b66e867d Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 15 Dec 2023 15:53:40 -0700 Subject: [PATCH 53/91] OF: added `NumStateTimes` to registry for sizing arrays of state derived types --- .../openfast-library/src/FAST_Registry.txt | 120 +++++++++--------- modules/openfast-library/src/FAST_Types.f90 | 119 ++++++++--------- 2 files changed, 121 insertions(+), 118 deletions(-) diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index 07a57f7c18..ed586e5b11 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -68,6 +68,8 @@ param ^ - INTEGER SS_Indx_WS - 3 - "wind speed" - param ^ - INTEGER SS_Indx_RotSpeed - 4 - "rotor speed" - param ^ - INTEGER SS_Indx_Err - 5 - "err in the ss solve" - param ^ - INTEGER SS_Indx_Iter - 6 - "number of iterations" - +# Size of state derived type arrays +param ^ - INTEGER NumStateTimes - 4 - "size of arrays of state derived types (Continuous state type etc). (STATE_CURR, STATE_PRED, STATE_SAVED_CURR, STATE_SAVED_PRED)" - # ...... Data for VTK surface visualization ............................................................................ typedef ^ FAST_VTK_BLSurfaceType SiKi AirfoilCoords {:}{:}{:} - - "x,y coordinates for airfoil around each blade node on a blade (relative to reference)" - @@ -429,10 +431,10 @@ typedef ^ ^ DbKi InputTimes {:}{:} - - "Array of times associated with Input Arr typedef ^ ^ DbKi InputTimes_Saved {:}{:} - - "Backup Array of times associated with Input Array" # ..... ElastoDyn data ....................................................................................................... -typedef FAST ElastoDyn_Data ED_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ ED_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ ED_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ ED_OtherStateType OtherSt {4} - - "Other states" +typedef FAST ElastoDyn_Data ED_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ ED_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ ED_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ ED_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ ED_ParameterType p - - - "Parameters" typedef ^ ^ ED_InputType u - - - "System inputs" typedef ^ ^ ED_OutputType y - - - "System outputs" @@ -447,10 +449,10 @@ typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with # ..... ServoDyn data ....................................................................................................... -typedef FAST ServoDyn_Data SrvD_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ SrvD_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ SrvD_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ SrvD_OtherStateType OtherSt {4} - - "Other states" +typedef FAST ServoDyn_Data SrvD_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ SrvD_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ SrvD_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ SrvD_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ SrvD_ParameterType p - - - "Parameters" typedef ^ ^ SrvD_InputType u - - - "System inputs" typedef ^ ^ SrvD_OutputType y - - - "System outputs" @@ -464,10 +466,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... AeroDyn14 data ....................................................................................................... -typedef FAST AeroDyn14_Data AD14_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ AD14_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ AD14_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ AD14_OtherStateType OtherSt {4} - - "Other states" +typedef FAST AeroDyn14_Data AD14_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ AD14_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ AD14_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ AD14_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ AD14_ParameterType p - - - "Parameters" typedef ^ ^ AD14_InputType u - - - "System inputs" typedef ^ ^ AD14_OutputType y - - - "System outputs" @@ -478,10 +480,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... AeroDyn data ....................................................................................................... -typedef FAST AeroDyn_Data AD_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ AD_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ AD_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ AD_OtherStateType OtherSt {4} - - "Other states" +typedef FAST AeroDyn_Data AD_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ AD_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ AD_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ AD_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ AD_ParameterType p - - - "Parameters" typedef ^ ^ AD_InputType u - - - "System inputs" typedef ^ ^ AD_OutputType y - - - "System outputs" @@ -494,10 +496,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... ExtLoads data ....................................................................................................... -typedef FAST ExtLoads_Data ExtLd_ContinuousStateType x {2} - - "Continuous states" -typedef ^ ^ ExtLd_DiscreteStateType xd {2} - - "Discrete states" -typedef ^ ^ ExtLd_ConstraintStateType z {2} - - "Constraint states" -typedef ^ ^ ExtLd_OtherStateType OtherSt {2} - - "Other states" +typedef FAST ExtLoads_Data ExtLd_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ ExtLd_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ ExtLd_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ ExtLd_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ ExtLd_ParameterType p - - - "Parameters" typedef ^ ^ ExtLd_InputType u - - - "System inputs" typedef ^ ^ ExtLd_OutputType y - - - "System outputs" @@ -505,10 +507,10 @@ typedef ^ ^ ExtLd_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" # ..... InflowWind data ....................................................................................................... -typedef FAST InflowWind_Data InflowWind_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ InflowWind_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ InflowWind_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ InflowWind_OtherStateType OtherSt {4} - - "Other states" +typedef FAST InflowWind_Data InflowWind_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ InflowWind_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ InflowWind_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ InflowWind_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ InflowWind_ParameterType p - - - "Parameters" typedef ^ ^ InflowWind_InputType u - - - "System inputs" typedef ^ ^ InflowWind_OutputType y - - - "System outputs" @@ -532,10 +534,10 @@ typedef ^ ^ SC_DX_OutputType y - - - "System outputs" typedef ^ ^ SC_DX_ParameterType p - - - "System parameters" # ..... SubDyn data ....................................................................................................... -typedef FAST SubDyn_Data SD_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ SD_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ SD_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ SD_OtherStateType OtherSt {4} - - "Other states" +typedef FAST SubDyn_Data SD_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ SD_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ SD_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ SD_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ SD_ParameterType p - - - "Parameters" typedef ^ ^ SD_InputType u - - - "System inputs" typedef ^ ^ SD_OutputType y - - - "System outputs" @@ -548,10 +550,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... ExtPtfm data ....................................................................................................... -typedef FAST ExtPtfm_Data ExtPtfm_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ ExtPtfm_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ ExtPtfm_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ ExtPtfm_OtherStateType OtherSt {4} - - "Other states" +typedef FAST ExtPtfm_Data ExtPtfm_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ ExtPtfm_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ ExtPtfm_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ ExtPtfm_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ ExtPtfm_ParameterType p - - - "Parameters" typedef ^ ^ ExtPtfm_InputType u - - - "System inputs" typedef ^ ^ ExtPtfm_OutputType y - - - "System outputs" @@ -562,10 +564,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... SeaState data ....................................................................................................... -typedef FAST SeaState_Data SeaSt_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ SeaSt_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ SeaSt_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ SeaSt_OtherStateType OtherSt {4} - - "Other states" +typedef FAST SeaState_Data SeaSt_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ SeaSt_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ SeaSt_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ SeaSt_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ SeaSt_ParameterType p - - - "Parameters" typedef ^ ^ SeaSt_InputType u - - - "System inputs" typedef ^ ^ SeaSt_OutputType y - - - "System outputs" @@ -578,10 +580,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... HydroDyn data ....................................................................................................... -typedef FAST HydroDyn_Data HydroDyn_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ HydroDyn_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ HydroDyn_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ HydroDyn_OtherStateType OtherSt {4} - - "Other states" +typedef FAST HydroDyn_Data HydroDyn_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ HydroDyn_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ HydroDyn_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ HydroDyn_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ HydroDyn_ParameterType p - - - "Parameters" typedef ^ ^ HydroDyn_InputType u - - - "System inputs" typedef ^ ^ HydroDyn_OutputType y - - - "System outputs" @@ -594,10 +596,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... IceFloe data ....................................................................................................... -typedef FAST IceFloe_Data IceFloe_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ IceFloe_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ IceFloe_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ IceFloe_OtherStateType OtherSt {4} - - "Other states" +typedef FAST IceFloe_Data IceFloe_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ IceFloe_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ IceFloe_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ IceFloe_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ IceFloe_ParameterType p - - - "Parameters" typedef ^ ^ IceFloe_InputType u - - - "System inputs" typedef ^ ^ IceFloe_OutputType y - - - "System outputs" @@ -608,9 +610,9 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... MAP data ....................................................................................................... -typedef FAST MAP_Data MAP_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ MAP_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ MAP_ConstraintStateType z {4} - - "Constraint states" +typedef FAST MAP_Data MAP_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ MAP_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ MAP_ConstraintStateType z {NumStateTimes} - - "Constraint states" typedef ^ ^ MAP_OtherStateType OtherSt - - - "Other/optimization states" typedef ^ ^ MAP_ParameterType p - - - "Parameters" typedef ^ ^ MAP_InputType u - - - "System inputs" @@ -624,10 +626,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... FEAMooring data ....................................................................................................... -typedef FAST FEAMooring_Data FEAM_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ FEAM_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ FEAM_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ FEAM_OtherStateType OtherSt {4} - - "Other states" +typedef FAST FEAMooring_Data FEAM_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ FEAM_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ FEAM_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ FEAM_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ FEAM_ParameterType p - - - "Parameters" typedef ^ ^ FEAM_InputType u - - - "System inputs" typedef ^ ^ FEAM_OutputType y - - - "System outputs" @@ -638,10 +640,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... MoorDyn data ....................................................................................................... -typedef FAST MoorDyn_Data MD_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ MD_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ MD_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ MD_OtherStateType OtherSt {4} - - "Other states" +typedef FAST MoorDyn_Data MD_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ MD_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ MD_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ MD_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ MD_ParameterType p - - - "Parameters" typedef ^ ^ MD_InputType u - - - "System inputs" typedef ^ ^ MD_OutputType y - - - "System outputs" @@ -654,10 +656,10 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" typedef ^ ^ DbKi InputTimes_Saved {:} - - "Backup Array of times associated with Input Array" # ..... OrcaFlex data ....................................................................................................... -typedef FAST OrcaFlex_Data Orca_ContinuousStateType x {4} - - "Continuous states" -typedef ^ ^ Orca_DiscreteStateType xd {4} - - "Discrete states" -typedef ^ ^ Orca_ConstraintStateType z {4} - - "Constraint states" -typedef ^ ^ Orca_OtherStateType OtherSt {4} - - "Other states" +typedef FAST OrcaFlex_Data Orca_ContinuousStateType x {NumStateTimes} - - "Continuous states" +typedef ^ ^ Orca_DiscreteStateType xd {NumStateTimes} - - "Discrete states" +typedef ^ ^ Orca_ConstraintStateType z {NumStateTimes} - - "Constraint states" +typedef ^ ^ Orca_OtherStateType OtherSt {NumStateTimes} - - "Other states" typedef ^ ^ Orca_ParameterType p - - - "Parameters" typedef ^ ^ Orca_InputType u - - - "System inputs" typedef ^ ^ Orca_OutputType y - - - "System outputs" diff --git a/modules/openfast-library/src/FAST_Types.f90 b/modules/openfast-library/src/FAST_Types.f90 index 06aa8e9627..f404c8acea 100644 --- a/modules/openfast-library/src/FAST_Types.f90 +++ b/modules/openfast-library/src/FAST_Types.f90 @@ -81,6 +81,7 @@ MODULE FAST_Types INTEGER(IntKi), PUBLIC, PARAMETER :: SS_Indx_RotSpeed = 4 ! rotor speed [-] INTEGER(IntKi), PUBLIC, PARAMETER :: SS_Indx_Err = 5 ! err in the ss solve [-] INTEGER(IntKi), PUBLIC, PARAMETER :: SS_Indx_Iter = 6 ! number of iterations [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: NumStateTimes = 4 ! size of arrays of state derived types (Continuous state type etc). (STATE_CURR, STATE_PRED, STATE_SAVED_CURR, STATE_SAVED_PRED) [-] ! ========= FAST_VTK_BLSurfaceType ======= TYPE, PUBLIC :: FAST_VTK_BLSurfaceType REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: AirfoilCoords !< x,y coordinates for airfoil around each blade node on a blade (relative to reference) [-] @@ -427,10 +428,10 @@ MODULE FAST_Types ! ======================= ! ========= ElastoDyn_Data ======= TYPE, PUBLIC :: ElastoDyn_Data - TYPE(ED_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(ED_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(ED_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(ED_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(ED_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(ED_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(ED_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(ED_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(ED_ParameterType) :: p !< Parameters [-] TYPE(ED_InputType) :: u !< System inputs [-] TYPE(ED_OutputType) :: y !< System outputs [-] @@ -446,10 +447,10 @@ MODULE FAST_Types ! ======================= ! ========= ServoDyn_Data ======= TYPE, PUBLIC :: ServoDyn_Data - TYPE(SrvD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(SrvD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(SrvD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(SrvD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(SrvD_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(SrvD_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(SrvD_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(SrvD_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(SrvD_ParameterType) :: p !< Parameters [-] TYPE(SrvD_InputType) :: u !< System inputs [-] TYPE(SrvD_OutputType) :: y !< System outputs [-] @@ -465,10 +466,10 @@ MODULE FAST_Types ! ======================= ! ========= AeroDyn14_Data ======= TYPE, PUBLIC :: AeroDyn14_Data - TYPE(AD14_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(AD14_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(AD14_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(AD14_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(AD14_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(AD14_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(AD14_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(AD14_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(AD14_ParameterType) :: p !< Parameters [-] TYPE(AD14_InputType) :: u !< System inputs [-] TYPE(AD14_OutputType) :: y !< System outputs [-] @@ -481,10 +482,10 @@ MODULE FAST_Types ! ======================= ! ========= AeroDyn_Data ======= TYPE, PUBLIC :: AeroDyn_Data - TYPE(AD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(AD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(AD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(AD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(AD_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(AD_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(AD_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(AD_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(AD_ParameterType) :: p !< Parameters [-] TYPE(AD_InputType) :: u !< System inputs [-] TYPE(AD_OutputType) :: y !< System outputs [-] @@ -499,10 +500,10 @@ MODULE FAST_Types ! ======================= ! ========= ExtLoads_Data ======= TYPE, PUBLIC :: ExtLoads_Data - TYPE(ExtLd_ContinuousStateType) , DIMENSION(1:2) :: x !< Continuous states [-] - TYPE(ExtLd_DiscreteStateType) , DIMENSION(1:2) :: xd !< Discrete states [-] - TYPE(ExtLd_ConstraintStateType) , DIMENSION(1:2) :: z !< Constraint states [-] - TYPE(ExtLd_OtherStateType) , DIMENSION(1:2) :: OtherSt !< Other states [-] + TYPE(ExtLd_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(ExtLd_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(ExtLd_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(ExtLd_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(ExtLd_ParameterType) :: p !< Parameters [-] TYPE(ExtLd_InputType) :: u !< System inputs [-] TYPE(ExtLd_OutputType) :: y !< System outputs [-] @@ -512,10 +513,10 @@ MODULE FAST_Types ! ======================= ! ========= InflowWind_Data ======= TYPE, PUBLIC :: InflowWind_Data - TYPE(InflowWind_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(InflowWind_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(InflowWind_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(InflowWind_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(InflowWind_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(InflowWind_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(InflowWind_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(InflowWind_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(InflowWind_ParameterType) :: p !< Parameters [-] TYPE(InflowWind_InputType) :: u !< System inputs [-] TYPE(InflowWind_OutputType) :: y !< System outputs [-] @@ -545,10 +546,10 @@ MODULE FAST_Types ! ======================= ! ========= SubDyn_Data ======= TYPE, PUBLIC :: SubDyn_Data - TYPE(SD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(SD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(SD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(SD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(SD_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(SD_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(SD_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(SD_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(SD_ParameterType) :: p !< Parameters [-] TYPE(SD_InputType) :: u !< System inputs [-] TYPE(SD_OutputType) :: y !< System outputs [-] @@ -563,10 +564,10 @@ MODULE FAST_Types ! ======================= ! ========= ExtPtfm_Data ======= TYPE, PUBLIC :: ExtPtfm_Data - TYPE(ExtPtfm_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(ExtPtfm_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(ExtPtfm_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(ExtPtfm_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(ExtPtfm_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(ExtPtfm_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(ExtPtfm_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(ExtPtfm_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(ExtPtfm_ParameterType) :: p !< Parameters [-] TYPE(ExtPtfm_InputType) :: u !< System inputs [-] TYPE(ExtPtfm_OutputType) :: y !< System outputs [-] @@ -579,10 +580,10 @@ MODULE FAST_Types ! ======================= ! ========= SeaState_Data ======= TYPE, PUBLIC :: SeaState_Data - TYPE(SeaSt_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(SeaSt_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(SeaSt_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(SeaSt_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(SeaSt_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(SeaSt_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(SeaSt_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(SeaSt_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(SeaSt_ParameterType) :: p !< Parameters [-] TYPE(SeaSt_InputType) :: u !< System inputs [-] TYPE(SeaSt_OutputType) :: y !< System outputs [-] @@ -597,10 +598,10 @@ MODULE FAST_Types ! ======================= ! ========= HydroDyn_Data ======= TYPE, PUBLIC :: HydroDyn_Data - TYPE(HydroDyn_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(HydroDyn_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(HydroDyn_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(HydroDyn_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(HydroDyn_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(HydroDyn_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(HydroDyn_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(HydroDyn_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(HydroDyn_ParameterType) :: p !< Parameters [-] TYPE(HydroDyn_InputType) :: u !< System inputs [-] TYPE(HydroDyn_OutputType) :: y !< System outputs [-] @@ -615,10 +616,10 @@ MODULE FAST_Types ! ======================= ! ========= IceFloe_Data ======= TYPE, PUBLIC :: IceFloe_Data - TYPE(IceFloe_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(IceFloe_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(IceFloe_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(IceFloe_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(IceFloe_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(IceFloe_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(IceFloe_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(IceFloe_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(IceFloe_ParameterType) :: p !< Parameters [-] TYPE(IceFloe_InputType) :: u !< System inputs [-] TYPE(IceFloe_OutputType) :: y !< System outputs [-] @@ -631,9 +632,9 @@ MODULE FAST_Types ! ======================= ! ========= MAP_Data ======= TYPE, PUBLIC :: MAP_Data - TYPE(MAP_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(MAP_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(MAP_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] + TYPE(MAP_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(MAP_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(MAP_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] TYPE(MAP_OtherStateType) :: OtherSt !< Other/optimization states [-] TYPE(MAP_ParameterType) :: p !< Parameters [-] TYPE(MAP_InputType) :: u !< System inputs [-] @@ -649,10 +650,10 @@ MODULE FAST_Types ! ======================= ! ========= FEAMooring_Data ======= TYPE, PUBLIC :: FEAMooring_Data - TYPE(FEAM_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(FEAM_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(FEAM_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(FEAM_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(FEAM_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(FEAM_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(FEAM_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(FEAM_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(FEAM_ParameterType) :: p !< Parameters [-] TYPE(FEAM_InputType) :: u !< System inputs [-] TYPE(FEAM_OutputType) :: y !< System outputs [-] @@ -665,10 +666,10 @@ MODULE FAST_Types ! ======================= ! ========= MoorDyn_Data ======= TYPE, PUBLIC :: MoorDyn_Data - TYPE(MD_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(MD_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(MD_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(MD_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(MD_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(MD_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(MD_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(MD_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(MD_ParameterType) :: p !< Parameters [-] TYPE(MD_InputType) :: u !< System inputs [-] TYPE(MD_OutputType) :: y !< System outputs [-] @@ -683,10 +684,10 @@ MODULE FAST_Types ! ======================= ! ========= OrcaFlex_Data ======= TYPE, PUBLIC :: OrcaFlex_Data - TYPE(Orca_ContinuousStateType) , DIMENSION(1:4) :: x !< Continuous states [-] - TYPE(Orca_DiscreteStateType) , DIMENSION(1:4) :: xd !< Discrete states [-] - TYPE(Orca_ConstraintStateType) , DIMENSION(1:4) :: z !< Constraint states [-] - TYPE(Orca_OtherStateType) , DIMENSION(1:4) :: OtherSt !< Other states [-] + TYPE(Orca_ContinuousStateType) , DIMENSION(NumStateTimes) :: x !< Continuous states [-] + TYPE(Orca_DiscreteStateType) , DIMENSION(NumStateTimes) :: xd !< Discrete states [-] + TYPE(Orca_ConstraintStateType) , DIMENSION(NumStateTimes) :: z !< Constraint states [-] + TYPE(Orca_OtherStateType) , DIMENSION(NumStateTimes) :: OtherSt !< Other states [-] TYPE(Orca_ParameterType) :: p !< Parameters [-] TYPE(Orca_InputType) :: u !< System inputs [-] TYPE(Orca_OutputType) :: y !< System outputs [-] From bfbf791f1b505a5a4ec3ca35139e617a4cccc51a Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 15 Dec 2023 16:29:27 -0700 Subject: [PATCH 54/91] Update r-test pointer after PR #1932 merge --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index 169eb370ba..7709178aed 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 169eb370ba152e522c075bacc29c46676deb9e7d +Subproject commit 7709178aed58df8f5df3b86a41c275cbaac5f70e From 04202d921620ad99cb1dad8f039bda6e0236719e Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 18 Dec 2023 11:31:56 -0700 Subject: [PATCH 55/91] ExtLoads: fix name of module ExtLoads --- modules/openfast-library/src/FAST_Registry.txt | 2 +- modules/openfast-library/src/FAST_Types.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index ed586e5b11..3fe4204562 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -45,7 +45,7 @@ param ^ - INTEGER Module_ED - 4 - "ElastoDyn" - param ^ - INTEGER Module_BD - 5 - "BeamDyn" - param ^ - INTEGER Module_AD14 - 6 - "AeroDyn14" - param ^ - INTEGER Module_AD - 7 - "AeroDyn" - -param ^ - INTEGER Module_ExtLd - 8 - "AeroDyn" - +param ^ - INTEGER Module_ExtLd - 8 - "ExternalLoads" - param ^ - INTEGER Module_SrvD - 9 - "ServoDyn" - param ^ - INTEGER Module_SeaSt - 10 - "SeaState" - param ^ - INTEGER Module_HD - 11 - "HydroDyn" - diff --git a/modules/openfast-library/src/FAST_Types.f90 b/modules/openfast-library/src/FAST_Types.f90 index f404c8acea..42035af7e1 100644 --- a/modules/openfast-library/src/FAST_Types.f90 +++ b/modules/openfast-library/src/FAST_Types.f90 @@ -60,7 +60,7 @@ MODULE FAST_Types INTEGER(IntKi), PUBLIC, PARAMETER :: Module_BD = 5 ! BeamDyn [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_AD14 = 6 ! AeroDyn14 [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_AD = 7 ! AeroDyn [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ExtLd = 8 ! AeroDyn [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Module_ExtLd = 8 ! ExternalLoads [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SrvD = 9 ! ServoDyn [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_SeaSt = 10 ! SeaState [-] INTEGER(IntKi), PUBLIC, PARAMETER :: Module_HD = 11 ! HydroDyn [-] From f56dc4dcd1c2528d85776c863dcd5cb4953abaa4 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 18 Dec 2023 12:22:53 -0700 Subject: [PATCH 56/91] FAST_Subs: make call to WriteOutputToFile consistent Replace argument `m_FAST%t_global` with calculated `t_global` in `FAST_SUBS::FAST_WriteOutput` --- modules/openfast-library/src/FAST_Subs.f90 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 3042f91ca3..a17b91db9e 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -7492,7 +7492,7 @@ SUBROUTINE FAST_Solution(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, !---------------------------------------------------------------------------------------- !! Write outputs !---------------------------------------------------------------------------------------- - call FAST_WriteOutput(m_FAST%t_global, n_t_global_next, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & + call FAST_WriteOutput(t_initial, n_t_global_next, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -8037,10 +8037,10 @@ SUBROUTINE FAST_WriteOutput_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg ) END SUBROUTINE FAST_WriteOutput_T !---------------------------------------------------------------------------------------------------------------------------------- !> This routine writes the outputs at this timestep -SUBROUTINE FAST_WriteOutput(t_global, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & +SUBROUTINE FAST_WriteOutput(t_initial, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, ExtLd, IfW, ExtInfw, SC_DX, & SeaSt, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat, ErrMsg ) - REAL(DbKi), INTENT(IN ) :: t_global !< initial time + REAL(DbKi), INTENT(IN ) :: t_initial !< initial time INTEGER(IntKi), INTENT(IN ) :: n_t_global !< loop counter TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Parameters for the glue code @@ -8074,7 +8074,7 @@ SUBROUTINE FAST_WriteOutput(t_global, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD ! local variables INTEGER(IntKi) :: I, k ! generic loop counters - + REAL(DbKi) :: t_global ! this simulation time (m_FAST%t_global + p_FAST%dt) INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'FAST_WriteOutput' @@ -8083,11 +8083,12 @@ SUBROUTINE FAST_WriteOutput(t_global, n_t_global, p_FAST, y_FAST, m_FAST, ED, BD ErrStat = ErrID_None ErrMsg = "" + t_global = t_initial + n_t_global*p_FAST%DT !---------------------------------------------------------------------------------------- !! Check to see if we should output data this time step: !---------------------------------------------------------------------------------------- - CALL WriteOutputToFile(n_t_global, m_FAST%t_global, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & + CALL WriteOutputToFile(n_t_global, t_global, p_FAST, y_FAST, ED, BD, AD14, AD, IfW, ExtInfw, SeaSt, HD, SD, ExtPtfm, & SrvD, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) From a05657e99bc2708d5cfb843706639432218be5f5 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 18 Dec 2023 13:29:22 -0700 Subject: [PATCH 57/91] Add check on tower nodes for ExtInflow with CFD --- modules/openfast-library/src/FAST_Library.f90 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 2c8ce3a2a6..7da7bd732b 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -741,8 +741,11 @@ subroutine FAST_ExtInfw_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c IF (NumBl_c > 0) THEN NumBlElem_c = Turbine(iTurb)%AD%Input(1)%rotors(1)%BladeMotion(1)%Nnodes END IF -!FIXME: need some checks on this. If the Tower mesh is not initialized, this will be garbage - NumTwrElem_c = Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Nnodes + if (Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Committed) then + NumTwrElem_c = Turbine(iTurb)%AD%y%rotors(1)%TowerLoad%Nnodes + else + NumTwrElem_c = 0 + endif ELSE NumBl_c = 0 NumBlElem_c = 0 From b5d739ada4cf9f856367dec6acc60538e7addff4 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 19 Dec 2023 13:26:16 -0700 Subject: [PATCH 58/91] Pass Python_EXECUTABLE from main OF cmake to external pfunit cmake This allows pfunit to use the same interpreter found by the main OF cmake. NOTE: pfunit uses `PYTHON_EXECUTABLE` --- unit_tests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt index 2535d8fad4..e88875d0b2 100644 --- a/unit_tests/CMakeLists.txt +++ b/unit_tests/CMakeLists.txt @@ -41,6 +41,7 @@ ExternalProject_Add(pfunit CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/pfunit -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER} + -DPYTHON_EXECUTABLE=${Python_EXECUTABLE} -DROBUST=OFF BUILD_BYPRODUCTS ${PFUNIT_LIB_PATH} From 5f8f8d21b7eb296abbb1830051718ccede58661b Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 19 Dec 2023 14:08:38 -0700 Subject: [PATCH 59/91] pfunit: add check that python version is less than 3.12 --- unit_tests/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt index e88875d0b2..4a3b7e4d08 100644 --- a/unit_tests/CMakeLists.txt +++ b/unit_tests/CMakeLists.txt @@ -23,6 +23,15 @@ project(OpenFAST_UnitTest Fortran) include(CTest) +if(NOT ${Python_Interpreter_FOUND}) + message(FATAL_ERROR "CMake did not find a Python interpreter. Python is required for unit tests." ) +endif() +if (${Python_VERSION} VERSION_GREATER_EQUAL "3.12.0") + message(FATAL_ERROR "Unit testing with pfunit not currently possible with Python 3.12 or greater." ) +endif() + + + ### pfunit include(ExternalProject) From 7da964b6f71488c20a7d3fc523e109f09dc44083 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 19 Dec 2023 14:28:09 -0700 Subject: [PATCH 60/91] rc-3.5.2: add release notes --- docs/changelogs/3.5.2.md | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 docs/changelogs/3.5.2.md diff --git a/docs/changelogs/3.5.2.md b/docs/changelogs/3.5.2.md new file mode 100644 index 0000000000..bae421240d --- /dev/null +++ b/docs/changelogs/3.5.2.md @@ -0,0 +1,66 @@ +**Feature or improvement description** +Pull request to merge `rc-3.5.2` into `main` and create a tagged release for v3.5.2. + +See the milestone and project pages for additional information + + https://github.com/OpenFAST/openfast/milestone/12 + +Test results, if applicable +See GitHub Actions + +### Release checklist: +- [ ] Update the documentation version in docs/conf.py +- [ ] Update the versions in docs/source/user/api_change.rst +- [ ] Verify readthedocs builds correctly +- [ ] Create a tag in OpenFAST +- [ ] Create a merge commit in r-test and add a corresponding tag +- [ ] Compile executables for Windows builds + - [ ] FAST_SFunc.mexw64 + - [ ] OpenFAST-Simulink_x64.dll + - [ ] openfast_x64.exe + - [ ] DISCON.dll (x64) + - [ ] AeroDyn_Driver + - [ ] AeroDyn_Inflow_C_Binding + - [ ] BeamDyn_Driver + - [ ] HydroDyn_Driver + - [ ] HydroDyn_C_Binding (x64) + - [ ] InflowWind_Driver + - [ ] IfW_C_Binding (x64) + - [ ] MoorDyn_Driver + - [ ] FAST.Farm (x64) + +# Changelog + +## General + +### Build systems + +#1948 Pass Python_EXECUTABLE to pfunit, add error check on Python version + + +## Module changes + +### AeroDyn + +#1913 ADI: memory leak in ADI_UpdateStates + +### HydroDyn + +#1872 Fix segfault in HD when no outputs specified + + + +## Regression tests + +#1886 Update floating MHK case input files + + + +## Input file changes + +No input files change with this release, as this only includes minor bugfixes. + +Full list of changes: https://openfast.readthedocs.io/en/main/source/user/api_change.html + +Full input file sets: https://github.com/OpenFAST/r-test/tree/v3.5.2 (example input files from the regression testing) + From 225c23fdf675d798d3788e345be0dfebbea45815 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 19 Dec 2023 14:31:05 -0700 Subject: [PATCH 61/91] rc-3.5.2: rename release notes changelog --- docs/changelogs/{3.5.2.md => v3.5.2.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/changelogs/{3.5.2.md => v3.5.2.md} (100%) diff --git a/docs/changelogs/3.5.2.md b/docs/changelogs/v3.5.2.md similarity index 100% rename from docs/changelogs/3.5.2.md rename to docs/changelogs/v3.5.2.md From 5308d053d73966d4c469946961f09266128b2ef8 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 19 Dec 2023 14:37:33 -0700 Subject: [PATCH 62/91] update version info for 3.5.2 --- docs/conf.py | 2 +- docs/source/user/api_change.rst | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 021086c9c4..c917452dac 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -130,7 +130,7 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # The short X.Y version. version = u'3.5' # The full version, including alpha/beta/rc tags. -release = u'v3.5.1' +release = u'v3.5.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 267a5809fc..7a09d05257 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -9,10 +9,16 @@ The changes are tabulated according to the module input file, line number, and f The line number corresponds to the resulting line number after all changes are implemented. Thus, be sure to implement each in order so that subsequent line numbers are correct. +OpenFAST v3.5.1 to OpenFAST v3.5.2 +---------------------------------- + +No input file changes were made. + + OpenFAST v3.5.0 to OpenFAST v3.5.1 ---------------------------------- -No input files changes were made. Some input files now include additional +No input file changes were made. Some input files now include additional output channels: AeroDyn nodal outputs for another coordinate system, new MoorDyn output names (Connect changed to Point). From 8b07e41221c6892cbcb33bc75115eaf63924e203 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 19 Dec 2023 21:34:09 -0700 Subject: [PATCH 63/91] Option to turn off unit_tests from cmake --- CMakeLists.txt | 11 ++++++++--- docs/source/testing/unit_test.rst | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e41e2b7bb3..8f2b48a625 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,10 @@ endif() option(BUILD_TESTING "Build the testing tree." OFF) if(BUILD_TESTING) option(CODECOVERAGE "Enable infrastructure for measuring code coverage." OFF) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DUNIT_TEST") + option(BUILD_UNIT_TESTING "Enable unit testing" ON) + if(BUILD_UNIT_TESTING) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DUNIT_TEST") + endif() endif() # Setup Fortran Compiler options based on architecture/compiler @@ -276,8 +279,10 @@ if(BUILD_TESTING) add_subdirectory(reg_tests) # unit tests - if(NOT (${CMAKE_Fortran_COMPILER_ID} STREQUAL "Flang")) - add_subdirectory(unit_tests) + if(BUILD_UNIT_TESTING) + if(NOT (${CMAKE_Fortran_COMPILER_ID} STREQUAL "Flang")) + add_subdirectory(unit_tests) + endif() endif() endif() diff --git a/docs/source/testing/unit_test.rst b/docs/source/testing/unit_test.rst index 31c9cca58c..314cc04466 100644 --- a/docs/source/testing/unit_test.rst +++ b/docs/source/testing/unit_test.rst @@ -12,7 +12,8 @@ Unit testing in OpenFAST modules is accomplished through `pFUnit `__ structure. pFUnit is compiled along with OpenFAST through CMake when the CMake variable ``BUILD_TESTING`` is -turned on. +turned on (default off) and the CMake variable ``BUILD_UNIT_TESTING`` is on +(turned on by default when ``BUILD_TEST`` is on). The BeamDyn and NWTC Library modules contain some sample unit tests and should serve as a reference for future development and testing. @@ -21,7 +22,7 @@ Dependencies ------------ The following packages are required for unit testing: -- Python 3.7+ +- Python 3.7+, <3.12 - CMake - pFUnit - Included in OpenFAST repo through a git-submodule From 18faddf3a830e009daad22edfe5bd313174ef29e Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Thu, 28 Dec 2023 14:51:14 -0700 Subject: [PATCH 64/91] Revamped log file. Still needs runtime outputs --- modules/moordyn/src/MoorDyn.f90 | 221 ++++++++++++++++++++++----- modules/moordyn/src/MoorDyn_Line.f90 | 19 --- modules/moordyn/src/MoorDyn_Misc.f90 | 6 +- modules/moordyn/src/MoorDyn_Rod.f90 | 18 --- 4 files changed, 185 insertions(+), 79 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 6e3f63272f..c3279f4893 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -249,29 +249,29 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! ----------------------------------------------------------------- ! Read the primary MoorDyn input file, or copy from passed input - if (InitInp%UsePrimaryInputFile) then - ! Read the entire input file, minus any comment lines, into the FileInfo_In - ! data structure in memory for further processing. - call ProcessComFile( InitInp%FileName, FileInfo_In, ErrStat2, ErrMsg2 ) - CALL GetPath( InitInp%FileName, p%PriPath ) ! Input files will be relative to the path where the primary input file is located. - else - call NWTC_Library_CopyFileInfoType( InitInp%PassedPrimaryInputData, FileInfo_In, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - p%PriPath = "" - endif - if (Failed()) return; - - ! For diagnostic purposes, the following can be used to display the contents - ! of the FileInfo_In data structure. - !call Print_FileInfo_Struct( CU, FileInfo_In ) ! CU is the screen -- different number on different systems. + if (InitInp%UsePrimaryInputFile) then + ! Read the entire input file, minus any comment lines, into the FileInfo_In + ! data structure in memory for further processing. + call ProcessComFile( InitInp%FileName, FileInfo_In, ErrStat2, ErrMsg2 ) + CALL GetPath( InitInp%FileName, p%PriPath ) ! Input files will be relative to the path where the primary input file is located. + else + call NWTC_Library_CopyFileInfoType( InitInp%PassedPrimaryInputData, FileInfo_In, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + p%PriPath = "" + endif + if (Failed()) return; + + ! For diagnostic purposes, the following can be used to display the contents + ! of the FileInfo_In data structure. + !call Print_FileInfo_Struct( CU, FileInfo_In ) ! CU is the screen -- different number on different systems. ! Parse the FileInfo_In structure of data from the inputfile into the InitInp%InputFile structure -! CALL ParsePrimaryFileInfo_BuildModel( PriPath, InitInp, FileInfo_In, InputFileDat, p, m, UnEc, ErrStat2, ErrMsg2 ) -! if (Failed()) return; + ! CALL ParsePrimaryFileInfo_BuildModel( PriPath, InitInp, FileInfo_In, InputFileDat, p, m, UnEc, ErrStat2, ErrMsg2 ) + ! if (Failed()) return; -!NOTE: This could be split into a separate routine for easier to read code + !NOTE: This could be split into a separate routine for easier to read code !------------------------------------------------------------------------------------------------- ! Parsing of input file from the FileInfo_In data structure ! - FileInfo_Type is essentially a string array with some metadata. @@ -429,6 +429,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er END IF write(p%UnLog,'(A)', IOSTAT=ErrStat2) "MoorDyn v2 log file with output level "//TRIM(Num2LStr(p%writeLog)) write(p%UnLog,'(A)', IOSTAT=ErrStat2) "Note: options above the writeLog line in the input file will not be recorded." + write(p%UnLog,'(A)', IOSTAT=ErrStat2) " Input File Summary:" end if else if ( OptString == 'DTM') THEN read (OptValue,*) p%dtM0 @@ -468,8 +469,28 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er nOpts = nOpts + 1 Line = NextLine(i) + END DO + if (p%writeLog > 1) then + write(p%UnLog, '(A)' ) " - Options List:" + write(p%UnLog, '(A17,f12.4)') " dtm : ", p%dtM0 + write(p%UnLog, '(A17,f12.4)') " g : ", p%g + write(p%UnLog, '(A17,f12.4)') " rhoW : ", p%rhoW + write(p%UnLog, '(A17,A)' ) " Depth : ", DepthValue ! water depth input read in as a string to be processed by setupBathymetry + write(p%UnLog, '(A17,f12.4)') " kBot : ", p%kBot + write(p%UnLog, '(A17,f12.4)') " cBot : ", p%cBot + write(p%UnLog, '(A17,f12.4)') " dtIC : ", InputFileDat%dtIC + write(p%UnLog, '(A17,f12.4)') " TMaxIC : ", InputFileDat%TMaxIC + write(p%UnLog, '(A17,f12.4)') " CdScaleIC: ", InputFileDat%CdScaleIC + write(p%UnLog, '(A17,f12.4)') " threshIC : ", InputFileDat%threshIC + write(p%UnLog, '(A17,A)' ) " WaterKin : ", WaterKinValue + write(p%UnLog, '(A17,f12.4)') " dtOut : ", p%dtOut + write(p%UnLog, '(A17,f12.4)') " mu_kT : ", p%mu_kT + write(p%UnLog, '(A17,f12.4)') " mu_kA : ", p%mu_kA + write(p%UnLog, '(A17,f12.4)') " mc : ", p%mc + write(p%UnLog, '(A17,f12.4)') " cv : ", p%cv + end if else if (INDEX(Line, "OUTPUT") > 0) then ! if output header @@ -588,8 +609,8 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er Line = NextLine(i) Line = NextLine(i) - ! process each line - DO l = 1,p%nLineTypes + ! process each line + DO l = 1,p%nLineTypes !read into a line Line = NextLine(i) @@ -641,6 +662,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er read(tempStrings(2), *) m%LineTypeList(l)%BA_D else if (m%LineTypeList(l)%ElasticMod == 2) then ! case where there is no dynamic damping for viscoelastic model (will it work)? CALL WrScr("Warning, viscoelastic model being used with zero damping on the dynamic stiffness.") + if (p%writeLog > 0) then + write(p%UnLog,'(A)') "Warning, viscoelastic model being used with zero damping on the dynamic stiffness." + end if end if ! get the regular/static coefficient or relation in all cases (can be from a lookup table?) CALL getCoefficientOrCurve(tempStrings(1), m%LineTypeList(l)%BA, & @@ -658,16 +682,16 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er m%LineTypeList(l)%IdNum = l ! write lineType information to log file - if (p%writeLog > 1) then - write(p%UnLog, '(A12,A20)' ) " LineType"//trim(num2lstr(l))//":" - write(p%UnLog, '(A12,A20)' ) " name: ", m%LineTypeList(l)%name - write(p%UnLog, '(A12,f12.4)') " d : ", m%LineTypeList(l)%d - write(p%UnLog, '(A12,f12.4)') " w : ", m%LineTypeList(l)%w - write(p%UnLog, '(A12,f12.4)') " Cdn : ", m%LineTypeList(l)%Cdn - write(p%UnLog, '(A12,f12.4)') " Can : ", m%LineTypeList(l)%Can - write(p%UnLog, '(A12,f12.4)') " Cdt : ", m%LineTypeList(l)%Cdt - write(p%UnLog, '(A12,f12.4)') " Cat : ", m%LineTypeList(l)%Cat - end if + if (p%writeLog > 1) then + write(p%UnLog, '(A)' ) " - LineType"//trim(num2lstr(l))//":" + write(p%UnLog, '(A12,A)' ) " name: ", trim(m%LineTypeList(l)%name) + write(p%UnLog, '(A12,f12.4)') " d : ", m%LineTypeList(l)%d + write(p%UnLog, '(A12,f12.4)') " w : ", m%LineTypeList(l)%w + write(p%UnLog, '(A12,f12.4)') " Cdn : ", m%LineTypeList(l)%Cdn + write(p%UnLog, '(A12,f12.4)') " Can : ", m%LineTypeList(l)%Can + write(p%UnLog, '(A12,f12.4)') " Cdt : ", m%LineTypeList(l)%Cdt + write(p%UnLog, '(A12,f12.4)') " Cat : ", m%LineTypeList(l)%Cat + end if IF ( ErrStat2 /= ErrID_None ) THEN CALL SetErrStat( ErrID_Fatal, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -712,16 +736,16 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! specify IdNum of rod type for error checking m%RodTypeList(l)%IdNum = l - ! write lineType information to log file + ! write rodType information to log file if (p%writeLog > 1) then - write(p%UnLog, '(A12,A20)' ) " RodType"//trim(num2lstr(l))//":" - write(p%UnLog, '(A12,A20)' ) " name: ", m%RodTypeList(l)%name - write(p%UnLog, '(A12,f12.4)') " d : ", m%RodTypeList(l)%d - write(p%UnLog, '(A12,f12.4)') " w : ", m%RodTypeList(l)%w - write(p%UnLog, '(A12,f12.4)') " Cdn : ", m%RodTypeList(l)%Cdn - write(p%UnLog, '(A12,f12.4)') " Can : ", m%RodTypeList(l)%Can - write(p%UnLog, '(A12,f12.4)') " Cdt : ", m%RodTypeList(l)%CdEnd - write(p%UnLog, '(A12,f12.4)') " Cat : ", m%RodTypeList(l)%CaEnd + write(p%UnLog, '(A)' ) " - RodType"//trim(num2lstr(l))//":" + write(p%UnLog, '(A14,A)' ) " name: ", trim(m%RodTypeList(l)%name) + write(p%UnLog, '(A14,f12.4)') " d : ", m%RodTypeList(l)%d + write(p%UnLog, '(A14,f12.4)') " w : ", m%RodTypeList(l)%w + write(p%UnLog, '(A14,f12.4)') " Cdn : ", m%RodTypeList(l)%Cdn + write(p%UnLog, '(A14,f12.4)') " Can : ", m%RodTypeList(l)%Can + write(p%UnLog, '(A14,f12.4)') " CdEnd : ", m%RodTypeList(l)%CdEnd + write(p%UnLog, '(A14,f12.4)') " CaEnd : ", m%RodTypeList(l)%CaEnd end if IF ( ErrStat2 /= ErrID_None ) THEN @@ -818,6 +842,10 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL WrScr(' Unable to parse Body '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file.') ! Specific screen output because errors likely CALL WrScr(' Ensure row has all 13 columns needed in MDv2 input file (13th Dec 2021).') CALL SetErrStat( ErrID_Fatal, 'Failed to read bodies.' , ErrStat, ErrMsg, RoutineName ) + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ' Unable to parse Body '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file.' + write(p%UnLog,'(A)') ' Ensure row has all 13 columns needed in MDv2 input file (13th Dec 2021).' + end if CALL CleanUp() RETURN END IF @@ -893,6 +921,19 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL CleanUp() RETURN END IF + + ! write body information to log file + if (p%writeLog > 1) then + write(p%UnLog, '(A)' ) " - Body"//trim(num2lstr(l))//":" + write(p%UnLog, '(A14,I2)' ) " id : ", m%BodyList(l)%IdNum + write(p%UnLog, '(A14,A)' ) " attach: ", trim(tempString1) + write(p%UnLog, '(A14,f12.4)') " v : ", m%BodyList(l)%bodyV + write(p%UnLog, '(A14,f12.4)') " m : ", m%BodyList(l)%bodyM + write(p%UnLog, '(A14,A)' ) " I : ", trim(num2lstr(m%BodyList(l)%BodyI(1)))//", "//trim(num2lstr(m%BodyList(l)%BodyI(2)))//", "//trim(num2lstr(m%BodyList(l)%BodyI(3))) + write(p%UnLog, '(A14,A)' ) " rCG : ", trim(num2lstr(m%BodyList(l)%rCG(1)))//", "//trim(num2lstr(m%BodyList(l)%rCG(2)))//", "//trim(num2lstr(m%BodyList(l)%rCG(3))) + write(p%UnLog, '(A14,A)' ) " CdA : ", trim(num2lstr(m%BodyList(l)%BodyCdA(1)))//", "//trim(num2lstr(m%BodyList(l)%BodyCdA(2)))//", "//trim(num2lstr(m%BodyList(l)%BodyCdA(3)))//", "//trim(num2lstr(m%BodyList(l)%BodyCdA(4)))//", "//trim(num2lstr(m%BodyList(l)%BodyCdA(5)))//", "//trim(num2lstr(m%BodyList(l)%BodyCdA(6))) + write(p%UnLog, '(A14,A)' ) " Ca : ", trim(num2lstr(m%BodyList(l)%BodyCa(1)))//", "//trim(num2lstr(m%BodyList(l)%BodyCa(2)))//", "//trim(num2lstr(m%BodyList(l)%BodyCa(3)))//", "//trim(num2lstr(m%BodyList(l)%BodyCa(4)))//", "//trim(num2lstr(m%BodyList(l)%BodyCa(5)))//", "//trim(num2lstr(m%BodyList(l)%BodyCa(6))) + end if IF (wordy > 1) print *, "Set up body ", l, " of type ", m%BodyList(l)%typeNum @@ -1069,6 +1110,14 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! specify IdNum of line for error checking m%RodList(l)%IdNum = l + if (p%writeLog > 1) then + write(p%UnLog, '(A)' ) " - Rod"//trim(num2lstr(m%RodList(l)%IdNum))//":" + write(p%UnLog, '(A15,I2)' ) " ID : ", m%RodList(l)%IdNum + write(p%UnLog, '(A15,A)' ) " Type : ", trim(m%RodTypeList(m%RodList(l)%PropsIdNum)%name) + write(p%UnLog, '(A15,A)' ) " Attach : ", trim(tempString2) + write(p%UnLog, '(A15,I2)' ) " NumSegs: ", m%RodList(l)%N + end if + ! check for sequential IdNums IF ( m%RodList(l)%IdNum .NE. l ) THEN CALL SetErrStat( ErrID_Fatal, 'Line numbers must be sequential starting from 1.', ErrStat, ErrMsg, RoutineName ) @@ -1124,6 +1173,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er if ((INDEX(tempString4, "SEABED") > 0 ) .or. (INDEX(tempString4, "GROUND") > 0 ) .or. (INDEX(tempString4, "FLOOR") > 0 )) then ! if keyword used CALL WrScr('Point '//trim(Num2LStr(l))//' depth set to be on the seabed; finding z location based on depth/bathymetry') ! interpret the anchor depth value as a 'seabed' input + if (p%writeLog > 0) then + write(p%UnLog,'(A)') 'Point '//trim(Num2LStr(l))//' depth set to be on the seabed; finding z location based on depth/bathymetry' + end if CALL getDepthFromBathymetry(m%BathymetryGrid, m%BathGrid_Xs, m%BathGrid_Ys, tempArray(1), tempArray(2), depth, nvec) ! meaning the anchor should be at the depth of the local bathymetry tempArray(3) = -depth else ! if the anchor depth input isn't one of the supported keywords, @@ -1143,6 +1195,10 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL WrScr(' Unable to parse Point '//trim(Num2LStr(l))//' row in input file.') ! Specific screen output because errors likely CALL WrScr(' Ensure row has all 9 columns, including CdA and Ca.') ! to be caused by non-updated input file formats. CALL SetErrStat( ErrID_Fatal, 'Failed to read points.' , ErrStat, ErrMsg, RoutineName ) ! would be nice to specify which line <<<<<<<<< + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ' Unable to parse Point '//trim(Num2LStr(l))//' row in input file.' + write(p%UnLog,'(A)') ' Ensure row has all 9 columns, including CdA and Ca.' + end if CALL CleanUp() RETURN END IF @@ -1207,6 +1263,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er p%nCpldPoints(J) = p%nCpldPoints(J) + 1 ! increment counter for the appropriate turbine m%CpldPointIs(p%nCpldPoints(J),J) = l CALL WrScr(' added point '//TRIM(int2lstr(l))//' as fairlead for turbine '//trim(int2lstr(J))) + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ' added point '//TRIM(int2lstr(l))//' as fairlead for turbine '//trim(int2lstr(J)) + end if else @@ -1231,6 +1290,16 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er !also set number of attached lines to zero initially m%PointList(l)%nAttached = 0 + ! write body information to log file + if (p%writeLog > 1) then + write(p%UnLog, '(A)' ) " - Point"//trim(num2lstr(l))//":" + write(p%UnLog, '(A12,I2)' ) " id : ", m%PointList(l)%IdNum + write(p%UnLog, '(A12,I2)' ) " type: ", m%PointList(l)%typeNum + write(p%UnLog, '(A12,f12.4)') " v : ", m%PointList(l)%pointV + write(p%UnLog, '(A12,f12.4)') " m : ", m%PointList(l)%pointM + write(p%UnLog, '(A12,f12.4)') " CdA : ", m%PointList(l)%pointCdA + write(p%UnLog, '(A12,f12.4)') " Ca : ", m%PointList(l)%pointCa + end if ! check for sequential IdNums IF ( m%PointList(l)%IdNum .NE. l ) THEN @@ -1409,6 +1478,15 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! specify IdNum of line for error checking m%LineList(l)%IdNum = l + if (p%writeLog > 1) then + write(p%UnLog, '(A)' ) " - Line"//trim(num2lstr(m%LineList(l)%IdNum))//":" + write(p%UnLog, '(A15,I2)' ) " ID : ", m%LineList(l)%IdNum + write(p%UnLog, '(A15,A)' ) " Type : ", trim(m%LineTypeList(m%LineList(l)%PropsIdNum)%name) + write(p%UnLog, '(A15,f12.4)') " Len : ", m%LineList(l)%UnstrLen + write(p%UnLog, '(A15,A)' ) " Node A : ", " "//tempString2 + write(p%UnLog, '(A15,A)' ) " Node B : ", " "//tempString3 + write(p%UnLog, '(A15,I2)' ) " NumSegs: ", m%LineList(l)%N + end if ! check for sequential IdNums IF ( m%LineList(l)%IdNum .NE. l ) THEN @@ -1462,11 +1540,20 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er if (m%LineList( TempIDnums(J) )%CtrlChan == 0) then ! ensure line doesn't already have a CtrlChan assigned m%LineList( TempIDnums(J) )%CtrlChan = Itemp CALL WrScr('Assigned Line '//TRIM(Int2LStr(TempIDnums(J)))//' to control channel '//TRIM(Int2LStr(Itemp))) + if (p%writeLog > 0) then + write(p%UnLog,'(A)') 'Assigned Line '//TRIM(Int2LStr(TempIDnums(J)))//' to control channel '//TRIM(Int2LStr(Itemp)) + end if else CALL WrScr('Error: Line '//TRIM(Int2LStr(TempIDnums(J)))//' already is assigned to control channel '//TRIM(Int2LStr(m%LineList( TempIDnums(J) )%CtrlChan))//' so cannot also be assigned to channel '//TRIM(Int2LStr(Itemp))) + if (p%writeLog > 0) then + write(p%UnLog,'(A)') 'Error: Line '//TRIM(Int2LStr(TempIDnums(J)))//' already is assigned to control channel '//TRIM(Int2LStr(m%LineList( TempIDnums(J) )%CtrlChan))//' so cannot also be assigned to channel '//TRIM(Int2LStr(Itemp)) + end if end if else CALL WrScr('Error: Line ID '//TRIM(Int2LStr(TempIDnums(J)))//' of CtrlChan '//TRIM(Int2LStr(Itemp))//' is out of range') + if (p%writeLog > 0) then + write(p%UnLog,'(A)') 'Error: Line ID '//TRIM(Int2LStr(TempIDnums(J)))//' of CtrlChan '//TRIM(Int2LStr(Itemp))//' is out of range' + end if end if END DO @@ -1478,6 +1565,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er else if (INDEX(Line, "FAILURE") > 0) then ! if failure conditions header CALL WrScr(" Warning: Failure capabilities are not yet implemented in MoorDyn.") + if (p%writeLog > 0) then + write(p%UnLog,'(A)') " Warning: Failure capabilities are not yet implemented in MoorDyn." + end if ! skip following two lines (label line and unit line) Line = NextLine(i) @@ -1553,7 +1643,12 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL CheckError( ErrStat2, ErrMsg2 ) IF (ErrStat >= AbortErrLev) RETURN - + if (p%writeLog > 1) then + write(p%UnLog, '(A)' ) " - Outputs List:" + DO J = 1, SIZE(Outlist) + write(p%UnLog, '(A)' ) " "//OutList(J) + END DO + end if !------------------------------------------------------------------------------------------- else ! otherwise ignore this line that isn't a recognized header line and read the next line Line = NextLine(i) @@ -1592,7 +1687,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! p%NAnchs = 0 ! this is the number of "fixed" type Points. <<<<<<<<<<<<<< CALL WrScr(trim(Num2LStr(p%nLines))//' lines, '//trim(Num2LStr(p%NPoints))//' points, '//trim(Num2LStr(p%nRods))//' rods, '//trim(Num2LStr(p%nBodies))//' bodies.') - + if (p%writeLog > 0) then + write(p%UnLog,'(A)') trim(Num2LStr(p%nLines))//' lines, '//trim(Num2LStr(p%NPoints))//' points, '//trim(Num2LStr(p%nRods))//' rods, '//trim(Num2LStr(p%nBodies))//' bodies.' + end if @@ -2091,6 +2188,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er if (InputFileDat%TMaxIC > 0.0_DbKi) then CALL WrScr(" Finalizing initial conditions using dynamic relaxation."//NewLine) ! newline because next line writes over itself + if (p%writeLog > 0) then + write(p%UnLog,'(A)') " Finalizing initial conditions using dynamic relaxation."//NewLine + end if ! boost drag coefficient of each line type <<<<<<<< does this actually do anything or do lines hold these coefficients??? DO I = 1, p%nLines @@ -2159,6 +2259,10 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er IF (ErrStat == ErrID_Fatal) THEN CALL WrScr("NaN detected at time "//TRIM(Num2LStr(t))//" during MoorDyn's dynamic relaxation process.") + if (p%writeLog > 0) then + write(p%UnLog,'(A)') "NaN detected at time "//TRIM(Num2LStr(t))//" during MoorDyn's dynamic relaxation process."//NewLine + end if + IF (wordy > 1) THEN print *, "Here is the state vector: " print *, x%states @@ -2212,9 +2316,17 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er IF (Converged == 1) THEN ! if we made it with all cases satisfying the threshold CALL WrScr('') ! serves as line break from write over command in previous printed line CALL WrScr(' Fairlead tensions converged to '//trim(Num2LStr(100.0*InputFileDat%threshIC))//'% after '//trim(Num2LStr(t))//' seconds.') + if (p%writeLog > 0) then + write(p%UnLog,'(A)') '' + write(p%UnLog,'(A)') ' Fairlead tensions converged to '//trim(Num2LStr(100.0*InputFileDat%threshIC))//'% after '//trim(Num2LStr(t))//' seconds.'//NewLine + end if DO l = 1, p%nLines CALL WrScr(' Fairlead tension: '//trim(Num2LStr(FairTensIC(l,1)))) CALL WrScr(' Fairlead forces: '//trim(Num2LStr(m%LineList(l)%Fnet(1, m%LineList(l)%N)))//', '//trim(Num2LStr(m%LineList(l)%Fnet(2, m%LineList(l)%N)))//', '//trim(Num2LStr(m%LineList(l)%Fnet(3, m%LineList(l)%N)))) + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ' Fairlead tension: '//trim(Num2LStr(FairTensIC(l,1))) + write(p%UnLog,'(A)') ' Fairlead forces: '//trim(Num2LStr(m%LineList(l)%Fnet(1, m%LineList(l)%N)))//', '//trim(Num2LStr(m%LineList(l)%Fnet(2, m%LineList(l)%N)))//', '//trim(Num2LStr(m%LineList(l)%Fnet(3, m%LineList(l)%N))) + end if ENDDO EXIT ! break out of the time stepping loop END IF @@ -2223,6 +2335,11 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er IF (I == ceiling(InputFileDat%TMaxIC/InputFileDat%dtIC) ) THEN CALL WrScr('') ! serves as line break from write over command in previous printed line CALL WrScr(' Fairlead tensions did not converge within TMaxIC='//trim(Num2LStr(InputFileDat%TMaxIC))//' seconds.') + if (p%writeLog > 0) then + write(p%UnLog,'(A)') '' + write(p%UnLog,'(A)') ' Fairlead tensions did not converge within TMaxIC='//trim(Num2LStr(InputFileDat%TMaxIC))//' seconds.' + end if + !ErrStat = ErrID_Warn !ErrMsg = ' MD_Init: ran dynamic convergence to TMaxIC without convergence' END IF @@ -2267,6 +2384,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er endif CALL WrScr(' MoorDyn initialization completed.') + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ' MoorDyn initialization completed.' + end if m%LastOutTime = -1.0_DbKi ! set to nonzero to ensure that output happens at the start of simulation at t=0 @@ -2460,6 +2580,9 @@ SUBROUTINE MD_UpdateStates( t, n, u, t_array, p, x, xd, z, other, m, ErrStat, Er IF (ErrStat == ErrID_Fatal) THEN CALL WrScr("NaN detected at time "//TRIM(Num2LStr(t2))//" in MoorDyn.") + if (p%writeLog > 0) then + write(p%UnLog,'(A)') "NaN detected at time "//TRIM(Num2LStr(t2))//" in MoorDyn." + end if IF (wordy > 1) THEN print *, ". Here is the state vector: " print *, x%states @@ -2491,6 +2614,9 @@ SUBROUTINE MD_UpdateStates( t, n, u, t_array, p, x, xd, z, other, m, ErrStat, Er IF (ErrStat == ErrID_Fatal) THEN CALL WrScr("NaN detected at time "//TRIM(Num2LStr(t2))//" in MoorDyn.") + if (p%writeLog > 0) then + write(p%UnLog,'(A)') "NaN detected at time "//TRIM(Num2LStr(t2))//" in MoorDyn." + end if IF (wordy > 1) THEN print *, ". Here is the state vector: " print *, x%states @@ -2513,6 +2639,9 @@ SUBROUTINE CheckError(ErrId, Msg) ErrStat = MAX(ErrStat, ErrID) CALL WrScr( ErrMsg ) ! do this always or only if warning level? + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ErrMsg + end if IF( ErrStat > ErrID_Warn ) THEN ! CALL MD_DestroyInput( u_interp, ErrStat, ErrMsg ) @@ -2717,6 +2846,9 @@ SUBROUTINE CheckError(ErrId, Msg) ErrStat = MAX(ErrStat, ErrID) CALL WrScr( ErrMsg ) ! do this always or only if warning level? <<<<<<<<<<<<<<<<<<<<<< probably should remove all instances + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ErrMsg + end if ! IF( ErrStat > ErrID_Warn ) THEN ! CALL MD_DestroyContState( dxdt, ErrStat2, ErrMsg2) @@ -2869,6 +3001,9 @@ SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, Er ErrStat = ErrID_Fatal ErrMsg = ' Active tension command will make a segment longer than the limit of twice its original length.' call WrScr(trim(Num2LStr(u%DeltaL(m%LineList(L)%CtrlChan)))//" is an increase of more than "//trim(Num2LStr(m%LineList(L)%UnstrLen / m%LineList(L)%N))) + if (p%writeLog > 0) then + write(p%UnLog,'(A)') trim(Num2LStr(u%DeltaL(m%LineList(L)%CtrlChan)))//" is an increase of more than "//trim(Num2LStr(m%LineList(L)%UnstrLen / m%LineList(L)%N)) + end if IF (wordy > 0) print *, u%DeltaL IF (wordy > 0) print*, m%LineList(L)%CtrlChan RETURN @@ -2877,6 +3012,9 @@ SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, Er ErrStat = ErrID_Fatal ErrMsg = ' Active tension command will make a segment shorter than the limit of half its original length.' call WrScr(trim(Num2LStr(u%DeltaL(m%LineList(L)%CtrlChan)))//" is a reduction of more than half of "//trim(Num2LStr(m%LineList(L)%UnstrLen / m%LineList(L)%N))) + if (p%writeLog > 0) then + write(p%UnLog,'(A)') trim(Num2LStr(u%DeltaL(m%LineList(L)%CtrlChan)))//" is a reduction of more than half of "//trim(Num2LStr(m%LineList(L)%UnstrLen / m%LineList(L)%N)) + end if IF (wordy > 0) print *, u%DeltaL IF (wordy > 0) print*, m%LineList(L)%CtrlChan RETURN @@ -3090,6 +3228,9 @@ SUBROUTINE CheckError(ErrId, Msg) ErrStat = MAX(ErrStat, ErrID) CALL WrScr( ErrMsg ) ! do this always or only if warning level? + if (p%writeLog > 0) then + write(p%UnLog,'(A)') ErrMsg + end if END IF diff --git a/modules/moordyn/src/MoorDyn_Line.f90 b/modules/moordyn/src/MoorDyn_Line.f90 index 37f406486a..190cc4d7eb 100644 --- a/modules/moordyn/src/MoorDyn_Line.f90 +++ b/modules/moordyn/src/MoorDyn_Line.f90 @@ -213,25 +213,6 @@ SUBROUTINE SetupLine (Line, LineProp, p, ErrStat, ErrMsg) RETURN END IF - - if (p%writeLog > 1) then - write(p%UnLog, '(A)') " - Line"//trim(num2lstr(Line%IdNum)) - write(p%UnLog, '(A)') " ID: "//trim(num2lstr(Line%IdNum)) - write(p%UnLog, '(A)') " UnstrLen: "//trim(num2lstr(Line%UnstrLen)) - write(p%UnLog, '(A)') " N : "//trim(num2lstr(Line%N )) - write(p%UnLog, '(A)') " d : "//trim(num2lstr(Line%d )) - write(p%UnLog, '(A)') " rho : "//trim(num2lstr(Line%rho )) - write(p%UnLog, '(A)') " E : "//trim(num2lstr(Line%EA )) - write(p%UnLog, '(A)') " EI : "//trim(num2lstr(Line%EI )) - !write(p%UnLog, '(A)') " BAin: "//trim(num2lstr(Line%BAin)) - write(p%UnLog, '(A)') " Can : "//trim(num2lstr(Line%Can )) - write(p%UnLog, '(A)') " Cat : "//trim(num2lstr(Line%Cat )) - write(p%UnLog, '(A)') " Cdn : "//trim(num2lstr(Line%Cdn )) - write(p%UnLog, '(A)') " Cdt : "//trim(num2lstr(Line%Cdt )) - !write(p%UnLog, '(A)') " ww_l: " << ( (rho - env->rho_w)*(pi/4.*d*d) )*9.81 << endl; - end if - - ! need to add cleanup sub <<< diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index 23189361f3..7c0e26c203 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -151,8 +151,10 @@ subroutine GetOrientationAngles(vec, phi, sinPhi, cosPhi, tanPhi, beta, sinBeta, vecLen = SQRT(Dot_Product(vec,vec)) vecLen2D = SQRT(vec(1)**2+vec(2)**2) if ( vecLen < 0.000001 ) then - print *, "ERROR in GetOrientationAngles in MoorDyn. Supplied vector is near zero" - print *, vec + if (wordy > 0) then + print *, "ERROR in GetOrientationAngles in MoorDyn. Supplied vector is near zero" + print *, vec + endif k_hat = NaN ! 1.0/0.0 else k_hat = vec / vecLen diff --git a/modules/moordyn/src/MoorDyn_Rod.f90 b/modules/moordyn/src/MoorDyn_Rod.f90 index 7302214f9d..49c61a5c56 100644 --- a/modules/moordyn/src/MoorDyn_Rod.f90 +++ b/modules/moordyn/src/MoorDyn_Rod.f90 @@ -151,24 +151,6 @@ SUBROUTINE Rod_Setup(Rod, RodProp, endCoords, p, ErrStat, ErrMsg) IF (wordy > 0) print *, "Set up Rod ",Rod%IdNum, ", type ", Rod%typeNum - - if (p%writeLog > 1) then - write(p%UnLog, '(A)') " - Rod "//trim(num2lstr(Rod%IdNum)) - write(p%UnLog, '(A)') " ID: "//trim(num2lstr(Rod%IdNum)) - write(p%UnLog, '(A)') " UnstrLen: "//trim(num2lstr(Rod%UnstrLen)) - write(p%UnLog, '(A)') " N : "//trim(num2lstr(Rod%N )) - write(p%UnLog, '(A)') " d : "//trim(num2lstr(Rod%d )) - write(p%UnLog, '(A)') " rho : "//trim(num2lstr(Rod%rho )) - write(p%UnLog, '(A)') " Can : "//trim(num2lstr(Rod%Can )) - write(p%UnLog, '(A)') " Cat : "//trim(num2lstr(Rod%Cat )) - write(p%UnLog, '(A)') " CaEnd: "//trim(num2lstr(Rod%CaEnd )) - write(p%UnLog, '(A)') " Cdn : "//trim(num2lstr(Rod%Cdn )) - write(p%UnLog, '(A)') " Cdt : "//trim(num2lstr(Rod%Cdt )) - write(p%UnLog, '(A)') " CdEnd: "//trim(num2lstr(Rod%CdEnd )) - !write(p%UnLog, '(A)') " ww_l: " << ( (rho - env->rho_w)*(pi/4.*d*d) )*9.81 << endl; - end if - - ! need to add cleanup sub <<< From d0a75b64ba329db8fe564683b585d8c5312af721 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Thu, 4 Jan 2024 14:55:46 -0700 Subject: [PATCH 65/91] Better driver handling and updated log --- modules/moordyn/src/MoorDyn.f90 | 28 +++++++++++++++----------- modules/moordyn/src/MoorDyn_Driver.f90 | 9 +++++++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index c3279f4893..e3881e7f1b 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -1645,7 +1645,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er if (p%writeLog > 1) then write(p%UnLog, '(A)' ) " - Outputs List:" - DO J = 1, SIZE(Outlist) + DO J = 1, p%NumOuts write(p%UnLog, '(A)' ) " "//OutList(J) END DO end if @@ -1688,7 +1688,8 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL WrScr(trim(Num2LStr(p%nLines))//' lines, '//trim(Num2LStr(p%NPoints))//' points, '//trim(Num2LStr(p%nRods))//' rods, '//trim(Num2LStr(p%nBodies))//' bodies.') if (p%writeLog > 0) then - write(p%UnLog,'(A)') trim(Num2LStr(p%nLines))//' lines, '//trim(Num2LStr(p%NPoints))//' points, '//trim(Num2LStr(p%nRods))//' rods, '//trim(Num2LStr(p%nBodies))//' bodies.' + write(p%UnLog, '(A)') NewLine + write(p%UnLog, '(A)') ' Created mooring system: '//trim(Num2LStr(p%nLines))//' lines, '//trim(Num2LStr(p%NPoints))//' points, '//trim(Num2LStr(p%nRods))//' rods, '//trim(Num2LStr(p%nBodies))//' bodies.' end if @@ -1730,7 +1731,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! write system description to log file if (p%writeLog > 1) then - write(p%UnLog, '(A)') "----- MoorDyn Model Summary (to be written) -----" + write(p%UnLog, '(A)') "----- MoorDyn Model Summary (unfinished) -----" end if @@ -2152,7 +2153,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! if log file, compute and write some object properties ! ------------------------------------------------------------------- if (p%writeLog > 1) then - + write(p%UnLog, '(A)' ) "Values after intialization before dynamic relaxation" write(p%UnLog, '(A)' ) " Bodies:" DO l = 1,p%nBodies write(p%UnLog, '(A)' ) " Body"//trim(num2lstr(l))//":" @@ -2162,21 +2163,21 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er write(p%UnLog, '(A)' ) " Rods:" DO l = 1,p%nRods write(p%UnLog, '(A)' ) " Rod"//trim(num2lstr(l))//":" - ! m%RodList(l) + write(p%UnLog, '(A12, f12.4)') " mass: ", m%RodList(l)%M6net(1,1) + write(p%UnLog, '(A17, A)') " direction: ", trim(num2lstr(m%RodList(l)%q(1)))//", "//trim(num2lstr(m%RodList(l)%q(2)))//", "//trim(num2lstr(m%RodList(l)%q(3))) END DO write(p%UnLog, '(A)' ) " Points:" DO l = 1,p%nFreePoints write(p%UnLog, '(A)' ) " Point"//trim(num2lstr(l))//":" - ! m%PointList(l) + write(p%UnLog, '(A12, f12.4)') " mass: ", m%PointList(l)%M END DO write(p%UnLog, '(A)' ) " Lines:" DO l = 1,p%nLines write(p%UnLog, '(A)' ) " Line"//trim(num2lstr(l))//":" - ! m%LineList(l) END DO - + write(p%UnLog, '(A)') "--------- End of Model Summary --------- "//NewLine end if @@ -2189,7 +2190,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL WrScr(" Finalizing initial conditions using dynamic relaxation."//NewLine) ! newline because next line writes over itself if (p%writeLog > 0) then - write(p%UnLog,'(A)') " Finalizing initial conditions using dynamic relaxation."//NewLine + write(p%UnLog,'(A)') "Finalizing initial conditions using dynamic relaxation."//NewLine end if ! boost drag coefficient of each line type <<<<<<<< does this actually do anything or do lines hold these coefficients??? @@ -2314,7 +2315,6 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er END DO IF (Converged == 1) THEN ! if we made it with all cases satisfying the threshold - CALL WrScr('') ! serves as line break from write over command in previous printed line CALL WrScr(' Fairlead tensions converged to '//trim(Num2LStr(100.0*InputFileDat%threshIC))//'% after '//trim(Num2LStr(t))//' seconds.') if (p%writeLog > 0) then write(p%UnLog,'(A)') '' @@ -2385,7 +2385,12 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL WrScr(' MoorDyn initialization completed.') if (p%writeLog > 0) then - write(p%UnLog,'(A)') ' MoorDyn initialization completed.' + write(p%UnLog, '(A)') NewLine//"MoorDyn initialization completed."//NewLine + if (ErrStat /= ErrID_None) then + write(p%UnLog, '(A34)') "Initalization Errors and Warnings:" + write(p%UnLog, '(A)' ) ErrMsg + end if + write(p%UnLog, '(A)') NewLine end if m%LastOutTime = -1.0_DbKi ! set to nonzero to ensure that output happens at the start of simulation at t=0 @@ -2468,7 +2473,6 @@ END SUBROUTINE CheckError SUBROUTINE CleanUp() ! ErrStat = ErrID_Fatal call MD_DestroyInputFileType( InputFileDat, ErrStat2, ErrMsg2 ) ! Ignore any error messages from this - IF (p%UnLog > 0_IntKi) CLOSE( p%UnLog ) ! Remove this when the log file is kept open during the full simulation END SUBROUTINE !> If for some reason the file is truncated, it is possible to get into an infinite loop diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 27428eb326..b83842dba9 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -697,6 +697,11 @@ PROGRAM MoorDyn_Driver call MD_DestroyInput( MD_u(j), ErrStat2, ErrMsg2) end do + if ( ErrStat /= ErrID_None ) THEN ! Display all errors + CALL WrScr1( "Errors: " ) + CALL WrScr( trim(GetErrStr(ErrStat))//': '//trim(ErrMsg) ) + endif + !close (un) call CleanUp() CALL NormStop() @@ -711,8 +716,8 @@ SUBROUTINE AbortIfFailed() if (ErrStat >= AbortErrLev) then call CleanUp() Call ProgAbort(trim(ErrMsg)) - elseif ( ErrStat /= ErrID_None ) THEN - CALL WrScr1( trim(GetErrStr(ErrStat))//': '//trim(ErrMsg) ) + elseif ( ErrStat2 /= ErrID_None ) THEN + CALL WrScr1( trim(GetErrStr(ErrStat2))//': '//trim(ErrMsg2)//NewLine) end if END SUBROUTINE AbortIfFailed From 41810273103046a0361ffe79408070b7bdd47bbe Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Mon, 8 Jan 2024 12:50:13 -0700 Subject: [PATCH 66/91] Add option to disable inertial forces in 6DOF coupling --- modules/moordyn/src/MoorDyn.f90 | 2 ++ modules/moordyn/src/MoorDyn_Body.f90 | 20 ++++++++++++++++---- modules/moordyn/src/MoorDyn_Registry.txt | 1 + modules/moordyn/src/MoorDyn_Rod.f90 | 20 +++++++++++++++----- modules/moordyn/src/MoorDyn_Types.f90 | 1 + 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index e3881e7f1b..22167aee53 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -463,6 +463,8 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er read (OptValue,*) p%mc else if ( OptString == 'CV') then read (OptValue,*) p%cv + else if ( OptString == 'INERTIALF') then + read (OptValue,*) p%inertialF else CALL SetErrStat( ErrID_Warn, 'Unable to interpret input '//trim(OptString)//' in OPTIONS section.', ErrStat, ErrMsg, RoutineName ) end if diff --git a/modules/moordyn/src/MoorDyn_Body.f90 b/modules/moordyn/src/MoorDyn_Body.f90 index f520265fae..2a1b2df68c 100644 --- a/modules/moordyn/src/MoorDyn_Body.f90 +++ b/modules/moordyn/src/MoorDyn_Body.f90 @@ -522,13 +522,25 @@ SUBROUTINE Body_GetCoupledForce(Body, Fnet_out, m, p) ! add inertial loads as appropriate if (Body%typeNum == -1) then - F6_iner = -MATMUL(Body%M, Body%a6) ! <<<<<<<< why does including F6_iner cause instability??? + if (p%inertialF == 1) then ! include inertial components + F6_iner = -MATMUL(Body%M, Body%a6) ! unstable in OpenFAST v4 and below becasue of loose coupling with ED and SD. Transients in acceleration can cause issues + else + ! When OpenFAST v5 is released w/ tight coupling, remove this hack and just use the inertial term above + F6_iner = 0.0 + endif + Body%F6net = Body%F6net + F6_iner ! add inertial loads Fnet_out = Body%F6net - else if (Body%typeNum == 2) then ! pinned coupled body - ! inertial loads ... from input translational ... and solved rotational ... acceleration - F6_iner(1:3) = -MATMUL(Body%M(1:3,1:3), Body%a6(1:3)) - MATMUL(Body%M(1:3,4:6), Body%a6(4:6)) + else if (Body%typeNum == 2) then ! pinned coupled body + + if (p%inertialF == 1) then ! include inertial components + ! inertial loads ... from input translational ... and solved rotational ... acceleration + F6_iner(1:3) = -MATMUL(Body%M(1:3,1:3), Body%a6(1:3)) - MATMUL(Body%M(1:3,4:6), Body%a6(4:6)) + else + F6_iner(1:3) = 0.0 + endif + Body%F6net(1:3) = Body%F6net(1:3) + F6_iner(1:3) ! add translational inertial loads Body%F6net(4:6) = 0.0_DbKi Fnet_out = Body%F6net diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index a8406ef193..8dbfcd08b3 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -423,6 +423,7 @@ typedef ^ ^ Integer dxIdx_map2_xStateIdx {:} typedef ^ ^ Logical VisMeshes - - - "Using visualization meshes as requested by glue code" - typedef ^ ^ VisDiam VisRodsDiam {:} - - "Diameters for visualization of rods" - typedef ^ ^ IntKi Standalone - - - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - +typedef ^ ^ IntKi inertialF - 1 - "Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no" - # ============================== Inputs ============================================================================================================================================ diff --git a/modules/moordyn/src/MoorDyn_Rod.f90 b/modules/moordyn/src/MoorDyn_Rod.f90 index 49c61a5c56..8e8b274d77 100644 --- a/modules/moordyn/src/MoorDyn_Rod.f90 +++ b/modules/moordyn/src/MoorDyn_Rod.f90 @@ -996,14 +996,24 @@ SUBROUTINE Rod_GetCoupledForce(Rod, Fnet_out, m, p) ! add inertial loads as appropriate (written out in a redundant way just for clarity, and to support load separation in future) ! fixed coupled rod if (Rod%typeNum == -2) then - - F6_iner = -MATMUL(Rod%M6net, Rod%a6) ! inertial loads + + if (p%inertialF == 1) then ! include inertial components + F6_iner = -MATMUL(Rod%M6net, Rod%a6) ! inertial loads + else + F6_iner = 0.0 + endif Rod%F6net = Rod%F6net + F6_iner ! add inertial loads Fnet_out = Rod%F6net ! pinned coupled rod - else if (Rod%typeNum == -1) then - ! inertial loads ... from input translational ... and solved rotational ... acceleration - F6_iner(1:3) = -MATMUL(Rod%M6net(1:3,1:3), Rod%a6(1:3)) - MATMUL(Rod%M6net(1:3,4:6), Rod%a6(4:6)) + else if (Rod%typeNum == -1) then + + if (p%inertialF == 1) then ! include inertial components + ! inertial loads ... from input translational ... and solved rotational ... acceleration + F6_iner(1:3) = -MATMUL(Rod%M6net(1:3,1:3), Rod%a6(1:3)) - MATMUL(Rod%M6net(1:3,4:6), Rod%a6(4:6)) + else + F6_iner(1:3) = 0.0 + endif + Rod%F6net(1:3) = Rod%F6net(1:3) + F6_iner(1:3) ! add translational inertial loads Rod%F6net(4:6) = 0.0_DbKi Fnet_out = Rod%F6net diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 125834a561..713a64b0fd 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -456,6 +456,7 @@ MODULE MoorDyn_Types LOGICAL :: VisMeshes !< Using visualization meshes as requested by glue code [-] TYPE(VisDiam) , DIMENSION(:), ALLOCATABLE :: VisRodsDiam !< Diameters for visualization of rods [-] INTEGER(IntKi) :: Standalone !< Indicates MoorDyn run as standalone code if 1, coupled if 0 [-] + INTEGER(IntKi) :: inertialF = 1 !< Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no [-] END TYPE MD_ParameterType ! ======================= ! ========= MD_InputType ======= From ddd97ca51d36cf6b318533c75a4070e406f1f3a5 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 8 Jan 2024 19:36:28 -0700 Subject: [PATCH 67/91] AWAE: Mod_AmbWind=3 add error if HR grid not centered on turbine in Y direction --- modules/awae/src/AWAE.f90 | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index beecc09957..a01fc742ed 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -817,6 +817,7 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO character(1024) :: rootDir, baseName, OutFileVTKDir ! Simulation root dir, basename for outputs integer(IntKi) :: i,j,nt ! loop counter real(ReKi) :: gridLoc ! Location of requested output slice in grid coordinates [0,sz-1] + real(ReKi) :: tmpDy,tmpRe integer(IntKi) :: errStat2 ! temporary error status of the operation character(ErrMsgLen) :: errMsg2 ! temporary error message character(*), parameter :: RoutineName = 'AWAE_Init' @@ -1053,25 +1054,47 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO do nt = 1,p%NumTurbines IfW_InitInp%TurbineID = nt - + call WrScr(NewLine//'Initializing high-resolution grid for Turbine '//trim(Num2Lstr(nt))) call InflowWind_Init( IfW_InitInp, m%u_IfW_High, p%IfW(nt), x%IfW(nt), xd%IfW(nt), z%IfW(nt), OtherState%IfW(nt), m%y_IfW_High, m%IfW(nt), Interval, IfW_InitOut, ErrStat2, ErrMsg2 ) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (errStat2 >= AbortErrLev) then return end if + ! Check that the high resolution grid placement is correct + ! The InflowWind grid location is exactly centered on the TurbPos location in the Y direction. The high resolution grid + ! must exactly match the sizing and location of the InflowWind grid. We are only going to check the Y and Z locations + ! for now and throw an error if these don't match appropriately. + if (IfW_InitOut%WindFileInfo%YRange_Limited) then ! only check boundaries if the YRange is limited (we don't care what kind of wind) + tmpRe = p%Y0_High(nt) + (real(p%nY_high,ReKi)-1.0_ReKi)*p%dY_high(nt) ! upper bound of high-res grid + if ((.not. EqualRealNos(p%WT_Position(2,nt)+IfW_InitOut%WindFileInfo%YRange(1),p%Y0_High(nt))) .or. & ! lower bound + (.not. EqualRealNos(p%WT_Position(2,nt)+IfW_InitOut%WindFileInfo%YRange(2),tmpRe)) ) then ! upper bound + ErrStat2 = ErrID_Fatal + ErrMsg2 = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires the InflowWind high-res data range exactly match the high-res grid '// & + 'and the turbine is exactly centered in the high-res grid in the Y direction. '//NewLine//' Try setting:'//NewLine// & + ' Y0_high = '// & + trim(Num2LStr(p%WT_Position(2,nt)+IfW_InitOut%WindFileInfo%YRange(1))) + if (allocated(p%IfW(nt)%FlowField%Grid3D%Vel)) then + tmpDy = abs(IfW_InitOut%WindFileInfo%YRange(2)-IfW_InitOut%WindFileInfo%YRange(1))/(real(p%nY_high,ReKi)-1.0_ReKi) + ErrMsg2=trim(ErrMsg2)//NewLine//' dY_High = '//trim(Num2LStr(tmpDy)) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + endif + endif + end do + if (errStat >= AbortErrLev) return end if ! Set the position inputs once for the low-resolution grid m%u_IfW_Low%PositionXYZ = p%Grid_low - ! Set the hub position and orientation to pass to IfW (IfW always calculates hub and disk avg vel) + ! Set the hub position and orientation to pass to IfW (FIXME: IfW always calculates hub and disk avg vel. Change this after IfW pointers fully enabled.) m%u_IfW_Low%HubPosition = (/ p%X0_low + 0.5*p%nX_low*p%dX_low, p%Y0_low + 0.5*p%nY_low*p%dY_low, p%Z0_low + 0.5*p%nZ_low*p%dZ_low /) call Eye(m%u_IfW_Low%HubOrientation,ErrStat2,ErrMsg2) ! Initialize the high-resolution grid inputs and outputs - IF ( .NOT. ALLOCATED( m%u_IfW_High%PositionXYZ ) ) THEN + IF ( .NOT. ALLOCATED( m%u_IfW_High%PositionXYZ ) ) THEN call AllocAry(m%u_IfW_High%PositionXYZ, 3, p%nX_high*p%nY_high*p%nZ_high, 'm%u_IfW_High%PositionXYZ', ErrStat2, ErrMsg2) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) call AllocAry(m%y_IfW_High%VelocityUVW, 3, p%nX_high*p%nY_high*p%nZ_high, 'm%y_IfW_High%VelocityUVW', ErrStat2, ErrMsg2) From 280d6d28259243c755e4ca9c5e4502c0aff4248b Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 9 Jan 2024 16:17:05 -0700 Subject: [PATCH 68/91] VS: update VS build process to include ExtLoads --- vs-build/FASTlib/FASTlib.vfproj | 39 +++++++++++++++++++++++++++++++++ vs-build/RunRegistry.bat | 15 ++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/vs-build/FASTlib/FASTlib.vfproj b/vs-build/FASTlib/FASTlib.vfproj index f587603d9a..e1b4b124c4 100644 --- a/vs-build/FASTlib/FASTlib.vfproj +++ b/vs-build/FASTlib/FASTlib.vfproj @@ -1469,6 +1469,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vs-build/RunRegistry.bat b/vs-build/RunRegistry.bat index 2649627f6b..319d158d37 100644 --- a/vs-build/RunRegistry.bat +++ b/vs-build/RunRegistry.bat @@ -36,6 +36,7 @@ SET IceF_Loc=%Modules_Loc%\icefloe\src\interfaces\FAST SET IceD_Loc=%Modules_Loc%\icedyn\src SET MD_Loc=%Modules_Loc%\moordyn\src SET ExtInfw_Loc=%Modules_Loc%\externalinflow\src +SET ExtLoads_Loc=%Modules_Loc%\extloads\src SET Orca_Loc=%Modules_Loc%\orcaflex-interface\src SET NWTC_Lib_Loc=%Modules_Loc%\nwtc-library\src SET ExtPtfm_Loc=%Modules_Loc%\extptfm\src @@ -51,7 +52,7 @@ SET Farm_Loc=%Root_Loc%\glue-codes\fast-farm\src SET ALL_FAST_Includes=-I "%FAST_Loc%" -I "%NWTC_Lib_Loc%" -I "%ED_Loc%" -I "%SrvD_Loc%" -I "%AD14_Loc%" -I^ "%AD_Loc%" -I "%BD_Loc%" -I "%SC_Loc%" -I^ "%IfW_Loc%" -I "%SD_Loc%" -I "%HD_Loc%" -I "%SEAST_Loc%" -I "%MAP_Loc%" -I "%FEAM_Loc%" -I^ - "%IceF_Loc%" -I "%IceD_Loc%" -I "%MD_Loc%" -I "%ExtInfw_Loc%" -I "%Orca_Loc%" -I "%ExtPtfm_Loc%" + "%IceF_Loc%" -I "%IceD_Loc%" -I "%MD_Loc%" -I "%ExtInfw_Loc%" -I "%Orca_Loc%" -I "%ExtPtfm_Loc%" -I "%ExtLoads_Loc%" SET ModuleName=%1 @@ -132,6 +133,18 @@ SET Output_Loc=%CURR_LOC% %REGISTRY% "%CURR_LOC%\%ModuleName%_Registry.txt" -I "%NWTC_Lib_Loc%" -ccode -O "%Output_Loc%" GOTO checkError +:ExtLoads +SET CURR_LOC=%ExtLoads_Loc% +SET Output_Loc=%CURR_LOC% +%REGISTRY% "%CURR_LOC%\%ModuleName%_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%ExtLoads_Loc%" -O "%Output_Loc%" +GOTO checkError + +:ExtLoadsDX +SET CURR_LOC=%ExtLoads_Loc% +SET Output_Loc=%CURR_LOC% +%REGISTRY% "%CURR_LOC%\%ModuleName%_Registry.txt" -I "%NWTC_Lib_Loc%" -ccode -O "%Output_Loc%" +GOTO checkError + :AeroDyn :BEMT :DBEMT From acc20caade8b2f5f652aabb93992082761fa19f2 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Tue, 9 Jan 2024 16:28:02 -0700 Subject: [PATCH 69/91] Add error handling to opening line EA file --- modules/moordyn/src/MoorDyn_IO.f90 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 271d9791d9..245c9afa1f 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -242,8 +242,7 @@ SUBROUTINE getCoefficientOrCurve(inputString, LineProp_c, LineProp_npoints, Line LineProp_npoints = 0; else ! otherwise interpet the input as a file name to load stress-strain lookup data from - - CALL WrScr("found A letter in the line coefficient value so will try to load the filename.") + CALL WrScr1(" Found a letter in the line EA coefficient value so will try to load the filename.") LineProp_c = 0.0 @@ -251,8 +250,13 @@ SUBROUTINE getCoefficientOrCurve(inputString, LineProp_c, LineProp_npoints, Line CALL GetNewUnit( UnCoef ) CALL OpenFInpFile( UnCoef, TRIM(inputString), ErrStat4, ErrMsg4 ) ! add error handling? + IF (ErrStat4 == ErrID_Fatal) then + ErrStat3 = ErrStat4 + ErrMsg3 = ErrMsg4 + RETURN + ENDIF - READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 ! skip the first two lines (title, names, and units) then parse + READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 ! skip the first three lines (title, names, and units) then parse READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 From 387857b1f6dbb5153a569ab70e5f547d06af492a Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Tue, 9 Jan 2024 16:33:42 -0700 Subject: [PATCH 70/91] Change default inertialF to 0 --- modules/moordyn/src/MoorDyn_Registry.txt | 2 +- modules/moordyn/src/MoorDyn_Types.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 8dbfcd08b3..6ebabf21c5 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -423,7 +423,7 @@ typedef ^ ^ Integer dxIdx_map2_xStateIdx {:} typedef ^ ^ Logical VisMeshes - - - "Using visualization meshes as requested by glue code" - typedef ^ ^ VisDiam VisRodsDiam {:} - - "Diameters for visualization of rods" - typedef ^ ^ IntKi Standalone - - - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - -typedef ^ ^ IntKi inertialF - 1 - "Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no" - +typedef ^ ^ IntKi inertialF - 0 - "Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no" - # ============================== Inputs ============================================================================================================================================ diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 713a64b0fd..1e640d4098 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -456,7 +456,7 @@ MODULE MoorDyn_Types LOGICAL :: VisMeshes !< Using visualization meshes as requested by glue code [-] TYPE(VisDiam) , DIMENSION(:), ALLOCATABLE :: VisRodsDiam !< Diameters for visualization of rods [-] INTEGER(IntKi) :: Standalone !< Indicates MoorDyn run as standalone code if 1, coupled if 0 [-] - INTEGER(IntKi) :: inertialF = 1 !< Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no [-] + INTEGER(IntKi) :: inertialF = 0 !< Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no [-] END TYPE MD_ParameterType ! ======================= ! ========= MD_InputType ======= From f814dba80d1fa25a2aa5f7dd53aadd35877e474a Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 9 Jan 2024 17:07:29 -0700 Subject: [PATCH 71/91] MD reg test: update input files --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index 7709178aed..49b70806aa 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 7709178aed58df8f5df3b86a41c275cbaac5f70e +Subproject commit 49b70806aa1d9d5dc1698075e89660cad69c38d7 From 5c67b9989365c458b036d7838727908a15e91102 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Wed, 10 Jan 2024 10:57:48 -0700 Subject: [PATCH 72/91] Replace print w WrScr and minor organize of registry --- modules/moordyn/src/MoorDyn_Body.f90 | 4 ++-- modules/moordyn/src/MoorDyn_Misc.f90 | 20 ++++++++++---------- modules/moordyn/src/MoorDyn_Point.f90 | 4 ++-- modules/moordyn/src/MoorDyn_Registry.txt | 4 ++-- modules/moordyn/src/MoorDyn_Rod.f90 | 8 ++++---- modules/moordyn/src/MoorDyn_Types.f90 | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_Body.f90 b/modules/moordyn/src/MoorDyn_Body.f90 index 2a1b2df68c..acf6f92098 100644 --- a/modules/moordyn/src/MoorDyn_Body.f90 +++ b/modules/moordyn/src/MoorDyn_Body.f90 @@ -570,7 +570,7 @@ SUBROUTINE Body_AddPoint(Body, pointID, coords) Body%AttachedC(Body%nAttachedC) = pointID Body%rPointRel(:,Body%nAttachedC) = coords ! store relative position of point on body ELSE - Print*, "too many Points attached to Body ", Body%IdNum, " in MoorDyn!" + call WrScr("too many Points attached to Body "//trim(num2lstr(Body%IdNum))//" in MoorDyn!") END IF END SUBROUTINE Body_AddPoint @@ -601,7 +601,7 @@ SUBROUTINE Body_AddRod(Body, rodID, coords) Body%r6RodRel(4:6, Body%nAttachedR) = tempUnitVec ELSE - Print*, "too many rods attached to Body ", Body%IdNum, " in MoorDyn" + call WrScr("too many rods attached to Body "//trim(num2lstr(Body%IdNum))//" in MoorDyn") END IF END SUBROUTINE Body_AddRod diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index 7c0e26c203..8fb91cf218 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -1350,7 +1350,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) ELSE IF (SCAN(WaterKinString, "abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ") == 0) THEN ! If the input has no letters, let's assume it's a number - print *, "ERROR WaveKin option does not currently support numeric entries. It must be a filename." + call WrScr( "ERROR WaveKin option does not currently support numeric entries. It must be a filename." ) p%WaveKin = 0 p%Current = 0 return @@ -1358,7 +1358,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) ! otherwise interpret the input as a file name to load the bathymetry lookup data from - print *, " The waterKin input contains letters so will load a water kinematics input file" + call WrScr( " The waterKin input contains letters so will load a water kinematics input file" ) ! -------- load water kinematics input file ------------- @@ -1413,7 +1413,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) EXIT ! break out of the loop if it couldn't read the line (i.e. if at end of file) end if if (i == 100) then - print*,"WARNING: MD can handle a maximum of 100 current profile points" + call WrScr("WARNING: MD can handle a maximum of 100 current profile points") exit end if END DO @@ -1449,7 +1449,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) ! --------------------- set from inputted wave elevation time series, grid approach ------------------- if (p%WaveKin == 3) then - print *, 'Setting up WaveKin 3 option: read wave elevation time series from file' + call WrScr( 'Setting up WaveKin 3 option: read wave elevation time series from file' ) IF ( LEN_TRIM( WaveKinFile ) == 0 ) THEN CALL SetErrStat( ErrID_Fatal,'WaveKinFile must not be an empty string.',ErrStat, ErrMsg, RoutineName); return @@ -1467,7 +1467,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) CALL OpenFInpFile ( UnElev, WaveKinFile, ErrStat2, ErrMsg2 ); if(Failed()) return - print *, 'Reading wave elevation data from ', trim(WaveKinFile) + call WrScr( 'Reading wave elevation data from '//trim(WaveKinFile) ) ! Read through length of file to find its length i = 1 ! start counter @@ -1502,7 +1502,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) ! Close the inputs file CLOSE ( UnElev ) - print *, "Read ", ntIn, " time steps from input file." + call WrScr( "Read "//trim(num2lstr(ntIn))//" time steps from input file." ) ! if (WaveTimeIn(ntIn) < TMax) then <<<< need to handle if time series is too short? @@ -1714,7 +1714,7 @@ SUBROUTINE gridAxisCoords(coordtype, entries, coordarray, n, ErrStat, ErrMsg) INTEGER(IntKi) :: nEntries, I IF (len(trim(entries)) == len(entries)) THEN - print*, "Warning: Only 120 characters read from wave grid coordinates" + call WrScr("Warning: Only 120 characters read from wave grid coordinates") END IF IF (entries(len(entries):len(entries)) == ',') THEN @@ -1732,7 +1732,7 @@ SUBROUTINE gridAxisCoords(coordtype, entries, coordarray, n, ErrStat, ErrMsg) else if (coordtype==2) then ! 2: uniform specified by -xlim, xlim, num n = int(tempArray(3)) else - print *, "Error: invalid coordinate type specified to gridAxisCoords" + call WrScr("Error: invalid coordinate type specified to gridAxisCoords") end if ! allocate coordinate array @@ -1755,7 +1755,7 @@ SUBROUTINE gridAxisCoords(coordtype, entries, coordarray, n, ErrStat, ErrMsg) end do else - print *, "Error: invalid coordinate type specified to gridAxisCoords" + call WrScr("Error: invalid coordinate type specified to gridAxisCoords") end if ! print *, "Set water grid coordinates to :" @@ -1791,7 +1791,7 @@ SUBROUTINE stringToArray(instring, n, outarray) END IF n = n + 1 if (n > 100) then - print *, "ERROR - stringToArray cannot do more than 100 entries" + call WrScr( "ERROR - stringToArray cannot do more than 100 entries") end if READ(instring(pos1:pos1+pos2-2), *) outarray(n) diff --git a/modules/moordyn/src/MoorDyn_Point.f90 b/modules/moordyn/src/MoorDyn_Point.f90 index f79d86858b..9328f4805d 100644 --- a/modules/moordyn/src/MoorDyn_Point.f90 +++ b/modules/moordyn/src/MoorDyn_Point.f90 @@ -362,7 +362,7 @@ SUBROUTINE Point_AddLine(Point, lineID, TopOfLine) Point%Attached(Point%nAttached) = lineID Point%Top(Point%nAttached) = TopOfLine ! attached to line ... 1 = top/fairlead(end B), 0 = bottom/anchor(end A) ELSE - Print*, "Too many lines connected to Point ", Point%IdNum, " in MoorDyn!" + call WrScr("Too many lines connected to Point "//trim(num2lstr(Point%IdNum))//" in MoorDyn!") END IF END SUBROUTINE Point_AddLine @@ -399,7 +399,7 @@ SUBROUTINE Point_RemoveLine(Point, lineID, TopOfLine, rEnd, rdEnd) rdEnd(J) = Point%rd(J) END DO - print*, "Detached line ", lineID, " from Point ", Point%IdNum + call WrScr( "Detached line "//trim(num2lstr(lineID))//" from Point "//trim(num2lstr(Point%IdNum))) EXIT END DO diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 6ebabf21c5..9c4d84e6d4 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -391,6 +391,8 @@ typedef ^ ^ DbKi mu_kT - typedef ^ ^ DbKi mu_kA - - - "axial kinetic friction coefficient" "(-)" typedef ^ ^ DbKi mc - - - "ratio of the static friction coefficient to the kinetic friction coefficient" "(-)" typedef ^ ^ DbKi cv - - - "saturated damping coefficient" "(-)" +typedef ^ ^ IntKi Standalone - - - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - +typedef ^ ^ IntKi inertialF - 0 - "Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no" - # --- parameters for wave and current --- typedef ^ ^ IntKi nxWave - - - "number of x wave grid points" - typedef ^ ^ IntKi nyWave - - - "number of y wave grid points" - @@ -422,8 +424,6 @@ typedef ^ ^ Integer Jac_nx - typedef ^ ^ Integer dxIdx_map2_xStateIdx {:} - - "Mapping array from index of dX array to corresponding state index" - typedef ^ ^ Logical VisMeshes - - - "Using visualization meshes as requested by glue code" - typedef ^ ^ VisDiam VisRodsDiam {:} - - "Diameters for visualization of rods" - -typedef ^ ^ IntKi Standalone - - - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - -typedef ^ ^ IntKi inertialF - 0 - "Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no" - # ============================== Inputs ============================================================================================================================================ diff --git a/modules/moordyn/src/MoorDyn_Rod.f90 b/modules/moordyn/src/MoorDyn_Rod.f90 index 8e8b274d77..f5f718198a 100644 --- a/modules/moordyn/src/MoorDyn_Rod.f90 +++ b/modules/moordyn/src/MoorDyn_Rod.f90 @@ -1081,7 +1081,7 @@ SUBROUTINE Rod_AddLine(Rod, lineID, TopOfLine, endB) Rod%AttachedB(Rod%nAttachedB) = lineID Rod%TopB(Rod%nAttachedB) = TopOfLine ! attached to line ... 1 = top/fairlead(end B), 0 = bottom/anchor(end A) ELSE - Print*, "too many lines connected to Rod ", Rod%IdNum, " in MoorDyn!" + call WrScr("too many lines connected to Rod "//trim(num2lstr(Rod%IdNum))//" in MoorDyn!") END IF else ! attaching to end A @@ -1093,7 +1093,7 @@ SUBROUTINE Rod_AddLine(Rod, lineID, TopOfLine, endB) Rod%AttachedA(Rod%nAttachedA) = lineID Rod%TopA(Rod%nAttachedA) = TopOfLine ! attached to line ... 1 = top/fairlead(end B), 0 = bottom/anchor(end A) ELSE - Print*, "too many lines connected to Rod ", Rod%IdNum, " in MoorDyn!" + call WrScr("too many lines connected to Rod "//trim(num2lstr(Rod%IdNum))//" in MoorDyn!") END IF end if @@ -1135,7 +1135,7 @@ SUBROUTINE Rod_RemoveLine(Rod, lineID, TopOfLine, endB, rEnd, rdEnd) rdEnd(J) = Rod%rd(J,Rod%N) END DO - print*, "Detached line ", lineID, " from Rod ", Rod%IdNum, " end B" + call WrScr( "Detached line "//trim(num2lstr(lineID))//" from Rod "//trim(num2lstr(Rod%IdNum))//" end B") EXIT END DO @@ -1167,7 +1167,7 @@ SUBROUTINE Rod_RemoveLine(Rod, lineID, TopOfLine, endB, rEnd, rdEnd) rdEnd(J) = Rod%rd(J,0) END DO - print*, "Detached line ", lineID, " from Rod ", Rod%IdNum, " end A" + call WrScr( "Detached line "//trim(num2lstr(lineID))//" from Rod "//trim(num2lstr(Rod%IdNum))//" end A") EXIT END DO diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 1e640d4098..82a6096104 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -426,6 +426,8 @@ MODULE MoorDyn_Types REAL(DbKi) :: mu_kA !< axial kinetic friction coefficient [(-)] REAL(DbKi) :: mc !< ratio of the static friction coefficient to the kinetic friction coefficient [(-)] REAL(DbKi) :: cv !< saturated damping coefficient [(-)] + INTEGER(IntKi) :: Standalone !< Indicates MoorDyn run as standalone code if 1, coupled if 0 [-] + INTEGER(IntKi) :: inertialF = 0 !< Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no [-] INTEGER(IntKi) :: nxWave !< number of x wave grid points [-] INTEGER(IntKi) :: nyWave !< number of y wave grid points [-] INTEGER(IntKi) :: nzWave !< number of z wave grid points [-] @@ -455,8 +457,6 @@ MODULE MoorDyn_Types INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: dxIdx_map2_xStateIdx !< Mapping array from index of dX array to corresponding state index [-] LOGICAL :: VisMeshes !< Using visualization meshes as requested by glue code [-] TYPE(VisDiam) , DIMENSION(:), ALLOCATABLE :: VisRodsDiam !< Diameters for visualization of rods [-] - INTEGER(IntKi) :: Standalone !< Indicates MoorDyn run as standalone code if 1, coupled if 0 [-] - INTEGER(IntKi) :: inertialF = 0 !< Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no [-] END TYPE MD_ParameterType ! ======================= ! ========= MD_InputType ======= From 7bdeeb35eb588aaee40c60e9dd08190f8b0d2653 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Wed, 10 Jan 2024 11:40:19 -0700 Subject: [PATCH 73/91] Removed unecessary standalone variable and cleaned logic --- modules/moordyn/src/MoorDyn.f90 | 4 -- modules/moordyn/src/MoorDyn_Driver.f90 | 55 +++++++----------------- modules/moordyn/src/MoorDyn_Registry.txt | 1 - modules/moordyn/src/MoorDyn_Types.f90 | 1 - 4 files changed, 16 insertions(+), 45 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 22167aee53..ebde8cf519 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -200,10 +200,6 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er m%PtfmInit = InitInp%PtfmInit(:,1) ! is this copying necssary in case this is an individual instance in FAST.Farm? - p%Standalone = InitInp%Standalone - - - ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) if (InitInp%FarmSize > 0) then CALL WrScr(' >>> MoorDyn is running in array mode <<< ') diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index b83842dba9..3fbe8b580a 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -173,13 +173,9 @@ PROGRAM MoorDyn_Driver MD_InitInp%FarmSize = drvrInitInp%FarmSize - MD_InitInp%Standalone = 0 if (drvrInitInp%FarmSize > 0) then ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) nTurbines = drvrInitInp%FarmSize - else if (drvrInitInp%FarmSize < 0) then ! FarmSize<0 indicates standalone mode - MD_InitInp%Standalone = 1 - nTurbines = 1 ! to keep routines happy - else ! FarmSize==0 indicates normal, FAST module mode + else ! FarmSize==0 indicates normal, FAST module mode; FarmSize<0 indicates standalone mode nTurbines = 1 ! if a regular FAST module mode, we treat it like a nTurbine=1 farm case end if @@ -494,13 +490,14 @@ PROGRAM MoorDyn_Driver i = 1 ! read first timestep data K = 1 ! the index of the coupling points in the input mesh CoupledKinematics J = 1 ! the starting index of the relevant DOFs in the input array + + IF (MD_InitInp%FarmSize < 0) THEN + MD_p%TurbineRefPos(:,iTurb) = 0.0 + ENDIF + ! any coupled bodies (type -1) DO l = 1,MD_p%nCpldBodies(iTurb) - IF (MD_InitInp%Standalone == 1) THEN - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - ELSE - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) - ENDIF + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) ! full Euler angle approach MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -513,12 +510,7 @@ PROGRAM MoorDyn_Driver ! any coupled rods (type -1 or -2) >>> need to make rotations ignored if it's a pinned rod <<< DO l = 1,MD_p%nCpldRods(iTurb) - - IF (MD_InitInp%Standalone == 1) THEN - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - ELSE - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) - ENDIF + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -531,12 +523,7 @@ PROGRAM MoorDyn_Driver ! any coupled points (type -1) DO l = 1, MD_p%nCpldPoints(iTurb) - - IF (MD_InitInp%Standalone == 1) THEN - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - ELSE - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) - ENDIF + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = 0.0_DbKi !rdd_in(i, J:J+2) @@ -595,13 +582,13 @@ PROGRAM MoorDyn_Driver K = 1 ! the index of the coupling points in the input mesh CoupledKinematics J = 1 ! the starting index of the relevant DOFs in the input array + IF (MD_InitInp%FarmSize < 0) THEN + MD_p%TurbineRefPos(:,iTurb) = 0.0 + ENDIF + ! any coupled bodies (type -1) DO l = 1,MD_p%nCpldBodies(iTurb) - IF (MD_InitInp%Standalone == 1) THEN - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - ELSE - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) - ENDIF + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) ! full Euler angle approach MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -614,12 +601,7 @@ PROGRAM MoorDyn_Driver ! any coupled rods (type -1 or -2) >>> need to make rotations ignored if it's a pinned rod <<< DO l = 1,MD_p%nCpldRods(iTurb) - - IF (MD_InitInp%Standalone == 1) THEN - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - ELSE - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) - ENDIF + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) @@ -632,12 +614,7 @@ PROGRAM MoorDyn_Driver ! any coupled points (type -1) DO l = 1, MD_p%nCpldPoints(iTurb) - - IF (MD_InitInp%Standalone == 1) THEN - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - ELSE - MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) - ENDIF + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = 0.0_DbKi !rdd_in(i, J:J+2) diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 9c4d84e6d4..d4df4982c8 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -25,7 +25,6 @@ typedef ^ ^ ReKi rhoW - -99 typedef ^ ^ ReKi WtrDepth - -999.9 - "depth of water" "[m]" typedef ^ ^ ReKi PtfmInit {:}{:} - - "initial position of platform(s) shape: 6, nTurbines" - typedef ^ ^ IntKi FarmSize - 0 - "Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0, standalone mode if -1" - -typedef ^ ^ IntKi Standalone - 0 - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - typedef ^ ^ ReKi TurbineRefPos {:}{:} - - "reference position of turbines in farm, shape: 3, nTurbines" - typedef ^ ^ ReKi Tmax - - - "simulation duration" "[s]" typedef ^ ^ CHARACTER(1024) FileName - "" - "MoorDyn input file" diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 82a6096104..c6a3e38d67 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -48,7 +48,6 @@ MODULE MoorDyn_Types REAL(ReKi) :: WtrDepth = -999.9 !< depth of water [[m]] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PtfmInit !< initial position of platform(s) shape: 6, nTurbines [-] INTEGER(IntKi) :: FarmSize = 0 !< Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0 [-] - INTEGER(IntKi) :: Standalone = 0 !< Indicates MoorDyn run as standalone code if 1, coupled if 0, standalone mode if -1 [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TurbineRefPos !< reference position of turbines in farm, shape: 3, nTurbines [-] REAL(ReKi) :: Tmax !< simulation duration [[s]] CHARACTER(1024) :: FileName !< MoorDyn input file [-] From 677d81158346668cd5ebc1eb876b927e715e6572 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 10 Jan 2024 16:53:56 -0700 Subject: [PATCH 74/91] AWAE: revise logic to allow high-res grids smaller than IfW grids Also allow for wind along Y direction --- modules/awae/src/AWAE.f90 | 88 ++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index a01fc742ed..e4f2d50358 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -799,7 +799,7 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO type(AWAE_InitInputType), intent(in ) :: InitInp !< Input data for initialization routine type(AWAE_InputType), intent( out) :: u !< An initial guess for the input; input mesh must be defined - type(AWAE_ParameterType), intent( out) :: p !< Parameters + type(AWAE_ParameterType),target,intent( out) :: p !< Parameters type(AWAE_ContinuousStateType), intent( out) :: x !< Initial continuous states type(AWAE_DiscreteStateType), intent( out) :: xd !< Initial discrete states type(AWAE_ConstraintStateType), intent( out) :: z !< Initial guess of the constraint states @@ -817,12 +817,11 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO character(1024) :: rootDir, baseName, OutFileVTKDir ! Simulation root dir, basename for outputs integer(IntKi) :: i,j,nt ! loop counter real(ReKi) :: gridLoc ! Location of requested output slice in grid coordinates [0,sz-1] - real(ReKi) :: tmpDy,tmpRe integer(IntKi) :: errStat2 ! temporary error status of the operation character(ErrMsgLen) :: errMsg2 ! temporary error message character(*), parameter :: RoutineName = 'AWAE_Init' type(InflowWind_InitInputType) :: IfW_InitInp - type(InflowWind_InitOutputType) :: IfW_InitOut + type(InflowWind_InitOutputType), target :: IfW_InitOut ! Initialize variables for this routine errStat = ErrID_None @@ -1057,7 +1056,7 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO call WrScr(NewLine//'Initializing high-resolution grid for Turbine '//trim(Num2Lstr(nt))) call InflowWind_Init( IfW_InitInp, m%u_IfW_High, p%IfW(nt), x%IfW(nt), xd%IfW(nt), z%IfW(nt), OtherState%IfW(nt), m%y_IfW_High, m%IfW(nt), Interval, IfW_InitOut, ErrStat2, ErrMsg2 ) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat2 >= AbortErrLev) then + if (errStat >= AbortErrLev) then return end if @@ -1065,22 +1064,7 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! The InflowWind grid location is exactly centered on the TurbPos location in the Y direction. The high resolution grid ! must exactly match the sizing and location of the InflowWind grid. We are only going to check the Y and Z locations ! for now and throw an error if these don't match appropriately. - if (IfW_InitOut%WindFileInfo%YRange_Limited) then ! only check boundaries if the YRange is limited (we don't care what kind of wind) - tmpRe = p%Y0_High(nt) + (real(p%nY_high,ReKi)-1.0_ReKi)*p%dY_high(nt) ! upper bound of high-res grid - if ((.not. EqualRealNos(p%WT_Position(2,nt)+IfW_InitOut%WindFileInfo%YRange(1),p%Y0_High(nt))) .or. & ! lower bound - (.not. EqualRealNos(p%WT_Position(2,nt)+IfW_InitOut%WindFileInfo%YRange(2),tmpRe)) ) then ! upper bound - ErrStat2 = ErrID_Fatal - ErrMsg2 = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires the InflowWind high-res data range exactly match the high-res grid '// & - 'and the turbine is exactly centered in the high-res grid in the Y direction. '//NewLine//' Try setting:'//NewLine// & - ' Y0_high = '// & - trim(Num2LStr(p%WT_Position(2,nt)+IfW_InitOut%WindFileInfo%YRange(1))) - if (allocated(p%IfW(nt)%FlowField%Grid3D%Vel)) then - tmpDy = abs(IfW_InitOut%WindFileInfo%YRange(2)-IfW_InitOut%WindFileInfo%YRange(1))/(real(p%nY_high,ReKi)-1.0_ReKi) - ErrMsg2=trim(ErrMsg2)//NewLine//' dY_High = '//trim(Num2LStr(tmpDy)) - call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) - endif - endif - endif + call CheckModAmb3Boundaries() end do if (errStat >= AbortErrLev) return @@ -1281,6 +1265,70 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO +contains + subroutine CheckModAmb3Boundaries() + real(ReKi) :: Dx,Dy,Dz + real(ReKi) :: ff_lim(2) + real(ReKi) :: hr_lim(2) + real(ReKi), parameter :: GridTol = 1.0E-3 ! Tolerance from IfW for checking the high-res grid (Mod_AmbWind=3 only). + type(FlowFieldType), pointer :: ff ! alias to shorten notation to fullfield + type(WindFileDat), pointer :: wfi ! alias to shorten notation to WindFileInfo + character(1024) :: tmpMsg + + ff => p%IfW(nt)%FlowField + wfi => IfW_InitOut%WindFileInfo + + tmpMsg = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires the InflowWind high-res data range exactly match the high-res grid '// & + 'and the turbine is exactly centered in the high-res grid in the Y direction (or X direction if FlowField is along Y). '//NewLine//' Try setting:'//NewLine + ! check Z limits, if ZRange is limited (we don't care what kind of wind) + if (wfi%ZRange_Limited) then + endif + + ! check X/Y limits if range limited. Depends on orientation of winds. + if (wfi%YRange_Limited) then + ! flow field limits (with grid tolerance) + ff_lim(1) = p%WT_Position(2,nt) + wfi%YRange(1) - GridTol + ff_lim(2) = p%WT_Position(2,nt) + wfi%YRange(2) + GridTol + + ! wind X aligned with high-res X + if (.not. ff%RotateWindBox) then + ! high-res Y limits + hr_lim(1) = p%Y0_High(nt) + hr_lim(2) = p%Y0_High(nt) + (real(p%nY_high,ReKi)-1.0_ReKi)*p%dY_high(nt) + if ((hr_lim(1) < ff_lim(1)) .or. & + (hr_lim(2) > ff_lim(2)) ) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = trim(tmpMsg)// & + ' Y0_high = '//trim(Num2LStr(p%WT_Position(2,nt)+wfi%YRange(1))) + if (allocated(ff%Grid3D%Vel)) then + Dy = abs(wfi%YRange(2)-wfi%YRange(1))/(real(p%nY_high,ReKi)-1.0_ReKi) + ErrMsg2=trim(ErrMsg2)//NewLine//' dY_High = '//trim(Num2LStr(Dy)) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + endif + + ! wind X aligned with high-res Y + elseif (EqualRealNos(abs(ff%PropagationDir),PiBy2)) then + ! high-res X limits + hr_lim(1) = p%X0_High(nt) + hr_lim(2) = p%X0_High(nt) + (real(p%nX_high,ReKi)-1.0_ReKi)*p%dX_high(nt) + if ((hr_lim(1) < ff_lim(1)) .or. & + (hr_lim(2) > ff_lim(2)) ) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = trim(tmpMsg)// & + ' X0_high = '//trim(Num2LStr(p%WT_Position(1,nt)+wfi%YRange(1))) + if (allocated(ff%Grid3D%Vel)) then + Dx = abs(wfi%YRange(2)-wfi%YRange(1))/(real(p%nX_high,ReKi)-1.0_ReKi) + ErrMsg2=trim(ErrMsg2)//NewLine//' dX_High = '//trim(Num2LStr(Dx)) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + endif + elseif (.not. EqualRealNos(ff%PropagationDir,0.0_ReKi)) then ! wind not aligned with X or Y. This is not allowed at present + ErrStat2 = ErrID_Fatal + ErrMsg2 = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires InflowWind propagation direction alignment with X or Y (0, 90, 180, 270 degrees).' + endif + endif + end subroutine CheckModAmb3Boundaries end subroutine AWAE_Init From b621edbd9c5f6e7078d73762e1c486268bb405a1 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 10 Jan 2024 17:05:28 -0700 Subject: [PATCH 75/91] AWAE: Mod_AmbWind=3 add check on z-range --- modules/awae/src/AWAE.f90 | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index e4f2d50358..7ba865997a 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -1267,7 +1267,7 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO contains subroutine CheckModAmb3Boundaries() - real(ReKi) :: Dx,Dy,Dz + real(ReKi) :: Dxyz real(ReKi) :: ff_lim(2) real(ReKi) :: hr_lim(2) real(ReKi), parameter :: GridTol = 1.0E-3 ! Tolerance from IfW for checking the high-res grid (Mod_AmbWind=3 only). @@ -1278,10 +1278,28 @@ subroutine CheckModAmb3Boundaries() ff => p%IfW(nt)%FlowField wfi => IfW_InitOut%WindFileInfo - tmpMsg = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires the InflowWind high-res data range exactly match the high-res grid '// & - 'and the turbine is exactly centered in the high-res grid in the Y direction (or X direction if FlowField is along Y). '//NewLine//' Try setting:'//NewLine + tmpMsg = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires the InflowWind high-res grid '// & + 'is entirely contained within the high-res flow-field from InflowWind. '//NewLine//' Try setting:'//NewLine + ! check Z limits, if ZRange is limited (we don't care what kind of wind) if (wfi%ZRange_Limited) then + ! flow field limits (with grid tolerance) + ff_lim(1) = p%WT_Position(3,nt) + wfi%ZRange(1) - GridTol + ff_lim(2) = p%WT_Position(3,nt) + wfi%ZRange(2) + GridTol + ! high-res Z limits + hr_lim(1) = p%Z0_High(nt) + hr_lim(2) = p%Z0_High(nt) + (real(p%nZ_high,ReKi)-1.0_ReKi)*p%dZ_high(nt) + if ((hr_lim(1) < ff_lim(1)) .or. & + (hr_lim(2) > ff_lim(2)) ) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = trim(tmpMsg)// & + ' Z0_high = '//trim(Num2LStr(p%WT_Position(3,nt)+wfi%ZRange(1))) + if (allocated(ff%Grid3D%Vel)) then + Dxyz = abs(wfi%ZRange(2)-wfi%ZRange(1))/(real(p%nZ_high,ReKi)-1.0_ReKi) + ErrMsg2=trim(ErrMsg2)//NewLine//' dZ_High = '//trim(Num2LStr(Dxyz)) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + endif endif ! check X/Y limits if range limited. Depends on orientation of winds. @@ -1301,8 +1319,8 @@ subroutine CheckModAmb3Boundaries() ErrMsg2 = trim(tmpMsg)// & ' Y0_high = '//trim(Num2LStr(p%WT_Position(2,nt)+wfi%YRange(1))) if (allocated(ff%Grid3D%Vel)) then - Dy = abs(wfi%YRange(2)-wfi%YRange(1))/(real(p%nY_high,ReKi)-1.0_ReKi) - ErrMsg2=trim(ErrMsg2)//NewLine//' dY_High = '//trim(Num2LStr(Dy)) + Dxyz = abs(wfi%YRange(2)-wfi%YRange(1))/(real(p%nY_high,ReKi)-1.0_ReKi) + ErrMsg2=trim(ErrMsg2)//NewLine//' dY_High = '//trim(Num2LStr(Dxyz)) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) endif endif @@ -1318,8 +1336,8 @@ subroutine CheckModAmb3Boundaries() ErrMsg2 = trim(tmpMsg)// & ' X0_high = '//trim(Num2LStr(p%WT_Position(1,nt)+wfi%YRange(1))) if (allocated(ff%Grid3D%Vel)) then - Dx = abs(wfi%YRange(2)-wfi%YRange(1))/(real(p%nX_high,ReKi)-1.0_ReKi) - ErrMsg2=trim(ErrMsg2)//NewLine//' dX_High = '//trim(Num2LStr(Dx)) + Dxyz = abs(wfi%YRange(2)-wfi%YRange(1))/(real(p%nX_high,ReKi)-1.0_ReKi) + ErrMsg2=trim(ErrMsg2)//NewLine//' dX_High = '//trim(Num2LStr(Dxyz)) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) endif endif From 25fb3b098d201265fba4c08c22553cdac9c6c6c3 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 16 Jan 2024 19:08:48 +0000 Subject: [PATCH 76/91] Fix bug in openfast-cpp CMakeLists.txt runtime install destination The install runtime destination was set to lib, this commit changes it to bin --- glue-codes/openfast-cpp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue-codes/openfast-cpp/CMakeLists.txt b/glue-codes/openfast-cpp/CMakeLists.txt index 55823e0465..658d502a01 100644 --- a/glue-codes/openfast-cpp/CMakeLists.txt +++ b/glue-codes/openfast-cpp/CMakeLists.txt @@ -72,7 +72,7 @@ endif(MPI_LINK_FLAGS) install(TARGETS openfastcpp openfastcpplib EXPORT "${CMAKE_PROJECT_NAME}Libraries" - RUNTIME DESTINATION lib + RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include From 4dd1b9c96c4a32e84d26ae281c8dc62af221c598 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 16 Jan 2024 12:53:40 -0700 Subject: [PATCH 77/91] AWAE: Mod_AmbWind=3 modify checks from GH PR suggestions --- modules/awae/src/AWAE.f90 | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index 7ba865997a..4710c2dcf9 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -1278,8 +1278,8 @@ subroutine CheckModAmb3Boundaries() ff => p%IfW(nt)%FlowField wfi => IfW_InitOut%WindFileInfo - tmpMsg = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires the InflowWind high-res grid '// & - 'is entirely contained within the high-res flow-field from InflowWind. '//NewLine//' Try setting:'//NewLine + tmpMsg = NewLine//NewLine//'Turbine '//trim(Num2LStr(nt))//' -- Mod_AmbWind=3 requires the FAST.Farm high-res grid '// & + 'is entirely contained within the flow-field from InflowWind. '//NewLine//' Try setting:'//NewLine ! check Z limits, if ZRange is limited (we don't care what kind of wind) if (wfi%ZRange_Limited) then @@ -1299,17 +1299,17 @@ subroutine CheckModAmb3Boundaries() ErrMsg2=trim(ErrMsg2)//NewLine//' dZ_High = '//trim(Num2LStr(Dxyz)) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) endif + ErrMsg2=NewLine//' for Turbine '//trim(Num2LStr(nt)) endif endif - ! check X/Y limits if range limited. Depends on orientation of winds. + ! check FlowField Y limits if range limited. Depends on orientation of winds. if (wfi%YRange_Limited) then - ! flow field limits (with grid tolerance) - ff_lim(1) = p%WT_Position(2,nt) + wfi%YRange(1) - GridTol - ff_lim(2) = p%WT_Position(2,nt) + wfi%YRange(2) + GridTol - ! wind X aligned with high-res X - if (.not. ff%RotateWindBox) then + if ((.not. ff%RotateWindBox) .or. EqualRealNos(abs(ff%PropagationDir),Pi)) then + ! flow field limits (with grid tolerance) + ff_lim(1) = p%WT_Position(2,nt) + wfi%YRange(1) - GridTol + ff_lim(2) = p%WT_Position(2,nt) + wfi%YRange(2) + GridTol ! high-res Y limits hr_lim(1) = p%Y0_High(nt) hr_lim(2) = p%Y0_High(nt) + (real(p%nY_high,ReKi)-1.0_ReKi)*p%dY_high(nt) @@ -1323,10 +1323,14 @@ subroutine CheckModAmb3Boundaries() ErrMsg2=trim(ErrMsg2)//NewLine//' dY_High = '//trim(Num2LStr(Dxyz)) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) endif + ErrMsg2=NewLine//' for Turbine '//trim(Num2LStr(nt)) endif ! wind X aligned with high-res Y elseif (EqualRealNos(abs(ff%PropagationDir),PiBy2)) then + ! flow field limits (with grid tolerance) + ff_lim(1) = p%WT_Position(1,nt) + wfi%YRange(1) - GridTol + ff_lim(2) = p%WT_Position(1,nt) + wfi%YRange(2) + GridTol ! high-res X limits hr_lim(1) = p%X0_High(nt) hr_lim(2) = p%X0_High(nt) + (real(p%nX_high,ReKi)-1.0_ReKi)*p%dX_high(nt) @@ -1340,6 +1344,7 @@ subroutine CheckModAmb3Boundaries() ErrMsg2=trim(ErrMsg2)//NewLine//' dX_High = '//trim(Num2LStr(Dxyz)) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) endif + ErrMsg2=NewLine//' for Turbine '//trim(Num2LStr(nt)) endif elseif (.not. EqualRealNos(ff%PropagationDir,0.0_ReKi)) then ! wind not aligned with X or Y. This is not allowed at present ErrStat2 = ErrID_Fatal From 66a7547437882756a407f9ae9c4c1e984f39a3aa Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 16 Jan 2024 14:00:14 -0700 Subject: [PATCH 78/91] update changelog --- docs/changelogs/v3.5.2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelogs/v3.5.2.md b/docs/changelogs/v3.5.2.md index bae421240d..e28b4dbed0 100644 --- a/docs/changelogs/v3.5.2.md +++ b/docs/changelogs/v3.5.2.md @@ -44,6 +44,10 @@ See GitHub Actions #1913 ADI: memory leak in ADI_UpdateStates +### AWAE + +#1963 FAST.Farm, Mod_AmbWind=3: add error if HR grid not centered on turbine in Y dimension + ### HydroDyn #1872 Fix segfault in HD when no outputs specified From 2acce08433fe1a7ee34067ddf33d3f051cc2e2e8 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Tue, 16 Jan 2024 16:24:04 -0700 Subject: [PATCH 79/91] MD version update --- modules/moordyn/src/MoorDyn.f90 | 4 ++-- modules/moordyn/src/MoorDyn_Driver.f90 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index ebde8cf519..54d8f1420f 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -34,7 +34,7 @@ MODULE MoorDyn PRIVATE - TYPE(ProgDesc), PARAMETER :: MD_ProgDesc = ProgDesc( 'MoorDyn', 'v2.0.0', '2023-09-18' ) + TYPE(ProgDesc), PARAMETER :: MD_ProgDesc = ProgDesc( 'MoorDyn', 'v2.2.2', '2024-01-16' ) INTEGER(IntKi), PARAMETER :: wordy = 0 ! verbosity level. >1 = more console output @@ -163,7 +163,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er InitOut%Ver = MD_ProgDesc CALL WrScr(' This is MoorDyn v2, with significant input file changes from v1.') - CALL WrScr(' Copyright: (C) 2023 National Renewable Energy Laboratory, (C) 2019 Matt Hall') + CALL WrScr(' Copyright: (C) 2024 National Renewable Energy Laboratory, (C) 2019 Matt Hall') !--------------------------------------------------------------------------------------------- diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 3fbe8b580a..26628b1634 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -132,7 +132,7 @@ PROGRAM MoorDyn_Driver IF ( LEN( TRIM(FlagArg) ) > 0 ) CALL NormStop() ! Display the copyright notice - CALL DispCopyrightLicense( version%Name, 'Copyright (C) 2021 NREL, 2019 Matt Hall' ) + CALL DispCopyrightLicense( version%Name, 'Copyright (C) 2024 NREL, 2019 Matt Hall' ) ! Obtain OpenFAST git commit hash git_commit = QueryGitVersion() ! Tell our users what they're running @@ -144,7 +144,7 @@ PROGRAM MoorDyn_Driver CALL CPU_TIME ( ProgStrtCPU ) ! Initial time (this zeros the start time when used as a MATLAB function) - CALL WrScr( ' MD Driver updated 2022-01-12') + CALL WrScr( ' MD Driver updated 2024-01-16') ! Parse the driver input file and run the simulation based on that file CALL get_command_argument(1, drvrFilename) From 208c806ad17256a6595b31025546574c4bdbca3f Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Thu, 18 Jan 2024 10:27:09 -0700 Subject: [PATCH 80/91] MD: change copyright display --- modules/moordyn/src/MoorDyn.f90 | 2 +- modules/moordyn/src/MoorDyn_Driver.f90 | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 54d8f1420f..fc6f47db6e 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -163,7 +163,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er InitOut%Ver = MD_ProgDesc CALL WrScr(' This is MoorDyn v2, with significant input file changes from v1.') - CALL WrScr(' Copyright: (C) 2024 National Renewable Energy Laboratory, (C) 2019 Matt Hall') + CALL DispCopyrightLicense( MD_ProgDesc%Name, 'Copyright (C) 2019 Matt Hall' ) !--------------------------------------------------------------------------------------------- diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 26628b1634..de826a52b1 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -114,7 +114,7 @@ PROGRAM MoorDyn_Driver CHARACTER(20) :: FlagArg ! flag argument from command line CHARACTER(200) :: git_commit ! String containing the current git commit hash - TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'MoorDyn Driver', '', '' ) + TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'MoorDyn Driver', '', '2024-01-18' ) @@ -131,8 +131,8 @@ PROGRAM MoorDyn_Driver CALL CheckArgs( MD_InitInp%FileName, Arg2=drvrInitInp%InputsFile, Flag=FlagArg ) IF ( LEN( TRIM(FlagArg) ) > 0 ) CALL NormStop() - ! Display the copyright notice - CALL DispCopyrightLicense( version%Name, 'Copyright (C) 2024 NREL, 2019 Matt Hall' ) + ! ! Display the copyright notice + ! CALL DispCopyrightLicense( version%Name, ' Copyright (C) 2019 Matt Hall' ) ! Obtain OpenFAST git commit hash git_commit = QueryGitVersion() ! Tell our users what they're running @@ -144,7 +144,7 @@ PROGRAM MoorDyn_Driver CALL CPU_TIME ( ProgStrtCPU ) ! Initial time (this zeros the start time when used as a MATLAB function) - CALL WrScr( ' MD Driver updated 2024-01-16') + CALL WrScr('MD Driver updated '//TRIM( version%Date )) ! Parse the driver input file and run the simulation based on that file CALL get_command_argument(1, drvrFilename) From da0ad544c19abc07ca30f3e5c97e44d7672ceb14 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Thu, 18 Jan 2024 15:04:19 -0700 Subject: [PATCH 81/91] Update pointer to r-test/main for 3.5.2 release --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index 58ced27ad1..b63e928023 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 58ced27ad1e6ca167ba174046891c63185b18901 +Subproject commit b63e9280234c2fb5695a37931d2329f3011e97ec From 418db34a0476e66fbc81ae5a8568ea02b1cc028c Mon Sep 17 00:00:00 2001 From: Garrett Barter Date: Fri, 19 Jan 2024 13:57:49 -0700 Subject: [PATCH 82/91] switch from -fpic to -fPIC for all gfortran builds --- cmake/OpenfastFortranOptions.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/OpenfastFortranOptions.cmake b/cmake/OpenfastFortranOptions.cmake index 0efa0aed55..f09837fbcf 100644 --- a/cmake/OpenfastFortranOptions.cmake +++ b/cmake/OpenfastFortranOptions.cmake @@ -109,9 +109,9 @@ endmacro(check_f2008_features) # macro(set_fast_gfortran) if(NOT WIN32) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpic ") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpic") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpic") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fPIC ") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") endif(NOT WIN32) # Fix free-form compilation for OpenFAST From 939674e4d83cb935f6115f110166f45ecbaa949b Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 22 Jan 2024 11:47:38 -0700 Subject: [PATCH 83/91] ExtLoads: move integers from DX_u to DX_p --- glue-codes/openfast-cpp/src/OpenFAST.H | 2 + glue-codes/openfast-cpp/src/OpenFAST.cpp | 11 +- modules/extloads/src/ExtLoads.f90 | 20 +- modules/extloads/src/ExtLoadsDX_Registry.txt | 7 +- modules/extloads/src/ExtLoadsDX_Types.f90 | 813 +++++++++++------- modules/extloads/src/ExtLoadsDX_Types.h | 10 +- modules/extloads/src/ExtLoads_Registry.txt | 1 + modules/extloads/src/ExtLoads_Types.f90 | 92 ++ modules/openfast-library/src/FAST_Library.f90 | 42 +- modules/openfast-library/src/FAST_Library.h | 4 +- 10 files changed, 637 insertions(+), 365 deletions(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.H b/glue-codes/openfast-cpp/src/OpenFAST.H index 8635f373dc..9915d7bbb3 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.H +++ b/glue-codes/openfast-cpp/src/OpenFAST.H @@ -333,6 +333,8 @@ class OpenFAST { //! Data structure to get deflections from ExternalLoads module in OpenFAST std::vector extld_i_f_FAST; // Input from OpenFAST + //! Data structure to get deflections from ExternalLoads module in OpenFAST + std::vector extld_p_f_FAST; // Parameter from OpenFAST //! Data structure to send force information to ExternalLoads module in OpenFAST std::vector extld_o_t_FAST; // Output to OpenFAST diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 58e2549a54..8afc735825 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -674,6 +674,7 @@ void fast::OpenFAST::init() { &turbineData[iTurb].numBlades, &ntStart, &extld_i_f_FAST[iTurb], + &extld_p_f_FAST[iTurb], &extld_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], @@ -778,6 +779,7 @@ void fast::OpenFAST::init() { &turbineData[iTurb].zRef, &turbineData[iTurb].shearExp, &extld_i_f_FAST[iTurb], + &extld_p_f_FAST[iTurb], &extld_o_t_FAST[iTurb], &sc->ip_from_FAST[iTurb], &sc->op_to_FAST[iTurb], @@ -2090,8 +2092,9 @@ void fast::OpenFAST::allocateMemory_preInit() { extinfw_i_f_FAST.resize(nTurbinesProc) ; extinfw_o_t_FAST.resize(nTurbinesProc) ; - // Allocate memory for ExtLd Input types in FAST + // Allocate memory for ExtLd Input/Parameter/Output types in FAST extld_i_f_FAST.resize(nTurbinesProc) ; + extld_p_f_FAST.resize(nTurbinesProc) ; extld_o_t_FAST.resize(nTurbinesProc) ; if(scStatus) { @@ -2150,11 +2153,11 @@ void fast::OpenFAST::allocateMemory_postInit(int iTurbLoc) { turbineData[iTurbLoc].nBRfsiPtsBlade.resize(turbineData[iTurbLoc].numBlades); int nTotBldNds = 0; for(int i=0; i < turbineData[iTurbLoc].numBlades; i++) { - nTotBldNds += extld_i_f_FAST[iTurbLoc].nBladeNodes[i]; - turbineData[iTurbLoc].nBRfsiPtsBlade[i] = extld_i_f_FAST[iTurbLoc].nBladeNodes[i]; + nTotBldNds += extld_p_f_FAST[iTurbLoc].nBladeNodes[i]; + turbineData[iTurbLoc].nBRfsiPtsBlade[i] = extld_p_f_FAST[iTurbLoc].nBladeNodes[i]; turbineData[iTurbLoc].nTotBRfsiPtsBlade += turbineData[iTurbLoc].nBRfsiPtsBlade[i]; } - turbineData[iTurbLoc].nBRfsiPtsTwr = extld_i_f_FAST[iTurbLoc].nTowerNodes[0]; + turbineData[iTurbLoc].nBRfsiPtsTwr = extld_p_f_FAST[iTurbLoc].nTowerNodes[0]; // Allocate memory for reference position only for 1 time step - np1 for(int k=0; k<4; k++) { diff --git a/modules/extloads/src/ExtLoads.f90 b/modules/extloads/src/ExtLoads.f90 index 84f034f13b..11f2ce86dc 100644 --- a/modules/extloads/src/ExtLoads.f90 +++ b/modules/extloads/src/ExtLoads.f90 @@ -299,7 +299,7 @@ subroutine Init_u( u, p, InitInp, errStat, errMsg ) USE BeamDyn_IO, ONLY: BD_CrvExtractCrv type(ExtLd_InputType), intent( out) :: u !< Input data - type(ExtLd_ParameterType), intent(in ) :: p !< Parameters + type(ExtLd_ParameterType), intent(inout) :: p !< Parameters (inout so can update DX_p) type(ExtLd_InitInputType), intent(in ) :: InitInp !< Input data for ExtLd initialization routine integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None @@ -542,15 +542,15 @@ subroutine Init_u( u, p, InitInp, errStat, errMsg ) end do !k=numBlades ! Set the parameters first - CALL AllocPAry( u%DX_u%nTowerNodes, 1, 'nTowerNodes', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - u%DX_u%c_obj%nTowerNodes_Len = 1; u%DX_u%c_obj%nTowerNodes = C_LOC( u%DX_u%nTowerNodes(1) ) - u%DX_u%nTowerNodes(1) = p%NumTwrNds - CALL AllocPAry( u%DX_u%nBlades, 1, 'nBlades', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - u%DX_u%c_obj%nBlades_Len = 1; u%DX_u%c_obj%nBlades = C_LOC( u%DX_u%nBlades(1) ) - u%DX_u%nBlades(1) = p%NumBlds - CALL AllocPAry( u%DX_u%nBladeNodes, p%NumBlds, 'nBladeNodes', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - u%DX_u%c_obj%nBladeNodes_Len = p%NumBlds; u%DX_u%c_obj%nBladeNodes = C_LOC( u%DX_u%nBladeNodes(1) ) - u%DX_u%nBladeNodes(:) = p%NumBldNds(:) + CALL AllocPAry( p%DX_p%nTowerNodes, 1, 'nTowerNodes', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + p%DX_p%c_obj%nTowerNodes_Len = 1; p%DX_p%c_obj%nTowerNodes = C_LOC( p%DX_p%nTowerNodes(1) ) + p%DX_p%nTowerNodes(1) = p%NumTwrNds + CALL AllocPAry( p%DX_p%nBlades, 1, 'nBlades', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + p%DX_p%c_obj%nBlades_Len = 1; p%DX_p%c_obj%nBlades = C_LOC( p%DX_p%nBlades(1) ) + p%DX_p%nBlades(1) = p%NumBlds + CALL AllocPAry( p%DX_p%nBladeNodes, p%NumBlds, 'nBladeNodes', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + p%DX_p%c_obj%nBladeNodes_Len = p%NumBlds; p%DX_p%c_obj%nBladeNodes = C_LOC( p%DX_p%nBladeNodes(1) ) + p%DX_p%nBladeNodes(:) = p%NumBldNds(:) ! Set the reference positions next CALL AllocPAry( u%DX_u%twrRefPos, p%NumTwrNds*6, 'twrRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) diff --git a/modules/extloads/src/ExtLoadsDX_Registry.txt b/modules/extloads/src/ExtLoadsDX_Registry.txt index 7f09fae1ca..042033a4a0 100644 --- a/modules/extloads/src/ExtLoadsDX_Registry.txt +++ b/modules/extloads/src/ExtLoadsDX_Registry.txt @@ -28,15 +28,16 @@ typedef ^ InputType R8Ki bldRefPos {:} - - typedef ^ InputType R8Ki hubRefPos {:} - - "Reference position of the tower nodes - to send to external driver" typedef ^ InputType R8Ki nacRefPos {:} - - "Reference position of the all blade nodes - to send to external driver" typedef ^ InputType R8Ki bldRootRefPos {:} - - "Reference position of the blade root nodes - to send to external driver" -typedef ^ InputType IntKi nBlades {:} - - "Number of blades" -typedef ^ InputType IntKi nBladeNodes {:} - - "Number of blade nodes for each blade" - -typedef ^ InputType IntKi nTowerNodes {:} - - "Number of tower nodes for each blade" - typedef ^ InputType R8Ki bldChord {:} - - "Blade chord" m typedef ^ InputType R8Ki bldRloc {:} - - "Radial location along the blade" m typedef ^ InputType R8Ki twrDia {:} - - "Tower diameter" m typedef ^ InputType R8Ki twrHloc {:} - - "Height location along the tower" m typedef ^ InputType R8Ki bldPitch {:} - - "Pitch angle of blade" +# ..... Parameters ................................................................................................................ +typedef ^ ParameterType IntKi nBlades {:} - - "Number of blades" +typedef ^ ParameterType IntKi nBladeNodes {:} - - "Number of blade nodes for each blade" - +typedef ^ ParameterType IntKi nTowerNodes {:} - - "Number of tower nodes for each blade" - # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: diff --git a/modules/extloads/src/ExtLoadsDX_Types.f90 b/modules/extloads/src/ExtLoadsDX_Types.f90 index 6fd8494e49..f989cb6ac9 100644 --- a/modules/extloads/src/ExtLoadsDX_Types.f90 +++ b/modules/extloads/src/ExtLoadsDX_Types.f90 @@ -57,12 +57,6 @@ MODULE ExtLoadsDX_Types INTEGER(C_int) :: nacRefPos_Len = 0 TYPE(C_ptr) :: bldRootRefPos = C_NULL_PTR INTEGER(C_int) :: bldRootRefPos_Len = 0 - TYPE(C_ptr) :: nBlades = C_NULL_PTR - INTEGER(C_int) :: nBlades_Len = 0 - TYPE(C_ptr) :: nBladeNodes = C_NULL_PTR - INTEGER(C_int) :: nBladeNodes_Len = 0 - TYPE(C_ptr) :: nTowerNodes = C_NULL_PTR - INTEGER(C_int) :: nTowerNodes_Len = 0 TYPE(C_ptr) :: bldChord = C_NULL_PTR INTEGER(C_int) :: bldChord_Len = 0 TYPE(C_ptr) :: bldRloc = C_NULL_PTR @@ -86,9 +80,6 @@ MODULE ExtLoadsDX_Types REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: hubRefPos => NULL() !< Reference position of the tower nodes - to send to external driver [-] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: nacRefPos => NULL() !< Reference position of the all blade nodes - to send to external driver [-] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRootRefPos => NULL() !< Reference position of the blade root nodes - to send to external driver [-] - INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBlades => NULL() !< Number of blades [-] - INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBladeNodes => NULL() !< Number of blade nodes for each blade [-] - INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nTowerNodes => NULL() !< Number of tower nodes for each blade [-] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldChord => NULL() !< Blade chord [m] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRloc => NULL() !< Radial location along the blade [m] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrDia => NULL() !< Tower diameter [m] @@ -96,6 +87,23 @@ MODULE ExtLoadsDX_Types REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldPitch => NULL() !< Pitch angle of blade [-] END TYPE ExtLdDX_InputType ! ======================= +! ========= ExtLdDX_ParameterType_C ======= + TYPE, BIND(C) :: ExtLdDX_ParameterType_C + TYPE(C_PTR) :: object = C_NULL_PTR + TYPE(C_ptr) :: nBlades = C_NULL_PTR + INTEGER(C_int) :: nBlades_Len = 0 + TYPE(C_ptr) :: nBladeNodes = C_NULL_PTR + INTEGER(C_int) :: nBladeNodes_Len = 0 + TYPE(C_ptr) :: nTowerNodes = C_NULL_PTR + INTEGER(C_int) :: nTowerNodes_Len = 0 + END TYPE ExtLdDX_ParameterType_C + TYPE, PUBLIC :: ExtLdDX_ParameterType + TYPE( ExtLdDX_ParameterType_C ) :: C_obj + INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBlades => NULL() !< Number of blades [-] + INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBladeNodes => NULL() !< Number of blade nodes for each blade [-] + INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nTowerNodes => NULL() !< Number of tower nodes for each blade [-] + END TYPE ExtLdDX_ParameterType +! ======================= ! ========= ExtLdDX_OutputType_C ======= TYPE, BIND(C) :: ExtLdDX_OutputType_C TYPE(C_PTR) :: object = C_NULL_PTR @@ -276,51 +284,6 @@ SUBROUTINE ExtLdDX_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Err END IF DstInputData%bldRootRefPos = SrcInputData%bldRootRefPos ENDIF -IF (ASSOCIATED(SrcInputData%nBlades)) THEN - i1_l = LBOUND(SrcInputData%nBlades,1) - i1_u = UBOUND(SrcInputData%nBlades,1) - IF (.NOT. ASSOCIATED(DstInputData%nBlades)) THEN - ALLOCATE(DstInputData%nBlades(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nBlades.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%nBlades_Len = SIZE(DstInputData%nBlades) - IF (DstInputData%c_obj%nBlades_Len > 0) & - DstInputData%c_obj%nBlades = C_LOC( DstInputData%nBlades( i1_l ) ) - END IF - DstInputData%nBlades = SrcInputData%nBlades -ENDIF -IF (ASSOCIATED(SrcInputData%nBladeNodes)) THEN - i1_l = LBOUND(SrcInputData%nBladeNodes,1) - i1_u = UBOUND(SrcInputData%nBladeNodes,1) - IF (.NOT. ASSOCIATED(DstInputData%nBladeNodes)) THEN - ALLOCATE(DstInputData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%nBladeNodes_Len = SIZE(DstInputData%nBladeNodes) - IF (DstInputData%c_obj%nBladeNodes_Len > 0) & - DstInputData%c_obj%nBladeNodes = C_LOC( DstInputData%nBladeNodes( i1_l ) ) - END IF - DstInputData%nBladeNodes = SrcInputData%nBladeNodes -ENDIF -IF (ASSOCIATED(SrcInputData%nTowerNodes)) THEN - i1_l = LBOUND(SrcInputData%nTowerNodes,1) - i1_u = UBOUND(SrcInputData%nTowerNodes,1) - IF (.NOT. ASSOCIATED(DstInputData%nTowerNodes)) THEN - ALLOCATE(DstInputData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%nTowerNodes_Len = SIZE(DstInputData%nTowerNodes) - IF (DstInputData%c_obj%nTowerNodes_Len > 0) & - DstInputData%c_obj%nTowerNodes = C_LOC( DstInputData%nTowerNodes( i1_l ) ) - END IF - DstInputData%nTowerNodes = SrcInputData%nTowerNodes -ENDIF IF (ASSOCIATED(SrcInputData%bldChord)) THEN i1_l = LBOUND(SrcInputData%bldChord,1) i1_u = UBOUND(SrcInputData%bldChord,1) @@ -489,27 +452,6 @@ SUBROUTINE ExtLdDX_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers InputData%C_obj%bldRootRefPos = C_NULL_PTR InputData%C_obj%bldRootRefPos_Len = 0 ENDIF -IF (ASSOCIATED(InputData%nBlades)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%nBlades) - InputData%nBlades => NULL() - InputData%C_obj%nBlades = C_NULL_PTR - InputData%C_obj%nBlades_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%nBladeNodes)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%nBladeNodes) - InputData%nBladeNodes => NULL() - InputData%C_obj%nBladeNodes = C_NULL_PTR - InputData%C_obj%nBladeNodes_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%nTowerNodes)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%nTowerNodes) - InputData%nTowerNodes => NULL() - InputData%C_obj%nTowerNodes = C_NULL_PTR - InputData%C_obj%nTowerNodes_Len = 0 -ENDIF IF (ASSOCIATED(InputData%bldChord)) THEN IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%bldChord) @@ -632,21 +574,6 @@ SUBROUTINE ExtLdDX_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 2*1 ! bldRootRefPos upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%bldRootRefPos) ! bldRootRefPos END IF - Int_BufSz = Int_BufSz + 1 ! nBlades allocated yes/no - IF ( ASSOCIATED(InData%nBlades) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! nBlades upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%nBlades) ! nBlades - END IF - Int_BufSz = Int_BufSz + 1 ! nBladeNodes allocated yes/no - IF ( ASSOCIATED(InData%nBladeNodes) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! nBladeNodes upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%nBladeNodes) ! nBladeNodes - END IF - Int_BufSz = Int_BufSz + 1 ! nTowerNodes allocated yes/no - IF ( ASSOCIATED(InData%nTowerNodes) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! nTowerNodes upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%nTowerNodes) ! nTowerNodes - END IF Int_BufSz = Int_BufSz + 1 ! bldChord allocated yes/no IF ( ASSOCIATED(InData%bldChord) ) THEN Int_BufSz = Int_BufSz + 2*1 ! bldChord upper/lower bounds for each dimension @@ -851,51 +778,6 @@ SUBROUTINE ExtLdDX_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ASSOCIATED(InData%nBlades) ) 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%nBlades,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nBlades,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%nBlades,1), UBOUND(InData%nBlades,1) - IntKiBuf(Int_Xferred) = InData%nBlades(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%nBladeNodes) ) 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%nBladeNodes,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nBladeNodes,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%nBladeNodes,1), UBOUND(InData%nBladeNodes,1) - IntKiBuf(Int_Xferred) = InData%nBladeNodes(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%nTowerNodes) ) 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%nTowerNodes,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nTowerNodes,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%nTowerNodes,1), UBOUND(InData%nTowerNodes,1) - IntKiBuf(Int_Xferred) = InData%nTowerNodes(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF IF ( .NOT. ASSOCIATED(InData%bldChord) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1210,69 +1092,6 @@ SUBROUTINE ExtLdDX_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nBlades 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 (ASSOCIATED(OutData%nBlades)) DEALLOCATE(OutData%nBlades) - ALLOCATE(OutData%nBlades(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBlades.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%nBlades_Len = SIZE(OutData%nBlades) - IF (OutData%c_obj%nBlades_Len > 0) & - OutData%c_obj%nBlades = C_LOC( OutData%nBlades( i1_l ) ) - DO i1 = LBOUND(OutData%nBlades,1), UBOUND(OutData%nBlades,1) - OutData%nBlades(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nBladeNodes 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 (ASSOCIATED(OutData%nBladeNodes)) DEALLOCATE(OutData%nBladeNodes) - ALLOCATE(OutData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%nBladeNodes_Len = SIZE(OutData%nBladeNodes) - IF (OutData%c_obj%nBladeNodes_Len > 0) & - OutData%c_obj%nBladeNodes = C_LOC( OutData%nBladeNodes( i1_l ) ) - DO i1 = LBOUND(OutData%nBladeNodes,1), UBOUND(OutData%nBladeNodes,1) - OutData%nBladeNodes(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nTowerNodes 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 (ASSOCIATED(OutData%nTowerNodes)) DEALLOCATE(OutData%nTowerNodes) - ALLOCATE(OutData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%nTowerNodes_Len = SIZE(OutData%nTowerNodes) - IF (OutData%c_obj%nTowerNodes_Len > 0) & - OutData%c_obj%nTowerNodes = C_LOC( OutData%nTowerNodes( i1_l ) ) - DO i1 = LBOUND(OutData%nTowerNodes,1), UBOUND(OutData%nTowerNodes,1) - OutData%nTowerNodes(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldChord not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -1486,33 +1305,6 @@ SUBROUTINE ExtLdDX_C2Fary_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) END IF END IF - ! -- nBlades Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nBlades ) ) THEN - NULLIFY( InputData%nBlades ) - ELSE - CALL C_F_POINTER(InputData%C_obj%nBlades, InputData%nBlades, (/InputData%C_obj%nBlades_Len/)) - END IF - END IF - - ! -- nBladeNodes Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nBladeNodes ) ) THEN - NULLIFY( InputData%nBladeNodes ) - ELSE - CALL C_F_POINTER(InputData%C_obj%nBladeNodes, InputData%nBladeNodes, (/InputData%C_obj%nBladeNodes_Len/)) - END IF - END IF - - ! -- nTowerNodes Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nTowerNodes ) ) THEN - NULLIFY( InputData%nTowerNodes ) - ELSE - CALL C_F_POINTER(InputData%C_obj%nTowerNodes, InputData%nTowerNodes, (/InputData%C_obj%nTowerNodes_Len/)) - END IF - END IF - ! -- bldChord Input Data fields IF ( .NOT. SkipPointers_local ) THEN IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldChord ) ) THEN @@ -1695,42 +1487,6 @@ SUBROUTINE ExtLdDX_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) END IF END IF - ! -- nBlades Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%nBlades)) THEN - InputData%c_obj%nBlades_Len = 0 - InputData%c_obj%nBlades = C_NULL_PTR - ELSE - InputData%c_obj%nBlades_Len = SIZE(InputData%nBlades) - IF (InputData%c_obj%nBlades_Len > 0) & - InputData%c_obj%nBlades = C_LOC( InputData%nBlades( LBOUND(InputData%nBlades,1) ) ) - END IF - END IF - - ! -- nBladeNodes Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%nBladeNodes)) THEN - InputData%c_obj%nBladeNodes_Len = 0 - InputData%c_obj%nBladeNodes = C_NULL_PTR - ELSE - InputData%c_obj%nBladeNodes_Len = SIZE(InputData%nBladeNodes) - IF (InputData%c_obj%nBladeNodes_Len > 0) & - InputData%c_obj%nBladeNodes = C_LOC( InputData%nBladeNodes( LBOUND(InputData%nBladeNodes,1) ) ) - END IF - END IF - - ! -- nTowerNodes Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%nTowerNodes)) THEN - InputData%c_obj%nTowerNodes_Len = 0 - InputData%c_obj%nTowerNodes = C_NULL_PTR - ELSE - InputData%c_obj%nTowerNodes_Len = SIZE(InputData%nTowerNodes) - IF (InputData%c_obj%nTowerNodes_Len > 0) & - InputData%c_obj%nTowerNodes = C_LOC( InputData%nTowerNodes( LBOUND(InputData%nTowerNodes,1) ) ) - END IF - END IF - ! -- bldChord Input Data fields IF ( .NOT. SkipPointers_local ) THEN IF ( .NOT. ASSOCIATED(InputData%bldChord)) THEN @@ -1792,9 +1548,9 @@ SUBROUTINE ExtLdDX_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) END IF END SUBROUTINE ExtLdDX_F2C_CopyInput - SUBROUTINE ExtLdDX_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(ExtLdDX_OutputType), INTENT(IN) :: SrcOutputData - TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: DstOutputData + SUBROUTINE ExtLdDX_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLdDX_ParameterType), INTENT(IN) :: SrcParamData + TYPE(ExtLdDX_ParameterType), INTENT(INOUT) :: DstParamData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -1803,44 +1559,59 @@ SUBROUTINE ExtLdDX_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_CopyOutput' + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_CopyParam' ! ErrStat = ErrID_None ErrMsg = "" -IF (ASSOCIATED(SrcOutputData%twrLd)) THEN - i1_l = LBOUND(SrcOutputData%twrLd,1) - i1_u = UBOUND(SrcOutputData%twrLd,1) - IF (.NOT. ASSOCIATED(DstOutputData%twrLd)) THEN - ALLOCATE(DstOutputData%twrLd(i1_l:i1_u),STAT=ErrStat2) +IF (ASSOCIATED(SrcParamData%nBlades)) THEN + i1_l = LBOUND(SrcParamData%nBlades,1) + i1_u = UBOUND(SrcParamData%nBlades,1) + IF (.NOT. ASSOCIATED(DstParamData%nBlades)) THEN + ALLOCATE(DstParamData%nBlades(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%twrLd.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nBlades.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DstOutputData%c_obj%twrLd_Len = SIZE(DstOutputData%twrLd) - IF (DstOutputData%c_obj%twrLd_Len > 0) & - DstOutputData%c_obj%twrLd = C_LOC( DstOutputData%twrLd( i1_l ) ) + DstParamData%c_obj%nBlades_Len = SIZE(DstParamData%nBlades) + IF (DstParamData%c_obj%nBlades_Len > 0) & + DstParamData%c_obj%nBlades = C_LOC( DstParamData%nBlades( i1_l ) ) END IF - DstOutputData%twrLd = SrcOutputData%twrLd + DstParamData%nBlades = SrcParamData%nBlades ENDIF -IF (ASSOCIATED(SrcOutputData%bldLd)) THEN - i1_l = LBOUND(SrcOutputData%bldLd,1) - i1_u = UBOUND(SrcOutputData%bldLd,1) - IF (.NOT. ASSOCIATED(DstOutputData%bldLd)) THEN - ALLOCATE(DstOutputData%bldLd(i1_l:i1_u),STAT=ErrStat2) +IF (ASSOCIATED(SrcParamData%nBladeNodes)) THEN + i1_l = LBOUND(SrcParamData%nBladeNodes,1) + i1_u = UBOUND(SrcParamData%nBladeNodes,1) + IF (.NOT. ASSOCIATED(DstParamData%nBladeNodes)) THEN + ALLOCATE(DstParamData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%bldLd.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DstOutputData%c_obj%bldLd_Len = SIZE(DstOutputData%bldLd) - IF (DstOutputData%c_obj%bldLd_Len > 0) & - DstOutputData%c_obj%bldLd = C_LOC( DstOutputData%bldLd( i1_l ) ) + DstParamData%c_obj%nBladeNodes_Len = SIZE(DstParamData%nBladeNodes) + IF (DstParamData%c_obj%nBladeNodes_Len > 0) & + DstParamData%c_obj%nBladeNodes = C_LOC( DstParamData%nBladeNodes( i1_l ) ) END IF - DstOutputData%bldLd = SrcOutputData%bldLd + DstParamData%nBladeNodes = SrcParamData%nBladeNodes ENDIF - END SUBROUTINE ExtLdDX_CopyOutput +IF (ASSOCIATED(SrcParamData%nTowerNodes)) THEN + i1_l = LBOUND(SrcParamData%nTowerNodes,1) + i1_u = UBOUND(SrcParamData%nTowerNodes,1) + IF (.NOT. ASSOCIATED(DstParamData%nTowerNodes)) THEN + ALLOCATE(DstParamData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%nTowerNodes_Len = SIZE(DstParamData%nTowerNodes) + IF (DstParamData%c_obj%nTowerNodes_Len > 0) & + DstParamData%c_obj%nTowerNodes = C_LOC( DstParamData%nTowerNodes( i1_l ) ) + END IF + DstParamData%nTowerNodes = SrcParamData%nTowerNodes +ENDIF + END SUBROUTINE ExtLdDX_CopyParam - SUBROUTINE ExtLdDX_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) - TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: OutputData + SUBROUTINE ExtLdDX_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLdDX_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers @@ -1849,7 +1620,7 @@ SUBROUTINE ExtLdDX_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointer LOGICAL :: DEALLOCATEpointers_local INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_DestroyOutput' + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_DestroyParam' ErrStat = ErrID_None ErrMsg = "" @@ -1860,27 +1631,34 @@ SUBROUTINE ExtLdDX_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointer DEALLOCATEpointers_local = .true. END IF -IF (ASSOCIATED(OutputData%twrLd)) THEN +IF (ASSOCIATED(ParamData%nBlades)) THEN IF (DEALLOCATEpointers_local) & - DEALLOCATE(OutputData%twrLd) - OutputData%twrLd => NULL() - OutputData%C_obj%twrLd = C_NULL_PTR - OutputData%C_obj%twrLd_Len = 0 + DEALLOCATE(ParamData%nBlades) + ParamData%nBlades => NULL() + ParamData%C_obj%nBlades = C_NULL_PTR + ParamData%C_obj%nBlades_Len = 0 ENDIF -IF (ASSOCIATED(OutputData%bldLd)) THEN +IF (ASSOCIATED(ParamData%nBladeNodes)) THEN IF (DEALLOCATEpointers_local) & - DEALLOCATE(OutputData%bldLd) - OutputData%bldLd => NULL() - OutputData%C_obj%bldLd = C_NULL_PTR - OutputData%C_obj%bldLd_Len = 0 + DEALLOCATE(ParamData%nBladeNodes) + ParamData%nBladeNodes => NULL() + ParamData%C_obj%nBladeNodes = C_NULL_PTR + ParamData%C_obj%nBladeNodes_Len = 0 ENDIF - END SUBROUTINE ExtLdDX_DestroyOutput +IF (ASSOCIATED(ParamData%nTowerNodes)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%nTowerNodes) + ParamData%nTowerNodes => NULL() + ParamData%C_obj%nTowerNodes = C_NULL_PTR + ParamData%C_obj%nTowerNodes_Len = 0 +ENDIF + END SUBROUTINE ExtLdDX_DestroyParam - SUBROUTINE ExtLdDX_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE ExtLdDX_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(ExtLdDX_OutputType), INTENT(IN) :: InData + TYPE(ExtLdDX_ParameterType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -1895,7 +1673,7 @@ SUBROUTINE ExtLdDX_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_PackOutput' + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_PackParam' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1911,15 +1689,414 @@ SUBROUTINE ExtLdDX_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! twrLd allocated yes/no - IF ( ASSOCIATED(InData%twrLd) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! twrLd upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%twrLd) ! twrLd - END IF - Int_BufSz = Int_BufSz + 1 ! bldLd allocated yes/no - IF ( ASSOCIATED(InData%bldLd) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! bldLd upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%bldLd) ! bldLd + Int_BufSz = Int_BufSz + 1 ! nBlades allocated yes/no + IF ( ASSOCIATED(InData%nBlades) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nBlades upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nBlades) ! nBlades + END IF + Int_BufSz = Int_BufSz + 1 ! nBladeNodes allocated yes/no + IF ( ASSOCIATED(InData%nBladeNodes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nBladeNodes upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nBladeNodes) ! nBladeNodes + END IF + Int_BufSz = Int_BufSz + 1 ! nTowerNodes allocated yes/no + IF ( ASSOCIATED(InData%nTowerNodes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nTowerNodes upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nTowerNodes) ! nTowerNodes + 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) + + IF (C_ASSOCIATED(InData%C_obj%object)) CALL SetErrStat(ErrID_Severe,'C_obj%object cannot be packed.',ErrStat,ErrMsg,RoutineName) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ASSOCIATED(InData%nBlades) ) 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%nBlades,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nBlades,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nBlades,1), UBOUND(InData%nBlades,1) + IntKiBuf(Int_Xferred) = InData%nBlades(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nBladeNodes) ) 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%nBladeNodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nBladeNodes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nBladeNodes,1), UBOUND(InData%nBladeNodes,1) + IntKiBuf(Int_Xferred) = InData%nBladeNodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nTowerNodes) ) 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%nTowerNodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nTowerNodes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nTowerNodes,1), UBOUND(InData%nTowerNodes,1) + IntKiBuf(Int_Xferred) = InData%nTowerNodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLdDX_PackParam + + SUBROUTINE ExtLdDX_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(ExtLdDX_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 = 'ExtLdDX_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 ! nBlades 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 (ASSOCIATED(OutData%nBlades)) DEALLOCATE(OutData%nBlades) + ALLOCATE(OutData%nBlades(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBlades.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nBlades_Len = SIZE(OutData%nBlades) + IF (OutData%c_obj%nBlades_Len > 0) & + OutData%c_obj%nBlades = C_LOC( OutData%nBlades( i1_l ) ) + DO i1 = LBOUND(OutData%nBlades,1), UBOUND(OutData%nBlades,1) + OutData%nBlades(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nBladeNodes 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 (ASSOCIATED(OutData%nBladeNodes)) DEALLOCATE(OutData%nBladeNodes) + ALLOCATE(OutData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nBladeNodes_Len = SIZE(OutData%nBladeNodes) + IF (OutData%c_obj%nBladeNodes_Len > 0) & + OutData%c_obj%nBladeNodes = C_LOC( OutData%nBladeNodes( i1_l ) ) + DO i1 = LBOUND(OutData%nBladeNodes,1), UBOUND(OutData%nBladeNodes,1) + OutData%nBladeNodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nTowerNodes 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 (ASSOCIATED(OutData%nTowerNodes)) DEALLOCATE(OutData%nTowerNodes) + ALLOCATE(OutData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nTowerNodes_Len = SIZE(OutData%nTowerNodes) + IF (OutData%c_obj%nTowerNodes_Len > 0) & + OutData%c_obj%nTowerNodes = C_LOC( OutData%nTowerNodes( i1_l ) ) + DO i1 = LBOUND(OutData%nTowerNodes,1), UBOUND(OutData%nTowerNodes,1) + OutData%nTowerNodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLdDX_UnPackParam + + SUBROUTINE ExtLdDX_C2Fary_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) + TYPE(ExtLdDX_ParameterType), INTENT(INOUT) :: ParamData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers + ! + LOGICAL :: SkipPointers_local + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(SkipPointers)) THEN + SkipPointers_local = SkipPointers + ELSE + SkipPointers_local = .false. + END IF + + ! -- nBlades Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%nBlades ) ) THEN + NULLIFY( ParamData%nBlades ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%nBlades, ParamData%nBlades, (/ParamData%C_obj%nBlades_Len/)) + END IF + END IF + + ! -- nBladeNodes Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%nBladeNodes ) ) THEN + NULLIFY( ParamData%nBladeNodes ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%nBladeNodes, ParamData%nBladeNodes, (/ParamData%C_obj%nBladeNodes_Len/)) + END IF + END IF + + ! -- nTowerNodes Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%nTowerNodes ) ) THEN + NULLIFY( ParamData%nTowerNodes ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%nTowerNodes, ParamData%nTowerNodes, (/ParamData%C_obj%nTowerNodes_Len/)) + END IF + END IF + END SUBROUTINE ExtLdDX_C2Fary_CopyParam + + SUBROUTINE ExtLdDX_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) + TYPE(ExtLdDX_ParameterType), INTENT(INOUT) :: ParamData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers + ! + LOGICAL :: SkipPointers_local + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(SkipPointers)) THEN + SkipPointers_local = SkipPointers + ELSE + SkipPointers_local = .false. + END IF + + ! -- nBlades Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%nBlades)) THEN + ParamData%c_obj%nBlades_Len = 0 + ParamData%c_obj%nBlades = C_NULL_PTR + ELSE + ParamData%c_obj%nBlades_Len = SIZE(ParamData%nBlades) + IF (ParamData%c_obj%nBlades_Len > 0) & + ParamData%c_obj%nBlades = C_LOC( ParamData%nBlades( LBOUND(ParamData%nBlades,1) ) ) + END IF + END IF + + ! -- nBladeNodes Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%nBladeNodes)) THEN + ParamData%c_obj%nBladeNodes_Len = 0 + ParamData%c_obj%nBladeNodes = C_NULL_PTR + ELSE + ParamData%c_obj%nBladeNodes_Len = SIZE(ParamData%nBladeNodes) + IF (ParamData%c_obj%nBladeNodes_Len > 0) & + ParamData%c_obj%nBladeNodes = C_LOC( ParamData%nBladeNodes( LBOUND(ParamData%nBladeNodes,1) ) ) + END IF + END IF + + ! -- nTowerNodes Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%nTowerNodes)) THEN + ParamData%c_obj%nTowerNodes_Len = 0 + ParamData%c_obj%nTowerNodes = C_NULL_PTR + ELSE + ParamData%c_obj%nTowerNodes_Len = SIZE(ParamData%nTowerNodes) + IF (ParamData%c_obj%nTowerNodes_Len > 0) & + ParamData%c_obj%nTowerNodes = C_LOC( ParamData%nTowerNodes( LBOUND(ParamData%nTowerNodes,1) ) ) + END IF + END IF + END SUBROUTINE ExtLdDX_F2C_CopyParam + + SUBROUTINE ExtLdDX_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLdDX_OutputType), INTENT(IN) :: SrcOutputData + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: DstOutputData + 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 = 'ExtLdDX_CopyOutput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ASSOCIATED(SrcOutputData%twrLd)) THEN + i1_l = LBOUND(SrcOutputData%twrLd,1) + i1_u = UBOUND(SrcOutputData%twrLd,1) + IF (.NOT. ASSOCIATED(DstOutputData%twrLd)) THEN + ALLOCATE(DstOutputData%twrLd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%twrLd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstOutputData%c_obj%twrLd_Len = SIZE(DstOutputData%twrLd) + IF (DstOutputData%c_obj%twrLd_Len > 0) & + DstOutputData%c_obj%twrLd = C_LOC( DstOutputData%twrLd( i1_l ) ) + END IF + DstOutputData%twrLd = SrcOutputData%twrLd +ENDIF +IF (ASSOCIATED(SrcOutputData%bldLd)) THEN + i1_l = LBOUND(SrcOutputData%bldLd,1) + i1_u = UBOUND(SrcOutputData%bldLd,1) + IF (.NOT. ASSOCIATED(DstOutputData%bldLd)) THEN + ALLOCATE(DstOutputData%bldLd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%bldLd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstOutputData%c_obj%bldLd_Len = SIZE(DstOutputData%bldLd) + IF (DstOutputData%c_obj%bldLd_Len > 0) & + DstOutputData%c_obj%bldLd = C_LOC( DstOutputData%bldLd( i1_l ) ) + END IF + DstOutputData%bldLd = SrcOutputData%bldLd +ENDIF + END SUBROUTINE ExtLdDX_CopyOutput + + SUBROUTINE ExtLdDX_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ExtLdDX_OutputType), INTENT(INOUT) :: OutputData + 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 = 'ExtLdDX_DestroyOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ASSOCIATED(OutputData%twrLd)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(OutputData%twrLd) + OutputData%twrLd => NULL() + OutputData%C_obj%twrLd = C_NULL_PTR + OutputData%C_obj%twrLd_Len = 0 +ENDIF +IF (ASSOCIATED(OutputData%bldLd)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(OutputData%bldLd) + OutputData%bldLd => NULL() + OutputData%C_obj%bldLd = C_NULL_PTR + OutputData%C_obj%bldLd_Len = 0 +ENDIF + END SUBROUTINE ExtLdDX_DestroyOutput + + SUBROUTINE ExtLdDX_PackOutput( 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(ExtLdDX_OutputType), 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 = 'ExtLdDX_PackOutput' + ! 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 ! twrLd allocated yes/no + IF ( ASSOCIATED(InData%twrLd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrLd upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrLd) ! twrLd + END IF + Int_BufSz = Int_BufSz + 1 ! bldLd allocated yes/no + IF ( ASSOCIATED(InData%bldLd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldLd upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldLd) ! bldLd END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -2284,12 +2461,6 @@ SUBROUTINE ExtLdDX_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, Err u_out%bldRootRefPos(i1) = u1%bldRootRefPos(i1) + b * ScaleFactor END DO END IF ! check if allocated -IF (ASSOCIATED(u_out%nBlades) .AND. ASSOCIATED(u1%nBlades)) THEN -END IF ! check if allocated -IF (ASSOCIATED(u_out%nBladeNodes) .AND. ASSOCIATED(u1%nBladeNodes)) THEN -END IF ! check if allocated -IF (ASSOCIATED(u_out%nTowerNodes) .AND. ASSOCIATED(u1%nTowerNodes)) THEN -END IF ! check if allocated IF (ASSOCIATED(u_out%bldChord) .AND. ASSOCIATED(u1%bldChord)) THEN DO i1 = LBOUND(u_out%bldChord,1),UBOUND(u_out%bldChord,1) b = -(u1%bldChord(i1) - u2%bldChord(i1)) @@ -2447,12 +2618,6 @@ SUBROUTINE ExtLdDX_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, u_out%bldRootRefPos(i1) = u1%bldRootRefPos(i1) + b + c * t_out END DO END IF ! check if allocated -IF (ASSOCIATED(u_out%nBlades) .AND. ASSOCIATED(u1%nBlades)) THEN -END IF ! check if allocated -IF (ASSOCIATED(u_out%nBladeNodes) .AND. ASSOCIATED(u1%nBladeNodes)) THEN -END IF ! check if allocated -IF (ASSOCIATED(u_out%nTowerNodes) .AND. ASSOCIATED(u1%nTowerNodes)) THEN -END IF ! check if allocated IF (ASSOCIATED(u_out%bldChord) .AND. ASSOCIATED(u1%bldChord)) THEN DO i1 = LBOUND(u_out%bldChord,1),UBOUND(u_out%bldChord,1) b = (t(3)**2*(u1%bldChord(i1) - u2%bldChord(i1)) + t(2)**2*(-u1%bldChord(i1) + u3%bldChord(i1)))* scaleFactor diff --git a/modules/extloads/src/ExtLoadsDX_Types.h b/modules/extloads/src/ExtLoadsDX_Types.h index 23d47a3a35..6a818f498c 100644 --- a/modules/extloads/src/ExtLoadsDX_Types.h +++ b/modules/extloads/src/ExtLoadsDX_Types.h @@ -32,15 +32,18 @@ double * hubRefPos ; int hubRefPos_Len ; double * nacRefPos ; int nacRefPos_Len ; double * bldRootRefPos ; int bldRootRefPos_Len ; - int * nBlades ; int nBlades_Len ; - int * nBladeNodes ; int nBladeNodes_Len ; - int * nTowerNodes ; int nTowerNodes_Len ; double * bldChord ; int bldChord_Len ; double * bldRloc ; int bldRloc_Len ; double * twrDia ; int twrDia_Len ; double * twrHloc ; int twrHloc_Len ; double * bldPitch ; int bldPitch_Len ; } ExtLdDX_InputType_t ; + typedef struct ExtLdDX_ParameterType { + void * object ; + int * nBlades ; int nBlades_Len ; + int * nBladeNodes ; int nBladeNodes_Len ; + int * nTowerNodes ; int nTowerNodes_Len ; + } ExtLdDX_ParameterType_t ; typedef struct ExtLdDX_OutputType { void * object ; double * twrLd ; int twrLd_Len ; @@ -48,6 +51,7 @@ } ExtLdDX_OutputType_t ; typedef struct ExtLdDX_UserData { ExtLdDX_InputType_t ExtLdDX_Input ; + ExtLdDX_ParameterType_t ExtLdDX_Param ; ExtLdDX_OutputType_t ExtLdDX_Output ; } ExtLdDX_t ; diff --git a/modules/extloads/src/ExtLoads_Registry.txt b/modules/extloads/src/ExtLoads_Registry.txt index 66f457ee8a..d70ba74433 100644 --- a/modules/extloads/src/ExtLoads_Registry.txt +++ b/modules/extloads/src/ExtLoads_Registry.txt @@ -72,6 +72,7 @@ typedef ^ OtherStateType ReKi blah - - - "Som # ..... Parameters ................................................................................................................ # Define parameters here: +typedef ^ ParameterType ExtLdDX_ParameterType DX_p - - - "Data to send to external driver" typedef ^ ParameterType IntKi NumBlds - - - "Number of blades on the turbine" - typedef ^ ParameterType IntKi NumBldNds {:} - - "Number of blade nodes for each blade" - typedef ^ ParameterType IntKi nTotBldNds - - - "Total number of blade nodes" - diff --git a/modules/extloads/src/ExtLoads_Types.f90 b/modules/extloads/src/ExtLoads_Types.f90 index 8b6debb03f..c093db875d 100644 --- a/modules/extloads/src/ExtLoads_Types.f90 +++ b/modules/extloads/src/ExtLoads_Types.f90 @@ -98,6 +98,7 @@ MODULE ExtLoads_Types ! ======================= ! ========= ExtLd_ParameterType ======= TYPE, PUBLIC :: ExtLd_ParameterType + TYPE(ExtLdDX_ParameterType) :: DX_p !< Data to send to external driver [-] INTEGER(IntKi) :: NumBlds !< Number of blades on the turbine [-] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: NumBldNds !< Number of blade nodes for each blade [-] INTEGER(IntKi) :: nTotBldNds !< Total number of blade nodes [-] @@ -2174,6 +2175,9 @@ SUBROUTINE ExtLd_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs ! ErrStat = ErrID_None ErrMsg = "" + CALL ExtLdDX_CopyParam( SrcParamData%DX_p, DstParamData%DX_p, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN DstParamData%NumBlds = SrcParamData%NumBlds IF (ALLOCATED(SrcParamData%NumBldNds)) THEN i1_l = LBOUND(SrcParamData%NumBldNds,1) @@ -2219,6 +2223,8 @@ SUBROUTINE ExtLd_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) DEALLOCATEpointers_local = .true. END IF + CALL ExtLdDX_DestroyParam( ParamData%DX_p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%NumBldNds)) THEN DEALLOCATE(ParamData%NumBldNds) ENDIF @@ -2259,6 +2265,24 @@ SUBROUTINE ExtLd_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, 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 ! DX_p: size of buffers for each call to pack subtype + CALL ExtLdDX_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%DX_p, ErrStat2, ErrMsg2, .TRUE. ) ! DX_p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! DX_p + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! DX_p + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! DX_p + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 1 ! NumBlds Int_BufSz = Int_BufSz + 1 ! NumBldNds allocated yes/no IF ( ALLOCATED(InData%NumBldNds) ) THEN @@ -2301,6 +2325,34 @@ SUBROUTINE ExtLd_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_Xferred = 1 Int_Xferred = 1 + CALL ExtLdDX_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%DX_p, ErrStat2, ErrMsg2, OnlySize ) ! DX_p + 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 IntKiBuf(Int_Xferred) = InData%NumBlds Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%NumBldNds) ) THEN @@ -2365,6 +2417,46 @@ SUBROUTINE ExtLd_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM 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 ExtLdDX_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%DX_p, ErrStat2, ErrMsg2 ) ! DX_p + 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%NumBlds = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NumBldNds not allocated diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 7da7bd732b..3d818c2fe9 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -510,7 +510,7 @@ end subroutine FAST_Restart !================================================================================================================================== subroutine FAST_ExtLoads_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_c, TurbPosn, AbortErrLev_c, dtDriver_c, dt_c, NumBl_c, & az_blend_mean_c, az_blend_delta_c, vel_mean_c, wind_dir_c, z_ref_c, shear_exp_c, & - ExtLd_Input_from_FAST, ExtLd_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtLoads_Init') + ExtLd_Input_from_FAST, ExtLd_Parameter_from_FAST, ExtLd_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtLoads_Init') !DEC$ ATTRIBUTES DLLEXPORT::FAST_ExtLoads_Init IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT @@ -533,10 +533,11 @@ subroutine FAST_ExtLoads_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_ REAL(C_DOUBLE), INTENT( OUT) :: dt_c INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c INTEGER(C_INT), INTENT( OUT) :: NumBl_c - TYPE(ExtLdDX_InputType_C), INTENT( OUT) :: ExtLd_Input_from_FAST - TYPE(ExtLdDX_OutputType_C),INTENT( OUT) :: ExtLd_Output_to_FAST - TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST - TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST + TYPE(ExtLdDX_InputType_C), INTENT( OUT) :: ExtLd_Input_from_FAST + TYPE(ExtLdDX_ParameterType_C), INTENT( OUT) :: ExtLd_Parameter_from_FAST + TYPE(ExtLdDX_OutputType_C), INTENT( OUT) :: ExtLd_Output_to_FAST + TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST + TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST INTEGER(C_INT), INTENT( OUT) :: ErrStat_c CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) @@ -597,7 +598,7 @@ subroutine FAST_ExtLoads_Init(iTurb, TMax, InputFileName_c, TurbID, OutFileRoot_ return end if - call SetExtLoads_pointers(iTurb, ExtLd_Input_from_FAST, ExtLd_Output_to_FAST) + call SetExtLoads_pointers(iTurb, ExtLd_Input_from_FAST, ExtLd_Parameter_from_FAST, ExtLd_Output_to_FAST) OutFileRoot_c = TRANSFER( trim(Turbine(iTurb)%p_FAST%OutFileRoot)//C_NULL_CHAR, OutFileRoot_c ) @@ -901,7 +902,7 @@ subroutine FAST_ExtInfw_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c end subroutine FAST_ExtInfw_Restart !================================================================================================================================== subroutine FAST_ExtLoads_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_c, numblades_c, & - n_t_global_c, ExtLd_Input_from_FAST, ExtLd_Output_to_FAST, & + n_t_global_c, ExtLd_Input_from_FAST, ExtLd_Parameter_from_FAST, ExtLd_Output_to_FAST, & SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_ExtLoads_Restart') !DEC$ ATTRIBUTES DLLEXPORT::FAST_ExtLoads_Restart IMPLICIT NONE @@ -915,10 +916,11 @@ subroutine FAST_ExtLoads_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_ INTEGER(C_INT), INTENT( OUT) :: numblades_c REAL(C_DOUBLE), INTENT( OUT) :: dt_c INTEGER(C_INT), INTENT( OUT) :: n_t_global_c - TYPE(ExtLdDX_InputType_C), INTENT( OUT) :: ExtLd_Input_from_FAST - TYPE(ExtLdDX_OutputType_C),INTENT( OUT) :: ExtLd_Output_to_FAST - TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST - TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST + TYPE(ExtLdDX_InputType_C), INTENT( OUT) :: ExtLd_Input_from_FAST + TYPE(ExtLdDX_ParameterType_C), INTENT( OUT) :: ExtLd_Parameter_from_FAST + TYPE(ExtLdDX_OutputType_C), INTENT( OUT) :: ExtLd_Output_to_FAST + TYPE(SC_DX_InputType_C), INTENT(INOUT) :: SC_DX_Input_from_FAST + TYPE(SC_DX_OutputType_C), INTENT(INOUT) :: SC_DX_Output_to_FAST INTEGER(C_INT), INTENT( OUT) :: ErrStat_c CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) @@ -972,19 +974,20 @@ subroutine FAST_ExtLoads_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, dt_ end if write(*,*) 'Finished restoring OpenFAST from checkpoint' - call SetExtLoads_pointers(iTurb, ExtLd_Input_from_FAST, ExtLd_Output_to_FAST) + call SetExtLoads_pointers(iTurb, ExtLd_Input_from_FAST, ExtLd_Parameter_from_FAST, ExtLd_Output_to_FAST) ErrStat_c = ErrStat ErrMsg_c = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_c ) end subroutine FAST_ExtLoads_Restart !================================================================================================================================== -subroutine SetExtLoads_pointers(iTurb, ExtLd_iFromOF, ExtLd_oToOF) +subroutine SetExtLoads_pointers(iTurb, ExtLd_iFromOF, ExtLd_pFromOF, ExtLd_oToOF) IMPLICIT NONE - INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number - TYPE(ExtLdDX_InputType_C), INTENT(INOUT) :: ExtLd_iFromOF - TYPE(ExtLdDX_OutputType_C),INTENT(INOUT) :: ExtLd_oToOF + INTEGER(C_INT), INTENT(IN ) :: iTurb ! Turbine number + TYPE(ExtLdDX_InputType_C), INTENT(INOUT) :: ExtLd_iFromOF + TYPE(ExtLdDX_ParameterType_C), INTENT(INOUT) :: ExtLd_pFromOF + TYPE(ExtLdDX_OutputType_C), INTENT(INOUT) :: ExtLd_oToOF ExtLd_iFromOF%bldPitch_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch_Len; ExtLd_iFromOF%bldPitch = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch ExtLd_iFromOF%twrHloc_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrHloc_Len; ExtLd_iFromOF%twrHloc = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrHloc @@ -996,9 +999,6 @@ subroutine SetExtLoads_pointers(iTurb, ExtLd_iFromOF, ExtLd_oToOF) ExtLd_iFromOF%bldRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRefPos_Len; ExtLd_iFromOF%bldRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRefPos ExtLd_iFromOF%bldRootRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootRefPos_Len; ExtLd_iFromOF%bldRootRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootRefPos ExtLd_iFromOF%bldDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef_Len; ExtLd_iFromOF%bldDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef - ExtLd_iFromOF%nBlades_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBlades_Len; ExtLd_iFromOF%nBlades = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBlades - ExtLd_iFromOF%nBladeNodes_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBladeNodes_Len; ExtLd_iFromOF%nBladeNodes = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nBladeNodes - ExtLd_iFromOF%nTowerNodes_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nTowerNodes_Len; ExtLd_iFromOF%nTowerNodes = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nTowerNodes ExtLd_iFromOF%bldRootDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef_Len; ExtLd_iFromOF%bldRootDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef @@ -1008,6 +1008,10 @@ subroutine SetExtLoads_pointers(iTurb, ExtLd_iFromOF, ExtLd_oToOF) ExtLd_iFromOF%nacRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacRefPos_Len; ExtLd_iFromOF%nacRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacRefPos ExtLd_iFromOF%nacDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef_Len; ExtLd_iFromOF%nacDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef + ExtLd_pFromOF%nBlades_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBlades_Len; ExtLd_pFromOF%nBlades = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBlades + ExtLd_pFromOF%nBladeNodes_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBladeNodes_Len; ExtLd_pFromOF%nBladeNodes = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBladeNodes + ExtLd_pFromOF%nTowerNodes_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nTowerNodes_Len; ExtLd_pFromOF%nTowerNodes = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nTowerNodes + ExtLd_oToOF%twrLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd_Len; ExtLd_oToOF%twrLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd ExtLd_oToOF%bldLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd_Len; ExtLd_oToOF%bldLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd diff --git a/modules/openfast-library/src/FAST_Library.h b/modules/openfast-library/src/FAST_Library.h index 5427cdbacf..89fbd014d2 100644 --- a/modules/openfast-library/src/FAST_Library.h +++ b/modules/openfast-library/src/FAST_Library.h @@ -27,8 +27,8 @@ EXTERNAL_ROUTINE void FAST_ExtInfw_Init(int * iTurb, double *TMax, const char *I ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_ExtLoads_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * n_t_global, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_ExtLoads_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, char *OutFileRoot, float * TurbinePosition, int *AbortErrLev, double * dtDriver, double * dt, int * NumBl, double * az_blend_mean, double * az_blend_delta, double * vel_mean, double * wind_dir, double * z_ref, double * shear_exp, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_ExtLoads_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * n_t_global, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_ParameterType_t* ExtLdDX_Parameter, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); +EXTERNAL_ROUTINE void FAST_ExtLoads_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, char *OutFileRoot, float * TurbinePosition, int *AbortErrLev, double * dtDriver, double * dt, int * NumBl, double * az_blend_mean, double * az_blend_delta, double * vel_mean, double * wind_dir, double * z_ref, double * shear_exp, ExtLdDX_InputType_t* ExtLdDX_Input, ExtLdDX_ParameterType_t* ExtLdDX_Parameter, ExtLdDX_OutputType_t* ExtLdDX_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_Solution0(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_InitIOarrays_SubStep(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_CFD_Prework(int * iTurb, int *ErrStat, char *ErrMsg); From bffd751d0a3b91a773170cc30b6d5f63472ef2cc Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 23 Jan 2024 13:44:30 -0700 Subject: [PATCH 84/91] ExtLoads: move additional inputs to parameters where they belong --- glue-codes/openfast-cpp/src/OpenFAST.cpp | 24 +- modules/extloads/src/ExtLoads.f90 | 64 +- modules/extloads/src/ExtLoadsDX_Registry.txt | 18 +- modules/extloads/src/ExtLoadsDX_Types.f90 | 2085 ++++++++--------- modules/extloads/src/ExtLoadsDX_Types.h | 14 +- modules/openfast-library/src/FAST_Library.f90 | 51 +- 6 files changed, 1070 insertions(+), 1186 deletions(-) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 8afc735825..6049368eb0 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -2984,10 +2984,10 @@ void fast::OpenFAST::get_ref_positions_from_openfast(int iTurb) { if(turbineData[iTurb].sType == EXTLOADS) { for (int i=0; i < 3; i++) { - brFSIData[iTurb][fast::STATE_NP1].hub_ref_pos[i] = extld_i_f_FAST[iTurb].hubRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; - brFSIData[iTurb][fast::STATE_NP1].nac_ref_pos[i] = extld_i_f_FAST[iTurb].nacRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; - brFSIData[iTurb][fast::STATE_NP1].hub_ref_pos[i+3] = extld_i_f_FAST[iTurb].hubRefPos[i+3]; - brFSIData[iTurb][fast::STATE_NP1].nac_ref_pos[i+3] = extld_i_f_FAST[iTurb].nacRefPos[i+3]; + brFSIData[iTurb][fast::STATE_NP1].hub_ref_pos[i] = extld_p_f_FAST[iTurb].hubRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; + brFSIData[iTurb][fast::STATE_NP1].nac_ref_pos[i] = extld_p_f_FAST[iTurb].nacRefPos[i] + turbineData[iTurb].TurbineBasePos[i]; + brFSIData[iTurb][fast::STATE_NP1].hub_ref_pos[i+3] = extld_p_f_FAST[iTurb].hubRefPos[i+3]; + brFSIData[iTurb][fast::STATE_NP1].nac_ref_pos[i+3] = extld_p_f_FAST[iTurb].nacRefPos[i+3]; } int nBlades = turbineData[iTurb].numBlades; @@ -2996,17 +2996,17 @@ void fast::OpenFAST::get_ref_positions_from_openfast(int iTurb) { int nPtsBlade = turbineData[iTurb].nBRfsiPtsBlade[i]; for (int j=0; j < nPtsBlade; j++) { for (int k=0; k < 3; k++) { - brFSIData[iTurb][fast::STATE_NP1].bld_ref_pos[iRunTot*6+k] = extld_i_f_FAST[iTurb].bldRefPos[iRunTot*6+k] + turbineData[iTurb].TurbineBasePos[k]; - brFSIData[iTurb][fast::STATE_NP1].bld_ref_pos[iRunTot*6+k+3] = extld_i_f_FAST[iTurb].bldRefPos[iRunTot*6+k+3]; + brFSIData[iTurb][fast::STATE_NP1].bld_ref_pos[iRunTot*6+k] = extld_p_f_FAST[iTurb].bldRefPos[iRunTot*6+k] + turbineData[iTurb].TurbineBasePos[k]; + brFSIData[iTurb][fast::STATE_NP1].bld_ref_pos[iRunTot*6+k+3] = extld_p_f_FAST[iTurb].bldRefPos[iRunTot*6+k+3]; } - brFSIData[iTurb][fast::STATE_NP1].bld_chord[iRunTot] = extld_i_f_FAST[iTurb].bldChord[iRunTot]; - brFSIData[iTurb][fast::STATE_NP1].bld_rloc[iRunTot] = extld_i_f_FAST[iTurb].bldRloc[iRunTot]; + brFSIData[iTurb][fast::STATE_NP1].bld_chord[iRunTot] = extld_p_f_FAST[iTurb].bldChord[iRunTot]; + brFSIData[iTurb][fast::STATE_NP1].bld_rloc[iRunTot] = extld_p_f_FAST[iTurb].bldRloc[iRunTot]; iRunTot++; } for (int k=0; k < 3; k++) { - brFSIData[iTurb][fast::STATE_NP1].bld_root_ref_pos[i*6+k] = extld_i_f_FAST[iTurb].bldRootRefPos[i*6+k] + turbineData[iTurb].TurbineBasePos[k]; - brFSIData[iTurb][fast::STATE_NP1].bld_root_ref_pos[i*6+k+3] = extld_i_f_FAST[iTurb].bldRootRefPos[i*6+k+3]; + brFSIData[iTurb][fast::STATE_NP1].bld_root_ref_pos[i*6+k] = extld_p_f_FAST[iTurb].bldRootRefPos[i*6+k] + turbineData[iTurb].TurbineBasePos[k]; + brFSIData[iTurb][fast::STATE_NP1].bld_root_ref_pos[i*6+k+3] = extld_p_f_FAST[iTurb].bldRootRefPos[i*6+k+3]; } } @@ -3014,8 +3014,8 @@ void fast::OpenFAST::get_ref_positions_from_openfast(int iTurb) { int nPtsTwr = turbineData[iTurb].nBRfsiPtsTwr; for (int i=0; i < nPtsTwr; i++) { for (int j = 0; j < 3; j++) { - brFSIData[iTurb][fast::STATE_NP1].twr_ref_pos[i*6+j] = extld_i_f_FAST[iTurb].twrRefPos[i*6+j] + turbineData[iTurb].TurbineBasePos[j]; - brFSIData[iTurb][fast::STATE_NP1].twr_ref_pos[i*6+j+3] = extld_i_f_FAST[iTurb].twrRefPos[i*6+j+3]; + brFSIData[iTurb][fast::STATE_NP1].twr_ref_pos[i*6+j] = extld_p_f_FAST[iTurb].twrRefPos[i*6+j] + turbineData[iTurb].TurbineBasePos[j]; + brFSIData[iTurb][fast::STATE_NP1].twr_ref_pos[i*6+j+3] = extld_p_f_FAST[iTurb].twrRefPos[i*6+j+3]; } } diff --git a/modules/extloads/src/ExtLoads.f90 b/modules/extloads/src/ExtLoads.f90 index 11f2ce86dc..86ae0c85d3 100644 --- a/modules/extloads/src/ExtLoads.f90 +++ b/modules/extloads/src/ExtLoads.f90 @@ -553,26 +553,26 @@ subroutine Init_u( u, p, InitInp, errStat, errMsg ) p%DX_p%nBladeNodes(:) = p%NumBldNds(:) ! Set the reference positions next - CALL AllocPAry( u%DX_u%twrRefPos, p%NumTwrNds*6, 'twrRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( u%DX_u%bldRefPos, p%nTotBldNds*6, 'bldRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( u%DX_u%hubRefPos, 6, 'hubRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( u%DX_u%nacRefPos, 6, 'nacRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry (u%DX_u%bldRootRefPos, p%NumBlds*6, 'bldRootRefPos', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%twrRefPos, p%NumTwrNds*6, 'twrRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%bldRefPos, p%nTotBldNds*6, 'bldRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%hubRefPos, 6, 'hubRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%nacRefPos, 6, 'nacRefPos', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry (p%DX_p%bldRootRefPos, p%NumBlds*6, 'bldRootRefPos', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! make sure the C versions are synced with these arrays - u%DX_u%c_obj%twrRefPos_Len = p%NumTwrNds*6; u%DX_u%c_obj%twrRefPos = C_LOC( u%DX_u%twrRefPos(1) ) - u%DX_u%c_obj%bldRefPos_Len = p%nTotBldNds*6; u%DX_u%c_obj%bldRefPos = C_LOC( u%DX_u%bldRefPos(1) ) - u%DX_u%c_obj%hubRefPos_Len = 6; u%DX_u%c_obj%hubRefPos = C_LOC( u%DX_u%hubRefPos(1) ) - u%DX_u%c_obj%nacRefPos_Len = 6; u%DX_u%c_obj%nacRefPos = C_LOC( u%DX_u%nacRefPos(1) ) - u%DX_u%c_obj%bldRootRefPos_Len = p%NumBlds*6; u%DX_u%c_obj%bldRootRefPos = C_LOC( u%DX_u%bldRootRefPos(1) ) + p%DX_p%c_obj%twrRefPos_Len = p%NumTwrNds*6; p%DX_p%c_obj%twrRefPos = C_LOC( p%DX_p%twrRefPos(1) ) + p%DX_p%c_obj%bldRefPos_Len = p%nTotBldNds*6; p%DX_p%c_obj%bldRefPos = C_LOC( p%DX_p%bldRefPos(1) ) + p%DX_p%c_obj%hubRefPos_Len = 6; p%DX_p%c_obj%hubRefPos = C_LOC( p%DX_p%hubRefPos(1) ) + p%DX_p%c_obj%nacRefPos_Len = 6; p%DX_p%c_obj%nacRefPos = C_LOC( p%DX_p%nacRefPos(1) ) + p%DX_p%c_obj%bldRootRefPos_Len = p%NumBlds*6; p%DX_p%c_obj%bldRootRefPos = C_LOC( p%DX_p%bldRootRefPos(1) ) if (p%TwrAero) then do j=1,p%NumTwrNds call BD_CrvExtractCrv(u%TowerMotion%RefOrientation(:,:,j), wm_crv, ErrStat2, ErrMsg2) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - u%DX_u%twrRefPos((j-1)*6+1:(j-1)*6+3) = u%TowerMotion%Position(:,j) - u%DX_u%twrRefPos((j-1)*6+4:(j-1)*6+6) = wm_crv + p%DX_p%twrRefPos((j-1)*6+1:(j-1)*6+3) = u%TowerMotion%Position(:,j) + p%DX_p%twrRefPos((j-1)*6+4:(j-1)*6+6) = wm_crv end do end if @@ -581,27 +581,27 @@ subroutine Init_u( u, p, InitInp, errStat, errMsg ) do j=1,p%NumBldNds(k) call BD_CrvExtractCrv(u%BladeMotion(k)%RefOrientation(:,:,j), wm_crv, ErrStat2, ErrMsg2) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - u%DX_u%bldRefPos((jTot-1)*6+1:(jTot-1)*6+3) = u%BladeMotion(k)%Position(:,j) - u%DX_u%bldRefPos((jTot-1)*6+4:(jTot-1)*6+6) = wm_crv + p%DX_p%bldRefPos((jTot-1)*6+1:(jTot-1)*6+3) = u%BladeMotion(k)%Position(:,j) + p%DX_p%bldRefPos((jTot-1)*6+4:(jTot-1)*6+6) = wm_crv jTot = jTot+1 end do end do call BD_CrvExtractCrv(u%HubMotion%RefOrientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - u%DX_u%hubRefPos(1:3) = u%HubMotion%Position(:,1) - u%DX_u%hubRefPos(4:6) = wm_crv + p%DX_p%hubRefPos(1:3) = u%HubMotion%Position(:,1) + p%DX_p%hubRefPos(4:6) = wm_crv call BD_CrvExtractCrv(u%NacelleMotion%RefOrientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - u%DX_u%nacRefPos(1:3) = u%NacelleMotion%Position(:,1) - u%DX_u%nacRefPos(4:6) = wm_crv + p%DX_p%nacRefPos(1:3) = u%NacelleMotion%Position(:,1) + p%DX_p%nacRefPos(4:6) = wm_crv do k=1,p%NumBlds call BD_CrvExtractCrv(u%BladeRootMotion(k)%RefOrientation(:,:,1), wm_crv, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - u%DX_u%bldRootRefPos((k-1)*6+1:(k-1)*6+3) = u%BladeRootMotion(k)%Position(:,1) - u%DX_u%bldRootRefPos((k-1)*6+4:(k-1)*6+6) = wm_crv + p%DX_p%bldRootRefPos((k-1)*6+1:(k-1)*6+3) = u%BladeRootMotion(k)%Position(:,1) + p%DX_p%bldRootRefPos((k-1)*6+4:(k-1)*6+6) = wm_crv end do @@ -621,31 +621,31 @@ subroutine Init_u( u, p, InitInp, errStat, errMsg ) call ExtLd_ConvertInpDataForExtProg(u, p, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( u%DX_u%bldChord, p%nTotBldNds, 'bldChord', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( u%DX_u%bldRloc, p%nTotBldNds, 'bldRloc', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( u%DX_u%twrdia, p%NumTwrNds, 'twrDia', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( u%DX_u%twrHloc, p%NumTwrNds, 'twrHloc', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%bldChord, p%nTotBldNds, 'bldChord', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%bldRloc, p%nTotBldNds, 'bldRloc', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%twrdia, p%NumTwrNds, 'twrDia', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocPAry( p%DX_p%twrHloc, p%NumTwrNds, 'twrHloc', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AllocPAry( u%DX_u%bldPitch, p%NumBlds, 'bldPitch', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! make sure the C versions are synced with these arrays - u%DX_u%c_obj%bldChord_Len = p%nTotBldNds; u%DX_u%c_obj%bldChord = C_LOC( u%DX_u%bldChord(1) ) - u%DX_u%c_obj%bldRloc_Len = p%nTotBldNds; u%DX_u%c_obj%bldRloc = C_LOC( u%DX_u%bldRloc(1) ) - u%DX_u%c_obj%twrDia_Len = p%NumTwrNds; u%DX_u%c_obj%twrDia = C_LOC( u%DX_u%twrDia(1) ) - u%DX_u%c_obj%twrHloc_Len = p%NumTwrNds; u%DX_u%c_obj%twrHloc = C_LOC( u%DX_u%twrHloc(1) ) + p%DX_p%c_obj%bldChord_Len = p%nTotBldNds; p%DX_p%c_obj%bldChord = C_LOC( p%DX_p%bldChord(1) ) + p%DX_p%c_obj%bldRloc_Len = p%nTotBldNds; p%DX_p%c_obj%bldRloc = C_LOC( p%DX_p%bldRloc(1) ) + p%DX_p%c_obj%twrDia_Len = p%NumTwrNds; p%DX_p%c_obj%twrDia = C_LOC( p%DX_p%twrDia(1) ) + p%DX_p%c_obj%twrHloc_Len = p%NumTwrNds; p%DX_p%c_obj%twrHloc = C_LOC( p%DX_p%twrHloc(1) ) u%DX_u%c_obj%bldPitch_Len = p%NumBlds; u%DX_u%c_obj%bldPitch = C_LOC( u%DX_u%bldPitch(1) ) jTot = 1 do k=1,p%NumBlds do j=1,p%NumBldNds(k) - u%DX_u%bldChord(jTot) = InitInp%bldChord(j,k) - u%DX_u%bldRloc(jTot) = InitInp%bldRloc(j,k) + p%DX_p%bldChord(jTot) = InitInp%bldChord(j,k) + p%DX_p%bldRloc(jTot) = InitInp%bldRloc(j,k) jTot = jTot+1 end do end do do j=1,p%NumTwrNds - u%DX_u%twrDia(j) = InitInp%twrDia(j) - u%DX_u%twrHloc(j) = InitInp%twrHloc(j) + p%DX_p%twrDia(j) = InitInp%twrDia(j) + p%DX_p%twrHloc(j) = InitInp%twrHloc(j) end do end subroutine Init_u diff --git a/modules/extloads/src/ExtLoadsDX_Registry.txt b/modules/extloads/src/ExtLoadsDX_Registry.txt index 042033a4a0..f7b87c44eb 100644 --- a/modules/extloads/src/ExtLoadsDX_Registry.txt +++ b/modules/extloads/src/ExtLoadsDX_Registry.txt @@ -23,21 +23,21 @@ typedef ^ InputType R8Ki bldDef {:} - - typedef ^ InputType R8Ki hubDef {:} - - "Deformations on the hub - to send to external driver" typedef ^ InputType R8Ki nacDef {:} - - "Deformations the nacelle - to send to external driver" typedef ^ InputType R8Ki bldRootDef {:} - - "Deformations of the blade root nodes - to send to external driver" -typedef ^ InputType R8Ki twrRefPos {:} - - "Reference position of the tower nodes - to send to external driver" -typedef ^ InputType R8Ki bldRefPos {:} - - "Reference position of the all blade nodes - to send to external driver" -typedef ^ InputType R8Ki hubRefPos {:} - - "Reference position of the tower nodes - to send to external driver" -typedef ^ InputType R8Ki nacRefPos {:} - - "Reference position of the all blade nodes - to send to external driver" -typedef ^ InputType R8Ki bldRootRefPos {:} - - "Reference position of the blade root nodes - to send to external driver" -typedef ^ InputType R8Ki bldChord {:} - - "Blade chord" m -typedef ^ InputType R8Ki bldRloc {:} - - "Radial location along the blade" m -typedef ^ InputType R8Ki twrDia {:} - - "Tower diameter" m -typedef ^ InputType R8Ki twrHloc {:} - - "Height location along the tower" m typedef ^ InputType R8Ki bldPitch {:} - - "Pitch angle of blade" # ..... Parameters ................................................................................................................ typedef ^ ParameterType IntKi nBlades {:} - - "Number of blades" typedef ^ ParameterType IntKi nBladeNodes {:} - - "Number of blade nodes for each blade" - typedef ^ ParameterType IntKi nTowerNodes {:} - - "Number of tower nodes for each blade" - +typedef ^ ParameterType R8Ki twrRefPos {:} - - "Reference position of the tower nodes - to send to external driver" +typedef ^ ParameterType R8Ki bldRefPos {:} - - "Reference position of the all blade nodes - to send to external driver" +typedef ^ ParameterType R8Ki hubRefPos {:} - - "Reference position of the tower nodes - to send to external driver" +typedef ^ ParameterType R8Ki nacRefPos {:} - - "Reference position of the all blade nodes - to send to external driver" +typedef ^ ParameterType R8Ki bldRootRefPos {:} - - "Reference position of the blade root nodes - to send to external driver" +typedef ^ ParameterType R8Ki bldChord {:} - - "Blade chord" m +typedef ^ ParameterType R8Ki bldRloc {:} - - "Radial location along the blade" m +typedef ^ ParameterType R8Ki twrDia {:} - - "Tower diameter" m +typedef ^ ParameterType R8Ki twrHloc {:} - - "Height location along the tower" m # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: diff --git a/modules/extloads/src/ExtLoadsDX_Types.f90 b/modules/extloads/src/ExtLoadsDX_Types.f90 index f989cb6ac9..ba13696190 100644 --- a/modules/extloads/src/ExtLoadsDX_Types.f90 +++ b/modules/extloads/src/ExtLoadsDX_Types.f90 @@ -47,24 +47,6 @@ MODULE ExtLoadsDX_Types INTEGER(C_int) :: nacDef_Len = 0 TYPE(C_ptr) :: bldRootDef = C_NULL_PTR INTEGER(C_int) :: bldRootDef_Len = 0 - TYPE(C_ptr) :: twrRefPos = C_NULL_PTR - INTEGER(C_int) :: twrRefPos_Len = 0 - TYPE(C_ptr) :: bldRefPos = C_NULL_PTR - INTEGER(C_int) :: bldRefPos_Len = 0 - TYPE(C_ptr) :: hubRefPos = C_NULL_PTR - INTEGER(C_int) :: hubRefPos_Len = 0 - TYPE(C_ptr) :: nacRefPos = C_NULL_PTR - INTEGER(C_int) :: nacRefPos_Len = 0 - TYPE(C_ptr) :: bldRootRefPos = C_NULL_PTR - INTEGER(C_int) :: bldRootRefPos_Len = 0 - TYPE(C_ptr) :: bldChord = C_NULL_PTR - INTEGER(C_int) :: bldChord_Len = 0 - TYPE(C_ptr) :: bldRloc = C_NULL_PTR - INTEGER(C_int) :: bldRloc_Len = 0 - TYPE(C_ptr) :: twrDia = C_NULL_PTR - INTEGER(C_int) :: twrDia_Len = 0 - TYPE(C_ptr) :: twrHloc = C_NULL_PTR - INTEGER(C_int) :: twrHloc_Len = 0 TYPE(C_ptr) :: bldPitch = C_NULL_PTR INTEGER(C_int) :: bldPitch_Len = 0 END TYPE ExtLdDX_InputType_C @@ -75,15 +57,6 @@ MODULE ExtLoadsDX_Types REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: hubDef => NULL() !< Deformations on the hub - to send to external driver [-] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: nacDef => NULL() !< Deformations the nacelle - to send to external driver [-] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRootDef => NULL() !< Deformations of the blade root nodes - to send to external driver [-] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrRefPos => NULL() !< Reference position of the tower nodes - to send to external driver [-] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRefPos => NULL() !< Reference position of the all blade nodes - to send to external driver [-] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: hubRefPos => NULL() !< Reference position of the tower nodes - to send to external driver [-] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: nacRefPos => NULL() !< Reference position of the all blade nodes - to send to external driver [-] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRootRefPos => NULL() !< Reference position of the blade root nodes - to send to external driver [-] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldChord => NULL() !< Blade chord [m] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRloc => NULL() !< Radial location along the blade [m] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrDia => NULL() !< Tower diameter [m] - REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrHloc => NULL() !< Height location along the tower [m] REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldPitch => NULL() !< Pitch angle of blade [-] END TYPE ExtLdDX_InputType ! ======================= @@ -96,12 +69,39 @@ MODULE ExtLoadsDX_Types INTEGER(C_int) :: nBladeNodes_Len = 0 TYPE(C_ptr) :: nTowerNodes = C_NULL_PTR INTEGER(C_int) :: nTowerNodes_Len = 0 + TYPE(C_ptr) :: twrRefPos = C_NULL_PTR + INTEGER(C_int) :: twrRefPos_Len = 0 + TYPE(C_ptr) :: bldRefPos = C_NULL_PTR + INTEGER(C_int) :: bldRefPos_Len = 0 + TYPE(C_ptr) :: hubRefPos = C_NULL_PTR + INTEGER(C_int) :: hubRefPos_Len = 0 + TYPE(C_ptr) :: nacRefPos = C_NULL_PTR + INTEGER(C_int) :: nacRefPos_Len = 0 + TYPE(C_ptr) :: bldRootRefPos = C_NULL_PTR + INTEGER(C_int) :: bldRootRefPos_Len = 0 + TYPE(C_ptr) :: bldChord = C_NULL_PTR + INTEGER(C_int) :: bldChord_Len = 0 + TYPE(C_ptr) :: bldRloc = C_NULL_PTR + INTEGER(C_int) :: bldRloc_Len = 0 + TYPE(C_ptr) :: twrDia = C_NULL_PTR + INTEGER(C_int) :: twrDia_Len = 0 + TYPE(C_ptr) :: twrHloc = C_NULL_PTR + INTEGER(C_int) :: twrHloc_Len = 0 END TYPE ExtLdDX_ParameterType_C TYPE, PUBLIC :: ExtLdDX_ParameterType TYPE( ExtLdDX_ParameterType_C ) :: C_obj INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBlades => NULL() !< Number of blades [-] INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nBladeNodes => NULL() !< Number of blade nodes for each blade [-] INTEGER(KIND=C_INT) , DIMENSION(:), POINTER :: nTowerNodes => NULL() !< Number of tower nodes for each blade [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrRefPos => NULL() !< Reference position of the tower nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRefPos => NULL() !< Reference position of the all blade nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: hubRefPos => NULL() !< Reference position of the tower nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: nacRefPos => NULL() !< Reference position of the all blade nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRootRefPos => NULL() !< Reference position of the blade root nodes - to send to external driver [-] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldChord => NULL() !< Blade chord [m] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: bldRloc => NULL() !< Radial location along the blade [m] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrDia => NULL() !< Tower diameter [m] + REAL(KIND=C_DOUBLE) , DIMENSION(:), POINTER :: twrHloc => NULL() !< Height location along the tower [m] END TYPE ExtLdDX_ParameterType ! ======================= ! ========= ExtLdDX_OutputType_C ======= @@ -209,141 +209,6 @@ SUBROUTINE ExtLdDX_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Err END IF DstInputData%bldRootDef = SrcInputData%bldRootDef ENDIF -IF (ASSOCIATED(SrcInputData%twrRefPos)) THEN - i1_l = LBOUND(SrcInputData%twrRefPos,1) - i1_u = UBOUND(SrcInputData%twrRefPos,1) - IF (.NOT. ASSOCIATED(DstInputData%twrRefPos)) THEN - ALLOCATE(DstInputData%twrRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%twrRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%twrRefPos_Len = SIZE(DstInputData%twrRefPos) - IF (DstInputData%c_obj%twrRefPos_Len > 0) & - DstInputData%c_obj%twrRefPos = C_LOC( DstInputData%twrRefPos( i1_l ) ) - END IF - DstInputData%twrRefPos = SrcInputData%twrRefPos -ENDIF -IF (ASSOCIATED(SrcInputData%bldRefPos)) THEN - i1_l = LBOUND(SrcInputData%bldRefPos,1) - i1_u = UBOUND(SrcInputData%bldRefPos,1) - IF (.NOT. ASSOCIATED(DstInputData%bldRefPos)) THEN - ALLOCATE(DstInputData%bldRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%bldRefPos_Len = SIZE(DstInputData%bldRefPos) - IF (DstInputData%c_obj%bldRefPos_Len > 0) & - DstInputData%c_obj%bldRefPos = C_LOC( DstInputData%bldRefPos( i1_l ) ) - END IF - DstInputData%bldRefPos = SrcInputData%bldRefPos -ENDIF -IF (ASSOCIATED(SrcInputData%hubRefPos)) THEN - i1_l = LBOUND(SrcInputData%hubRefPos,1) - i1_u = UBOUND(SrcInputData%hubRefPos,1) - IF (.NOT. ASSOCIATED(DstInputData%hubRefPos)) THEN - ALLOCATE(DstInputData%hubRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%hubRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%hubRefPos_Len = SIZE(DstInputData%hubRefPos) - IF (DstInputData%c_obj%hubRefPos_Len > 0) & - DstInputData%c_obj%hubRefPos = C_LOC( DstInputData%hubRefPos( i1_l ) ) - END IF - DstInputData%hubRefPos = SrcInputData%hubRefPos -ENDIF -IF (ASSOCIATED(SrcInputData%nacRefPos)) THEN - i1_l = LBOUND(SrcInputData%nacRefPos,1) - i1_u = UBOUND(SrcInputData%nacRefPos,1) - IF (.NOT. ASSOCIATED(DstInputData%nacRefPos)) THEN - ALLOCATE(DstInputData%nacRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%nacRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%nacRefPos_Len = SIZE(DstInputData%nacRefPos) - IF (DstInputData%c_obj%nacRefPos_Len > 0) & - DstInputData%c_obj%nacRefPos = C_LOC( DstInputData%nacRefPos( i1_l ) ) - END IF - DstInputData%nacRefPos = SrcInputData%nacRefPos -ENDIF -IF (ASSOCIATED(SrcInputData%bldRootRefPos)) THEN - i1_l = LBOUND(SrcInputData%bldRootRefPos,1) - i1_u = UBOUND(SrcInputData%bldRootRefPos,1) - IF (.NOT. ASSOCIATED(DstInputData%bldRootRefPos)) THEN - ALLOCATE(DstInputData%bldRootRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldRootRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%bldRootRefPos_Len = SIZE(DstInputData%bldRootRefPos) - IF (DstInputData%c_obj%bldRootRefPos_Len > 0) & - DstInputData%c_obj%bldRootRefPos = C_LOC( DstInputData%bldRootRefPos( i1_l ) ) - END IF - DstInputData%bldRootRefPos = SrcInputData%bldRootRefPos -ENDIF -IF (ASSOCIATED(SrcInputData%bldChord)) THEN - i1_l = LBOUND(SrcInputData%bldChord,1) - i1_u = UBOUND(SrcInputData%bldChord,1) - IF (.NOT. ASSOCIATED(DstInputData%bldChord)) THEN - ALLOCATE(DstInputData%bldChord(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldChord.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%bldChord_Len = SIZE(DstInputData%bldChord) - IF (DstInputData%c_obj%bldChord_Len > 0) & - DstInputData%c_obj%bldChord = C_LOC( DstInputData%bldChord( i1_l ) ) - END IF - DstInputData%bldChord = SrcInputData%bldChord -ENDIF -IF (ASSOCIATED(SrcInputData%bldRloc)) THEN - i1_l = LBOUND(SrcInputData%bldRloc,1) - i1_u = UBOUND(SrcInputData%bldRloc,1) - IF (.NOT. ASSOCIATED(DstInputData%bldRloc)) THEN - ALLOCATE(DstInputData%bldRloc(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%bldRloc.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%bldRloc_Len = SIZE(DstInputData%bldRloc) - IF (DstInputData%c_obj%bldRloc_Len > 0) & - DstInputData%c_obj%bldRloc = C_LOC( DstInputData%bldRloc( i1_l ) ) - END IF - DstInputData%bldRloc = SrcInputData%bldRloc -ENDIF -IF (ASSOCIATED(SrcInputData%twrDia)) THEN - i1_l = LBOUND(SrcInputData%twrDia,1) - i1_u = UBOUND(SrcInputData%twrDia,1) - IF (.NOT. ASSOCIATED(DstInputData%twrDia)) THEN - ALLOCATE(DstInputData%twrDia(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%twrDia.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%twrDia_Len = SIZE(DstInputData%twrDia) - IF (DstInputData%c_obj%twrDia_Len > 0) & - DstInputData%c_obj%twrDia = C_LOC( DstInputData%twrDia( i1_l ) ) - END IF - DstInputData%twrDia = SrcInputData%twrDia -ENDIF -IF (ASSOCIATED(SrcInputData%twrHloc)) THEN - i1_l = LBOUND(SrcInputData%twrHloc,1) - i1_u = UBOUND(SrcInputData%twrHloc,1) - IF (.NOT. ASSOCIATED(DstInputData%twrHloc)) THEN - ALLOCATE(DstInputData%twrHloc(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%twrHloc.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DstInputData%c_obj%twrHloc_Len = SIZE(DstInputData%twrHloc) - IF (DstInputData%c_obj%twrHloc_Len > 0) & - DstInputData%c_obj%twrHloc = C_LOC( DstInputData%twrHloc( i1_l ) ) - END IF - DstInputData%twrHloc = SrcInputData%twrHloc -ENDIF IF (ASSOCIATED(SrcInputData%bldPitch)) THEN i1_l = LBOUND(SrcInputData%bldPitch,1) i1_u = UBOUND(SrcInputData%bldPitch,1) @@ -417,69 +282,6 @@ SUBROUTINE ExtLdDX_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers InputData%C_obj%bldRootDef = C_NULL_PTR InputData%C_obj%bldRootDef_Len = 0 ENDIF -IF (ASSOCIATED(InputData%twrRefPos)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%twrRefPos) - InputData%twrRefPos => NULL() - InputData%C_obj%twrRefPos = C_NULL_PTR - InputData%C_obj%twrRefPos_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%bldRefPos)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%bldRefPos) - InputData%bldRefPos => NULL() - InputData%C_obj%bldRefPos = C_NULL_PTR - InputData%C_obj%bldRefPos_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%hubRefPos)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%hubRefPos) - InputData%hubRefPos => NULL() - InputData%C_obj%hubRefPos = C_NULL_PTR - InputData%C_obj%hubRefPos_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%nacRefPos)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%nacRefPos) - InputData%nacRefPos => NULL() - InputData%C_obj%nacRefPos = C_NULL_PTR - InputData%C_obj%nacRefPos_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%bldRootRefPos)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%bldRootRefPos) - InputData%bldRootRefPos => NULL() - InputData%C_obj%bldRootRefPos = C_NULL_PTR - InputData%C_obj%bldRootRefPos_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%bldChord)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%bldChord) - InputData%bldChord => NULL() - InputData%C_obj%bldChord = C_NULL_PTR - InputData%C_obj%bldChord_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%bldRloc)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%bldRloc) - InputData%bldRloc => NULL() - InputData%C_obj%bldRloc = C_NULL_PTR - InputData%C_obj%bldRloc_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%twrDia)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%twrDia) - InputData%twrDia => NULL() - InputData%C_obj%twrDia = C_NULL_PTR - InputData%C_obj%twrDia_Len = 0 -ENDIF -IF (ASSOCIATED(InputData%twrHloc)) THEN - IF (DEALLOCATEpointers_local) & - DEALLOCATE(InputData%twrHloc) - InputData%twrHloc => NULL() - InputData%C_obj%twrHloc = C_NULL_PTR - InputData%C_obj%twrHloc_Len = 0 -ENDIF IF (ASSOCIATED(InputData%bldPitch)) THEN IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%bldPitch) @@ -549,51 +351,6 @@ SUBROUTINE ExtLdDX_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 2*1 ! bldRootDef upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%bldRootDef) ! bldRootDef END IF - Int_BufSz = Int_BufSz + 1 ! twrRefPos allocated yes/no - IF ( ASSOCIATED(InData%twrRefPos) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! twrRefPos upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%twrRefPos) ! twrRefPos - END IF - Int_BufSz = Int_BufSz + 1 ! bldRefPos allocated yes/no - IF ( ASSOCIATED(InData%bldRefPos) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! bldRefPos upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%bldRefPos) ! bldRefPos - END IF - Int_BufSz = Int_BufSz + 1 ! hubRefPos allocated yes/no - IF ( ASSOCIATED(InData%hubRefPos) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! hubRefPos upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%hubRefPos) ! hubRefPos - END IF - Int_BufSz = Int_BufSz + 1 ! nacRefPos allocated yes/no - IF ( ASSOCIATED(InData%nacRefPos) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! nacRefPos upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%nacRefPos) ! nacRefPos - END IF - Int_BufSz = Int_BufSz + 1 ! bldRootRefPos allocated yes/no - IF ( ASSOCIATED(InData%bldRootRefPos) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! bldRootRefPos upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%bldRootRefPos) ! bldRootRefPos - END IF - Int_BufSz = Int_BufSz + 1 ! bldChord allocated yes/no - IF ( ASSOCIATED(InData%bldChord) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! bldChord upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%bldChord) ! bldChord - END IF - Int_BufSz = Int_BufSz + 1 ! bldRloc allocated yes/no - IF ( ASSOCIATED(InData%bldRloc) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! bldRloc upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%bldRloc) ! bldRloc - END IF - Int_BufSz = Int_BufSz + 1 ! twrDia allocated yes/no - IF ( ASSOCIATED(InData%twrDia) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! twrDia upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%twrDia) ! twrDia - END IF - Int_BufSz = Int_BufSz + 1 ! twrHloc allocated yes/no - IF ( ASSOCIATED(InData%twrHloc) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! twrHloc upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%twrHloc) ! twrHloc - END IF Int_BufSz = Int_BufSz + 1 ! bldPitch allocated yes/no IF ( ASSOCIATED(InData%bldPitch) ) THEN Int_BufSz = Int_BufSz + 2*1 ! bldPitch upper/lower bounds for each dimension @@ -703,233 +460,98 @@ SUBROUTINE ExtLdDX_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ASSOCIATED(InData%twrRefPos) ) THEN + IF ( .NOT. ASSOCIATED(InData%bldPitch) ) 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%twrRefPos,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrRefPos,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%bldPitch,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldPitch,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%twrRefPos,1), UBOUND(InData%twrRefPos,1) - DbKiBuf(Db_Xferred) = InData%twrRefPos(i1) + DO i1 = LBOUND(InData%bldPitch,1), UBOUND(InData%bldPitch,1) + DbKiBuf(Db_Xferred) = InData%bldPitch(i1) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ASSOCIATED(InData%bldRefPos) ) THEN - IntKiBuf( Int_Xferred ) = 0 + END SUBROUTINE ExtLdDX_PackInput + + SUBROUTINE ExtLdDX_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(ExtLdDX_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) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_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 ! twrDef not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%bldRefPos,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRefPos,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%bldRefPos,1), UBOUND(InData%bldRefPos,1) - DbKiBuf(Db_Xferred) = InData%bldRefPos(i1) + IF (ASSOCIATED(OutData%twrDef)) DEALLOCATE(OutData%twrDef) + ALLOCATE(OutData%twrDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%twrDef_Len = SIZE(OutData%twrDef) + IF (OutData%c_obj%twrDef_Len > 0) & + OutData%c_obj%twrDef = C_LOC( OutData%twrDef( i1_l ) ) + DO i1 = LBOUND(OutData%twrDef,1), UBOUND(OutData%twrDef,1) + OutData%twrDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ASSOCIATED(InData%hubRefPos) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldDef not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%hubRefPos,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%hubRefPos,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%hubRefPos,1), UBOUND(InData%hubRefPos,1) - DbKiBuf(Db_Xferred) = InData%hubRefPos(i1) + IF (ASSOCIATED(OutData%bldDef)) DEALLOCATE(OutData%bldDef) + ALLOCATE(OutData%bldDef(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldDef.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldDef_Len = SIZE(OutData%bldDef) + IF (OutData%c_obj%bldDef_Len > 0) & + OutData%c_obj%bldDef = C_LOC( OutData%bldDef( i1_l ) ) + DO i1 = LBOUND(OutData%bldDef,1), UBOUND(OutData%bldDef,1) + OutData%bldDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ASSOCIATED(InData%nacRefPos) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hubDef not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%nacRefPos,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nacRefPos,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%nacRefPos,1), UBOUND(InData%nacRefPos,1) - DbKiBuf(Db_Xferred) = InData%nacRefPos(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%bldRootRefPos) ) 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%bldRootRefPos,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRootRefPos,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%bldRootRefPos,1), UBOUND(InData%bldRootRefPos,1) - DbKiBuf(Db_Xferred) = InData%bldRootRefPos(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%bldChord) ) 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%bldChord,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldChord,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%bldChord,1), UBOUND(InData%bldChord,1) - DbKiBuf(Db_Xferred) = InData%bldChord(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%bldRloc) ) 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%bldRloc,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRloc,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%bldRloc,1), UBOUND(InData%bldRloc,1) - DbKiBuf(Db_Xferred) = InData%bldRloc(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%twrDia) ) 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%twrDia,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrDia,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%twrDia,1), UBOUND(InData%twrDia,1) - DbKiBuf(Db_Xferred) = InData%twrDia(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%twrHloc) ) 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%twrHloc,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrHloc,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%twrHloc,1), UBOUND(InData%twrHloc,1) - DbKiBuf(Db_Xferred) = InData%twrHloc(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( .NOT. ASSOCIATED(InData%bldPitch) ) 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%bldPitch,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldPitch,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%bldPitch,1), UBOUND(InData%bldPitch,1) - DbKiBuf(Db_Xferred) = InData%bldPitch(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - END SUBROUTINE ExtLdDX_PackInput - - SUBROUTINE ExtLdDX_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(ExtLdDX_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) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ExtLdDX_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 ! twrDef 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 (ASSOCIATED(OutData%twrDef)) DEALLOCATE(OutData%twrDef) - ALLOCATE(OutData%twrDef(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrDef.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%twrDef_Len = SIZE(OutData%twrDef) - IF (OutData%c_obj%twrDef_Len > 0) & - OutData%c_obj%twrDef = C_LOC( OutData%twrDef( i1_l ) ) - DO i1 = LBOUND(OutData%twrDef,1), UBOUND(OutData%twrDef,1) - OutData%twrDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldDef 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 (ASSOCIATED(OutData%bldDef)) DEALLOCATE(OutData%bldDef) - ALLOCATE(OutData%bldDef(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldDef.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%bldDef_Len = SIZE(OutData%bldDef) - IF (OutData%c_obj%bldDef_Len > 0) & - OutData%c_obj%bldDef = C_LOC( OutData%bldDef( i1_l ) ) - DO i1 = LBOUND(OutData%bldDef,1), UBOUND(OutData%bldDef,1) - OutData%bldDef(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hubDef not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 IF (ASSOCIATED(OutData%hubDef)) DEALLOCATE(OutData%hubDef) ALLOCATE(OutData%hubDef(i1_l:i1_u),STAT=ErrStat2) @@ -987,241 +609,52 @@ SUBROUTINE ExtLdDX_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrRefPos not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldPitch 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 (ASSOCIATED(OutData%twrRefPos)) DEALLOCATE(OutData%twrRefPos) - ALLOCATE(OutData%twrRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ASSOCIATED(OutData%bldPitch)) DEALLOCATE(OutData%bldPitch) + ALLOCATE(OutData%bldPitch(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrRefPos.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldPitch.', ErrStat, ErrMsg,RoutineName) RETURN END IF - OutData%c_obj%twrRefPos_Len = SIZE(OutData%twrRefPos) - IF (OutData%c_obj%twrRefPos_Len > 0) & - OutData%c_obj%twrRefPos = C_LOC( OutData%twrRefPos( i1_l ) ) - DO i1 = LBOUND(OutData%twrRefPos,1), UBOUND(OutData%twrRefPos,1) - OutData%twrRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + OutData%c_obj%bldPitch_Len = SIZE(OutData%bldPitch) + IF (OutData%c_obj%bldPitch_Len > 0) & + OutData%c_obj%bldPitch = C_LOC( OutData%bldPitch( i1_l ) ) + DO i1 = LBOUND(OutData%bldPitch,1), UBOUND(OutData%bldPitch,1) + OutData%bldPitch(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRefPos 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 (ASSOCIATED(OutData%bldRefPos)) DEALLOCATE(OutData%bldRefPos) - ALLOCATE(OutData%bldRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN + END SUBROUTINE ExtLdDX_UnPackInput + + SUBROUTINE ExtLdDX_C2Fary_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) + TYPE(ExtLdDX_InputType), INTENT(INOUT) :: InputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers + ! + LOGICAL :: SkipPointers_local + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(SkipPointers)) THEN + SkipPointers_local = SkipPointers + ELSE + SkipPointers_local = .false. END IF - OutData%c_obj%bldRefPos_Len = SIZE(OutData%bldRefPos) - IF (OutData%c_obj%bldRefPos_Len > 0) & - OutData%c_obj%bldRefPos = C_LOC( OutData%bldRefPos( i1_l ) ) - DO i1 = LBOUND(OutData%bldRefPos,1), UBOUND(OutData%bldRefPos,1) - OutData%bldRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hubRefPos 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 (ASSOCIATED(OutData%hubRefPos)) DEALLOCATE(OutData%hubRefPos) - ALLOCATE(OutData%hubRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%hubRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%hubRefPos_Len = SIZE(OutData%hubRefPos) - IF (OutData%c_obj%hubRefPos_Len > 0) & - OutData%c_obj%hubRefPos = C_LOC( OutData%hubRefPos( i1_l ) ) - DO i1 = LBOUND(OutData%hubRefPos,1), UBOUND(OutData%hubRefPos,1) - OutData%hubRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nacRefPos 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 (ASSOCIATED(OutData%nacRefPos)) DEALLOCATE(OutData%nacRefPos) - ALLOCATE(OutData%nacRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nacRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%nacRefPos_Len = SIZE(OutData%nacRefPos) - IF (OutData%c_obj%nacRefPos_Len > 0) & - OutData%c_obj%nacRefPos = C_LOC( OutData%nacRefPos( i1_l ) ) - DO i1 = LBOUND(OutData%nacRefPos,1), UBOUND(OutData%nacRefPos,1) - OutData%nacRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRootRefPos 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 (ASSOCIATED(OutData%bldRootRefPos)) DEALLOCATE(OutData%bldRootRefPos) - ALLOCATE(OutData%bldRootRefPos(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRootRefPos.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%bldRootRefPos_Len = SIZE(OutData%bldRootRefPos) - IF (OutData%c_obj%bldRootRefPos_Len > 0) & - OutData%c_obj%bldRootRefPos = C_LOC( OutData%bldRootRefPos( i1_l ) ) - DO i1 = LBOUND(OutData%bldRootRefPos,1), UBOUND(OutData%bldRootRefPos,1) - OutData%bldRootRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldChord 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 (ASSOCIATED(OutData%bldChord)) DEALLOCATE(OutData%bldChord) - ALLOCATE(OutData%bldChord(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldChord.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%bldChord_Len = SIZE(OutData%bldChord) - IF (OutData%c_obj%bldChord_Len > 0) & - OutData%c_obj%bldChord = C_LOC( OutData%bldChord( i1_l ) ) - DO i1 = LBOUND(OutData%bldChord,1), UBOUND(OutData%bldChord,1) - OutData%bldChord(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRloc 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 (ASSOCIATED(OutData%bldRloc)) DEALLOCATE(OutData%bldRloc) - ALLOCATE(OutData%bldRloc(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRloc.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%bldRloc_Len = SIZE(OutData%bldRloc) - IF (OutData%c_obj%bldRloc_Len > 0) & - OutData%c_obj%bldRloc = C_LOC( OutData%bldRloc( i1_l ) ) - DO i1 = LBOUND(OutData%bldRloc,1), UBOUND(OutData%bldRloc,1) - OutData%bldRloc(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrDia 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 (ASSOCIATED(OutData%twrDia)) DEALLOCATE(OutData%twrDia) - ALLOCATE(OutData%twrDia(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrDia.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%twrDia_Len = SIZE(OutData%twrDia) - IF (OutData%c_obj%twrDia_Len > 0) & - OutData%c_obj%twrDia = C_LOC( OutData%twrDia( i1_l ) ) - DO i1 = LBOUND(OutData%twrDia,1), UBOUND(OutData%twrDia,1) - OutData%twrDia(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrHloc 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 (ASSOCIATED(OutData%twrHloc)) DEALLOCATE(OutData%twrHloc) - ALLOCATE(OutData%twrHloc(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrHloc.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%twrHloc_Len = SIZE(OutData%twrHloc) - IF (OutData%c_obj%twrHloc_Len > 0) & - OutData%c_obj%twrHloc = C_LOC( OutData%twrHloc( i1_l ) ) - DO i1 = LBOUND(OutData%twrHloc,1), UBOUND(OutData%twrHloc,1) - OutData%twrHloc(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldPitch 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 (ASSOCIATED(OutData%bldPitch)) DEALLOCATE(OutData%bldPitch) - ALLOCATE(OutData%bldPitch(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldPitch.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - OutData%c_obj%bldPitch_Len = SIZE(OutData%bldPitch) - IF (OutData%c_obj%bldPitch_Len > 0) & - OutData%c_obj%bldPitch = C_LOC( OutData%bldPitch( i1_l ) ) - DO i1 = LBOUND(OutData%bldPitch,1), UBOUND(OutData%bldPitch,1) - OutData%bldPitch(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) - Db_Xferred = Db_Xferred + 1 - END DO - END IF - END SUBROUTINE ExtLdDX_UnPackInput - - SUBROUTINE ExtLdDX_C2Fary_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) - TYPE(ExtLdDX_InputType), INTENT(INOUT) :: InputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL,INTENT(IN ) :: SkipPointers - ! - LOGICAL :: SkipPointers_local - ErrStat = ErrID_None - ErrMsg = "" - - IF (PRESENT(SkipPointers)) THEN - SkipPointers_local = SkipPointers - ELSE - SkipPointers_local = .false. - END IF - - ! -- twrDef Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrDef ) ) THEN - NULLIFY( InputData%twrDef ) - ELSE - CALL C_F_POINTER(InputData%C_obj%twrDef, InputData%twrDef, (/InputData%C_obj%twrDef_Len/)) - END IF + + ! -- twrDef Input Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrDef ) ) THEN + NULLIFY( InputData%twrDef ) + ELSE + CALL C_F_POINTER(InputData%C_obj%twrDef, InputData%twrDef, (/InputData%C_obj%twrDef_Len/)) + END IF END IF ! -- bldDef Input Data fields @@ -1260,87 +693,6 @@ SUBROUTINE ExtLdDX_C2Fary_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) END IF END IF - ! -- twrRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrRefPos ) ) THEN - NULLIFY( InputData%twrRefPos ) - ELSE - CALL C_F_POINTER(InputData%C_obj%twrRefPos, InputData%twrRefPos, (/InputData%C_obj%twrRefPos_Len/)) - END IF - END IF - - ! -- bldRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldRefPos ) ) THEN - NULLIFY( InputData%bldRefPos ) - ELSE - CALL C_F_POINTER(InputData%C_obj%bldRefPos, InputData%bldRefPos, (/InputData%C_obj%bldRefPos_Len/)) - END IF - END IF - - ! -- hubRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%hubRefPos ) ) THEN - NULLIFY( InputData%hubRefPos ) - ELSE - CALL C_F_POINTER(InputData%C_obj%hubRefPos, InputData%hubRefPos, (/InputData%C_obj%hubRefPos_Len/)) - END IF - END IF - - ! -- nacRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%nacRefPos ) ) THEN - NULLIFY( InputData%nacRefPos ) - ELSE - CALL C_F_POINTER(InputData%C_obj%nacRefPos, InputData%nacRefPos, (/InputData%C_obj%nacRefPos_Len/)) - END IF - END IF - - ! -- bldRootRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldRootRefPos ) ) THEN - NULLIFY( InputData%bldRootRefPos ) - ELSE - CALL C_F_POINTER(InputData%C_obj%bldRootRefPos, InputData%bldRootRefPos, (/InputData%C_obj%bldRootRefPos_Len/)) - END IF - END IF - - ! -- bldChord Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldChord ) ) THEN - NULLIFY( InputData%bldChord ) - ELSE - CALL C_F_POINTER(InputData%C_obj%bldChord, InputData%bldChord, (/InputData%C_obj%bldChord_Len/)) - END IF - END IF - - ! -- bldRloc Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldRloc ) ) THEN - NULLIFY( InputData%bldRloc ) - ELSE - CALL C_F_POINTER(InputData%C_obj%bldRloc, InputData%bldRloc, (/InputData%C_obj%bldRloc_Len/)) - END IF - END IF - - ! -- twrDia Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrDia ) ) THEN - NULLIFY( InputData%twrDia ) - ELSE - CALL C_F_POINTER(InputData%C_obj%twrDia, InputData%twrDia, (/InputData%C_obj%twrDia_Len/)) - END IF - END IF - - ! -- twrHloc Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. C_ASSOCIATED( InputData%C_obj%twrHloc ) ) THEN - NULLIFY( InputData%twrHloc ) - ELSE - CALL C_F_POINTER(InputData%C_obj%twrHloc, InputData%twrHloc, (/InputData%C_obj%twrHloc_Len/)) - END IF - END IF - ! -- bldPitch Input Data fields IF ( .NOT. SkipPointers_local ) THEN IF ( .NOT. C_ASSOCIATED( InputData%C_obj%bldPitch ) ) THEN @@ -1427,150 +779,42 @@ SUBROUTINE ExtLdDX_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) END IF END IF - ! -- twrRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%twrRefPos)) THEN - InputData%c_obj%twrRefPos_Len = 0 - InputData%c_obj%twrRefPos = C_NULL_PTR - ELSE - InputData%c_obj%twrRefPos_Len = SIZE(InputData%twrRefPos) - IF (InputData%c_obj%twrRefPos_Len > 0) & - InputData%c_obj%twrRefPos = C_LOC( InputData%twrRefPos( LBOUND(InputData%twrRefPos,1) ) ) - END IF - END IF - - ! -- bldRefPos Input Data fields + ! -- bldPitch Input Data fields IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%bldRefPos)) THEN - InputData%c_obj%bldRefPos_Len = 0 - InputData%c_obj%bldRefPos = C_NULL_PTR + IF ( .NOT. ASSOCIATED(InputData%bldPitch)) THEN + InputData%c_obj%bldPitch_Len = 0 + InputData%c_obj%bldPitch = C_NULL_PTR ELSE - InputData%c_obj%bldRefPos_Len = SIZE(InputData%bldRefPos) - IF (InputData%c_obj%bldRefPos_Len > 0) & - InputData%c_obj%bldRefPos = C_LOC( InputData%bldRefPos( LBOUND(InputData%bldRefPos,1) ) ) + InputData%c_obj%bldPitch_Len = SIZE(InputData%bldPitch) + IF (InputData%c_obj%bldPitch_Len > 0) & + InputData%c_obj%bldPitch = C_LOC( InputData%bldPitch( LBOUND(InputData%bldPitch,1) ) ) END IF END IF + END SUBROUTINE ExtLdDX_F2C_CopyInput - ! -- hubRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%hubRefPos)) THEN - InputData%c_obj%hubRefPos_Len = 0 - InputData%c_obj%hubRefPos = C_NULL_PTR - ELSE - InputData%c_obj%hubRefPos_Len = SIZE(InputData%hubRefPos) - IF (InputData%c_obj%hubRefPos_Len > 0) & - InputData%c_obj%hubRefPos = C_LOC( InputData%hubRefPos( LBOUND(InputData%hubRefPos,1) ) ) - END IF - END IF - - ! -- nacRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%nacRefPos)) THEN - InputData%c_obj%nacRefPos_Len = 0 - InputData%c_obj%nacRefPos = C_NULL_PTR - ELSE - InputData%c_obj%nacRefPos_Len = SIZE(InputData%nacRefPos) - IF (InputData%c_obj%nacRefPos_Len > 0) & - InputData%c_obj%nacRefPos = C_LOC( InputData%nacRefPos( LBOUND(InputData%nacRefPos,1) ) ) - END IF - END IF - - ! -- bldRootRefPos Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%bldRootRefPos)) THEN - InputData%c_obj%bldRootRefPos_Len = 0 - InputData%c_obj%bldRootRefPos = C_NULL_PTR - ELSE - InputData%c_obj%bldRootRefPos_Len = SIZE(InputData%bldRootRefPos) - IF (InputData%c_obj%bldRootRefPos_Len > 0) & - InputData%c_obj%bldRootRefPos = C_LOC( InputData%bldRootRefPos( LBOUND(InputData%bldRootRefPos,1) ) ) - END IF - END IF - - ! -- bldChord Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%bldChord)) THEN - InputData%c_obj%bldChord_Len = 0 - InputData%c_obj%bldChord = C_NULL_PTR - ELSE - InputData%c_obj%bldChord_Len = SIZE(InputData%bldChord) - IF (InputData%c_obj%bldChord_Len > 0) & - InputData%c_obj%bldChord = C_LOC( InputData%bldChord( LBOUND(InputData%bldChord,1) ) ) - END IF - END IF - - ! -- bldRloc Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%bldRloc)) THEN - InputData%c_obj%bldRloc_Len = 0 - InputData%c_obj%bldRloc = C_NULL_PTR - ELSE - InputData%c_obj%bldRloc_Len = SIZE(InputData%bldRloc) - IF (InputData%c_obj%bldRloc_Len > 0) & - InputData%c_obj%bldRloc = C_LOC( InputData%bldRloc( LBOUND(InputData%bldRloc,1) ) ) - END IF - END IF - - ! -- twrDia Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%twrDia)) THEN - InputData%c_obj%twrDia_Len = 0 - InputData%c_obj%twrDia = C_NULL_PTR - ELSE - InputData%c_obj%twrDia_Len = SIZE(InputData%twrDia) - IF (InputData%c_obj%twrDia_Len > 0) & - InputData%c_obj%twrDia = C_LOC( InputData%twrDia( LBOUND(InputData%twrDia,1) ) ) - END IF - END IF - - ! -- twrHloc Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%twrHloc)) THEN - InputData%c_obj%twrHloc_Len = 0 - InputData%c_obj%twrHloc = C_NULL_PTR - ELSE - InputData%c_obj%twrHloc_Len = SIZE(InputData%twrHloc) - IF (InputData%c_obj%twrHloc_Len > 0) & - InputData%c_obj%twrHloc = C_LOC( InputData%twrHloc( LBOUND(InputData%twrHloc,1) ) ) - END IF - END IF - - ! -- bldPitch Input Data fields - IF ( .NOT. SkipPointers_local ) THEN - IF ( .NOT. ASSOCIATED(InputData%bldPitch)) THEN - InputData%c_obj%bldPitch_Len = 0 - InputData%c_obj%bldPitch = C_NULL_PTR - ELSE - InputData%c_obj%bldPitch_Len = SIZE(InputData%bldPitch) - IF (InputData%c_obj%bldPitch_Len > 0) & - InputData%c_obj%bldPitch = C_LOC( InputData%bldPitch( LBOUND(InputData%bldPitch,1) ) ) - END IF - END IF - END SUBROUTINE ExtLdDX_F2C_CopyInput - - SUBROUTINE ExtLdDX_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(ExtLdDX_ParameterType), INTENT(IN) :: SrcParamData - TYPE(ExtLdDX_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 = 'ExtLdDX_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ASSOCIATED(SrcParamData%nBlades)) THEN - i1_l = LBOUND(SrcParamData%nBlades,1) - i1_u = UBOUND(SrcParamData%nBlades,1) - IF (.NOT. ASSOCIATED(DstParamData%nBlades)) THEN - ALLOCATE(DstParamData%nBlades(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nBlades.', ErrStat, ErrMsg,RoutineName) - RETURN + SUBROUTINE ExtLdDX_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ExtLdDX_ParameterType), INTENT(IN) :: SrcParamData + TYPE(ExtLdDX_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 = 'ExtLdDX_CopyParam' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ASSOCIATED(SrcParamData%nBlades)) THEN + i1_l = LBOUND(SrcParamData%nBlades,1) + i1_u = UBOUND(SrcParamData%nBlades,1) + IF (.NOT. ASSOCIATED(DstParamData%nBlades)) THEN + ALLOCATE(DstParamData%nBlades(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nBlades.', ErrStat, ErrMsg,RoutineName) + RETURN END IF DstParamData%c_obj%nBlades_Len = SIZE(DstParamData%nBlades) IF (DstParamData%c_obj%nBlades_Len > 0) & @@ -1607,6 +851,141 @@ SUBROUTINE ExtLdDX_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err DstParamData%c_obj%nTowerNodes = C_LOC( DstParamData%nTowerNodes( i1_l ) ) END IF DstParamData%nTowerNodes = SrcParamData%nTowerNodes +ENDIF +IF (ASSOCIATED(SrcParamData%twrRefPos)) THEN + i1_l = LBOUND(SrcParamData%twrRefPos,1) + i1_u = UBOUND(SrcParamData%twrRefPos,1) + IF (.NOT. ASSOCIATED(DstParamData%twrRefPos)) THEN + ALLOCATE(DstParamData%twrRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%twrRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%twrRefPos_Len = SIZE(DstParamData%twrRefPos) + IF (DstParamData%c_obj%twrRefPos_Len > 0) & + DstParamData%c_obj%twrRefPos = C_LOC( DstParamData%twrRefPos( i1_l ) ) + END IF + DstParamData%twrRefPos = SrcParamData%twrRefPos +ENDIF +IF (ASSOCIATED(SrcParamData%bldRefPos)) THEN + i1_l = LBOUND(SrcParamData%bldRefPos,1) + i1_u = UBOUND(SrcParamData%bldRefPos,1) + IF (.NOT. ASSOCIATED(DstParamData%bldRefPos)) THEN + ALLOCATE(DstParamData%bldRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%bldRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%bldRefPos_Len = SIZE(DstParamData%bldRefPos) + IF (DstParamData%c_obj%bldRefPos_Len > 0) & + DstParamData%c_obj%bldRefPos = C_LOC( DstParamData%bldRefPos( i1_l ) ) + END IF + DstParamData%bldRefPos = SrcParamData%bldRefPos +ENDIF +IF (ASSOCIATED(SrcParamData%hubRefPos)) THEN + i1_l = LBOUND(SrcParamData%hubRefPos,1) + i1_u = UBOUND(SrcParamData%hubRefPos,1) + IF (.NOT. ASSOCIATED(DstParamData%hubRefPos)) THEN + ALLOCATE(DstParamData%hubRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%hubRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%hubRefPos_Len = SIZE(DstParamData%hubRefPos) + IF (DstParamData%c_obj%hubRefPos_Len > 0) & + DstParamData%c_obj%hubRefPos = C_LOC( DstParamData%hubRefPos( i1_l ) ) + END IF + DstParamData%hubRefPos = SrcParamData%hubRefPos +ENDIF +IF (ASSOCIATED(SrcParamData%nacRefPos)) THEN + i1_l = LBOUND(SrcParamData%nacRefPos,1) + i1_u = UBOUND(SrcParamData%nacRefPos,1) + IF (.NOT. ASSOCIATED(DstParamData%nacRefPos)) THEN + ALLOCATE(DstParamData%nacRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nacRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%nacRefPos_Len = SIZE(DstParamData%nacRefPos) + IF (DstParamData%c_obj%nacRefPos_Len > 0) & + DstParamData%c_obj%nacRefPos = C_LOC( DstParamData%nacRefPos( i1_l ) ) + END IF + DstParamData%nacRefPos = SrcParamData%nacRefPos +ENDIF +IF (ASSOCIATED(SrcParamData%bldRootRefPos)) THEN + i1_l = LBOUND(SrcParamData%bldRootRefPos,1) + i1_u = UBOUND(SrcParamData%bldRootRefPos,1) + IF (.NOT. ASSOCIATED(DstParamData%bldRootRefPos)) THEN + ALLOCATE(DstParamData%bldRootRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%bldRootRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%bldRootRefPos_Len = SIZE(DstParamData%bldRootRefPos) + IF (DstParamData%c_obj%bldRootRefPos_Len > 0) & + DstParamData%c_obj%bldRootRefPos = C_LOC( DstParamData%bldRootRefPos( i1_l ) ) + END IF + DstParamData%bldRootRefPos = SrcParamData%bldRootRefPos +ENDIF +IF (ASSOCIATED(SrcParamData%bldChord)) THEN + i1_l = LBOUND(SrcParamData%bldChord,1) + i1_u = UBOUND(SrcParamData%bldChord,1) + IF (.NOT. ASSOCIATED(DstParamData%bldChord)) THEN + ALLOCATE(DstParamData%bldChord(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%bldChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%bldChord_Len = SIZE(DstParamData%bldChord) + IF (DstParamData%c_obj%bldChord_Len > 0) & + DstParamData%c_obj%bldChord = C_LOC( DstParamData%bldChord( i1_l ) ) + END IF + DstParamData%bldChord = SrcParamData%bldChord +ENDIF +IF (ASSOCIATED(SrcParamData%bldRloc)) THEN + i1_l = LBOUND(SrcParamData%bldRloc,1) + i1_u = UBOUND(SrcParamData%bldRloc,1) + IF (.NOT. ASSOCIATED(DstParamData%bldRloc)) THEN + ALLOCATE(DstParamData%bldRloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%bldRloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%bldRloc_Len = SIZE(DstParamData%bldRloc) + IF (DstParamData%c_obj%bldRloc_Len > 0) & + DstParamData%c_obj%bldRloc = C_LOC( DstParamData%bldRloc( i1_l ) ) + END IF + DstParamData%bldRloc = SrcParamData%bldRloc +ENDIF +IF (ASSOCIATED(SrcParamData%twrDia)) THEN + i1_l = LBOUND(SrcParamData%twrDia,1) + i1_u = UBOUND(SrcParamData%twrDia,1) + IF (.NOT. ASSOCIATED(DstParamData%twrDia)) THEN + ALLOCATE(DstParamData%twrDia(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%twrDia.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%twrDia_Len = SIZE(DstParamData%twrDia) + IF (DstParamData%c_obj%twrDia_Len > 0) & + DstParamData%c_obj%twrDia = C_LOC( DstParamData%twrDia( i1_l ) ) + END IF + DstParamData%twrDia = SrcParamData%twrDia +ENDIF +IF (ASSOCIATED(SrcParamData%twrHloc)) THEN + i1_l = LBOUND(SrcParamData%twrHloc,1) + i1_u = UBOUND(SrcParamData%twrHloc,1) + IF (.NOT. ASSOCIATED(DstParamData%twrHloc)) THEN + ALLOCATE(DstParamData%twrHloc(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%twrHloc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DstParamData%c_obj%twrHloc_Len = SIZE(DstParamData%twrHloc) + IF (DstParamData%c_obj%twrHloc_Len > 0) & + DstParamData%c_obj%twrHloc = C_LOC( DstParamData%twrHloc( i1_l ) ) + END IF + DstParamData%twrHloc = SrcParamData%twrHloc ENDIF END SUBROUTINE ExtLdDX_CopyParam @@ -1651,6 +1030,69 @@ SUBROUTINE ExtLdDX_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ParamData%nTowerNodes => NULL() ParamData%C_obj%nTowerNodes = C_NULL_PTR ParamData%C_obj%nTowerNodes_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%twrRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%twrRefPos) + ParamData%twrRefPos => NULL() + ParamData%C_obj%twrRefPos = C_NULL_PTR + ParamData%C_obj%twrRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%bldRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%bldRefPos) + ParamData%bldRefPos => NULL() + ParamData%C_obj%bldRefPos = C_NULL_PTR + ParamData%C_obj%bldRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%hubRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%hubRefPos) + ParamData%hubRefPos => NULL() + ParamData%C_obj%hubRefPos = C_NULL_PTR + ParamData%C_obj%hubRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%nacRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%nacRefPos) + ParamData%nacRefPos => NULL() + ParamData%C_obj%nacRefPos = C_NULL_PTR + ParamData%C_obj%nacRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%bldRootRefPos)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%bldRootRefPos) + ParamData%bldRootRefPos => NULL() + ParamData%C_obj%bldRootRefPos = C_NULL_PTR + ParamData%C_obj%bldRootRefPos_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%bldChord)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%bldChord) + ParamData%bldChord => NULL() + ParamData%C_obj%bldChord = C_NULL_PTR + ParamData%C_obj%bldChord_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%bldRloc)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%bldRloc) + ParamData%bldRloc => NULL() + ParamData%C_obj%bldRloc = C_NULL_PTR + ParamData%C_obj%bldRloc_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%twrDia)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%twrDia) + ParamData%twrDia => NULL() + ParamData%C_obj%twrDia = C_NULL_PTR + ParamData%C_obj%twrDia_Len = 0 +ENDIF +IF (ASSOCIATED(ParamData%twrHloc)) THEN + IF (DEALLOCATEpointers_local) & + DEALLOCATE(ParamData%twrHloc) + ParamData%twrHloc => NULL() + ParamData%C_obj%twrHloc = C_NULL_PTR + ParamData%C_obj%twrHloc_Len = 0 ENDIF END SUBROUTINE ExtLdDX_DestroyParam @@ -1704,6 +1146,51 @@ SUBROUTINE ExtLdDX_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 2*1 ! nTowerNodes upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%nTowerNodes) ! nTowerNodes END IF + Int_BufSz = Int_BufSz + 1 ! twrRefPos allocated yes/no + IF ( ASSOCIATED(InData%twrRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrRefPos) ! twrRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! bldRefPos allocated yes/no + IF ( ASSOCIATED(InData%bldRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldRefPos) ! bldRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! hubRefPos allocated yes/no + IF ( ASSOCIATED(InData%hubRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! hubRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%hubRefPos) ! hubRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! nacRefPos allocated yes/no + IF ( ASSOCIATED(InData%nacRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nacRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%nacRefPos) ! nacRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! bldRootRefPos allocated yes/no + IF ( ASSOCIATED(InData%bldRootRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldRootRefPos upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldRootRefPos) ! bldRootRefPos + END IF + Int_BufSz = Int_BufSz + 1 ! bldChord allocated yes/no + IF ( ASSOCIATED(InData%bldChord) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldChord upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldChord) ! bldChord + END IF + Int_BufSz = Int_BufSz + 1 ! bldRloc allocated yes/no + IF ( ASSOCIATED(InData%bldRloc) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! bldRloc upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%bldRloc) ! bldRloc + END IF + Int_BufSz = Int_BufSz + 1 ! twrDia allocated yes/no + IF ( ASSOCIATED(InData%twrDia) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrDia upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrDia) ! twrDia + END IF + Int_BufSz = Int_BufSz + 1 ! twrHloc allocated yes/no + IF ( ASSOCIATED(InData%twrHloc) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! twrHloc upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%twrHloc) ! twrHloc + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1757,117 +1244,441 @@ SUBROUTINE ExtLdDX_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs IntKiBuf( Int_Xferred ) = LBOUND(InData%nBladeNodes,1) IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nBladeNodes,1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%nBladeNodes,1), UBOUND(InData%nBladeNodes,1) - IntKiBuf(Int_Xferred) = InData%nBladeNodes(i1) - Int_Xferred = Int_Xferred + 1 + + DO i1 = LBOUND(InData%nBladeNodes,1), UBOUND(InData%nBladeNodes,1) + IntKiBuf(Int_Xferred) = InData%nBladeNodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nTowerNodes) ) 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%nTowerNodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nTowerNodes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nTowerNodes,1), UBOUND(InData%nTowerNodes,1) + IntKiBuf(Int_Xferred) = InData%nTowerNodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%twrRefPos) ) 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%twrRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrRefPos,1), UBOUND(InData%twrRefPos,1) + DbKiBuf(Db_Xferred) = InData%twrRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldRefPos) ) 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%bldRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldRefPos,1), UBOUND(InData%bldRefPos,1) + DbKiBuf(Db_Xferred) = InData%bldRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%hubRefPos) ) 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%hubRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%hubRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%hubRefPos,1), UBOUND(InData%hubRefPos,1) + DbKiBuf(Db_Xferred) = InData%hubRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%nacRefPos) ) 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%nacRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nacRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nacRefPos,1), UBOUND(InData%nacRefPos,1) + DbKiBuf(Db_Xferred) = InData%nacRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldRootRefPos) ) 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%bldRootRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRootRefPos,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldRootRefPos,1), UBOUND(InData%bldRootRefPos,1) + DbKiBuf(Db_Xferred) = InData%bldRootRefPos(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldChord) ) 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%bldChord,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldChord,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldChord,1), UBOUND(InData%bldChord,1) + DbKiBuf(Db_Xferred) = InData%bldChord(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%bldRloc) ) 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%bldRloc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%bldRloc,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%bldRloc,1), UBOUND(InData%bldRloc,1) + DbKiBuf(Db_Xferred) = InData%bldRloc(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%twrDia) ) 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%twrDia,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrDia,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrDia,1), UBOUND(InData%twrDia,1) + DbKiBuf(Db_Xferred) = InData%twrDia(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ASSOCIATED(InData%twrHloc) ) 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%twrHloc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%twrHloc,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%twrHloc,1), UBOUND(InData%twrHloc,1) + DbKiBuf(Db_Xferred) = InData%twrHloc(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE ExtLdDX_PackParam + + SUBROUTINE ExtLdDX_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(ExtLdDX_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 = 'ExtLdDX_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 ! nBlades 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 (ASSOCIATED(OutData%nBlades)) DEALLOCATE(OutData%nBlades) + ALLOCATE(OutData%nBlades(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBlades.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nBlades_Len = SIZE(OutData%nBlades) + IF (OutData%c_obj%nBlades_Len > 0) & + OutData%c_obj%nBlades = C_LOC( OutData%nBlades( i1_l ) ) + DO i1 = LBOUND(OutData%nBlades,1), UBOUND(OutData%nBlades,1) + OutData%nBlades(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nBladeNodes 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 (ASSOCIATED(OutData%nBladeNodes)) DEALLOCATE(OutData%nBladeNodes) + ALLOCATE(OutData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nBladeNodes_Len = SIZE(OutData%nBladeNodes) + IF (OutData%c_obj%nBladeNodes_Len > 0) & + OutData%c_obj%nBladeNodes = C_LOC( OutData%nBladeNodes( i1_l ) ) + DO i1 = LBOUND(OutData%nBladeNodes,1), UBOUND(OutData%nBladeNodes,1) + OutData%nBladeNodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nTowerNodes 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 (ASSOCIATED(OutData%nTowerNodes)) DEALLOCATE(OutData%nTowerNodes) + ALLOCATE(OutData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nTowerNodes_Len = SIZE(OutData%nTowerNodes) + IF (OutData%c_obj%nTowerNodes_Len > 0) & + OutData%c_obj%nTowerNodes = C_LOC( OutData%nTowerNodes( i1_l ) ) + DO i1 = LBOUND(OutData%nTowerNodes,1), UBOUND(OutData%nTowerNodes,1) + OutData%nTowerNodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrRefPos 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 (ASSOCIATED(OutData%twrRefPos)) DEALLOCATE(OutData%twrRefPos) + ALLOCATE(OutData%twrRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%twrRefPos_Len = SIZE(OutData%twrRefPos) + IF (OutData%c_obj%twrRefPos_Len > 0) & + OutData%c_obj%twrRefPos = C_LOC( OutData%twrRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%twrRefPos,1), UBOUND(OutData%twrRefPos,1) + OutData%twrRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRefPos 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 (ASSOCIATED(OutData%bldRefPos)) DEALLOCATE(OutData%bldRefPos) + ALLOCATE(OutData%bldRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldRefPos_Len = SIZE(OutData%bldRefPos) + IF (OutData%c_obj%bldRefPos_Len > 0) & + OutData%c_obj%bldRefPos = C_LOC( OutData%bldRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%bldRefPos,1), UBOUND(OutData%bldRefPos,1) + OutData%bldRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hubRefPos 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 (ASSOCIATED(OutData%hubRefPos)) DEALLOCATE(OutData%hubRefPos) + ALLOCATE(OutData%hubRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%hubRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%hubRefPos_Len = SIZE(OutData%hubRefPos) + IF (OutData%c_obj%hubRefPos_Len > 0) & + OutData%c_obj%hubRefPos = C_LOC( OutData%hubRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%hubRefPos,1), UBOUND(OutData%hubRefPos,1) + OutData%hubRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nacRefPos 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 (ASSOCIATED(OutData%nacRefPos)) DEALLOCATE(OutData%nacRefPos) + ALLOCATE(OutData%nacRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nacRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%nacRefPos_Len = SIZE(OutData%nacRefPos) + IF (OutData%c_obj%nacRefPos_Len > 0) & + OutData%c_obj%nacRefPos = C_LOC( OutData%nacRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%nacRefPos,1), UBOUND(OutData%nacRefPos,1) + OutData%nacRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRootRefPos 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 (ASSOCIATED(OutData%bldRootRefPos)) DEALLOCATE(OutData%bldRootRefPos) + ALLOCATE(OutData%bldRootRefPos(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRootRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldRootRefPos_Len = SIZE(OutData%bldRootRefPos) + IF (OutData%c_obj%bldRootRefPos_Len > 0) & + OutData%c_obj%bldRootRefPos = C_LOC( OutData%bldRootRefPos( i1_l ) ) + DO i1 = LBOUND(OutData%bldRootRefPos,1), UBOUND(OutData%bldRootRefPos,1) + OutData%bldRootRefPos(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ASSOCIATED(InData%nTowerNodes) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldChord not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%nTowerNodes,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nTowerNodes,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%nTowerNodes,1), UBOUND(InData%nTowerNodes,1) - IntKiBuf(Int_Xferred) = InData%nTowerNodes(i1) - Int_Xferred = Int_Xferred + 1 + IF (ASSOCIATED(OutData%bldChord)) DEALLOCATE(OutData%bldChord) + ALLOCATE(OutData%bldChord(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + OutData%c_obj%bldChord_Len = SIZE(OutData%bldChord) + IF (OutData%c_obj%bldChord_Len > 0) & + OutData%c_obj%bldChord = C_LOC( OutData%bldChord( i1_l ) ) + DO i1 = LBOUND(OutData%bldChord,1), UBOUND(OutData%bldChord,1) + OutData%bldChord(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 END DO END IF - END SUBROUTINE ExtLdDX_PackParam - - SUBROUTINE ExtLdDX_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(ExtLdDX_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 = 'ExtLdDX_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 ! nBlades not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! bldRloc 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 (ASSOCIATED(OutData%nBlades)) DEALLOCATE(OutData%nBlades) - ALLOCATE(OutData%nBlades(i1_l:i1_u),STAT=ErrStat2) + IF (ASSOCIATED(OutData%bldRloc)) DEALLOCATE(OutData%bldRloc) + ALLOCATE(OutData%bldRloc(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBlades.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%bldRloc.', ErrStat, ErrMsg,RoutineName) RETURN END IF - OutData%c_obj%nBlades_Len = SIZE(OutData%nBlades) - IF (OutData%c_obj%nBlades_Len > 0) & - OutData%c_obj%nBlades = C_LOC( OutData%nBlades( i1_l ) ) - DO i1 = LBOUND(OutData%nBlades,1), UBOUND(OutData%nBlades,1) - OutData%nBlades(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + OutData%c_obj%bldRloc_Len = SIZE(OutData%bldRloc) + IF (OutData%c_obj%bldRloc_Len > 0) & + OutData%c_obj%bldRloc = C_LOC( OutData%bldRloc( i1_l ) ) + DO i1 = LBOUND(OutData%bldRloc,1), UBOUND(OutData%bldRloc,1) + OutData%bldRloc(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nBladeNodes not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrDia 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 (ASSOCIATED(OutData%nBladeNodes)) DEALLOCATE(OutData%nBladeNodes) - ALLOCATE(OutData%nBladeNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ASSOCIATED(OutData%twrDia)) DEALLOCATE(OutData%twrDia) + ALLOCATE(OutData%twrDia(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nBladeNodes.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrDia.', ErrStat, ErrMsg,RoutineName) RETURN END IF - OutData%c_obj%nBladeNodes_Len = SIZE(OutData%nBladeNodes) - IF (OutData%c_obj%nBladeNodes_Len > 0) & - OutData%c_obj%nBladeNodes = C_LOC( OutData%nBladeNodes( i1_l ) ) - DO i1 = LBOUND(OutData%nBladeNodes,1), UBOUND(OutData%nBladeNodes,1) - OutData%nBladeNodes(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + OutData%c_obj%twrDia_Len = SIZE(OutData%twrDia) + IF (OutData%c_obj%twrDia_Len > 0) & + OutData%c_obj%twrDia = C_LOC( OutData%twrDia( i1_l ) ) + DO i1 = LBOUND(OutData%twrDia,1), UBOUND(OutData%twrDia,1) + OutData%twrDia(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nTowerNodes not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! twrHloc 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 (ASSOCIATED(OutData%nTowerNodes)) DEALLOCATE(OutData%nTowerNodes) - ALLOCATE(OutData%nTowerNodes(i1_l:i1_u),STAT=ErrStat2) + IF (ASSOCIATED(OutData%twrHloc)) DEALLOCATE(OutData%twrHloc) + ALLOCATE(OutData%twrHloc(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nTowerNodes.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%twrHloc.', ErrStat, ErrMsg,RoutineName) RETURN END IF - OutData%c_obj%nTowerNodes_Len = SIZE(OutData%nTowerNodes) - IF (OutData%c_obj%nTowerNodes_Len > 0) & - OutData%c_obj%nTowerNodes = C_LOC( OutData%nTowerNodes( i1_l ) ) - DO i1 = LBOUND(OutData%nTowerNodes,1), UBOUND(OutData%nTowerNodes,1) - OutData%nTowerNodes(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + OutData%c_obj%twrHloc_Len = SIZE(OutData%twrHloc) + IF (OutData%c_obj%twrHloc_Len > 0) & + OutData%c_obj%twrHloc = C_LOC( OutData%twrHloc( i1_l ) ) + DO i1 = LBOUND(OutData%twrHloc,1), UBOUND(OutData%twrHloc,1) + OutData%twrHloc(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) + Db_Xferred = Db_Xferred + 1 END DO END IF END SUBROUTINE ExtLdDX_UnPackParam @@ -1914,6 +1725,87 @@ SUBROUTINE ExtLdDX_C2Fary_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) CALL C_F_POINTER(ParamData%C_obj%nTowerNodes, ParamData%nTowerNodes, (/ParamData%C_obj%nTowerNodes_Len/)) END IF END IF + + ! -- twrRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%twrRefPos ) ) THEN + NULLIFY( ParamData%twrRefPos ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%twrRefPos, ParamData%twrRefPos, (/ParamData%C_obj%twrRefPos_Len/)) + END IF + END IF + + ! -- bldRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%bldRefPos ) ) THEN + NULLIFY( ParamData%bldRefPos ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%bldRefPos, ParamData%bldRefPos, (/ParamData%C_obj%bldRefPos_Len/)) + END IF + END IF + + ! -- hubRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%hubRefPos ) ) THEN + NULLIFY( ParamData%hubRefPos ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%hubRefPos, ParamData%hubRefPos, (/ParamData%C_obj%hubRefPos_Len/)) + END IF + END IF + + ! -- nacRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%nacRefPos ) ) THEN + NULLIFY( ParamData%nacRefPos ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%nacRefPos, ParamData%nacRefPos, (/ParamData%C_obj%nacRefPos_Len/)) + END IF + END IF + + ! -- bldRootRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%bldRootRefPos ) ) THEN + NULLIFY( ParamData%bldRootRefPos ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%bldRootRefPos, ParamData%bldRootRefPos, (/ParamData%C_obj%bldRootRefPos_Len/)) + END IF + END IF + + ! -- bldChord Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%bldChord ) ) THEN + NULLIFY( ParamData%bldChord ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%bldChord, ParamData%bldChord, (/ParamData%C_obj%bldChord_Len/)) + END IF + END IF + + ! -- bldRloc Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%bldRloc ) ) THEN + NULLIFY( ParamData%bldRloc ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%bldRloc, ParamData%bldRloc, (/ParamData%C_obj%bldRloc_Len/)) + END IF + END IF + + ! -- twrDia Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%twrDia ) ) THEN + NULLIFY( ParamData%twrDia ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%twrDia, ParamData%twrDia, (/ParamData%C_obj%twrDia_Len/)) + END IF + END IF + + ! -- twrHloc Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. C_ASSOCIATED( ParamData%C_obj%twrHloc ) ) THEN + NULLIFY( ParamData%twrHloc ) + ELSE + CALL C_F_POINTER(ParamData%C_obj%twrHloc, ParamData%twrHloc, (/ParamData%C_obj%twrHloc_Len/)) + END IF + END IF END SUBROUTINE ExtLdDX_C2Fary_CopyParam SUBROUTINE ExtLdDX_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) @@ -1967,6 +1859,114 @@ SUBROUTINE ExtLdDX_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) ParamData%c_obj%nTowerNodes = C_LOC( ParamData%nTowerNodes( LBOUND(ParamData%nTowerNodes,1) ) ) END IF END IF + + ! -- twrRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%twrRefPos)) THEN + ParamData%c_obj%twrRefPos_Len = 0 + ParamData%c_obj%twrRefPos = C_NULL_PTR + ELSE + ParamData%c_obj%twrRefPos_Len = SIZE(ParamData%twrRefPos) + IF (ParamData%c_obj%twrRefPos_Len > 0) & + ParamData%c_obj%twrRefPos = C_LOC( ParamData%twrRefPos( LBOUND(ParamData%twrRefPos,1) ) ) + END IF + END IF + + ! -- bldRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%bldRefPos)) THEN + ParamData%c_obj%bldRefPos_Len = 0 + ParamData%c_obj%bldRefPos = C_NULL_PTR + ELSE + ParamData%c_obj%bldRefPos_Len = SIZE(ParamData%bldRefPos) + IF (ParamData%c_obj%bldRefPos_Len > 0) & + ParamData%c_obj%bldRefPos = C_LOC( ParamData%bldRefPos( LBOUND(ParamData%bldRefPos,1) ) ) + END IF + END IF + + ! -- hubRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%hubRefPos)) THEN + ParamData%c_obj%hubRefPos_Len = 0 + ParamData%c_obj%hubRefPos = C_NULL_PTR + ELSE + ParamData%c_obj%hubRefPos_Len = SIZE(ParamData%hubRefPos) + IF (ParamData%c_obj%hubRefPos_Len > 0) & + ParamData%c_obj%hubRefPos = C_LOC( ParamData%hubRefPos( LBOUND(ParamData%hubRefPos,1) ) ) + END IF + END IF + + ! -- nacRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%nacRefPos)) THEN + ParamData%c_obj%nacRefPos_Len = 0 + ParamData%c_obj%nacRefPos = C_NULL_PTR + ELSE + ParamData%c_obj%nacRefPos_Len = SIZE(ParamData%nacRefPos) + IF (ParamData%c_obj%nacRefPos_Len > 0) & + ParamData%c_obj%nacRefPos = C_LOC( ParamData%nacRefPos( LBOUND(ParamData%nacRefPos,1) ) ) + END IF + END IF + + ! -- bldRootRefPos Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%bldRootRefPos)) THEN + ParamData%c_obj%bldRootRefPos_Len = 0 + ParamData%c_obj%bldRootRefPos = C_NULL_PTR + ELSE + ParamData%c_obj%bldRootRefPos_Len = SIZE(ParamData%bldRootRefPos) + IF (ParamData%c_obj%bldRootRefPos_Len > 0) & + ParamData%c_obj%bldRootRefPos = C_LOC( ParamData%bldRootRefPos( LBOUND(ParamData%bldRootRefPos,1) ) ) + END IF + END IF + + ! -- bldChord Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%bldChord)) THEN + ParamData%c_obj%bldChord_Len = 0 + ParamData%c_obj%bldChord = C_NULL_PTR + ELSE + ParamData%c_obj%bldChord_Len = SIZE(ParamData%bldChord) + IF (ParamData%c_obj%bldChord_Len > 0) & + ParamData%c_obj%bldChord = C_LOC( ParamData%bldChord( LBOUND(ParamData%bldChord,1) ) ) + END IF + END IF + + ! -- bldRloc Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%bldRloc)) THEN + ParamData%c_obj%bldRloc_Len = 0 + ParamData%c_obj%bldRloc = C_NULL_PTR + ELSE + ParamData%c_obj%bldRloc_Len = SIZE(ParamData%bldRloc) + IF (ParamData%c_obj%bldRloc_Len > 0) & + ParamData%c_obj%bldRloc = C_LOC( ParamData%bldRloc( LBOUND(ParamData%bldRloc,1) ) ) + END IF + END IF + + ! -- twrDia Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%twrDia)) THEN + ParamData%c_obj%twrDia_Len = 0 + ParamData%c_obj%twrDia = C_NULL_PTR + ELSE + ParamData%c_obj%twrDia_Len = SIZE(ParamData%twrDia) + IF (ParamData%c_obj%twrDia_Len > 0) & + ParamData%c_obj%twrDia = C_LOC( ParamData%twrDia( LBOUND(ParamData%twrDia,1) ) ) + END IF + END IF + + ! -- twrHloc Param Data fields + IF ( .NOT. SkipPointers_local ) THEN + IF ( .NOT. ASSOCIATED(ParamData%twrHloc)) THEN + ParamData%c_obj%twrHloc_Len = 0 + ParamData%c_obj%twrHloc = C_NULL_PTR + ELSE + ParamData%c_obj%twrHloc_Len = SIZE(ParamData%twrHloc) + IF (ParamData%c_obj%twrHloc_Len > 0) & + ParamData%c_obj%twrHloc = C_LOC( ParamData%twrHloc( LBOUND(ParamData%twrHloc,1) ) ) + END IF + END IF END SUBROUTINE ExtLdDX_F2C_CopyParam SUBROUTINE ExtLdDX_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -2431,60 +2431,6 @@ SUBROUTINE ExtLdDX_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, Err u_out%bldRootDef(i1) = u1%bldRootDef(i1) + b * ScaleFactor END DO END IF ! check if allocated -IF (ASSOCIATED(u_out%twrRefPos) .AND. ASSOCIATED(u1%twrRefPos)) THEN - DO i1 = LBOUND(u_out%twrRefPos,1),UBOUND(u_out%twrRefPos,1) - b = -(u1%twrRefPos(i1) - u2%twrRefPos(i1)) - u_out%twrRefPos(i1) = u1%twrRefPos(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldRefPos) .AND. ASSOCIATED(u1%bldRefPos)) THEN - DO i1 = LBOUND(u_out%bldRefPos,1),UBOUND(u_out%bldRefPos,1) - b = -(u1%bldRefPos(i1) - u2%bldRefPos(i1)) - u_out%bldRefPos(i1) = u1%bldRefPos(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%hubRefPos) .AND. ASSOCIATED(u1%hubRefPos)) THEN - DO i1 = LBOUND(u_out%hubRefPos,1),UBOUND(u_out%hubRefPos,1) - b = -(u1%hubRefPos(i1) - u2%hubRefPos(i1)) - u_out%hubRefPos(i1) = u1%hubRefPos(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%nacRefPos) .AND. ASSOCIATED(u1%nacRefPos)) THEN - DO i1 = LBOUND(u_out%nacRefPos,1),UBOUND(u_out%nacRefPos,1) - b = -(u1%nacRefPos(i1) - u2%nacRefPos(i1)) - u_out%nacRefPos(i1) = u1%nacRefPos(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldRootRefPos) .AND. ASSOCIATED(u1%bldRootRefPos)) THEN - DO i1 = LBOUND(u_out%bldRootRefPos,1),UBOUND(u_out%bldRootRefPos,1) - b = -(u1%bldRootRefPos(i1) - u2%bldRootRefPos(i1)) - u_out%bldRootRefPos(i1) = u1%bldRootRefPos(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldChord) .AND. ASSOCIATED(u1%bldChord)) THEN - DO i1 = LBOUND(u_out%bldChord,1),UBOUND(u_out%bldChord,1) - b = -(u1%bldChord(i1) - u2%bldChord(i1)) - u_out%bldChord(i1) = u1%bldChord(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldRloc) .AND. ASSOCIATED(u1%bldRloc)) THEN - DO i1 = LBOUND(u_out%bldRloc,1),UBOUND(u_out%bldRloc,1) - b = -(u1%bldRloc(i1) - u2%bldRloc(i1)) - u_out%bldRloc(i1) = u1%bldRloc(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%twrDia) .AND. ASSOCIATED(u1%twrDia)) THEN - DO i1 = LBOUND(u_out%twrDia,1),UBOUND(u_out%twrDia,1) - b = -(u1%twrDia(i1) - u2%twrDia(i1)) - u_out%twrDia(i1) = u1%twrDia(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%twrHloc) .AND. ASSOCIATED(u1%twrHloc)) THEN - DO i1 = LBOUND(u_out%twrHloc,1),UBOUND(u_out%twrHloc,1) - b = -(u1%twrHloc(i1) - u2%twrHloc(i1)) - u_out%twrHloc(i1) = u1%twrHloc(i1) + b * ScaleFactor - END DO -END IF ! check if allocated IF (ASSOCIATED(u_out%bldPitch) .AND. ASSOCIATED(u1%bldPitch)) THEN DO i1 = LBOUND(u_out%bldPitch,1),UBOUND(u_out%bldPitch,1) b = -(u1%bldPitch(i1) - u2%bldPitch(i1)) @@ -2583,69 +2529,6 @@ SUBROUTINE ExtLdDX_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, u_out%bldRootDef(i1) = u1%bldRootDef(i1) + b + c * t_out END DO END IF ! check if allocated -IF (ASSOCIATED(u_out%twrRefPos) .AND. ASSOCIATED(u1%twrRefPos)) THEN - DO i1 = LBOUND(u_out%twrRefPos,1),UBOUND(u_out%twrRefPos,1) - b = (t(3)**2*(u1%twrRefPos(i1) - u2%twrRefPos(i1)) + t(2)**2*(-u1%twrRefPos(i1) + u3%twrRefPos(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%twrRefPos(i1) + t(3)*u2%twrRefPos(i1) - t(2)*u3%twrRefPos(i1) ) * scaleFactor - u_out%twrRefPos(i1) = u1%twrRefPos(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldRefPos) .AND. ASSOCIATED(u1%bldRefPos)) THEN - DO i1 = LBOUND(u_out%bldRefPos,1),UBOUND(u_out%bldRefPos,1) - b = (t(3)**2*(u1%bldRefPos(i1) - u2%bldRefPos(i1)) + t(2)**2*(-u1%bldRefPos(i1) + u3%bldRefPos(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%bldRefPos(i1) + t(3)*u2%bldRefPos(i1) - t(2)*u3%bldRefPos(i1) ) * scaleFactor - u_out%bldRefPos(i1) = u1%bldRefPos(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%hubRefPos) .AND. ASSOCIATED(u1%hubRefPos)) THEN - DO i1 = LBOUND(u_out%hubRefPos,1),UBOUND(u_out%hubRefPos,1) - b = (t(3)**2*(u1%hubRefPos(i1) - u2%hubRefPos(i1)) + t(2)**2*(-u1%hubRefPos(i1) + u3%hubRefPos(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%hubRefPos(i1) + t(3)*u2%hubRefPos(i1) - t(2)*u3%hubRefPos(i1) ) * scaleFactor - u_out%hubRefPos(i1) = u1%hubRefPos(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%nacRefPos) .AND. ASSOCIATED(u1%nacRefPos)) THEN - DO i1 = LBOUND(u_out%nacRefPos,1),UBOUND(u_out%nacRefPos,1) - b = (t(3)**2*(u1%nacRefPos(i1) - u2%nacRefPos(i1)) + t(2)**2*(-u1%nacRefPos(i1) + u3%nacRefPos(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%nacRefPos(i1) + t(3)*u2%nacRefPos(i1) - t(2)*u3%nacRefPos(i1) ) * scaleFactor - u_out%nacRefPos(i1) = u1%nacRefPos(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldRootRefPos) .AND. ASSOCIATED(u1%bldRootRefPos)) THEN - DO i1 = LBOUND(u_out%bldRootRefPos,1),UBOUND(u_out%bldRootRefPos,1) - b = (t(3)**2*(u1%bldRootRefPos(i1) - u2%bldRootRefPos(i1)) + t(2)**2*(-u1%bldRootRefPos(i1) + u3%bldRootRefPos(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%bldRootRefPos(i1) + t(3)*u2%bldRootRefPos(i1) - t(2)*u3%bldRootRefPos(i1) ) * scaleFactor - u_out%bldRootRefPos(i1) = u1%bldRootRefPos(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldChord) .AND. ASSOCIATED(u1%bldChord)) THEN - DO i1 = LBOUND(u_out%bldChord,1),UBOUND(u_out%bldChord,1) - b = (t(3)**2*(u1%bldChord(i1) - u2%bldChord(i1)) + t(2)**2*(-u1%bldChord(i1) + u3%bldChord(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%bldChord(i1) + t(3)*u2%bldChord(i1) - t(2)*u3%bldChord(i1) ) * scaleFactor - u_out%bldChord(i1) = u1%bldChord(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%bldRloc) .AND. ASSOCIATED(u1%bldRloc)) THEN - DO i1 = LBOUND(u_out%bldRloc,1),UBOUND(u_out%bldRloc,1) - b = (t(3)**2*(u1%bldRloc(i1) - u2%bldRloc(i1)) + t(2)**2*(-u1%bldRloc(i1) + u3%bldRloc(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%bldRloc(i1) + t(3)*u2%bldRloc(i1) - t(2)*u3%bldRloc(i1) ) * scaleFactor - u_out%bldRloc(i1) = u1%bldRloc(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%twrDia) .AND. ASSOCIATED(u1%twrDia)) THEN - DO i1 = LBOUND(u_out%twrDia,1),UBOUND(u_out%twrDia,1) - b = (t(3)**2*(u1%twrDia(i1) - u2%twrDia(i1)) + t(2)**2*(-u1%twrDia(i1) + u3%twrDia(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%twrDia(i1) + t(3)*u2%twrDia(i1) - t(2)*u3%twrDia(i1) ) * scaleFactor - u_out%twrDia(i1) = u1%twrDia(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ASSOCIATED(u_out%twrHloc) .AND. ASSOCIATED(u1%twrHloc)) THEN - DO i1 = LBOUND(u_out%twrHloc,1),UBOUND(u_out%twrHloc,1) - b = (t(3)**2*(u1%twrHloc(i1) - u2%twrHloc(i1)) + t(2)**2*(-u1%twrHloc(i1) + u3%twrHloc(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%twrHloc(i1) + t(3)*u2%twrHloc(i1) - t(2)*u3%twrHloc(i1) ) * scaleFactor - u_out%twrHloc(i1) = u1%twrHloc(i1) + b + c * t_out - END DO -END IF ! check if allocated IF (ASSOCIATED(u_out%bldPitch) .AND. ASSOCIATED(u1%bldPitch)) THEN DO i1 = LBOUND(u_out%bldPitch,1),UBOUND(u_out%bldPitch,1) b = (t(3)**2*(u1%bldPitch(i1) - u2%bldPitch(i1)) + t(2)**2*(-u1%bldPitch(i1) + u3%bldPitch(i1)))* scaleFactor diff --git a/modules/extloads/src/ExtLoadsDX_Types.h b/modules/extloads/src/ExtLoadsDX_Types.h index 6a818f498c..da9ebc41b7 100644 --- a/modules/extloads/src/ExtLoadsDX_Types.h +++ b/modules/extloads/src/ExtLoadsDX_Types.h @@ -27,6 +27,13 @@ double * hubDef ; int hubDef_Len ; double * nacDef ; int nacDef_Len ; double * bldRootDef ; int bldRootDef_Len ; + double * bldPitch ; int bldPitch_Len ; + } ExtLdDX_InputType_t ; + typedef struct ExtLdDX_ParameterType { + void * object ; + int * nBlades ; int nBlades_Len ; + int * nBladeNodes ; int nBladeNodes_Len ; + int * nTowerNodes ; int nTowerNodes_Len ; double * twrRefPos ; int twrRefPos_Len ; double * bldRefPos ; int bldRefPos_Len ; double * hubRefPos ; int hubRefPos_Len ; @@ -36,13 +43,6 @@ double * bldRloc ; int bldRloc_Len ; double * twrDia ; int twrDia_Len ; double * twrHloc ; int twrHloc_Len ; - double * bldPitch ; int bldPitch_Len ; - } ExtLdDX_InputType_t ; - typedef struct ExtLdDX_ParameterType { - void * object ; - int * nBlades ; int nBlades_Len ; - int * nBladeNodes ; int nBladeNodes_Len ; - int * nTowerNodes ; int nTowerNodes_Len ; } ExtLdDX_ParameterType_t ; typedef struct ExtLdDX_OutputType { void * object ; diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 3d818c2fe9..82a5d9d96c 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -989,31 +989,32 @@ subroutine SetExtLoads_pointers(iTurb, ExtLd_iFromOF, ExtLd_pFromOF, ExtLd_oToOF TYPE(ExtLdDX_ParameterType_C), INTENT(INOUT) :: ExtLd_pFromOF TYPE(ExtLdDX_OutputType_C), INTENT(INOUT) :: ExtLd_oToOF - ExtLd_iFromOF%bldPitch_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch_Len; ExtLd_iFromOF%bldPitch = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch - ExtLd_iFromOF%twrHloc_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrHloc_Len; ExtLd_iFromOF%twrHloc = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrHloc - ExtLd_iFromOF%twrDia_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDia_Len; ExtLd_iFromOF%twrDia = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDia - ExtLd_iFromOF%twrRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrRefPos_Len; ExtLd_iFromOF%twrRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrRefPos - ExtLd_iFromOF%twrDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDef_Len; ExtLd_iFromOF%twrDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDef - ExtLd_iFromOF%bldRloc_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRloc_Len; ExtLd_iFromOF%bldRloc = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRloc - ExtLd_iFromOF%bldChord_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldChord_Len; ExtLd_iFromOF%bldChord = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldChord - ExtLd_iFromOF%bldRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRefPos_Len; ExtLd_iFromOF%bldRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRefPos - ExtLd_iFromOF%bldRootRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootRefPos_Len; ExtLd_iFromOF%bldRootRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootRefPos - ExtLd_iFromOF%bldDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef_Len; ExtLd_iFromOF%bldDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef - - ExtLd_iFromOF%bldRootDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef_Len; ExtLd_iFromOF%bldRootDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef - - ExtLd_iFromOF%hubRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubRefPos_Len; ExtLd_iFromOF%hubRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubRefPos - ExtLd_iFromOF%hubDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubDef_Len; ExtLd_iFromOF%hubDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubDef - - ExtLd_iFromOF%nacRefPos_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacRefPos_Len; ExtLd_iFromOF%nacRefPos = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacRefPos - ExtLd_iFromOF%nacDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef_Len; ExtLd_iFromOF%nacDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef - - ExtLd_pFromOF%nBlades_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBlades_Len; ExtLd_pFromOF%nBlades = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBlades - ExtLd_pFromOF%nBladeNodes_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBladeNodes_Len; ExtLd_pFromOF%nBladeNodes = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBladeNodes - ExtLd_pFromOF%nTowerNodes_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nTowerNodes_Len; ExtLd_pFromOF%nTowerNodes = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nTowerNodes - - ExtLd_oToOF%twrLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd_Len; ExtLd_oToOF%twrLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd - ExtLd_oToOF%bldLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd_Len; ExtLd_oToOF%bldLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd + ! Inputs + ExtLd_iFromOF%bldPitch_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch_Len; ExtLd_iFromOF%bldPitch = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldPitch + ExtLd_iFromOF%twrDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDef_Len; ExtLd_iFromOF%twrDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%twrDef + ExtLd_iFromOF%bldDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef_Len; ExtLd_iFromOF%bldDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldDef + ExtLd_iFromOF%bldRootDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef_Len; ExtLd_iFromOF%bldRootDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%bldRootDef + ExtLd_iFromOF%hubDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubDef_Len; ExtLd_iFromOF%hubDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%hubDef + ExtLd_iFromOF%nacDef_Len = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef_Len; ExtLd_iFromOF%nacDef = Turbine(iTurb)%ExtLd%u%DX_u%c_obj%nacDef + + ! Parameters + ExtLd_pFromOF%nBlades_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBlades_Len; ExtLd_pFromOF%nBlades = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBlades + ExtLd_pFromOF%nBladeNodes_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBladeNodes_Len; ExtLd_pFromOF%nBladeNodes = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nBladeNodes + ExtLd_pFromOF%nTowerNodes_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nTowerNodes_Len; ExtLd_pFromOF%nTowerNodes = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nTowerNodes + + ExtLd_pFromOF%twrHloc_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%twrHloc_Len; ExtLd_pFromOF%twrHloc = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%twrHloc + ExtLd_pFromOF%twrDia_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%twrDia_Len; ExtLd_pFromOF%twrDia = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%twrDia + ExtLd_pFromOF%twrRefPos_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%twrRefPos_Len; ExtLd_pFromOF%twrRefPos = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%twrRefPos + ExtLd_pFromOF%bldRloc_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldRloc_Len; ExtLd_pFromOF%bldRloc = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldRloc + ExtLd_pFromOF%bldChord_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldChord_Len; ExtLd_pFromOF%bldChord = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldChord + ExtLd_pFromOF%bldRefPos_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldRefPos_Len; ExtLd_pFromOF%bldRefPos = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldRefPos + ExtLd_pFromOF%bldRootRefPos_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldRootRefPos_Len; ExtLd_pFromOF%bldRootRefPos = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%bldRootRefPos + ExtLd_pFromOF%hubRefPos_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%hubRefPos_Len; ExtLd_pFromOF%hubRefPos = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%hubRefPos + ExtLd_pFromOF%nacRefPos_Len = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nacRefPos_Len; ExtLd_pFromOF%nacRefPos = Turbine(iTurb)%ExtLd%p%DX_p%c_obj%nacRefPos + + ! Outputs + ExtLd_oToOF%twrLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd_Len; ExtLd_oToOF%twrLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%twrLd + ExtLd_oToOF%bldLd_Len = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd_Len; ExtLd_oToOF%bldLd = Turbine(iTurb)%ExtLd%y%DX_y%c_obj%bldLd end subroutine SetExtLoads_pointers From d6f4061bfdecad4102973ab480bd5e41b1c7a7e0 Mon Sep 17 00:00:00 2001 From: Matt Hall <5151457+mattEhall@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:45:16 -0700 Subject: [PATCH 85/91] MoorDyn body initial condition adjustment - Edited Body position/orientation used for input mesh setup and initial positions before dynamic relaxation, to hopefully solve that coupled bodies were previously being initialized at 0,0,0. - Coupled bodies should now initialize with position and orientation that is a combination of the relative values in the input file, plus any PtfmInit value passed from the glue code. - With this change, it's possible the p%Standalone flag is not needed - TBD. --- modules/moordyn/src/MoorDyn.f90 | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index fc6f47db6e..b0e6c07063 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -1868,27 +1868,34 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL CheckError( ErrStat2, ErrMsg2 ) IF (ErrStat >= AbortErrLev) RETURN - ! note: in MoorDyn-F v2, the points in the mesh correspond in order to all the coupled bodies, then rods, then points - ! >>> make sure all coupled objects have been offset correctly by the PtfmInit values, including if it's a farm situation -- below or where the objects are first created <<<< + ! Note: in MoorDyn-F v2, the points in the mesh correspond in order to + ! all the coupled bodies, then rods, then points. The below code makes + ! sure all coupled objects have been offset correctly by the PtfmInit + ! values (initial platform pose), including if using FAST.Farm. + ! rRef and OrMatRef or the position and orientation matrix of the + ! coupled object relative to the platform, based on the input file. + ! They are used to set the "reference" pose of each coupled mesh + ! entry before the intial offsets from PtfmInit are applied. J = 0 ! this is the counter through the mesh points for each turbine DO l = 1,p%nCpldBodies(iTurb) J = J + 1 - rRef = m%BodyList(m%CpldBodyIs(l,iTurb))%r6 ! for now set reference position as per input file <<< - - CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) ! defaults to identity orientation matrix + rRef = m%BodyList(m%CpldBodyIs(l,iTurb))%r6 ! set reference position as per input file + OrMatRef = ( m%RodList(m%CpldBodyIs(l,iTurb))%OrMat ) ! set reference orientation as per input file + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! set absolute initial positions in MoorDyn IF (p%Standalone /= 1) THEN - !TODO: >>> should also maybe set reference orientation (which might make part of a couple lines down redundant) <<< - OrMat2 = MATMUL(OrMat, ( EulerConstruct( rRef(4:6)))) ! combine the Body's relative orientation with the turbine's initial orientation - u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body <<< + OrMat2 = MATMUL(OrMat, OrMatRef) ! combine the Body's relative orientation with the turbine's initial orientation + u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body - ! calculate initial point relative position, adjusted due to initial platform translations - u%CoupledKinematics(iTurb)%TranslationDisp(:,J) = InitInp%PtfmInit(1:3,iTurb) - rRef(1:3) + ! calculate initial body relative position, adjusted due to initial platform translations + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(OrMat2) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation ENDIF @@ -1907,12 +1914,12 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! set absolute initial positions in MoorDyn IF (p%Standalone /= 1) THEN - OrMatRef = ( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! for now set reference orientation as per input file <<< + OrMatRef = ( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! set reference orientation as per input file CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation OrMat2 = MATMUL(OrMat, OrMatRef) ! combine the Rod's relative orientation with the turbine's initial orientation u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< - ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math + ! calculate initial rod relative position, adjusted due to initial platform rotations and translations <<< could convert to array math u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) From 68d162ee7283c2a6166aa192642eeec3ab3e0a6e Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Wed, 24 Jan 2024 18:04:25 -0700 Subject: [PATCH 86/91] Removes standalone driver option --- modules/moordyn/src/MoorDyn.f90 | 63 ++++++++++-------------- modules/moordyn/src/MoorDyn_Driver.f90 | 9 +--- modules/moordyn/src/MoorDyn_Registry.txt | 3 +- modules/moordyn/src/MoorDyn_Types.f90 | 9 +--- 4 files changed, 30 insertions(+), 54 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index b0e6c07063..e3304fdd48 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -205,9 +205,6 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL WrScr(' >>> MoorDyn is running in array mode <<< ') ! could make sure the size of this is right: SIZE(InitInp%FarmCoupledKinematics) p%nTurbines = InitInp%FarmSize - else if (InitInp%FarmSize < 0) then ! Farmsize==-1 indicates standlone, run MoorDyn as a standalone code with no openfast coupling - p%Standalone = 1 - p%nTurbines = 1 else ! FarmSize==0 indicates normal, FAST module mode p%nTurbines = 1 ! if a regular FAST module mode, we treat it like a nTurbine=1 farm case END IF @@ -1887,18 +1884,16 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er OrMatRef = ( m%RodList(m%CpldBodyIs(l,iTurb))%OrMat ) ! set reference orientation as per input file CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) - ! set absolute initial positions in MoorDyn - IF (p%Standalone /= 1) THEN - OrMat2 = MATMUL(OrMat, OrMatRef) ! combine the Body's relative orientation with the turbine's initial orientation - u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body - - ! calculate initial body relative position, adjusted due to initial platform translations - u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) - u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) - u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) - m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) - m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(OrMat2) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation - ENDIF + ! set absolute initial positions in MoorDyn + OrMat2 = MATMUL(OrMat, OrMatRef) ! combine the Body's relative orientation with the turbine's initial orientation + u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body + + ! calculate initial body relative position, adjusted due to initial platform translations + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(OrMat2) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! set node as point element @@ -1913,19 +1908,17 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er rRef = m%RodList(m%CpldRodIs(l,iTurb))%r6 ! for now set reference position as per input file <<< ! set absolute initial positions in MoorDyn - IF (p%Standalone /= 1) THEN - OrMatRef = ( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! set reference orientation as per input file - CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation - OrMat2 = MATMUL(OrMat, OrMatRef) ! combine the Rod's relative orientation with the turbine's initial orientation - u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< - - ! calculate initial rod relative position, adjusted due to initial platform rotations and translations <<< could convert to array math - u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) - u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) - u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) - m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) - m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = MATMUL(OrMat2 , (/0.0, 0.0, 1.0/) ) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation - ENDIF + OrMatRef = ( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! set reference orientation as per input file + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation + OrMat2 = MATMUL(OrMat, OrMatRef) ! combine the Rod's relative orientation with the turbine's initial orientation + u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< + + ! calculate initial rod relative position, adjusted due to initial platform rotations and translations <<< could convert to array math + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) + m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = MATMUL(OrMat2 , (/0.0, 0.0, 1.0/) ) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation ! >>> still need to set Rod initial orientations accounting for PtfmInit rotation <<< @@ -1942,14 +1935,12 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er rRef(1:3) = m%PointList(m%CpldPointIs(l,iTurb))%r ! set absolute initial positions in MoorDyn - IF (p%Standalone /= 1) THEN - CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) - ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math - u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) - u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) - u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) - m%PointList(m%CpldPointIs(l,iTurb))%r = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) - ENDIF + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) + ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) + m%PointList(m%CpldPointIs(l,iTurb))%r = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! lastly, do this to set the attached line endpoint positions: diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index de826a52b1..b0522c9326 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -175,7 +175,7 @@ PROGRAM MoorDyn_Driver if (drvrInitInp%FarmSize > 0) then ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) nTurbines = drvrInitInp%FarmSize - else ! FarmSize==0 indicates normal, FAST module mode; FarmSize<0 indicates standalone mode + else ! FarmSize==0 indicates normal, FAST module mode nTurbines = 1 ! if a regular FAST module mode, we treat it like a nTurbine=1 farm case end if @@ -491,10 +491,6 @@ PROGRAM MoorDyn_Driver K = 1 ! the index of the coupling points in the input mesh CoupledKinematics J = 1 ! the starting index of the relevant DOFs in the input array - IF (MD_InitInp%FarmSize < 0) THEN - MD_p%TurbineRefPos(:,iTurb) = 0.0 - ENDIF - ! any coupled bodies (type -1) DO l = 1,MD_p%nCpldBodies(iTurb) MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) @@ -582,9 +578,6 @@ PROGRAM MoorDyn_Driver K = 1 ! the index of the coupling points in the input mesh CoupledKinematics J = 1 ! the starting index of the relevant DOFs in the input array - IF (MD_InitInp%FarmSize < 0) THEN - MD_p%TurbineRefPos(:,iTurb) = 0.0 - ENDIF ! any coupled bodies (type -1) DO l = 1,MD_p%nCpldBodies(iTurb) diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index d4df4982c8..283fca0bed 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -24,7 +24,7 @@ typedef MoorDyn/MD InitInputType ReKi g - -99 typedef ^ ^ ReKi rhoW - -999.9 - "sea density" "[kg/m^3]" typedef ^ ^ ReKi WtrDepth - -999.9 - "depth of water" "[m]" typedef ^ ^ ReKi PtfmInit {:}{:} - - "initial position of platform(s) shape: 6, nTurbines" - -typedef ^ ^ IntKi FarmSize - 0 - "Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0, standalone mode if -1" - +typedef ^ ^ IntKi FarmSize - 0 - "Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0" - typedef ^ ^ ReKi TurbineRefPos {:}{:} - - "reference position of turbines in farm, shape: 3, nTurbines" - typedef ^ ^ ReKi Tmax - - - "simulation duration" "[s]" typedef ^ ^ CHARACTER(1024) FileName - "" - "MoorDyn input file" @@ -390,7 +390,6 @@ typedef ^ ^ DbKi mu_kT - typedef ^ ^ DbKi mu_kA - - - "axial kinetic friction coefficient" "(-)" typedef ^ ^ DbKi mc - - - "ratio of the static friction coefficient to the kinetic friction coefficient" "(-)" typedef ^ ^ DbKi cv - - - "saturated damping coefficient" "(-)" -typedef ^ ^ IntKi Standalone - - - "Indicates MoorDyn run as standalone code if 1, coupled if 0" - typedef ^ ^ IntKi inertialF - 0 - "Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no" - # --- parameters for wave and current --- typedef ^ ^ IntKi nxWave - - - "number of x wave grid points" - diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 2c8071eefe..6f94451de3 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -47,7 +47,7 @@ MODULE MoorDyn_Types REAL(ReKi) :: rhoW = -999.9 !< sea density [[kg/m^3]] REAL(ReKi) :: WtrDepth = -999.9 !< depth of water [[m]] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PtfmInit !< initial position of platform(s) shape: 6, nTurbines [-] - INTEGER(IntKi) :: FarmSize = 0 !< Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0, standalone mode if -1 [-] + INTEGER(IntKi) :: FarmSize = 0 !< Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0 [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TurbineRefPos !< reference position of turbines in farm, shape: 3, nTurbines [-] REAL(ReKi) :: Tmax !< simulation duration [[s]] CHARACTER(1024) :: FileName !< MoorDyn input file [-] @@ -425,7 +425,6 @@ MODULE MoorDyn_Types REAL(DbKi) :: mu_kA !< axial kinetic friction coefficient [(-)] REAL(DbKi) :: mc !< ratio of the static friction coefficient to the kinetic friction coefficient [(-)] REAL(DbKi) :: cv !< saturated damping coefficient [(-)] - INTEGER(IntKi) :: Standalone !< Indicates MoorDyn run as standalone code if 1, coupled if 0 [-] INTEGER(IntKi) :: inertialF = 0 !< Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 1 if yes, 0 if no [-] INTEGER(IntKi) :: nxWave !< number of x wave grid points [-] INTEGER(IntKi) :: nyWave !< number of y wave grid points [-] @@ -10787,7 +10786,6 @@ SUBROUTINE MD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%mu_kA = SrcParamData%mu_kA DstParamData%mc = SrcParamData%mc DstParamData%cv = SrcParamData%cv - DstParamData%Standalone = SrcParamData%Standalone DstParamData%inertialF = SrcParamData%inertialF DstParamData%nxWave = SrcParamData%nxWave DstParamData%nyWave = SrcParamData%nyWave @@ -11300,7 +11298,6 @@ SUBROUTINE MD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_BufSz = Db_BufSz + 1 ! mu_kA Db_BufSz = Db_BufSz + 1 ! mc Db_BufSz = Db_BufSz + 1 ! cv - Int_BufSz = Int_BufSz + 1 ! Standalone Int_BufSz = Int_BufSz + 1 ! inertialF Int_BufSz = Int_BufSz + 1 ! nxWave Int_BufSz = Int_BufSz + 1 ! nyWave @@ -11638,8 +11635,6 @@ SUBROUTINE MD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%cv Db_Xferred = Db_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%Standalone - Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%inertialF Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%nxWave @@ -12338,8 +12333,6 @@ SUBROUTINE MD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Db_Xferred = Db_Xferred + 1 OutData%cv = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - OutData%Standalone = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 OutData%inertialF = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%nxWave = IntKiBuf(Int_Xferred) From 80c88a20356b232fb2f5f560d2484eddfd25f531 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Fri, 26 Jan 2024 12:17:02 -0700 Subject: [PATCH 87/91] Remove typo in warning, retains c/con option for output flags for backwards compatibility --- modules/moordyn/src/MoorDyn_IO.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 245c9afa1f..119ff7a3f2 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -567,7 +567,7 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) END IF ! Point case - ELSE IF (let1(1:1) == 'P') THEN ! Look for P?xxx or Point?xxx + ELSE IF (let1(1:1) == 'P' .OR. let1(1:1) == 'C') THEN ! Look for P?xxx or Point?xxx (C?xxx and Con?xxx for backwards compatability) p%OutParam(I)%OType = 2 ! Point object type qVal = let2 ! quantity type string @@ -605,7 +605,7 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) ! error ELSE CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid - CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Must start with L, C, R, or B') + CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Must start with L, R, or B') CYCLE END IF From fd41e426acd0b5bf21f1714c254cd6294b5e1ca7 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Mon, 29 Jan 2024 09:37:09 -0700 Subject: [PATCH 88/91] Bathymetry grid bug fix --- modules/moordyn/src/MoorDyn_IO.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 119ff7a3f2..7cc83414d7 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -182,7 +182,7 @@ SUBROUTINE setupBathymetry(inputString, defaultDepth, BathGrid, BathGrid_Xs, Bat READ(UnCoef,*,IOSTAT=ErrStat4) nGridY_string, nGridY ! read in the third line as the number of y values in the BathGrid ! Allocate the bathymetry matrix and associated grid x and y values - ALLOCATE(BathGrid(nGridX, nGridY), STAT=ErrStat4) + ALLOCATE(BathGrid(nGridY, nGridX), STAT=ErrStat4) ALLOCATE(BathGrid_Xs(nGridX), STAT=ErrStat4) ALLOCATE(BathGrid_Ys(nGridY), STAT=ErrStat4) From 75f987c1147e7f8cf053f4f261fa1102800241a1 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Mon, 29 Jan 2024 12:42:27 -0700 Subject: [PATCH 89/91] Bathymetry grid slope normal vector bug fix --- modules/moordyn/src/MoorDyn_Misc.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index 8fb91cf218..e8e9cf7ace 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -885,7 +885,7 @@ SUBROUTINE getDepthFromBathymetry(BathymetryGrid, BathGrid_Xs, BathGrid_Ys, Line else dc_dx = 0.0_DbKi ! maybe this should raise an error end if - if ( dx > 0.0 ) then + if ( dy > 0.0 ) then dc_dy = (cx1-cx0)/dy else dc_dy = 0.0_DbKi ! maybe this should raise an error From 57e110a1512b40842a36e7d7ece655aded4a516a Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Tue, 30 Jan 2024 16:03:13 -0700 Subject: [PATCH 90/91] Change input string size for bathgrid and waterkin --- modules/moordyn/src/MoorDyn_IO.f90 | 2 +- modules/moordyn/src/MoorDyn_Misc.f90 | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 7cc83414d7..5a5f319a09 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -139,7 +139,7 @@ SUBROUTINE setupBathymetry(inputString, defaultDepth, BathGrid, BathGrid_Xs, Bat INTEGER(IntKi) :: ErrStat4 CHARACTER(120) :: ErrMsg4 - CHARACTER(120) :: Line2 + CHARACTER(4096) :: Line2 CHARACTER(20) :: nGridX_string ! string to temporarily hold the nGridX string from Line2 CHARACTER(20) :: nGridY_string ! string to temporarily hold the nGridY string from Line3 diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index e8e9cf7ace..c54dea1f2e 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -1300,8 +1300,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) REAL(SiKi) :: t, Frac CHARACTER(1024) :: FileName ! Name of MoorDyn input file CHARACTER(120) :: Line -! CHARACTER(120) :: Line2 - CHARACTER(120) :: entries2 + CHARACTER(4096) :: entries2 INTEGER(IntKi) :: coordtype INTEGER(IntKi) :: NStepWave ! From ba95b2321180cc567a324a0184dbecf7189ba691 Mon Sep 17 00:00:00 2001 From: Bonnie Jonkman Date: Thu, 7 Mar 2024 09:48:22 -0700 Subject: [PATCH 91/91] UA driver: fix indices on alpha, U, and omega our regression tests found this issue --- modules/aerodyn/src/UA_Dvr_Subs.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/aerodyn/src/UA_Dvr_Subs.f90 b/modules/aerodyn/src/UA_Dvr_Subs.f90 index 1d7e12f955..43fc33e67d 100644 --- a/modules/aerodyn/src/UA_Dvr_Subs.f90 +++ b/modules/aerodyn/src/UA_Dvr_Subs.f90 @@ -360,7 +360,7 @@ subroutine Dvr_SetParameters(p, errStat, errMsg) else if ( p%SimMod == 2 ) then ! Read time-series data file with columns:( time, Angle-of-attack, Vrel, omega ) - call WrScr( ' Opening prescribe-aero time-series input file: '//trim(p%AeroTSFile) ) + call WrScr( ' Opening prescribed-aero time-series input file: '//trim(p%AeroTSFile) ) call ReadDelimFile(p%AeroTSFile, 4, p%vPrescrAero, errStat2, errMsg2); if(Failed()) return p%vPrescrAero(:,2) = p%vPrescrAero(:,2)*D2R ! Deg 2 rad p%dt = p%dt_PA @@ -709,9 +709,9 @@ subroutine setUAinputsAlphaSim(n, u, t, p, m, errStat, errMsg) else ! Interpolate at current time call interpTimeValue(p%vPrescrAero, t, m%iPALast, m%uPA) - u%alpha = m%uPA(2) ! rad - u%U = m%uPA(3) - u%omega = m%uPA(4) + u%alpha = m%uPA(1) ! rad + u%U = m%uPA(2) + u%omega = m%uPA(3) u%v_ac(1) = sin(u%alpha)*u%U u%v_ac(2) = cos(u%alpha)*u%U u%Re = u%U * p%chord / p%KinVisc

xTAj)L+$<@cL`CJZa=&9@hjz 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 literal 0 HcmV?d00001 diff --git a/docs/source/dev/cppapi/files/thrustXActuatorForcePoints.png b/docs/source/dev/cppapi/files/thrustXActuatorForcePoints.png new file mode 100644 index 0000000000000000000000000000000000000000..5bf845481b977cf2a19a5acfa87273c7d9b5dd0b GIT binary patch literal 41122 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 literal 0 HcmV?d00001 diff --git a/docs/source/dev/cppapi/files/torqueXActuatorForcePoints.png b/docs/source/dev/cppapi/files/torqueXActuatorForcePoints.png new file mode 100644 index 0000000000000000000000000000000000000000..fa751ad1be01b6d25e9e308c9e8e6897d342d860 GIT binary patch literal 29483 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