diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..096b1c29a1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +# add (semi-useful) version info to git archive +CreateGitVersion.bat ident export-subst + +# Declare files that will always have CRLF line endings on checkout. +*.bat text eol=crlf + diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..a9fd553b08 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,56 @@ +--- +name: Bug report +about: Report a bug to help us improve +title: 'Bug report' +labels: "Type: Bug" +--- + +**Bug description** + + +**To Reproduce** + +Steps to reproduce the behavior: +1. Compile with '...' +2. Run '...' case with '...' settings +3. Open '...' output +4. See the error + +**Expected behavior** + + +**Screenshots, if applicable** + + +**OpenFAST Version** + + +``` +************************************************************************************************** + OpenFAST + + Copyright (C) National Renewable Energy Laboratory + Copyright (C) Envision Energy USA LTD + + This program is licensed under Apache License Version 2.0 and comes with ABSOLUTELY NO WARRANTY. + See the "LICENSE" file distributed with this software for details. + ************************************************************************************************** + + OpenFAST-v2.0.0 + Compile Info: + - Architecture: 64 bit + - Precision: double + - Date: Nov 27 2018 + - Time: 17:19:38 + Execution Info: + - Date: 11/29/2018 + - Time: 10:52:28-0700 +``` + +**System Information (please complete the following information):** + - OS: + - Compiler: + - Compiler settings: + +**Additional context** + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..b1a58ca9f0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: 'Feature request' +labels: 'Type: Enhancement' +--- + +**Is your feature request related to a problem? Please describe.** + + +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..ed889feb77 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ + +**Complete this sentence** +THIS PULL REQUEST __ [IS/IS NOT] __ READY TO MERGE + +**Feature or improvement description** + + +**Related issue, if one exists** + + +**Impacted areas of the software** + + +**Additional supporting information** + + +**Test results, if applicable** + diff --git a/.travis.yml b/.travis.yml index 1d2817a78d..79c99f28a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,61 +7,58 @@ language: c -os: - - linux - - osx +matrix: + include: + - os: linux + dist: bionic + env: FC=/usr/bin/gfortran-7; DOUBLE_PRECISION=ON + - os: linux + dist: bionic + env: FC=/usr/bin/gfortran-7; DOUBLE_PRECISION=OFF + - os: linux + dist: bionic + env: FC=/usr/bin/gfortran-7; DOUBLE_PRECISION=ON; CPP_API=ON; CMAKE_FLAGS="-DBUILD_OPENFAST_CPP_API=$CPP_API" + - os: osx + osx_image: xcode9.2 + env: FC=/usr/local/bin/gfortran-7; DOUBLE_PRECISION=ON + - os: osx + osx_image: xcode9.2 + env: FC=/usr/local/bin/gfortran-7; DOUBLE_PRECISION=OFF -# linux configuration; container-based environments (default for linux) require the following setup block +# macos dependency install addons: - apt: + homebrew: packages: - - gfortran - - libblas-dev - - liblapack-dev - -env: - - FC=/usr/local/bin/gfortran-7; DOUBLE_PRECISION=ON - - FC=/usr/local/bin/gfortran-7; DOUBLE_PRECISION=OFF - - FC=/usr/bin/gfortran; DOUBLE_PRECISION=ON - - FC=/usr/bin/gfortran; DOUBLE_PRECISION=OFF - -# mac configuration + - gcc@7 + - yaml-cpp + - hdf5 + - open-mpi + update: true + before_install: - # first uninstall a conflicting package - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew cask uninstall oclint; fi - - # install required packages - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi + # mac configuration - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew upgrade python; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install gcc@7; fi - # - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake; fi # cmake is already installed in the default mac image + + # linux configuration + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install gfortran libblas-dev liblapack-dev; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" && "$CPP_API" == "ON" ]]; then sudo apt-get install libopenmpi-dev libyaml-cpp-dev libhdf5-dev libxml2-dev; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pyenv shell 3.7.1; fi # common configuration - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pyenv shell 3.6.3; fi - pip3 install numpy install: - mkdir build && cd build - - cmake .. -DBUILD_TESTING=ON -DDOUBLE_PRECISION=$DOUBLE_PRECISION - - make -j 8 install - -matrix: - exclude: - - os: linux - env: FC=/usr/local/bin/gfortran-7; DOUBLE_PRECISION=ON - - os: linux - env: FC=/usr/local/bin/gfortran-7; DOUBLE_PRECISION=OFF - - os: osx - env: FC=/usr/bin/gfortran; DOUBLE_PRECISION=ON - - os: osx - env: FC=/usr/bin/gfortran; DOUBLE_PRECISION=OFF + - cmake .. -DCMAKE_BUILD_TYPE=DEBUG -DBUILD_TESTING=ON -DBUILD_SHARED_LIBS=ON -DDOUBLE_PRECISION=$DOUBLE_PRECISION $CMAKE_FLAGS + - cat CMakeCache.txt + - make -j4 install script: # beamdyn unit tests - - if [[ "$DOUBLE_PRECISION" == "ON" ]]; then ctest -R beamdyn_utest; fi + - if [[ "$DOUBLE_PRECISION" == "ON" ]]; then ctest -VV -R beamdyn_utest; fi # beamdyn regression tests - - if [[ "$DOUBLE_PRECISION" == "ON" ]]; then ctest -R bd_; fi + - if [[ "$DOUBLE_PRECISION" == "ON" ]]; then ctest -j4 -VV -R bd_; fi # subset of openfast regression tests # do not run @@ -71,4 +68,3 @@ script: # CURRENTLY, TESTS FAIL WITH VERY MINOR DIFFERENCES # - ctest -VV -j 18 -I 1,1,1,2,5,6,8,9,10,11,12,13,14,18,19,22,23,24,25,26 # - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ctest -j 18 -I 1,1,1,2,5,6,8,9,10,11,12,13,14,18,19,22,23,24,25,26 ; fi - diff --git a/CMakeLists.txt b/CMakeLists.txt index c1ab75980c..2d34f96bca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,12 +22,6 @@ include(${CMAKE_SOURCE_DIR}/cmake/OpenfastFortranOptions.cmake) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -# Get the git info into the executable -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") -include(GetGitRevisionDescription) -git_describe(GIT_DESCRIBE) -add_definitions(-DGIT_VERSION_INFO="${GIT_DESCRIBE}") - # CMake Configuration variables if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING @@ -77,12 +71,12 @@ endif() ######################################################################## # Build rules for OpenFAST Registry # -add_subdirectory(modules-local/openfast-registry) +add_subdirectory(modules/openfast-registry) ######################################################################## -# OpenFAST Core modules +# OpenFAST modules # -set(OPENFAST_MODULES_LOCAL +set(OPENFAST_MODULES nwtc-library inflowwind aerodyn @@ -98,12 +92,7 @@ set(OPENFAST_MODULES_LOCAL supercontroller turbsim openfast-library - ) - -######################################################################## -# OpenFAST External modules -# -set(OPENFAST_MODULES_EXTERNAL + version feamooring moordyn icedyn @@ -112,20 +101,15 @@ set(OPENFAST_MODULES_EXTERNAL ) set(OPENFAST_REGISTRY_INCLUDES "" CACHE INTERNAL "Registry includes paths") -set_registry_includes("modules-local" ${OPENFAST_MODULES_LOCAL}) -set_registry_includes("modules-ext" ${OPENFAST_MODULES_EXTERNAL}) +set_registry_includes("modules" ${OPENFAST_MODULES}) # Fix non-standard path addition to OPENFAST_REGISTRY_INCLUDES in icefloe module set(OPENFAST_REGISTRY_INCLUDES - ${OPENFAST_REGISTRY_INCLUDES} -I ${CMAKE_SOURCE_DIR}/modules-ext/icefloe/src/interfaces/FAST/ + ${OPENFAST_REGISTRY_INCLUDES} -I ${CMAKE_SOURCE_DIR}/modules/icefloe/src/interfaces/FAST/ CACHE INTERNAL "Registry includes paths") -foreach(IDIR IN ITEMS ${OPENFAST_MODULES_LOCAL}) - add_subdirectory("${CMAKE_SOURCE_DIR}/modules-local/${IDIR}") -endforeach(IDIR IN ITEMS ${OPENFAST_MODULES_LOCAL}) - -foreach(IDIR IN ITEMS ${OPENFAST_MODULES_EXTERNAL}) - add_subdirectory("${CMAKE_SOURCE_DIR}/modules-ext/${IDIR}") -endforeach(IDIR IN ITEMS ${OPENFAST_MODULES_EXTERNAL}) +foreach(IDIR IN ITEMS ${OPENFAST_MODULES}) + add_subdirectory("${CMAKE_SOURCE_DIR}/modules/${IDIR}") +endforeach(IDIR IN ITEMS ${OPENFAST_MODULES}) add_subdirectory(glue-codes) diff --git a/README.md b/README.md index 2410cb5ba5..ee5384bfc4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ # OpenFAST -OpenFAST is an open-source wind turbine simulation tool which builds on FAST v8. OpenFAST was created with the goal of being a community model developed and used by research laboratories, academia, and industry. It is managed by a dedicated team at the National Renewable Energy Lab. Our objective is to ensure that OpenFAST is sustainable software that is well tested and well documented. +OpenFAST is a wind turbine simulation tool which builds on FAST v8. It was +created with the goal of being a community model developed and used by research +laboratories, academia, and industry. It is managed by a dedicated team at the +National Renewable Energy Lab. Our objective is to ensure that OpenFAST is +sustainable software that is well tested and well documented. If you'd like +to contribute, see the +[Developer Documentation](https://openfast.readthedocs.io/en/dev/source/dev/index.html) +and any open GitHub issues with the +[Help Wanted](https://github.com/OpenFAST/openfast/issues?q=is%3Aopen+is%3Aissue+label%3A"Help+wanted") +tag. **OpenFAST is under active development**. diff --git a/cmake/FindMKL.cmake b/cmake/FindMKL.cmake index 98d1f4d964..d2dfb9ebb4 100644 --- a/cmake/FindMKL.cmake +++ b/cmake/FindMKL.cmake @@ -19,17 +19,40 @@ # HINTS $ENV{MKLROOT} # PATH_SUFFIXES include) +# infer the architecture build type +# https://cmake.org/cmake/help/v3.0/variable/CMAKE_SIZEOF_VOID_P.html +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + set(ARCHDIR "ia32") + set(WINDOWS_INTERFACE "_c_") + set(UNIX_INTERFACE "") +elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") + set(ARCHDIR "intel64") + set(WINDOWS_INTERFACE "_lp64_") + set(UNIX_INTERFACE "_lp64") +endif() + +set(MKLSEARCHPATHS + $ENV{MKLROOT}/lib/${ARCHDIR}_win + $ENV{MKLROOT}/lib/${ARCHDIR} + $ENV{MKLROOT}/lib +) + +# using mkl_intel_c on windows since that is the default for intel compilers +# https://software.intel.com/en-us/mkl-windows-developer-guide-using-the-cdecl-and-stdcall-interfaces find_library(MKL_IFACE_LIB - NAMES mkl_intel_lp64 libmkl_intel_lp64.a mkl_intel_lp64_dll.lib - PATHS $ENV{MKLROOT}/lib $ENV{MKLROOT}/lib/intel64 $ENV{INTEL}/mkl/lib/intel64 $ENV{INTEL}/mkl/lib/intel64_win) + NAMES mkl_intel${UNIX_INTERFACE} libmkl_intel${UNIX_INTERFACE} mkl_intel${WINDOWS_INTERFACE}dll + PATHS ${MKLSEARCHPATHS} + NO_DEFAULT_PATH) find_library(MKL_SEQ_LIB - NAMES mkl_sequential libmkl_sequential.a mkl_sequential.lib - PATHS $ENV{MKLROOT}/lib $ENV{MKLROOT}/lib/intel64 $ENV{INTEL}/mkl/lib/intel64 $ENV{INTEL}/mkl/lib/intel64_win) + NAMES mkl_sequential libmkl_sequential mkl_sequential_dll + PATHS ${MKLSEARCHPATHS} + NO_DEFAULT_PATH) find_library(MKL_CORE_LIB - NAMES mkl_core libmkl_core.a mkl_core_dll.lib - PATHS $ENV{MKLROOT}/lib $ENV{MKLROOT}/lib/intel64 $ENV{INTEL}/mkl/lib/intel64 $ENV{INTEL}/mkl/lib/intel64_win) + NAMES mkl_core libmkl_core mkl_core_dll + PATHS ${MKLSEARCHPATHS} + NO_DEFAULT_PATH) if (MKL_IFACE_LIB AND MKL_SEQ_LIB AND MKL_CORE_LIB) set(MKL_LIBRARIES ${MKL_IFACE_LIB} ${MKL_SEQ_LIB} ${MKL_CORE_LIB}) diff --git a/cmake/FindYAMLCPP.cmake b/cmake/FindYAMLCPP.cmake index a5fd6db76d..a3557319e3 100644 --- a/cmake/FindYAMLCPP.cmake +++ b/cmake/FindYAMLCPP.cmake @@ -18,7 +18,7 @@ find_path(YAML_INCLUDES PATH_SUFFIXES include) find_library(YAML_LIBRARIES - NAMES libyaml-cpp.a yaml-cpp + NAMES yaml-cpp libyaml-cpp.a HINTS ${YAML_ROOT} ${CMAKE_INSTALL_PREFIX} PATH_SUFFIXES lib) diff --git a/cmake/OpenfastCmakeUtils.cmake b/cmake/OpenfastCmakeUtils.cmake index 297ad7bda8..a182282e0e 100644 --- a/cmake/OpenfastCmakeUtils.cmake +++ b/cmake/OpenfastCmakeUtils.cmake @@ -48,7 +48,7 @@ function(generate_f90_types regfile outfile) add_custom_command( OUTPUT ${output} DEPENDS openfast_registry ${input} - COMMAND ${CMAKE_BINARY_DIR}/modules-local/openfast-registry/openfast_registry + COMMAND ${CMAKE_BINARY_DIR}/modules/openfast-registry/openfast_registry ${input} ${OPENFAST_REGISTRY_INCLUDES} ${ARGN}) set_source_files_properties(${output} PROPERTIES GENERATED TRUE) endfunction(generate_f90_types) diff --git a/cmake/OpenfastFortranOptions.cmake b/cmake/OpenfastFortranOptions.cmake index 02e3707d76..6e8980f809 100644 --- a/cmake/OpenfastFortranOptions.cmake +++ b/cmake/OpenfastFortranOptions.cmake @@ -95,6 +95,13 @@ macro(set_fast_gfortran) if(CMAKE_BUILD_TYPE MATCHES Debug) set( CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fcheck=all -pedantic -fbacktrace" ) endif() + + if(CYGWIN) + # increase the default 2MB stack size to 16 MB + MATH(EXPR stack_size "16 * 1024 * 1024") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS},--stack,${stack_size}") + endif() + endmacro(set_fast_gfortran) # diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index 415453239f..e154543c1a 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -277,8 +277,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# language is one of the parsers supported byen:IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed @@ -791,9 +790,7 @@ WARN_LOGFILE = # Note: If this tag is empty the current directory is searched. INPUT = @CMAKE_SOURCE_DIR@/glue-codes/ \ - @CMAKE_SOURCE_DIR@/modules-local/ \ - @CMAKE_SOURCE_DIR@/modules-ext/ - + @CMAKE_SOURCE_DIR@/modules/ \ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -849,8 +846,8 @@ EXCLUDE_PATTERNS = @CMAKE_SOURCE_DIR@/.git/* \ @CMAKE_SOURCE_DIR@/build/* \ @CMAKE_SOURCE_DIR@/cmake/* \ @CMAKE_SOURCE_DIR@/docs/* \ - @CMAKE_SOURCE_DIR@/modules-local/orcaflex-interface/src/OrcaFlexInterface.f90 \ - @CMAKE_SOURCE_DIR@/modules-local/servodyn/src/BladedInterface.f90 + @CMAKE_SOURCE_DIR@/modules/orcaflex-interface/src/OrcaFlexInterface.f90 \ + @CMAKE_SOURCE_DIR@/modules/servodyn/src/BladedInterface.f90 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -946,9 +943,7 @@ FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. +# it is also possible to disable source filtering for a specific pattern usihistag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = diff --git a/docs/conf.py b/docs/conf.py index e9337f8150..85479a74d3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -112,9 +112,9 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # built documents. # # The short X.Y version. -version = u'1.0' +version = u'2.1' # The full version, including alpha/beta/rc tags. -release = u'1.0' +release = u'v2.1.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/index.rst b/docs/index.rst index 4d2ff8cbcb..b2258bb525 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,28 +1,60 @@ .. OpenFAST documentation master file, created by sphinx-quickstart on Wed Jan 25 13:52:07 2017. -###################### OpenFAST Documentation -###################### +====================== .. only:: html - :Version: |version| + :Version: |release| :Date: |today| +OpenFAST is an open-source wind turbine simulation tool established in 2017 +which builds on FAST v8 (see :ref:`fast_to_openfast`). It was +created with the goal of being a community model developed and used by research +laboratories, academia, and industry. It is managed by a dedicated team at the +National Renewable Energy Lab. Our objective is to ensure that OpenFAST is +sustainable software that is well tested and well documented. If you'd like +to contribute, see the :ref:`dev_guide` and any open GitHub issues with the +`Help Wanted `_ +tag. + +OpenFAST is a multi-physics, multi-fidelity tool for simulating the coupled +dynamic response of wind turbines. Practically speaking, OpenFAST is the +framework (or glue code) that couples computational modules for +aerodynamics, hydrodynamics for offshore structures, control and electrical +system (servo) dynamics, and structural dynamics to enable coupled nonlinear +aero-hydro-servo-elastic simulation in the time domain. OpenFAST enables the +analysis of a range of wind turbine configurations, including two- or +three-blade horizontal-axis rotor, pitch or stall regulation, rigid or +teetering hub, upwind or downwind rotor, and lattice or tubular tower. +The wind turbine can be modeled on land or offshore on fixed-bottom or floating +substructures. + +OpenFAST and its underlying modules are mostly written in Fortran (adhering to +the 2003 standard), but modules can be written in C/C++. OpenFAST was created +with the goal of being a community model, with developers and users from +research laboratories, academia, and industry. Our goal is also to ensure that +OpenFAST is sustainable software that is well tested and well documented. To +that end, we are continually improving the documentation and test coverage for +existing code, and we expect that new capabilities will include adequate +testing and documentation. + +Here are some important links: +- `Github Organization Page `_ +- `Github Repository `_ +- `Nightly Testing Results `_ .. toctree:: :numbered: :maxdepth: 2 - source/overview.rst source/this_doc.rst source/get_started.rst source/install/index.rst source/testing/index.rst source/user/index.rst source/dev/index.rst - source/links.rst source/license.rst source/help.rst source/acknowledgements.rst diff --git a/docs/source/dev/build_doc.rst b/docs/source/dev/build_doc.rst index b5213b97bc..d8e57eeca7 100644 --- a/docs/source/dev/build_doc.rst +++ b/docs/source/dev/build_doc.rst @@ -1,36 +1,59 @@ .. _build_doc: +Developing Documentation +======================== +OpenFAST documentation is hosted on +`readthedocs `_. It is automatically generated +through the readthedocs build system from both the ``master`` and ``dev`` +branches whenever new commits are added. This documentation uses the +`restructured text `_ +markup language. + Building this documentation locally -=================================== +----------------------------------- +The documentation is compiled with Sphinx, which is a Python based tool. +Install it and the other required Python packages listed in +``docs/requirements.txt`` with pip or another python package manager. + +These packages are optional: +- `Doxygen `__ +- `Doxylink `__ +- `Graphviz `__ + +Doxygen and Graphviz can be installed directly from their website or with a +package manager like ``brew``, ``yum``, or ``apt``. -This document describes how to build the OpenFAST documentation on your local machine. The official documentation is automatically built -and updated on `readthedocs `__ when new material is pushed to the github repo. -However, while developing documentation, it is helpful to build locally in order to see changes quickly and without needing -to publish your changes to the public facing site. +Pure python build +----------------- +If CMake and Make are not available on your system, the documentation can +be generated directly with `sphinx`. +**Note: This method does not generate the API documentation through Doxygen.** -Dependencies ------------- -The documentation is built in `Sphinx `__ with optional support for -`Doxygen `__, `Doxylink `__, and -`Graphviz `__. Therefore users will need to install these tools as well as several extensions of Sphinx that are utilized. +First, align your build structure to the standard OpenFAST build by creating +a directory at ``openfast/build``. -Doxygen and Graphviz can be installed directly from their website or with a package manager like ``brew``, ``yum``, or ``apt``. +If all tools are available, move into ``openfast/build`` and run the `sphinx` +command: -The remaining tools are Python based and should be installed with `pip` using the requirements file at -``docs/requirements.txt``. +:: -With CMake and Make -------------------- -In the OpenFAST repository checkout, if it has not been created yet, -create a ``build`` directory. Change -to the build directory and run CMake with ``BUILD_DOCUMENTATION`` on. If all + # sphinx-build -b + sphinx-build -b html ../docs ./docs/html + +If this completes successfully, a html file will be created at +``build/docs/html/index.html`` which can be opened with any web browser. + +Building with CMake and Make +---------------------------- +In the OpenFAST directory, create a ``build`` directory and move into it. +Then, run CMake with this flag: ``-DBUILD_DOCUMENTATION=ON``. If all of the required tools are found successfully, CMake will configure with the ability to build the documentation. -Issue the command ``make docs`` which will first build the Doxygen +Next, run the command ``make docs`` which will first build the Doxygen documentation and then the Sphinx documentation. If this completes -successfully, the entry point to the documentation will be in -``build/docs/html/index.html``. +successfully, a html file will be created at ``build/docs/html/index.html`` +which can be opened with any web browser. For example, from the OpenFAST directory: @@ -41,42 +64,20 @@ For example, from the OpenFAST directory: cmake .. -DBUILD_DOCUMENTATION=ON make docs -If you modify document source files in ``OpenFAST/docs/source``, you can simply update the html files through another ``make docs`` in ``OpenFAST/build``: +If you modify document source files in ``openfast/docs/source``, you can simply +update the html files through another ``make docs`` in ``openfast/build``: :: make docs -Pure python ------------ -If CMake and Make are not available on your system, the documentation can be generated directly -with `sphinx`. **Note: This method does not generate the API documentation through Doxygen.** - -First, align your build structure to the standard OpenFAST build by creating a directory -at ``openfast/build``. - -If all tools are available, move into ``openfast/build`` and run the `sphinx` command: - -:: - - # sphinx-build -b - sphinx-build -b html ../docs ./docs/html - - - -Documentation Output --------------------- - -After building the documentation, it can be accessed by opening the output in a browser. -Open the high level html file generated at ``openfast/build/docs/html/index.html`` -and begin using the page as any other web page. - - -Additional Build Targets ------------------------- - -The html portion of the documentation can be built with ``make sphinx-html``, and -the output is available at ``openfast/build/docs/html/index.html``. +Building only the html +~~~~~~~~~~~~~~~~~~~~~~ +Generating the only html is much faster than compiling all components of the +documentation. This can be done with ``make sphinx-html``. +Building the PDF +~~~~~~~~~~~~~~~~ If LaTeX is installed, a pdf version of the documentation can be built with -``make sphinx-pdf``, and the output is available at ``openfast/build/docs/latex/Openfast.pdf``. +``make sphinx-pdf``, and the output is available at +``OpenFAT/build/docs/latex/Openfast.pdf``. diff --git a/docs/source/dev/debugging.rst b/docs/source/dev/debugging.rst new file mode 100644 index 0000000000..e2620ce261 --- /dev/null +++ b/docs/source/dev/debugging.rst @@ -0,0 +1,93 @@ +.. _debugging: + +Debugging OpenFAST +================== + +Being a Fortran project, OpenFAST can be challenging to debug and the process +is unique for each system and environment. However, a common requirement for +all systems is to compile OpenFAST in debug mode. + +Keep in mind that some OpenFAST cases can be quite large in their memory +footprint and may take a long time to reach the point you're targetting in +the code. Choosing a minimal test case could save significant time. + +It may by helpful to write a small fortran program to verify that your +debugging tools are set up properly before diving in to OpenFAST. Be sure to +simulate a bug by doing something like accessing an array element that is not +allocated and verify that you can catch the bug with your tools. + +Debugging on Windows +-------------------- +Windows developers using Intel tools can use Visual Studio for debugging. This +is a straightforward process with lots of support from Intel. + +Otherwise, Windows developers compiling with CygWin or MinGW should proceed to +the section for debugging with linux. + +Debugging on Linux and macOS +---------------------------- +First, compile OpenFAST in debug mode by setting CMAKE_BUILD_TYPE to Debug. +You can do this on the command line with + +.. code-block:: bash + + cmake .. -D CMAKE_BUILD_TYPE=Debug + +or by using ccmake to open the command line cmake gui to change it. + +The GNU debugger, GDB, works well for debugging compiled code. It has a +comprehensive command line interface which enables developers to add +breakpoints and inspect variables. + +Driving the debugger through an IDE can make inspecting the code much more +efficient. One IDE known to work well is Visual Studio Code with the Native +Debug extension. You can set up a launch configuration in VS Code so that +you can debug a particular OpenFAST case through the IDE. To do this, open +the launch configuration and add a block similar to this: + +.. code-block:: json + + { + "name": "AOC_WSt", + "type": "gdb", + "request": "launch", + "printCalls": false, + "showDevDebugOutput": false, + "valuesFormatting": "prettyPrinters", + "gdbpath": "gdb", + "target": "${workspaceRoot}/build/glue-codes/openfast/openfast", + "cwd": "${workspaceRoot}/build/reg_tests/glue-codes/openfast/AOC_WSt/", + "arguments": "${workspaceRoot}/build/reg_tests/glue-codes/openfast/AOC_WSt/AOC_WSt.fst", + }, + +macOS configuration +~~~~~~~~~~~~~~~~~~~ +GDB on macOS needs some configuration before the system allows it to take +over a process. It is recommended that gdb be installed with homebrew + +.. code-block:: bash + + brew info gdb + brew install gdb + +After that completes, be sure to follow the caveats to finish the installation. +For gdb 8.2.1, it looks like this: + +.. code-block:: bash + + ==> Caveats + gdb requires special privileges to access Mach ports. + You will need to codesign the binary. For instructions, see: + + https://sourceware.org/gdb/wiki/BuildingOnDarwin + + On 10.12 (Sierra) or later with SIP, you need to run this: + + echo "set startup-with-shell off" >> ~/.gdbinit + +For Native Debug on macOS, you have to sort of hack the extension to allow +breakpoints in fortran files by adding this line to your settings.json: + +.. code-block:: json + + "debug.allowBreakpointsEverywhere": true, diff --git a/docs/source/dev/dev_phil.rst b/docs/source/dev/dev_phil.rst index fa0d586d6c..3211cb5a43 100644 --- a/docs/source/dev/dev_phil.rst +++ b/docs/source/dev/dev_phil.rst @@ -3,46 +3,57 @@ OpenFAST Development Philosophy =============================== -OpenFAST is intended to be a self sustaining community developed software. A couple of tenets of -this goal are that the code should be reasonably straightforward to comprehend and manageable to -improve. With that in mind, we expect that new capabilities will include adequate testing and documentation. +OpenFAST is intended to be a self sustaining community developed software. +A couple of tenets of this goal are that the code should be reasonably +straightforward to comprehend and manageable to improve. With that in mind, we +expect that new capabilities will include adequate testing and documentation. We have the following guidance for developers: -- When fixing a bug, first introduce a unit test that exposes the bug, fix the bug, and submit a Pull Request. - See :numref:`testing` and :numref:`github_workflow` for information on testing and the GitHub workflow. +- When fixing a bug, first introduce a unit test that exposes the bug, fix the + bug, and submit a Pull Request. See :numref:`testing` and + :numref:`github_workflow` for information on testing and the GitHub workflow. -- When adding a new feature, create appropriate automated unit and regression tests as described in :numref:`testing`. - The objective is to create a GitHub pull request that provides adequate verification and validation such that the NREL OpenFAST developer team - can merge the pull request with confidence that the new feature is "correct" and supports our goal of self-sustaining software. - See :numref:`pull_requests` for detailed information on submitting a pull request. - -- If a code modification affects regression test results in an expected manner, work with the NREL OpenFAST developer team to upgrade the - regression test suite via a GitHub issue or pull request at the `openfast/r-test `_ repository. +- When adding a new feature, create appropriate automated unit and regression + tests as described in :numref:`testing`. The objective is to create a GitHub + pull request that provides adequate verification and validation such that the + NREL OpenFAST developer team can merge the pull request with confidence that + the new feature is "correct" and supports our goal of self-sustaining + software. See :numref:`pull_requests` for detailed information on submitting + a pull request. + +- If a code modification affects regression test results in an expected manner, + work with the NREL OpenFAST developer team to upgrade the regression test + suite via a GitHub issue or pull request at the `openfast/r-test `_ + repository. Versioning ---------- -OpenFAST follows `semantic versioning `_. In summary, this means that with a version number as MAJOR.MINOR.PATCH, -the components will be incremented as follows: +OpenFAST follows `semantic versioning `_. In summary, this +means that with a version number as MAJOR.MINOR.PATCH, the components will be +incremented as follows: - MAJOR version when introducing incompatible API changes, - MINOR version when adding functionality in a backwards-compatible manner, and - PATCH version when making backwards-compatible bug fixes. -Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. - For example, ``OpenFAST-v1.0.0-123-gabcd1234-dirty`` describes OpenFAST as: -- v1.0.0 is the MAJOR.MINOR.PATCH numbering system and corresponds to a tagged commit made by NREL on GitHub -- 123-g is the number of additional commits after the most recent tag for a build [the ``-g`` is for ``git``] +- v1.0.0 is the MAJOR.MINOR.PATCH numbering system and corresponds to a tagged + commit made by NREL on GitHub +- 123-g is the number of additional commits after the most recent tag for a + build [the ``-g`` is for ``git``] - abcd1234 is the first 8 characters of the current commit hash - dirty denotes that local changes have been made but not committed Code Style ---------- -OpenFAST and its underlying modules are mostly written in Fortran adhering to the 2003 standard, but modules can be written in C or C++. -Indentation is typically three spaces and no tabs. - -Generally, code should be written such that it is straightforward to read. Syntactic sugar or brevity should not -detract from readability. The exception to this is in situations where performance dictates a poorly readable -code. Here, comment blocks should be used to describe what is not readily apparent in the code. \ No newline at end of file +OpenFAST and its underlying modules are mostly written in Fortran adhering to +the 2003 standard, but modules can be written in C or C++. Indentation is +typically three spaces and no tabs. + +Generally, code should be written such that it is straightforward to read. +Syntactic sugar or brevity should not detract from readability. The exception +to this is in situations where performance dictates a poorly readable code. +Here, comment blocks should be used to describe what is not readily apparent +in the code. diff --git a/docs/source/dev/github_workflow.rst b/docs/source/dev/github_workflow.rst index fc3d848ff3..6c10939f0c 100644 --- a/docs/source/dev/github_workflow.rst +++ b/docs/source/dev/github_workflow.rst @@ -1,68 +1,94 @@ .. _github_workflow: -Workflow for interacting with the OpenFAST github.com repo -========================================================== +Working with OpenFAST on GitHub +=============================== +The majority of the collaboration and development for OpenFAST takes place +on the `github repository `__. There, +`issues `__ and +`pull requests `__ +are discussed and new versions are released. It is the best mechanism for +engaging with the NREL OpenFAST team and other developers throughout +the OpenFAST community. + +Issues and work assignment +-------------------------- +Issues should be opened with proper documentation and data to fully describe +the problem or feature gap. It is here that communication and coordination +should happen regarding ongoing work for new development, and developers should +make clear any intention to complete a task. + +.. _pull_requests: + +Pull Requests +------------- +When a code modification is ready for review, a pull request should be +submitted along with all appropriate documentation and tests. An NREL OpenFAST +team member will assign a reviewer and work with the developer to have the +code merged into the main repository. + +New pull requests should contain + +- A description of the need for modifications + + - If the pull request fixes a bug, + the accompanying GitHub issue should be referenced + +- A highlight of the work implemented +- Regression test results + + - If all tests pass, the summary print out should be provided + - If any tests fail, an explanation of the failing + cases and supporting data like plots should be included + +- Updated unit tests, if applicable +- Updated documentation in applicable sections ready for compilation and + deployment to `readthedocs `__. -OpenFAST development should follow "Git Flow" when interacting with the github repository. -Git Flow is a git workflow outlining safe methods of pushing and pulling commits -to a shared repository. Maintaining Git Flow is critical to prevent remote changes -from blocking your local development. +Git workflow and interacting with the main repository +----------------------------------------------------- +OpenFAST development should follow "Git Flow" when interacting with the github +repository. Git Flow is a git workflow outlining safe methods of pushing and +pulling commits to a shared repository. Maintaining Git Flow is critical to +prevent remote changes from blocking your local development. Git Flow -------- - -The Git Flow process is well defined and adopted throughout the software development -community. It is detailed nicely `here `__ +The Git Flow process is well defined and adopted throughout the software +development community. It is detailed nicely +`here `__ and the chart below provides a high level perspective. .. image:: ../../_static/GitFlowFeatureBranches.png :align: center - -Reference: http://nvie.com/posts/a-successful-git-branching-model +Reference: http://nvie.com/posts/a-successful-git-branching-model OpenFAST Specific Git Flow -------------------------- - -It is important to consider how your current work will be affected by other developer's -commits and how your commits will affect other developers. On public branches, avoid using +It is important to consider how your current work will be affected by other +developer's commits and how your commits will affect other developers. +On public branches, avoid using `git rebase `__ -and never `force push `__. +and never `force push `__. In OpenFAST development, the typical workflow follows this procedure 1. Fork the OpenFAST/OpenFAST repository on GitHub -2. Clone your new fork: ``git clone https://github.com/youruser/OpenFAST`` +2. Clone your new fork: ``git clone https://github.com//OpenFAST`` 3. Add OpenFAST/OpenFAST as a remote: ``git remote add upstream https://github.com/OpenFAST/OpenFAST`` - -4. Create a feature branch for active development: ``git branch feature/a_great_feature`` or ``git checkout -b feature/a_great_feature`` - -5. Add new development on feature/a_great_feature: ``git add a_file.f90 && git commit -m "A message" && git push`` -5. Update your feature branch with OpenFAST/dev: ``git pull upstream dev && git push`` +4. Create a feature branch for active development: +``git branch feature/a_great_feature`` or +``git checkout -b feature/a_great_feature`` -6. Create a GitHub pull request to merge ``youruser/OpenFAST/feature/a_great_feature`` into ``OpenFAST/OpenFAST/dev`` - +5. Add new development on `feature/a_great_feature`: +``git add a_file.f90 && git commit -m "A message" && git push`` -.. _pull_requests: +5. Update your feature branch with OpenFAST/dev: +``git pull upstream dev && git push`` -Pull Requests -------------- +6. Create a GitHub pull request to merge +``youruser/OpenFAST/feature/a_great_feature`` into ``OpenFAST/OpenFAST/dev`` -New pull requests should contain - -- A description of the need for modifications - - - If the pull request fixes a bug, the accompanying GitHub issue should be referenced - -- A highlight of the work implemented -- Regression test results - - - If all tests pass, the summary print out should be provided - - If any tests fail, an explanation of the failing cases and supporting data like plots should be included - -- Updated unit tests, if applicable -- Updated documentation in applicable sections ready for compilation and deployment to `readthedocs `__. - \ No newline at end of file diff --git a/docs/source/dev/images/offshore_lapack.png b/docs/source/dev/images/offshore_lapack.png new file mode 100644 index 0000000000..9aa9d2438f Binary files /dev/null and b/docs/source/dev/images/offshore_lapack.png differ diff --git a/docs/source/dev/index.rst b/docs/source/dev/index.rst index 946fb79e99..1bccef2141 100644 --- a/docs/source/dev/index.rst +++ b/docs/source/dev/index.rst @@ -3,69 +3,44 @@ Developer Documentation ======================= -**Our goal as developers is to ensure that OpenFAST is a sustainable open source software that is well tested and well documented.** -To that end, we continually work to improve the documentation and test coverage along with feature additions and improvements. -This section of the documentation outlines the processes and procedures we have established for external developers +**Our goal as developers is to ensure that OpenFAST is a sustainable open +source software that is well tested and well documented.** To that end, we +continually work to improve the documentation and test coverage along with +feature additions and improvements. This section of the documentation outlines +the processes and procedures we have established for external developers to work with the NREL OpenFAST team on code development. -Getting in touch ----------------- -Please use `GitHub Issues `_ to: +If you'd like to help with general OpenFAST development or work on a particular +feature, then first install OpenFAST following the +:doc:`installation instructions <../install/index>` for your machine. Next, +verify that your installation is valid by running the test suite following the +:doc:`testing instructions <../testing/index>`. -- ask usage or development questions -- report bugs -- suggest code enhancements +After a successful and validated build, we encourage reading through the +:doc:`OpenFAST development philosophy ` to understand the general +workflow for individual and coordinated development. Finally, be sure to review +the :doc:`GitHub workflow ` to avoid any merge or code +conflicts. -For other questions regarding OpenFAST, please contact `Mike Sprague `_. +With development happening in parallel between NREL, industry partners, and +universities, NREL relies on these GitHub tools to coordinate efforts: -Contributing to OpenFAST ------------------------- -If you'd like to help with general OpenFAST development or work on a particular feature, then first install OpenFAST -following the :doc:`installation instructions <../install/index>` for your machine. Next, verify that your installation is -valid by running the test suite following the :doc:`testing instructions <../testing/index>`. +- `GitHub Issues `_ is the place + to ask usage or development questions, report bugs, and + suggest code enhancements +- `GitHub Pull Requests `_ + is the place for engaging with the OpenFAST team to have your new code + merged into the main repository. -After a successful and validated build, we encourage reading through the :doc:`OpenFAST development philosophy ` to -understand the general workflow for individual and coordinated development. Finally, be sure to review the :doc:`GitHub workflow ` -to avoid any merge or code conflicts. +For other questions regarding OpenFAST, please contact +`Mike Sprague `_. -Coordination ------------- -With development happening in parallel between NREL, industry partners, and universities, duplicated effort is likely without -proper communication. In that regard, the NREL OpenFAST team maintains the GitHub -`Issues `_ and `Pull Request `_ pages. -Any suggested bug fixes, improvements, or new features should be documented there. - -Issues and work assignment -~~~~~~~~~~~~~~~~~~~~~~~~~~ -Issues should be opened with proper documentation and data to fully describe the problem or feature gap. It is here that -communication and coordination should happen regarding ongoing work for new development, and developers should make clear -any intention to complete a task. - -Pull requests and reviews -~~~~~~~~~~~~~~~~~~~~~~~~~ -When a code modification is ready for review, a pull request should be submitted along with all appropriate documentation and tests -as described in the :doc:`GitHub workflow `. An NREL OpenFAST team member will assign a reviewer and work with the -developer to have the code merged into the main repository. - -Documentation -------------- -OpenFAST documentation is hosted on `readthedocs `_. It -is automatically generated from both the ``master`` and ``dev`` branches whenever new commits are added. -The documentation can also be generated locally as described in :doc:`build docs ` while in development. - -Note that a PDF of the documentation can be retrieved from `readthedocs `_ by clicking the arrow on the -lower left corner of the page next to ``v:master`` or ``v:dev``. - -While OpenFAST developer documentation is being enhanced here, developers are encouraged to -consult the legacy FAST v8 `Programmer's Handbook `_. - -Section Map ------------ .. toctree:: - :maxdepth: 1 - - dev_phil.rst - github_workflow.rst - build_doc.rst - doxy_doc.rst - + :maxdepth: 1 + + dev_phil.rst + github_workflow.rst + build_doc.rst + debugging.rst + doxy_doc.rst + performance.rst diff --git a/docs/source/dev/performance.rst b/docs/source/dev/performance.rst new file mode 100644 index 0000000000..049bbe38c1 --- /dev/null +++ b/docs/source/dev/performance.rst @@ -0,0 +1,223 @@ +Performance-Profiling and Optimization +====================================== +The OpenFAST team has been engaged in performance-profiling and optimization +work in an effort to improve the time-to-solution performance for the most +computationally expensive use cases. This work is supported by Intel® through +its designation of NREL as an +`Intel® Parallel Computing Center (IPCC) `_. + +After initial profiling and hotspot analysis, specific subroutines in the +physics modules of OpenFAST were targeted for optimization. Among other +takeaways, it was learned that the memory alignment of the derived data +types could yield a significant increase in performance. Ultimately, tuning +the Intel® tools to perform best on NREL's hardware and adding high level +multithreading yielded a maximum 3.8x time-to-solution improvement for one +of the benchmark cases. + +Approach +-------- +The general mechanisms identified for performance improvements in OpenFAST are: + +- Intel® compiler suite and Intel® Math Kernel Library (Intel® MKL) +- Algorithmic improvements +- Memory-access optimization enabling more efficient cache usage +- Data type alignment allowing for SIMD vectorization +- Multithreading with OpenMP + +To establish a path forward with any of these options, OpenFAST was first +profiled with Intel® VTune™ Amplifier which provides a clear breakdown of +time spent in the simulation. Then, the optimization report generated from the +Intel® Fortran compiler was analyzed to determine area which were not +autovectorized. Finally, Intel® Advisor was used to highlight areas of the code +which the compiler identified as potentially improved with multithreading. + +Test cases +---------- +Two OpenFAST test cases have been chosen to provide meaningful and +realistic timing benchmarks. In addition to real-world turbine and +atmospheric models, these cases are computationally expensive and expose +the areas where performance improvements would make a difference. + +5MW_Land_BD_DLL_WTurb +~~~~~~~~~~~~~~~~~~~~~ +Download files `here `__. + +The physics modules used in this case are: + +- BeamDyn +- InflowWind +- AeroDyn 15 +- ServoDyn + +This is a land based NREL 5-MW turbine simulation using BeamDyn as the +structural module. It simulates 20 seconds with a time step size of 0.001 +seconds and executes in `3m 55s `__ +on NREL's `Peregrine `__ +supercomputer. + +5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Download files `here `__. + +This is an offshore, fixed-bottom NREL 5-MW turbine simulation with the +majority of the computational expense occurring in the HydroDyn wave-dynamics +calculation. + +The physics modules used in this case are: + +- ElastoDyn +- InflowWind +- AeroDyn 15 +- ServoDyn +- HydroDyn +- SubDyn + +It simulates 60 seconds with a time step size of 0.01 seconds and executes in +`20m 27s `__ +on NREL's `Peregrine `__ +supercomputer. + +Profiling +--------- +The OpenFAST test cases were profiled with Intel® VTune™ Amplifier to +identify performance hotspots. Being that the two test cases exercise +difference portions of the OpenFAST software, different hotspots were +identified. In all cases and environment settings, the majority of the +CPU time was spent in `fast_solution` loop which is a high-level subroutine +that coordinates the solution calculation from each physics module. + +LAPACK +~~~~~~ +In the offshore case, the LAPACK usage was identified as a performance load. +Within the `fast_solution` loop, the calls to the LAPACK function `dgetrs` +consume 3.3% of the total CPU time. + +.. figure:: images/offshore_lapack.png + :width: 100% + :align: center + +BeamDyn +~~~~~~~ +While BeamDyn provides a high-fidelity blade-response calculation, it is a +computationally expensive module. Initial profiling highlighted the +`bd_elementmatrixga2` subroutine, in particular, as a hotspot. However, initial +attempts to improve performance in BeamDyn highlighted needs for algorithmic +improvements and refinements to the module's data structures. + +Results +------- +Though work is ongoing, OpenFAST time-to-solution performance has improved +and the performance potential is better understood. + +Some keys outcomes from the first year of the IPCC project are as follows: + +- Use of Intel® compiler and MKL library provides dramatic speedup over GCC + and LAPACK + + - Additional significant gains are possible through MKL threading for + offshore simulations + +- Offshore-wind-turbine simulations are poorly load balanced + across modules + + - Land-based-turbine configuration better balanced + - OpenMP Tasks are employed to achieve better load-balancing + +- OpenMP module-level parallelism provides significant, but limited speed + up due to imbalance across different module tasks +- Core algorithms need significant modification to enable OpenMP and SIMD + benefits + + +Speedup - Intel® Compiler and MKL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +By employing the standard Intel® developer tools tech stack, a performance +improvement over GNU tools was demonstrated: + +========= ================= ===================== ====================================== +Compiler Math Library 5MW_Land_BD_DLL_WTurb 5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth +========= ================= ===================== ====================================== +GNU LAPACK 2265 s (1.0x) 673 s (1.0x) +Intel® 17 LAPACK 1650 s (1.4x) 251 s (2.7x) +Intel® 17 MKL 1235 s (1.8x) --- +Intel® 17 MKL Multithreaded 722 s (3.1x) --- +========= ================= ===================== ====================================== + + +Speedup - OpenMP at FAST_Solver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A performance improvement was domenstrated by adding OpenMP directives to the +`FAST_Solver` module. Although the solution scheme is not well balanced, +parallelizing mesh mapping and calculation routines resulted in the following +speedup: + +========= =============== ===================== ====================================== +Compiler Math Library 5MW_Land_BD_DLL_WTurb 5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth +========= =============== ===================== ====================================== +Intel® 17 MKL - 1 thread 1073 s (2.1x) 100 s (6.7x) +Intel® 17 MKL - 8 threads 597 s (3.8x) --- +========= =============== ===================== ====================================== + + +Ongoing Work +------------ +The next phase of the OpenFAST performance improvements are focused in two key +areas: + +1. Implementing the outcomes from previous work throughout OpenFAST modules and + glue codes +2. Preparing OpenFAST for efficient execution on Intel®'s next generation + platforms + +.. Year 2 stuff: + +.. Further, `Envision Energy USA, Ltd `_ +.. has continuously contributed code and expertise in this area. + + +.. Furthermore, NREL is optimizing OpenFAST for the future through profiling on +.. Intel next generation platform (NGP) simulators. + +.. bd_5MW_dynamic +.. ~~~~~~~~~~~~~~ +.. Download files `here `__. + +.. This is a standalone BeamDyn case of the NREL 5MW wind turbine. It simulates 30 +.. seconds with a time step size of 0.002 seconds and executes in 24s on NREL's +.. Peregrine supercomputer. + +.. BeamDyn dynamic solve + +.. Performance Improvements +.. ------------------------ +.. BeamDyn chosen as the module to improve from year 1 + +.. How to improve vectorization + +.. BeamDyn Memory Alignment +.. ~~~~~~~~~~~~~~~~~~~~~~~~ +.. Work accomplished to align beamdyn types in the dervive types module +.. - Ultimately, this needs to be done in the registry + +.. Multithreading +.. ~~~~~~~~~~~~~~ +.. OpenMP at the highest level +.. OpenMP added to BeamDyn dynamic solve + +.. Speedup +.. ------- + +.. These are the areas where we have demonstrated performance improvements + +.. BeamDyn Dynamic +.. --------------- +.. This improved beamdyn's time to solution by XX% + +.. - VTune / Advisor +.. - Vectorization report +.. - SIMD report + +.. Optimization Reports +.. The optimization reports provided by the Intel fortran compiler give a static +.. analysis of code optimization. Specifically, the vectorization and openmp +.. reports were analyzed to determine diff --git a/docs/source/install/get_openfast.rst b/docs/source/install/get_openfast.rst deleted file mode 100644 index 7a4c84f90e..0000000000 --- a/docs/source/install/get_openfast.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. _get_openfast: - -Obtaining the OpenFAST source code -================================== - -OpenFAST can be cloned (i.e., downloaded) from its `Github Repository `_. -For example, from a command line: - -:: - - git clone https://github.com/OpenFAST/OpenFAST.git - -It can also be downloaded directly from https://github.com/OpenFAST/OpenFAST.git. - - diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst index 352e49ac17..72ecebbec0 100644 --- a/docs/source/install/index.rst +++ b/docs/source/install/index.rst @@ -4,15 +4,36 @@ Installing OpenFAST =================== The following pages provide instructions for building OpenFAST and/or its modules from source code. -The developer team is moving towards a CMake-only approach that well supports Window Visual Studio users, but at this time we provide a separate build path for those users. +The developer team is moving towards a CMake-only approach that well supports Window Visual Studio users, +but at this time we provide a separate build path for those users. + +Obtaining the OpenFAST source code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +OpenFAST can be cloned (i.e., downloaded) from its `Github Repository `_. +For example, from a command line: + +:: + + git clone https://github.com/OpenFAST/OpenFAST.git + +It can also be downloaded directly from https://github.com/OpenFAST/OpenFAST. + +Linux and Mac +~~~~~~~~~~~~~ .. toctree:: :maxdepth: 1 - get_openfast.rst install_cmake_linux.rst install_spack.rst - install_cmake_cygwin.rst + +Windows +~~~~~~~ + +.. toctree:: + :maxdepth: 1 + install_cmake_windows.rst install_vs_windows.rst - + install_cmake_cygwin.rst diff --git a/docs/source/install/install_cmake_cygwin.rst b/docs/source/install/install_cmake_cygwin.rst index 59e3fad3f0..b4fd1a595f 100644 --- a/docs/source/install/install_cmake_cygwin.rst +++ b/docs/source/install/install_cmake_cygwin.rst @@ -2,6 +2,8 @@ Building OpenFAST on Windows with CMake and Cygwin 64-bit ========================================================= +WARNING: This build process takes a significantly long amount of time. If GNU tools are not required, +it is recommended that Windows users follow the instructions at :ref:`install_cmake_windows` or :ref:`install_vs_windows`. Installing prerequisites ------------------------ @@ -14,7 +16,7 @@ Installing prerequisites - Choose the default install location - Choose the default package download location - Choose ``Direct connection`` - - Choose ``http://www.gtlib.gatech.edu`` as the download site + - Choose a download site - See next step for ``select packages``. Alternately, you can skip this step and run ``setup-x86_64.exe`` anytime later to select and install required software. @@ -42,6 +44,11 @@ Installing prerequisites - ``liblapack-devel`` - ``libopenblas`` + - To run the test suite, install these optional packages from ``Python``: + + - ``python3`` + - ``Python3-numpy`` + - Click ``Next`` and accept all additional packages that the setup process requests to install to satisfy dependencies @@ -50,165 +57,13 @@ Installing prerequisites Compiling OpenFAST ------------------ - -1. Open ``Cygwin64 Terminal`` from the ``Start`` menu - -2. Create a directory where you will clone OpenFAST repository (change - ``code`` to your preferred name) - -:: - - mkdir code - cd code - -3. Clone the OpenFAST repository - -:: - - git clone https://github.com/OpenFAST/OpenFAST.git - -This will create a directory called ``OpenFAST`` within the ``code`` -directory. - -4. Create a build directory - -:: - - cd OpenFAST - mkdir build - cd build - -5. Run ``cmake``. Note that this step is necessary only if you change - compiler settings, or add new files to any of the ``CMakeLists.txt``. - Modification of ``.f90`` files do not require you to run ``cmake`` - again, just re-run ``make`` command (see next item) to recompile with - latest source code modifications. - -:: - - FC=gfortran cmake ../ - -Sample output is shown below: - -:: - - $ FC=gfortran cmake ../ - -- The Fortran compiler identification is GNU 5.4.0 - -- The C compiler identification is GNU 5.4.0 - -- Check for working Fortran compiler: /usr/bin/gfortran.exe - -- Check for working Fortran compiler: /usr/bin/gfortran.exe -- works - -- Detecting Fortran compiler ABI info - -- Detecting Fortran compiler ABI info - done - -- Checking whether /usr/bin/gfortran.exe supports Fortran 90 - -- Checking whether /usr/bin/gfortran.exe supports Fortran 90 -- yes - -- Check for working C compiler: /usr/bin/cc - -- Check for working C compiler: /usr/bin/cc -- works - -- Detecting C compiler ABI info - -- Detecting C compiler ABI info - done - -- Detecting C compile features - -- Detecting C compile features - done - -- Looking for Fortran sgemm - -- Looking for Fortran sgemm - found - -- Looking for pthread.h - -- Looking for pthread.h - found - -- Looking for pthread_create - -- Looking for pthread_create - found - -- Found Threads: TRUE - -- A library with BLAS API found. - -- A library with BLAS API found. - -- Looking for Fortran cheev - -- Looking for Fortran cheev - found - -- A library with LAPACK API found. - -- Setting system file as: src/SysGnuLinux.f90 - -- Configuring done - -- Generating done - -- Build files have been written to: /home/sanantha/code/OpenFAST/build - -6. Compile ``OpenFAST`` - -:: - - make - -Grab a cup of coffee as this takes a while on Cygwin. Once the -compilation is completed, the ``OpenFAST`` executable is present in -``OpenFAST/build/glue-codes/fast/openfast.exe`` - -7. Test the executable - -:: - - $ glue-codes/fast/openfast.exe -h - - - ************************************************************************************************** - FAST (v8.17.00a-bjj, 27-Aug-2016) - - Copyright (C) 2016 National Renewable Energy Laboratory - - This program comes with ABSOLUTELY NO WARRANTY. See the "license.txt" file distributed with this - software for details. - ************************************************************************************************** - - Running FAST (v8.17.00a-bjj, 27-Aug-2016), compiled as a 64-bit application using double - precision - linked with NWTC Subroutine Library (v2.11.00, 12-Nov-2016) - - - Syntax is: - - FAST_x64.exe [-h] - - where: - - -h generates this help message. - is the name of the required primary input file. - - Note: values enclosed in square brackets [] are optional. Do not enter the brackets. - - - FAST_InitializeAll:The required input file was not specified on the command line. - - FAST encountered an error during module initialization. - Simulation error level: FATAL ERROR - - Aborting FAST. - -\`\`\` +From here, pick up from the Linux with CMake instructions at :ref:`cmake-build-instructions`. Other tips ---------- -- You can specify an installation location during your ``cmake`` - process so that the executable, libraries, and headers (e.g., ``MAP`` - and ``OpenFOAM`` headers) are installed in a common location that you - can use to update your environment variables. - -:: - - # 1. Create an installation location mkdir -p ~/software - - # 2. Instruct CMake to use the custom install location FC=gfortran cmake - -DCMAKE\_INSTALL\_PREFIX:PATH=$HOME/software ../ - - # 3. Compile OpenFAST executable make - - # 4. Install OpenFAST to custom install location make install \`\`\` - -With this step, you can execute ``make install`` after ``make`` (see -step 6 above). Now the ``openfast.exe`` and other executables (e.g., -``aerodyn.exe``) are available in ``~/software/bin/`` directory. - - If you desire to be able to run ``openfast.exe`` from the ``cmd`` window, then you must add the ``C:\cygwin64\lib\lapack`` and ``C:\cygwin64\home\\software\bin`` to your ``%PATH%`` variable in environment setting. Replace ```` with your account name on windows system. - -- In addition to ``openfast.exe``, the current CMake setup also allows - the user to compile other executables or libraries without compiling - the entire codebase. Use ``make help`` to see what targets are - available and then do ``make `` to choose your desired - target. For example, ``make aerodyn`` will compile only the - ``aerodyn.exe`` executable and its dependencies without compiling the - remaining targets. diff --git a/docs/source/install/install_cmake_linux.rst b/docs/source/install/install_cmake_linux.rst index 0061184800..020e9c2f14 100644 --- a/docs/source/install/install_cmake_linux.rst +++ b/docs/source/install/install_cmake_linux.rst @@ -32,6 +32,8 @@ OpenFAST has the following dependencies: - **Optional:** For the testing framework, Python 3+ +.. _cmake-build-instructions: + CMake build instructions ------------------------ @@ -77,7 +79,7 @@ Current CMake options Below is a list of current CMake options including their default settings (which will effect, e.g., the targets in a resulting ``Makefile``. - ``BUILD_DOCUMENTATION`` - Build documentation (Default: OFF) -- ``BUILD_FAST_CPP_API`` - Enable building OpenFAST - C++ API (Default: OFF) +- ``BUILD_OPENFAST_CPP_API`` - Enable building OpenFAST - C++ API (Default: OFF) - ``BUILD_SHARED_LIBS`` - Enable building shared libraries (Default: OFF) - ``BUILD_TESTING`` - Build the testing tree (Default: OFF) - ``CMAKE_BUILD_TYPE`` - Choose the build type: Debug Release (Default: Release) @@ -98,6 +100,33 @@ CMake options can be configured through command line, e.g. cmake .. -DDOUBLE_PRECISION:BOOL=OFF +Custom CMake builds +~~~~~~~~~~~~~~~~~~~ + +The CMake configuration and resulting build can be customized easily through explicitly setting CMake variables. In general, +this is done by passing a flag in the CMake configuration command + +.. code-block:: bash + + cmake .. -D=ON + cmake .. -D=/usr/local/bin/this_thing + +This syntax is the same as in setting a CMake option and the result is used very similarly in the CMake configuration files. +Common customizations revolve around choosing a compiler or math library; for example + +.. code-block:: bash + + cmake .. -DCMAKE_Fortran_COMPILER=/usr/local/bin/gfortran-8 -DLAPACK_LIBRARIES=/System/Library/Frameworks/Accelerate.framework -DLAPACK_LIBRARIES=/System/Library/Frameworks/Accelerate.framework + +**NOTE** Many CMake configurations can also be set through an environment variable. +For example, when using Intel's MKL, the math libraries can be discovered automatically by setting the ``MKLROOT`` +environment variable. The Fortran compiler can also be set explicitly with the ``FC`` environment variable. + +Here is a good resource for useful CMake variables: `GitLab useful cmake variables `_. +The `CMake documentation `_ is also helpful for searching +through variables and determining the resulting action. + + Parallel build ~~~~~~~~~~~~~~ diff --git a/docs/source/install/install_cmake_windows.rst b/docs/source/install/install_cmake_windows.rst index e2c1bc58cd..645c1b3d8d 100644 --- a/docs/source/install/install_cmake_windows.rst +++ b/docs/source/install/install_cmake_windows.rst @@ -1,7 +1,7 @@ .. _install_cmake_windows: -Building OpenFAST with CMake on Windows -======================================= +Building OpenFAST on Windows with CMake and Visual Studio +========================================================= We describe here how to install OpenFAST (or any of its modules) using the `CMake `_ build system on Windows systems. Separate CMake documentation is @@ -69,13 +69,14 @@ before their associated registry type files are seen by Visual Studio so an init will fail. However, a simple work around is to run the build command in Visual Studio multiple times until it succeeds. -Current CMake options -~~~~~~~~~~~~~~~~~~~~~ + +CMake options +~~~~~~~~~~~~~ Below is a list of current CMake options including their default settings (which will effect, e.g., the targets in a resulting ``Makefile``. - ``BUILD_DOCUMENTATION`` - Build documentation (Default: OFF) -- ``BUILD_FAST_CPP_API`` - Enable building OpenFAST - C++ API (Default: OFF) +- ``BUILD_OPENFAST_CPP_API`` - Enable building OpenFAST - C++ API (Default: OFF) - ``BUILD_SHARED_LIBS`` - Enable building shared libraries (Default: OFF) - ``BUILD_TESTING`` - Build the testing tree (Default: OFF) - ``CMAKE_BUILD_TYPE`` - Choose the build type: Debug Release (Default: Release) @@ -94,4 +95,30 @@ CMake options can be configured through command line, e.g. # to compile OpenFAST in single precision cmake .. -DDOUBLE_PRECISION:BOOL=OFF - \ No newline at end of file + + +Custom CMake builds +~~~~~~~~~~~~~~~~~~~ + +The CMake configuration and resulting build can be customized easily by explicitly setting CMake variables. In general, +this is done by passing a flag in the CMake configuration command + +.. code-block:: bash + + cmake .. -D=ON + cmake .. -D=\home\user\Desktop\this_thing + +This syntax is the same as in setting a CMake option and the result is used very similarly in the CMake configuration files. +Common customizations revolve around choosing a compiler or math library; for example + +.. code-block:: bash + + cmake .. -DCMAKE_Fortran_COMPILER=/usr/local/bin/gfortran-8 -DLAPACK_LIBRARIES=/System/Library/Frameworks/Accelerate.framework -DLAPACK_LIBRARIES=/System/Library/Frameworks/Accelerate.framework + +**NOTE** Many CMake configurations can also be set through an environment variable. +For example, when using Intel's MKL, the math libraries can be discovered automatically by setting the ``MKLROOT`` +environment variable. The Fortran compiler can also be set explicitly with the ``FC`` environment variable. + +Here is a good resource for useful CMake variables: `GitLab useful cmake variables `_. +The `CMake documentation `_ is also helpful for searching +through variables and determining the resulting action. diff --git a/docs/source/links.rst b/docs/source/links.rst deleted file mode 100644 index 0c7ae00247..0000000000 --- a/docs/source/links.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _links: - -Important Links -=============== - -* readthedocs.com Documentation: http://openfast.readthedocs.io/en/latest/ -* Github Organization Page: https://github.com/OpenFAST -* Github Repository: https://github.com/OpenFAST/OpenFAST -* Nightly Testing Results: http://my.cdash.org/index.php?project=OpenFAST - - diff --git a/docs/source/overview.rst b/docs/source/overview.rst deleted file mode 100644 index 1f22d9e9cf..0000000000 --- a/docs/source/overview.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. _overview: - -Overview -======== - -OpenFAST is an open-source wind turbine simulation tool that was established in 2017 with the FAST v8 code as its starting point (see :ref:`fast_to_openfast`). -OpenFAST is a multi-physics, multi-fidelity tool for simulating the coupled dynamic response of wind turbines. -Practically speaking, OpenFAST is the framework (or glue code) that couples computational modules for -aerodynamics, hydrodynamics for offshore structures, control and electrical system (servo) dynamics, and structural dynamics to enable coupled nonlinear aero-hydro-servo-elastic simulation in the time domain. -OpenFAST enables the analysis of a range of wind turbine configurations, including two- or three-blade horizontal-axis rotor, pitch or stall regulation, rigid or teetering hub, upwind or downwind rotor, and lattice or tubular tower. -The wind turbine can be modeled on land or offshore on fixed-bottom or floating substructures. - -OpenFAST and its underlying modules are mostly written in Fortran (adhering to the 2003 standard), but modules can be written in C/C++. -OpenFAST was created with the goal of being a community model, with developers and users from research laboratories, academia, and industry. -Our goal is also to ensure that OpenFAST is sustainable software that is well tested and well documented. -To that end, we are continually improving the documentation and test coverage for existing code, and we expect that new capabilities will include adequate testing and documentation. - -OpenFAST is under development; our team at NREL is now enhancing this documentation and automated unit/regression testing. -During this transition period, users can find FAST v8 documentation at https://nwtc.nrel.gov/. - diff --git a/docs/source/testing/index.rst b/docs/source/testing/index.rst index c98b592863..79c40b97df 100644 --- a/docs/source/testing/index.rst +++ b/docs/source/testing/index.rst @@ -41,3 +41,57 @@ Test specific documentation unit_test.rst regression_test.rst regression_test_windows.rst + +Continuous Integration +---------------------- +A TravisCI configuration file is included with the OpenFAST source code at ``openfast/.travis.yml``. +The continuous integration infrastructure is still under development, but the status for all branches +and pull requests can be found on the `TravisCI OpenFAST page `_. + +Note that if you use the included TravisCI configuration, you will need to add your own Intel compiler +license serial number to your TravisCI project. Otherwise, simply remove the ``ifort`` line from the +environment list. + +For development and testing purposes, a version of the TravisCI test can be run locally with Docker. +Below is a guide which should be modified depending on the particular build being replicated + +.. code-block:: bash + + # Running a travis ci image on docker locally + + # Run this on your local machine's command line + BUILDID="build-1" + INSTANCE="travisci/ci-garnet:packer-1512502276-986baf0" + docker run --name $BUILDID -dit $INSTANCE /sbin/init + docker exec -it $BUILDID bash -l + + # Now you're inside your docker image + sudo apt-get update + sudo apt-get install python3-pip + sudo -E apt-get -yq --no-install-suggests --no-install-recommends install gfortran libblas-dev liblapack-dev + git clone --depth=50 https://github.com/OpenFAST/openfast.git OpenFAST/openfast + cd OpenFAST/openfast + + # Modify this line for the commit or pull request to build + git fetch origin +refs/pull/203/merge: + + git checkout -qf FETCH_HEAD + git submodule update --init --recursive + + export INTEL_SERIAL_NUMBER=VFGH-65656FTH + export FC=ifort + export DOUBLE_PRECISION=ON + export TRAVIS_BUILD_INTEL=YES + export TRAVIS_COMPILER=gcc + export CC=gcc + gcc --version + pyenv shell 3.6.3 + + wget 'https://raw.githubusercontent.com/nemequ/icc-travis/master/install-icc.sh' # installs from http://registrationcenter-download.intel.com/akdlm/irc_nas/9061/parallel_studio_xe_2016_update3_online.sh + chmod 755 install-icc.sh + ./install-icc.sh --components ifort,icc,mkl + source ~/.bashrc + pip3 install numpy + mkdir build && cd build + cmake .. -DBUILD_TESTING=ON -DDOUBLE_PRECISION=$DOUBLE_PRECISION -DBUILD_SHARED_LIBS=ON + make -j 8 install diff --git a/docs/source/testing/regression_test.rst b/docs/source/testing/regression_test.rst index e94478f081..f856c26c74 100644 --- a/docs/source/testing/regression_test.rst +++ b/docs/source/testing/regression_test.rst @@ -105,12 +105,12 @@ but be aware that these three DISCON controllers must exist .. code-block:: bash - openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline/ServoDyn/DISCON.dll - openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline/ServoDyn/DISCON_ITIBarge.dll - openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline/ServoDyn/DISCON_OC3Hywind.dll + openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline/ServoData/DISCON.dll + openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline/ServoData/DISCON_ITIBarge.dll + openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline/ServoData/DISCON_OC3Hywind.dll This can be accomplished manually with the CMake projects included with the DISCON source codes -at ``openfast/reg_tests/r-test/glue-codes/openfast/5MW_Baseline/ServoDyn/`` +at ``openfast/reg_tests/r-test/glue-codes/openfast/5MW_Baseline/ServoData/`` or during CMake configuration by setting the ``CMAKE_INSTALL_PREFIX`` CMake variable. If using this method, the install prefix variable should point to an existing and appropriate location for CMake to place the compiled binaries. This is important because the NREL 5MW turbine external diff --git a/docs/source/testing/regression_test_windows.rst b/docs/source/testing/regression_test_windows.rst index d00ac671b7..4894e7b514 100644 --- a/docs/source/testing/regression_test_windows.rst +++ b/docs/source/testing/regression_test_windows.rst @@ -68,16 +68,23 @@ Windows with Visual Studio regression test iii) Close your Visual Studio and then Repeat Steps (a) through (c) - d) You should now see the file ``openfast_x64.exe`` in your ``openfast\build\bin`` folder + d) You should now see the file ``openfast_x64_Double.exe`` in your ``openfast\build\bin`` folder. -4) Execute the OpenFAST regression Tests +4) Prepare regression tests + + a) Create a subdirectory called ``reg_tests`` in your ``openfast\build`` folder. + + b) Copy the contents of ``openfast\reg_tests\r-test`` to ``openfast\build\reg_tests``. + + +5) Execute the OpenFAST regression Tests a) Open a command prompt which is configured for Python [ like Anaconda3 ] b) Change your working directory to ``openfast\reg_tests`` - c) Type: ``python manualRegressionTest.py ..\build\bin\openfast_x64.exe Windows Intel 1e-5`` + c) Type: ``python manualRegressionTest.py ..\build\bin\openfast_x64_Double.exe Windows Intel 1e-5`` You should see this: ``executing AWT_YFix_WSt`` d) The tests will continue to execute one-by-one until you finally see something like this: diff --git a/docs/source/testing/unit_test.rst b/docs/source/testing/unit_test.rst index 521eab6d26..2308a2c33b 100644 --- a/docs/source/testing/unit_test.rst +++ b/docs/source/testing/unit_test.rst @@ -99,7 +99,7 @@ structured as :: openfast/ - |-- modules-local/ + |-- modules/ |-- beamdyn/ |-- src/ |-- BeamDyn.f90 diff --git a/docs/source/this_doc.rst b/docs/source/this_doc.rst index 20a3b1ebde..a08d8d369c 100644 --- a/docs/source/this_doc.rst +++ b/docs/source/this_doc.rst @@ -1,27 +1,34 @@ -.. _this_doc: - -This documentation -================== - -OpenFAST documentation is built using `Sphinx `_, which uses `reStructuredText `_ as its markup language. -Online documentation is hosted on `readthedocs `_, where one can choose between documentation generated from the OpenFAST `master` or `dev` github branches (if viewing this on http://openfast.readthedocs.io click on ``Read the Docs`` "box" on the lower left corner of the browser screen for options). - -This documentation is divided into two parts: - -:ref:`user_guide` - - Directed towards end-users, this part provides detailed documentation - regarding installation and usage of the OpenFAST and its underlying modules, - as well as theory and verification documentation. - Also included are instructions for using the automated test suite, which - serves as a suite of examples. - -:ref:`dev_guide` - - The developer guide is targeted towards users wishing to extend the - functionality provided within OpenFAST. Here you will find details - regarding the code structure, API supported by various classes, and links to - source code documentation extracted using Doxygen. - -**Note:** If viewing this on http://openfast.readthedocs.io, one can get this documentation in PDF form via ``Read the Docs`` "box" on the lower left corner of the browser screen. - +.. _this_doc: + +This documentation +================== + +OpenFAST documentation is hosted on +`readthedocs `_, and is automatically +generated from both the +`master `_ and +`dev `_ branches whenever +new commits are added. A PDF of the documentation can be retrieved from +`readthedocs `_ by clicking the arrow on the +lower left corner of the page next to ``v:master`` or ``v:dev``. + +While OpenFAST developer documentation is being enhanced here, developers are +encouraged to consult the legacy FAST v8 +`Programmer's Handbook `_. + +This documentation is divided into two parts: + +:ref:`user_guide` + + Directed towards end-users, this part provides detailed documentation + regarding installation and usage of the OpenFAST and its underlying modules, + as well as theory and verification documentation. Also included are + instructions for using the automated test suite, which serves as a suite of + examples. + +:ref:`dev_guide` + + The developer guide is targeted towards users wishing to extend the + functionality provided within OpenFAST. Here you will find details + regarding the code structure, API supported by various classes, and links to + source code documentation extracted using Doxygen. diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst new file mode 100644 index 0000000000..5b7e747929 --- /dev/null +++ b/docs/source/user/api_change.rst @@ -0,0 +1,72 @@ +.. _api_change: + +API changes between versions +============================ + +This page lists the main changes in the OpenFAST API (input files) between different versions. +For completeness, some changes in the previous versions of the FAST software are also included. + +The changes are tabulated according to the module input file, line number, and flag name. +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 v2.0.0 to OpenFAST v2.1.0 +---------------------------------- + +No changes required. + +OpenFAST v1.0.0 to OpenFAST v2.0.0 +---------------------------------- + +========= ==== =============== ===================================================================================================================================================================== +Removed in OpenFAST v2.0.0 +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +========= ==== =============== ===================================================================================================================================================================== +BeamDyn 5 analysis_type analysis_type - 1: Static analysis; 2: Dynamic analysis +========= ==== =============== ===================================================================================================================================================================== + + +========= ==== ================== ===================================================================================================================================================================== + Added in OpenFAST v2.0.0 +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Module Line Flag Name Example Value +========= ==== ================== ===================================================================================================================================================================== +AeroDyn 22 SkewModFactor "default" SkewModFactor - Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when SkewMod=2; unused when WakeMod=0] +AeroDyn 30 Section header ====== Dynamic Blade-Element/Momentum Theory Options ============================================== [used only when WakeMod=2] +AeroDyn 31 DBEMT_Mod 2 DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2] +AeroDyn 32 tau1_const 4 tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1] +BeamDyn 5 QuasiStaticInit True QuasiStaticInit - Use quasistatic pre-conditioning with centripetal accelerations in initialization (flag) [dynamic solve only] +BeamDyn 11 load_retries DEFAULT load_retries - Number of factored load retries before quitting the aimulation +BeamDyn 14 tngt_stf_fd DEFAULT tngt_stf_fd - Flag to use finite differenced tangent stiffness matrix (-) +BeamDyn 15 tngt_stf_comp DEFAULT tngt_stf_comp - Flag to compare analytical finite differenced tangent stiffness matrix (-) +BeamDyn 16 tngt_stf_pert DEFAULT tngt_stf_pert - perturbation size for finite differencing (-) +BeamDyn 17 tngt_stf_difftol DEFAULT tngt_stf_difftol - Maximum allowable relative difference between analytical and fd tangent stiffness (-) +BeamDyn 18 RotStates True RotStates - Orient states in the rotating frame during linearization? (flag) [used only when linearizing] +========= ==== ================== ===================================================================================================================================================================== + +FAST v8.16 to OpenFAST v1.0.0 +----------------------------- + +The transition from FAST v8 to OpenFAST is described in detail at :ref:`fast_to_openfast`. + +========== ==== =============== ==================================================================================================== +Removed in OpenFAST v1.0. +------------------------------------------------------------------------------------------------------------------------------------ +Module Line Flag Name Example Value +========== ==== =============== ==================================================================================================== +OpenFAST 18 CompSub 0 CompSub - Compute sub-structural dynamics (switch) {0=None; 1=SubDyn} +========== ==== =============== ==================================================================================================== + + +========= ==== =============== ==================================================================================================== + Added in OpenFAST v1.0. +----------------------------------------------------------------------------------------------------------------------------------- + Module Line Flag Name Example Value +========= ==== =============== ==================================================================================================== +OpenFAST 18 CompSub 0 CompSub - Compute sub-structural dynamics (switch) {0=None; 1=SubDyn; 2=External Platform MCKF} +AeroDyn 12 CavityCheck False CavitCheck - Perform cavitation check? (flag) +AeroDyn 17 Patm 9999.9 Patm - Atmospheric pressure (Pa) [used only when CavitCheck=True] +AeroDyn 18 Pvap 9999.9 Pvap - Vapour pressure of fluid (Pa) [used only when CavitCheck=True] +AeroDyn 19 FluidDepth 9999.9 FluidDepth - Water depth above mid-hub height (m) [used only when CavitCheck=True] +========= ==== =============== ==================================================================================================== diff --git a/docs/source/user/beamdyn/input_files.rst b/docs/source/user/beamdyn/input_files.rst index aad503e5e5..d7bdc2fbdb 100644 --- a/docs/source/user/beamdyn/input_files.rst +++ b/docs/source/user/beamdyn/input_files.rst @@ -57,7 +57,7 @@ And the following :math:`3 \times 3` direction cosine matrix (``GlbDCM``) relate .. _frame: -.. figure:: figs/Frame.jpg +.. figure:: figs/frame.jpg :width: 80% :align: center @@ -348,7 +348,7 @@ cases for member and key-point definition. .. _geometry1-case1: -.. figure:: figs/Geometry_Member1.png +.. figure:: figs/geometry_member1.png :width: 60% :align: center @@ -356,7 +356,7 @@ cases for member and key-point definition. .. _geometry1-case2: -.. figure:: figs/Geometry_Member2.png +.. figure:: figs/geometry_member2.png :width: 60% :align: center diff --git a/docs/source/user/cppapi/index.rst b/docs/source/user/cppapi/index.rst index 37048aed3e..f364465560 100644 --- a/docs/source/user/cppapi/index.rst +++ b/docs/source/user/cppapi/index.rst @@ -9,7 +9,7 @@ C++ API Users Guide issued and as needed to provide further information on advancements or modifications to the software. -The C++ API provides a high level API to run OpenFAST through a C++ gluecode. The primary purpose of the C++ API is to help interface OpenFAST to external programs like CFD solvers that are typically written in C++. The installation of C++ API is enabled via CMake by turning on the :cmakeval:`BUILD_FAST_CPP_API` flag. +The C++ API provides a high level API to run OpenFAST through a C++ gluecode. The primary purpose of the C++ API is to help interface OpenFAST to external programs like CFD solvers that are typically written in C++. The installation of C++ API is enabled via CMake by turning on the :cmakeval:`BUILD_OPENFAST_CPP_API` flag. A sample glue-code `FAST_Prog.cpp `_ 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 parallel over multiple processors. The glue-code takes a single input file named ``cDriver.i`` (:download:`download `). diff --git a/docs/source/user/index.rst b/docs/source/user/index.rst index 463c5a45ac..125a16da8e 100644 --- a/docs/source/user/index.rst +++ b/docs/source/user/index.rst @@ -4,13 +4,15 @@ User Documentation ================== This section contains documentation for the OpenFAST module-coupling environment and its underlying modules. -Documentation covers usage of models, underlying theory, and in some cases module verification. +Documentation covers usage of models, underlying theory, and in some cases module verification. -We are in the process of transitioning legacy FAST v8 documentation, which can be found at https://nwtc.nrel.gov/. Details on the transition from FAST v8 to OpenFAST may be found in :numref:`fast_to_openfast` +We are in the process of transitioning legacy FAST v8 documentation, which can be found at https://nwtc.nrel.gov/. +Details on the transition from FAST v8 to OpenFAST may be found in :numref:`fast_to_openfast` .. toctree:: :maxdepth: 1 + api_change.rst aerodyn/index.rst beamdyn/index.rst fast_to_openfast.rst diff --git a/glue-codes/CMakeLists.txt b/glue-codes/CMakeLists.txt index 2fd5049d25..9c1f8e3b5a 100644 --- a/glue-codes/CMakeLists.txt +++ b/glue-codes/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(openfast) -if(BUILD_FAST_CPP_API) +if(BUILD_OPENFAST_CPP_API) add_subdirectory(openfast-cpp) endif() diff --git a/glue-codes/openfast-cpp/CMakeLists.txt b/glue-codes/openfast-cpp/CMakeLists.txt index 8df4405e10..aecb5f77d3 100644 --- a/glue-codes/openfast-cpp/CMakeLists.txt +++ b/glue-codes/openfast-cpp/CMakeLists.txt @@ -28,9 +28,9 @@ include_directories(${HDF5_INCLUDES}) include_directories(${HDF5_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDES}) include_directories(${LIBXML2_INCLUDE_DIR}) -include_directories(${CMAKE_SOURCE_DIR}/modules-local/openfast-library/src/) -include_directories(${CMAKE_BINARY_DIR}/modules-local/openfoam/) -include_directories(${CMAKE_BINARY_DIR}/modules-local/supercontroller/) +include_directories(${CMAKE_SOURCE_DIR}/modules/openfast-library/src/) +include_directories(${CMAKE_BINARY_DIR}/modules/openfoam/) +include_directories(${CMAKE_BINARY_DIR}/modules/supercontroller/) include_directories(${MPI_INCLUDE_PATH}) add_library(openfastcpplib @@ -42,6 +42,7 @@ target_link_libraries(openfastcpplib ${HDF5_HL_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBXML2_LIBRARIES} + ${MPI_LIBRARIES} ${CMAKE_DL_LIBS}) add_executable(openfastcpp diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 8ffb03af01..c04a4330e2 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -2,6 +2,7 @@ #include #include #include +#include int fast::OpenFAST::AbortErrLev = ErrID_Fatal; // abort error level; compare with NWTC Library @@ -39,6 +40,8 @@ inline bool fast::OpenFAST::checkFileExists(const std::string& name) { } void fast::OpenFAST::init() { + // Temporary buffer to pass filenames to OpenFAST fortran subroutines + char currentFileName[INTERFACE_STRING_LENGTH]; allocateMemory(); @@ -49,7 +52,14 @@ void fast::OpenFAST::init() { for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { /* note that this will set nt_global inside the FAST library */ - FAST_OpFM_Restart(&iTurb, CheckpointFileRoot[iTurb].data(), &AbortErrLev, &dtFAST, &numBlades[iTurb], &numVelPtsBlade[iTurb], &ntStart, &cDriver_Input_from_FAST[iTurb], &cDriver_Output_to_FAST[iTurb], &cDriverSC_Input_from_FAST[iTurb], &cDriverSC_Output_to_FAST[iTurb], &ErrStat, ErrMsg); + 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], &cDriverSC_Input_from_FAST[iTurb], + &cDriverSC_Output_to_FAST[iTurb], &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); nt_global = ntStart; @@ -72,9 +82,19 @@ void fast::OpenFAST::init() { // this calls the Init() routines of each module for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - FAST_OpFM_Init(&iTurb, &tMax, FASTInputFileName[iTurb].data(), &TurbID[iTurb], &numScOutputs, &numScInputs, &numForcePtsBlade[iTurb], &numForcePtsTwr[iTurb], TurbineBasePos[iTurb].data(), &AbortErrLev, &dtFAST, &numBlades[iTurb], &numVelPtsBlade[iTurb], &cDriver_Input_from_FAST[iTurb], &cDriver_Output_to_FAST[iTurb], &cDriverSC_Input_from_FAST[iTurb], &cDriverSC_Output_to_FAST[iTurb], &ErrStat, ErrMsg); + std::copy(FASTInputFileName[iTurb].data(), + FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), + currentFileName); + FAST_OpFM_Init(&iTurb, &tMax, currentFileName, &TurbID[iTurb], + &numScOutputs, &numScInputs, &numForcePtsBlade[iTurb], + &numForcePtsTwr[iTurb], TurbineBasePos[iTurb].data(), + &AbortErrLev, &dtFAST, &numBlades[iTurb], + &numVelPtsBlade[iTurb], &cDriver_Input_from_FAST[iTurb], + &cDriver_Output_to_FAST[iTurb], + &cDriverSC_Input_from_FAST[iTurb], + &cDriverSC_Output_to_FAST[iTurb], &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); - + timeZero = true; numVelPtsTwr[iTurb] = cDriver_Output_to_FAST[iTurb].u_Len - numBlades[iTurb]*numVelPtsBlade[iTurb] - 1; @@ -102,9 +122,19 @@ void fast::OpenFAST::init() { case fast::restartDriverInitFAST: for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - FAST_OpFM_Init(&iTurb, &tMax, FASTInputFileName[iTurb].data(), &TurbID[iTurb], &numScOutputs, &numScInputs, &numForcePtsBlade[iTurb], &numForcePtsTwr[iTurb], TurbineBasePos[iTurb].data(), &AbortErrLev, &dtFAST, &numBlades[iTurb], &numVelPtsBlade[iTurb], &cDriver_Input_from_FAST[iTurb], &cDriver_Output_to_FAST[iTurb], &cDriverSC_Input_from_FAST[iTurb], &cDriverSC_Output_to_FAST[iTurb], &ErrStat, ErrMsg); + std::copy(FASTInputFileName[iTurb].data(), + FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), + currentFileName); + FAST_OpFM_Init(&iTurb, &tMax, currentFileName, &TurbID[iTurb], + &numScOutputs, &numScInputs, &numForcePtsBlade[iTurb], + &numForcePtsTwr[iTurb], TurbineBasePos[iTurb].data(), + &AbortErrLev, &dtFAST, &numBlades[iTurb], + &numVelPtsBlade[iTurb], &cDriver_Input_from_FAST[iTurb], + &cDriver_Output_to_FAST[iTurb], + &cDriverSC_Input_from_FAST[iTurb], + &cDriverSC_Output_to_FAST[iTurb], &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); - + timeZero = true; numVelPtsTwr[iTurb] = cDriver_Output_to_FAST[iTurb].u_Len - numBlades[iTurb]*numVelPtsBlade[iTurb] - 1; @@ -258,12 +288,16 @@ void fast::OpenFAST::step() { nt_global = nt_global + 1; if ( (((nt_global - ntStart) % nEveryCheckPoint) == 0 ) && (nt_global != ntStart) ) { + // Use default FAST naming convention for checkpoint file + // . + char dummyCheckPointRoot[INTERFACE_STRING_LENGTH] = " "; + // Ensure that we have a null character + dummyCheckPointRoot[1] = 0; + if (nTurbinesProc > 0) backupVelocityDataFile(nt_global, velNodeDataFile); - - //sprintf(CheckpointFileRoot, "../../CertTest/Test18.%d", nt_global); + for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { - CheckpointFileRoot[iTurb] = " "; // if blank, it will use FAST convention .nt_global - FAST_CreateCheckpoint(&iTurb, CheckpointFileRoot[iTurb].data(), &ErrStat, ErrMsg); + FAST_CreateCheckpoint(&iTurb, dummyCheckPointRoot, &ErrStat, ErrMsg); checkError(ErrStat, ErrMsg); } if(scStatus) { diff --git a/glue-codes/openfast/src/FAST_Prog.f90 b/glue-codes/openfast/src/FAST_Prog.f90 index 303a468260..a0e712363e 100644 --- a/glue-codes/openfast/src/FAST_Prog.f90 +++ b/glue-codes/openfast/src/FAST_Prog.f90 @@ -73,7 +73,7 @@ PROGRAM FAST ! initialization !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - CALL FAST_InitializeAll_T( t_initial, i_turb, Turbine(i_turb), ErrStat, ErrMsg ) ! bjj: we need to get the input files for each turbine (not necessarially the same one) + CALL FAST_InitializeAll_T( t_initial, i_turb, Turbine(i_turb), ErrStat, ErrMsg ) ! bjj: we need to get the input files for each turbine (not necessarily the same one) CALL CheckError( ErrStat, ErrMsg, 'during module initialization' ) !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/modules-local/turbsim/README.md b/modules-local/turbsim/README.md deleted file mode 100644 index 4fa4ebcce1..0000000000 --- a/modules-local/turbsim/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# TurbSim -A stochastic, full-field, turbulence simulator, primarialy for use with [InflowWind](https://nwtc.nrel.gov/InflowWind "InflowWind")-based simulation tools - -**Authors**: Neil Kelley and [Bonnie Jonkman](mailto:bonnie.jonkman@nrel.gov), NREL - -TurbSim is a stochastic, full-field, turbulent-wind simulator. It uses a statistical model (as opposed to a physics-based model) to -numerically simulate time series of three-component wind-speed vectors at points in a two-dimensional vertical rectangular -grid that is fixed in space. - -Spectra of velocity components and spatial coherence are defined in the frequency domain, and -an inverse Fourier transform produces time series. The underlying theory behind this method of -simulating time series assumes a stationary process. - -For more information, please refer to documentation on the [TurbSim web site](https://nwtc.nrel.gov/TurbSim). - diff --git a/modules-local/aerodyn/CMakeLists.txt b/modules/aerodyn/CMakeLists.txt similarity index 80% rename from modules-local/aerodyn/CMakeLists.txt rename to modules/aerodyn/CMakeLists.txt index 81862fe163..7b976d9c62 100644 --- a/modules-local/aerodyn/CMakeLists.txt +++ b/modules/aerodyn/CMakeLists.txt @@ -23,6 +23,7 @@ generate_f90_types(src/UnsteadyAero_Registry.txt UnsteadyAero_Types.f90) generate_f90_types(src/AeroDyn_Driver_Registry.txt AeroDyn_Driver_Types.f90 -noextrap) +# AeroDyn lib set(AD_LIBS_SOURCES src/AeroDyn.f90 src/AeroDyn_IO.f90 @@ -45,6 +46,7 @@ set(AD_LIBS_SOURCES add_library(aerodynlib ${AD_LIBS_SOURCES}) target_link_libraries(aerodynlib nwtclibs) +# AeroDyn driver set(AD_DRIVER_SOURCES src/AeroDyn_Driver.f90 src/AeroDyn_Driver_Subs.f90 @@ -53,9 +55,17 @@ set(AD_DRIVER_SOURCES AeroDyn_Driver_Types.f90) add_executable(aerodyn_driver ${AD_DRIVER_SOURCES}) -target_link_libraries(aerodyn_driver aerodynlib nwtclibs ${CMAKE_DL_LIBS}) +target_link_libraries(aerodyn_driver aerodynlib nwtclibs versioninfolib ${CMAKE_DL_LIBS}) -install(TARGETS aerodyn_driver aerodynlib +# UnsteadyAero driver +set(UA_DRIVER_SOURCES + src/UnsteadyAero_Driver.f90 + src/UA_Dvr_Subs.f90 +) +add_executable(unsteadyaero_driver ${UA_DRIVER_SOURCES}) +target_link_libraries(unsteadyaero_driver aerodynlib nwtclibs versioninfolib ${CMAKE_DL_LIBS}) + +install(TARGETS unsteadyaero_driver aerodyn_driver aerodynlib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib diff --git a/modules/aerodyn/README.md b/modules/aerodyn/README.md new file mode 100644 index 0000000000..96c14d9040 --- /dev/null +++ b/modules/aerodyn/README.md @@ -0,0 +1,14 @@ +# AeroDyn Module +The legacy version of this module and additional documentation are available +the [NWTC Software Portal](https://nwtc.nrel.gov/AeroDyn/). + +## Overview +AeroDyn is a time-domain wind and MHK turbine aerodynamics module that can be +coupled into the OpenFAST multi-physics engineering tool to enable aero-elastic +simulation of horizontal-axis wind turbines. AeroDyn can also be driven as a +standalone code to compute wind turbine aerodynamic response uncoupled from +OpenFAST. + +## Manual +AeroDyn documentation is available on the OpenFAST +[ReadTheDocs](https://openfast.readthedocs.io/en/master/source/user/aerodyn/index.html) site. diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules/aerodyn/src/AeroDyn.f90 similarity index 99% rename from modules-local/aerodyn/src/AeroDyn.f90 rename to modules/aerodyn/src/AeroDyn.f90 index 3f30163783..e2edb62b2b 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules/aerodyn/src/AeroDyn.f90 @@ -177,7 +177,7 @@ subroutine AD_SetInitOut(p, InputFileData, InitOut, errStat, errMsg) if ( p%AFI%AFInfo(1)%NumCoords > 0 ) then NumCoords = p%AFI%AFInfo(1)%NumCoords do i=2,size(p%AFI%AFInfo) - if (p%AFI%AFInfo(1)%NumCoords /= NumCoords) then + if (p%AFI%AFInfo(i)%NumCoords /= NumCoords) then call SetErrStat( ErrID_Info, 'Airfoil files do not contain the same number of x-y coordinates.', ErrStat, ErrMsg, RoutineName ) NumCoords = -1 exit @@ -231,14 +231,14 @@ subroutine AD_SetInitOut(p, InputFileData, InitOut, errStat, errMsg) end do !Tower data - ALLOCATE(InitOut%TwrElev(p%NumTwrNds), STAT = ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal,"Error allocating memory for TwrElev.", ErrStat, ErrMsg, RoutineName) - RETURN - END IF - InitOut%TwrElev(:) = InputFileData%TwrElev(:) - IF ( p%NumTwrNds > 0 ) THEN + ALLOCATE(InitOut%TwrElev(p%NumTwrNds), STAT = ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating memory for TwrElev.", ErrStat, ErrMsg, RoutineName) + RETURN + END IF + InitOut%TwrElev(:) = InputFileData%TwrElev(:) + ALLOCATE(InitOut%TwrDiam(p%NumTwrNds), STAT = ErrStat2) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating memory for TwrDiam.", ErrStat, ErrMsg, RoutineName) @@ -3854,7 +3854,7 @@ FUNCTION CheckBEMTInputPerturbations( p, m ) RESULT(ValidPerturb) do j=1,p%NumBlNds ! don't allow the input perturbations to change Vx or Vy so that Vx=0 or Vy=0: - if ( EqualRealNos( m%BEMT_u(indx)%Vx(j,k), 0.0_ReKi ) .or. EqualRealNos( m%BEMT_u(indx)%Vy(j,k), 0.0_ReKi ) ) then + if ( EqualRealNos( m%BEMT_u(indx)%Vx(j,k), 0.0_ReKi ) .and. EqualRealNos( m%BEMT_u(indx)%Vy(j,k), 0.0_ReKi ) ) then ValidPerturb = .false. return end if diff --git a/modules-local/aerodyn/src/AeroDyn_Driver.f90 b/modules/aerodyn/src/AeroDyn_Driver.f90 similarity index 100% rename from modules-local/aerodyn/src/AeroDyn_Driver.f90 rename to modules/aerodyn/src/AeroDyn_Driver.f90 diff --git a/modules-local/aerodyn/src/AeroDyn_Driver_Registry.txt b/modules/aerodyn/src/AeroDyn_Driver_Registry.txt similarity index 100% rename from modules-local/aerodyn/src/AeroDyn_Driver_Registry.txt rename to modules/aerodyn/src/AeroDyn_Driver_Registry.txt diff --git a/modules-local/aerodyn/src/AeroDyn_Driver_Subs.f90 b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 similarity index 99% rename from modules-local/aerodyn/src/AeroDyn_Driver_Subs.f90 rename to modules/aerodyn/src/AeroDyn_Driver_Subs.f90 index 6fb6682ace..2ca6fe5fc6 100644 --- a/modules-local/aerodyn/src/AeroDyn_Driver_Subs.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 @@ -22,7 +22,8 @@ module AeroDyn_Driver_Subs use AeroDyn_Driver_Types use AeroDyn - + use VersionInfo + implicit none TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'AeroDyn_driver', '', '' ) ! The version number of this program. diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules/aerodyn/src/AeroDyn_IO.f90 similarity index 100% rename from modules-local/aerodyn/src/AeroDyn_IO.f90 rename to modules/aerodyn/src/AeroDyn_IO.f90 diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules/aerodyn/src/AeroDyn_Registry.txt similarity index 100% rename from modules-local/aerodyn/src/AeroDyn_Registry.txt rename to modules/aerodyn/src/AeroDyn_Registry.txt diff --git a/modules-local/aerodyn/src/AirfoilInfo.f90 b/modules/aerodyn/src/AirfoilInfo.f90 similarity index 100% rename from modules-local/aerodyn/src/AirfoilInfo.f90 rename to modules/aerodyn/src/AirfoilInfo.f90 diff --git a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt b/modules/aerodyn/src/AirfoilInfo_Registry.txt similarity index 100% rename from modules-local/aerodyn/src/AirfoilInfo_Registry.txt rename to modules/aerodyn/src/AirfoilInfo_Registry.txt diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules/aerodyn/src/BEMT.f90 similarity index 96% rename from modules-local/aerodyn/src/BEMT.f90 rename to modules/aerodyn/src/BEMT.f90 index 5ba379e495..c34c08d897 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules/aerodyn/src/BEMT.f90 @@ -930,8 +930,6 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, integer(IntKi) :: errStat2 ! temporary Error status of the operation character(*), parameter :: RoutineName = 'BEMT_UpdateStates' - character(20) :: NodeTxt - ErrStat = ErrID_None ErrMsg = "" @@ -944,13 +942,14 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, do j = 1,p%numBlades ! Loop through all blades do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' - call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u1%rlocal(i,j), p%chord(i,j), u1%theta(i,j), & + call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%kinVisc, AFInfo(p%AFIndx(i,j)), u1%rlocal(i,j), p%chord(i,j), u1%theta(i,j), & u1%Vx(i,j), u1%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & p%maxIndIterations, p%aTol, OtherState%ValidPhi(i,j), m%FirstWarn_Phi, errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if end do end do else @@ -995,10 +994,12 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, ! over the blade elements. do j = 1,p%numBlades do i = 1,p%numBladeNodes - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' call calculate_Inductions_from_BEMT(i, j, p, z%phi(i,j), u1, OtherState, AFInfo, m%axInduction(i,j), m%tanInduction(i,j), ErrStat2,ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if end do end do @@ -1029,8 +1030,6 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, do i = 1,p%numBladeNodes - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' - !............................. ! Update UA states: !............................. @@ -1054,8 +1053,10 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, if (p%DBEMT_Mod == DBEMT_none ) then call calculate_Inductions_from_BEMT(i,j,p,z%phi(i,j),u1,OtherState,AFInfo,m%axInduction(i,j), m%tanInduction(i,j), ErrStat2,ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if else ! use DBEMT @@ -1093,7 +1094,7 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, ! Need to compute local velocity including both axial and tangential induction ! COMPUTE: u_UA%U, u_UA%Re - call BEMTU_Wind( m%axInduction(i,j), m%tanInduction(i,j), u1%Vx(i,j), u1%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, u_UA%U, u_UA%Re) + call BEMTU_Wind( m%axInduction(i,j), m%tanInduction(i,j), u1%Vx(i,j), u1%Vy(i,j), p%chord(i,j), p%kinVisc, u_UA%U, u_UA%Re) ! check if UA inputs are valid, or if we should turn it off: call Mpi2pi(u_UA%alpha) ! put alpha in [-pi,pi] before checking its value @@ -1107,8 +1108,10 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, else ! COMPUTE: xd%UA, OtherState%UA call UA_UpdateStates( i, j, u_UA, p%UA, xd%UA, OtherState%UA, AFInfo(p%AFIndx(i,j)), m%UA, errStat2, errMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if end if end if ! if (OtherState%UA_Flag(i,j)) then @@ -1128,11 +1131,13 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, ! Solve this without any skewed wake correction and without UA ! call BEMT_UnCoupledSolve2(i, j, u, p, z, Rtip, AFInfo, phiOut, axIndOut, tanIndOut, errStat, errMsg) ! COMPUTE: z%phi(i,j) - call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u2%rlocal(i,j), p%chord(i,j), u2%theta(i,j), & + call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%kinVisc, AFInfo(p%AFIndx(i,j)), u2%rlocal(i,j), p%chord(i,j), u2%theta(i,j), & u2%Vx(i,j), u2%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & p%maxIndIterations, p%aTol, OtherState%ValidPhi(i,j), m%FirstWarn_Phi, errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if if ( p%DBEMT_Mod /= DBEMT_none ) then ! Generate DBEMT inputs @@ -1145,8 +1150,10 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, if (errStat >= AbortErrLev) return call DBEMT_UpdateStates(i, j, t, DBEMT_u, p%DBEMT, x%DBEMT, OtherState%DBEMT, m%DBEMT, errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) if (errStat >= AbortErrLev) return + end if end if else @@ -1165,8 +1172,10 @@ subroutine get_DBEMT_inputs(indx,u) type(BEMT_InputType), intent(in ) :: u ! BEMT Input at t or t + dt call calculate_Inductions_from_BEMT(i, j, p, z%phi(i,j), u, OtherState, AFInfo, m%axInduction(i,j), m%tanInduction(i,j), ErrStat2,ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if DBEMT_u(Indx)%vind_s(1) = -u%Vx(i,j)*m%axInduction(i,j) @@ -1207,7 +1216,7 @@ subroutine calculate_Inductions_from_BEMT(i,j,p,phi,u,OtherState,AFInfo,axInduct if (OtherState%ValidPhi(i,j)) then AoA = phi - u%theta(i,j) - call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) + call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%kinVisc, Vrel, Re ) ! Need to get the induction factors for these conditions without skewed wake correction and without UA ! COMPUTE: axInduction, tanInduction @@ -1315,8 +1324,6 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat integer(IntKi) :: errStat2 ! temporary Error status of the operation character(*), parameter :: RoutineName = 'BEMT_CalcOutput' - character(20) :: NodeTxt - #ifdef UA_OUTS integer(IntKi) :: k @@ -1345,14 +1352,15 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat do j = 1,p%numBlades ! Loop through all blades do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' y%phi(i,j) = z%phi(i,j) - call BEMT_UnCoupledSolve(y%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u%rlocal(i,j), p%chord(i,j), u%theta(i,j), & + call BEMT_UnCoupledSolve(y%phi(i,j), p%numBlades, p%kinVisc, AFInfo(p%AFIndx(i,j)), u%rlocal(i,j), p%chord(i,j), u%theta(i,j), & u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & p%maxIndIterations, p%aTol, IsValidSolution, m%FirstWarn_Phi, errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if end do end do @@ -1362,11 +1370,12 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat if (p%DBEMT_Mod /= DBEMT_none) then do j = 1,p%numBlades ! Loop through all blades do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' call calculate_Inductions_from_BEMT(i, j, p, y%phi(i,j), u, OtherState, AFInfo, y%axInduction(i,j), y%tanInduction(i,j), ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if end do end do @@ -1404,8 +1413,6 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' - ! Set the active blade element for UnsteadyAero m%UA%iBladeNode = i m%UA%iBlade = j @@ -1429,8 +1436,10 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat if (p%DBEMT_Mod == DBEMT_none) then call calculate_Inductions_from_BEMT(i, j, p, y%phi(i,j), u, OtherState, AFInfo, y%axInduction(i,j), y%tanInduction(i,j), ErrStat2,ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if else ! if (p%DBEMT_Mod /= DBEMT_none) then @@ -1463,20 +1472,24 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat y%AOA(i,j) = y%phi(i,j) - u%theta(i,j) ! Compute Re, Vrel based on current values of axInduction, tanInduction - call BEMTU_Wind( y%axInduction(i,j), y%tanInduction(i,j), u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, y%Vrel(I,J), y%Re(i,j) ) + call BEMTU_Wind( y%axInduction(i,j), y%tanInduction(i,j), u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%kinVisc, y%Vrel(I,J), y%Re(i,j) ) ! Now depending on the option for UA get the airfoil coefs, Cl, Cd, Cm for unsteady or steady implementation if (OtherState%UA_Flag(i,j) .and. ( .not. EqualRealNos(y%Vrel(I,J),0.0_ReKi) ) ) then call Compute_UA_AirfoilCoefs( y%AOA(i,j), y%Vrel(I,J), y%Re(i,j), AFInfo(p%AFindx(i,j)), p%UA, xd%UA, OtherState%UA, m%y_UA, m%UA, & y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), errStat2, errMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if else ! TODO: When we start using Re, should we use the uninduced Re since we used uninduced Re to solve for the inductions!? Probably this won't change, instead create a Re loop up above. call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), y%Cpmin(i,j), errStat2, errMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return + if (ErrStat2 /= ErrID_None) then + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeText(i,j))) + if (errStat >= AbortErrLev) return + end if end if @@ -1638,7 +1651,7 @@ subroutine BEMT_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m, z_ tanInduction = 0.0_ReKi ! Need to call BEMTU_Wind to obtain Re, even though we aren't using it in this version. - call BEMTU_Wind( axInduction, tanInduction, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) + call BEMTU_Wind( axInduction, tanInduction, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%kinVisc, Vrel, Re ) ! Solve for the constraint states here: Z_residual%phi(i,j) = UncoupledErrFn(z%phi(i,j), u%theta(i,j), Re, p%numBlades, u%rlocal(i,j), p%chord(i,j), AFInfo(p%AFindx(i,j)), & @@ -1733,7 +1746,7 @@ SUBROUTINE CheckLinearizationInput(p, u, z, m, OtherState, ErrStat, ErrMsg) do k = 1,p%numBlades do j = 1,p%numBladeNodes if (.not. OtherState%ValidPhi(j,k)) then - call SetErrSTat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + call SetErrSTat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(j))//& ": Current operating point does not contain a valid value of phi.",ErrStat,ErrMsg,RoutineName) return end if @@ -1749,7 +1762,7 @@ SUBROUTINE CheckLinearizationInput(p, u, z, m, OtherState, ErrStat, ErrMsg) do j = 1,p%numBladeNodes if ( VelocityIsZero( u%Vy(j,k)+m%TnInd_op(j,k)) .and. VelocityIsZero( u%Vx(j,k)+m%AxInd_op(j,k) ) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(j))//& ": residual is undefined because u%Vy + TnInd_op = u%Vx + AxInd_op = 0.",ErrStat,ErrMsg,RoutineName) return end if @@ -1763,15 +1776,15 @@ SUBROUTINE CheckLinearizationInput(p, u, z, m, OtherState, ErrStat, ErrMsg) do j = 1,p%numBladeNodes if ( EqualRealNos(z%phi(j,k), 0.0_ReKi) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(j))//& ": residual is discontinuous or undefined because z%phi = 0.",ErrStat,ErrMsg,RoutineName) return else if ( VelocityIsZero(u%Vy(j,k)) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(j))//& ": residual is discontinuous or undefined because u%Vy = 0.",ErrStat,ErrMsg,RoutineName) return else if ( VelocityIsZero(u%Vx(j,k)) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(j))//& ": residual is discontinuous or undefined because u%Vx = 0.",ErrStat,ErrMsg,RoutineName) return end if @@ -1789,7 +1802,7 @@ SUBROUTINE CheckLinearizationInput(p, u, z, m, OtherState, ErrStat, ErrMsg) do j = 1,p%numBladeNodes if ( EqualRealNos( u%Vy(j,k), 0.0_ReKi ) .and. EqualRealNos( u%Vx(j,k), 0.0_ReKi ) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(j))//& ": residual is undefined because u%Vy = u%Vx = 0.",ErrStat,ErrMsg,RoutineName) return end if @@ -2015,7 +2028,7 @@ integer function TestRegion(phiLower, phiUpper, numBlades, rlocal, chord, theta, end function TestRegion -subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, chord, theta, & +subroutine BEMT_UnCoupledSolve( phi, numBlades, nu, AFInfo, rlocal, chord, theta, & Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & maxIndIterations, aTol, ValidPhi, FirstWarn, ErrStat, ErrMsg) @@ -2023,8 +2036,7 @@ subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, cho !use fminMod real(ReKi), intent(inout) :: phi integer, intent(in ) :: numBlades - real(ReKi), intent(in ) :: airDens - real(ReKi), intent(in ) :: mu + real(ReKi), intent(in ) :: nu TYPE(AFInfoType), INTENT(IN ) :: AFInfo real(ReKi), intent(in ) :: rlocal real(ReKi), intent(in ) :: chord @@ -2081,7 +2093,7 @@ subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, cho ! Need to call BEMTU_Wind to obtain Re, even though we aren't using it in this version. ! inductions are set to zero! - call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, Vx, Vy, chord, airDens, mu, Vrel, Re ) + call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, Vx, Vy, chord, nu, Vrel, Re ) !# ------ BEM solution method see (Ning, doi:10.1002/we.1636) ------ @@ -2113,8 +2125,7 @@ subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, cho ! Set up the fcn argument settings for Brent's method - fcnArgs%airDens = airDens - fcnArgs%mu = mu + fcnArgs%nu = nu fcnArgs%numBlades = numBlades fcnArgs%rlocal = rlocal fcnArgs%chord = chord @@ -2194,5 +2205,13 @@ end subroutine BEMT_UnCoupledSolve +function NodeText(i,j) + integer(IntKi), intent(in) :: i ! node number + integer(IntKi), intent(in) :: j ! blade number + character(25) :: NodeText + + NodeText = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' +end function NodeText + end module BEMT diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules/aerodyn/src/BEMTUncoupled.f90 similarity index 99% rename from modules-local/aerodyn/src/BEMTUncoupled.f90 rename to modules/aerodyn/src/BEMTUncoupled.f90 index bf3ee4daff..6ce710753c 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules/aerodyn/src/BEMTUncoupled.f90 @@ -69,12 +69,12 @@ function VelocityIsZero ( v ) end function VelocityIsZero !.................................................................................................................................. - subroutine BEMTU_Wind( axInduction, tanInduction, Vx, Vy, chord, airDens, mu, W, Re ) + subroutine BEMTU_Wind( axInduction, tanInduction, Vx, Vy, chord, nu, W, Re ) ! in real(ReKi), intent(in) :: axInduction, tanInduction, Vx, Vy - real(ReKi), intent(in) :: chord, airDens, mu + real(ReKi), intent(in) :: chord, nu ! out real(ReKi), intent(out) :: Re, W @@ -94,7 +94,7 @@ subroutine BEMTU_Wind( axInduction, tanInduction, Vx, Vy, chord, airDens, mu, W W = sqrt((Vx*(1-axInduction))**2 + (Vy*(1+tanInduction))**2) !end if - Re = airDens * W * chord / mu + Re = W * chord / nu if ( EqualRealNos(Re, 0.0_ReKi) ) Re = 0.001 ! Do this to avoid a singularity when we take log(Re) in the airfoil lookup. end subroutine BEMTU_Wind diff --git a/modules-local/aerodyn/src/BEMT_Registry.txt b/modules/aerodyn/src/BEMT_Registry.txt similarity index 100% rename from modules-local/aerodyn/src/BEMT_Registry.txt rename to modules/aerodyn/src/BEMT_Registry.txt diff --git a/modules-local/aerodyn/src/DBEMT.f90 b/modules/aerodyn/src/DBEMT.f90 similarity index 96% rename from modules-local/aerodyn/src/DBEMT.f90 rename to modules/aerodyn/src/DBEMT.f90 index efb504c58e..981f5f5f3e 100644 --- a/modules-local/aerodyn/src/DBEMT.f90 +++ b/modules/aerodyn/src/DBEMT.f90 @@ -238,8 +238,6 @@ subroutine DBEMT_UpdateStates( i, j, t, u, p, x, OtherState, m, errStat, errMsg real(ReKi) :: Un_disk real(ReKi) :: AxInd_disk integer(IntKi) :: indx - real(ReKi), parameter :: max_AxInd = 0.7_ReKi - real(ReKi), parameter :: min_Un = 0.0001_ReKi character(*), parameter :: RoutineName = 'DBEMT_UpdateStates' @@ -312,10 +310,10 @@ subroutine ComputeTau1(u, p, m, tau1, errStat, errMsg) real(ReKi) :: temp real(ReKi) :: AxInd_disk - real(ReKi), parameter :: max_AxInd = 0.7_ReKi + real(ReKi), parameter :: max_AxInd = 0.5_ReKi real(ReKi) :: Un_disk - real(ReKi), parameter :: min_Un = 0.0001_ReKi + real(ReKi), parameter :: min_Un = 0.1_ReKi character(*), parameter :: RoutineName = 'ComputeTau1' @@ -337,8 +335,9 @@ subroutine ComputeTau1(u, p, m, tau1, errStat, errMsg) if ( u%AxInd_disk > max_AxInd ) then AxInd_disk = max_AxInd if (m%FirstWarn_tau1) then - call setErrStat( ErrID_Severe, 'Rotor-averaged axial induction factor is greater than 0.7; limiting time-varying tau1.' & - //' This message will not be repeated though the condition may persist.', ErrStat, ErrMsg, RoutineName ) ! don't print this error more than one time + call setErrStat( ErrID_Severe, 'Rotor-averaged axial induction factor is greater than '//trim(num2lstr(max_AxInd)) & + //'; limiting time-varying tau1. This message will not be repeated though the condition may persist.', & + ErrStat, ErrMsg, RoutineName ) ! don't print this error more than one time m%FirstWarn_tau1 = .false. end if else @@ -348,8 +347,9 @@ subroutine ComputeTau1(u, p, m, tau1, errStat, errMsg) if ( u%Un_disk < min_Un ) then Un_disk = min_Un if (m%FirstWarn_tau1) then - call setErrStat( ErrID_Severe, 'Induced axial relative air-speed, Un, is not positive; limiting time-varying tau1.' & - //' This message will not be repeated though the condition may persist.', ErrStat, ErrMsg, RoutineName ) ! don't print this error more than one time + call setErrStat( ErrID_Severe, 'Induced axial relative air speed, Un, is less than '//trim(num2lstr(min_Un)) & + // ' m/s; limiting time-varying tau1. This message will not be repeated though the ' & + //'condition may persist.', ErrStat, ErrMsg, RoutineName ) ! don't print this error more than one time m%FirstWarn_tau1 = .false. end if else @@ -358,7 +358,8 @@ subroutine ComputeTau1(u, p, m, tau1, errStat, errMsg) temp = (1.0-1.3*AxInd_disk)*Un_disk - tau1 = 1.1*u%R_disk/temp ! Eqn. 1.2 (note that we've eliminated possibility of temp being 0) + tau1 = 1.1*u%R_disk/temp ! Eqn. 1.2 (note that we've eliminated possibility of temp being 0) + tau1 = min(tau1, 100.0_ReKi) ! put a limit on this time constant so it isn't unrealistically long (particularly at initialization) end if diff --git a/modules-local/aerodyn/src/DBEMT_Registry.txt b/modules/aerodyn/src/DBEMT_Registry.txt similarity index 100% rename from modules-local/aerodyn/src/DBEMT_Registry.txt rename to modules/aerodyn/src/DBEMT_Registry.txt diff --git a/modules-local/aerodyn/src/DBEMT_Test.f90 b/modules/aerodyn/src/DBEMT_Test.f90 similarity index 100% rename from modules-local/aerodyn/src/DBEMT_Test.f90 rename to modules/aerodyn/src/DBEMT_Test.f90 diff --git a/modules-local/aerodyn/src/OutListParameters.xlsx b/modules/aerodyn/src/OutListParameters.xlsx similarity index 100% rename from modules-local/aerodyn/src/OutListParameters.xlsx rename to modules/aerodyn/src/OutListParameters.xlsx diff --git a/modules-local/aerodyn/src/ToDoList.txt b/modules/aerodyn/src/ToDoList.txt similarity index 100% rename from modules-local/aerodyn/src/ToDoList.txt rename to modules/aerodyn/src/ToDoList.txt diff --git a/modules-local/aerodyn/src/UA_Dvr_Subs.f90 b/modules/aerodyn/src/UA_Dvr_Subs.f90 similarity index 100% rename from modules-local/aerodyn/src/UA_Dvr_Subs.f90 rename to modules/aerodyn/src/UA_Dvr_Subs.f90 diff --git a/modules-local/aerodyn/src/UnsteadyAero.f90 b/modules/aerodyn/src/UnsteadyAero.f90 similarity index 100% rename from modules-local/aerodyn/src/UnsteadyAero.f90 rename to modules/aerodyn/src/UnsteadyAero.f90 diff --git a/modules-local/aerodyn/src/UnsteadyAero_Driver.f90 b/modules/aerodyn/src/UnsteadyAero_Driver.f90 similarity index 99% rename from modules-local/aerodyn/src/UnsteadyAero_Driver.f90 rename to modules/aerodyn/src/UnsteadyAero_Driver.f90 index db73ec86ba..360a6c0fad 100644 --- a/modules-local/aerodyn/src/UnsteadyAero_Driver.f90 +++ b/modules/aerodyn/src/UnsteadyAero_Driver.f90 @@ -32,7 +32,8 @@ program UnsteadyAero_Driver use UnsteadyAero_Types use UnsteadyAero use UA_Dvr_Subs - + USE VersionInfo + implicit none diff --git a/modules-local/aerodyn/src/UnsteadyAero_Registry.txt b/modules/aerodyn/src/UnsteadyAero_Registry.txt similarity index 100% rename from modules-local/aerodyn/src/UnsteadyAero_Registry.txt rename to modules/aerodyn/src/UnsteadyAero_Registry.txt diff --git a/modules-local/aerodyn/src/fmin_fcn.f90 b/modules/aerodyn/src/fmin_fcn.f90 similarity index 97% rename from modules-local/aerodyn/src/fmin_fcn.f90 rename to modules/aerodyn/src/fmin_fcn.f90 index 4a47938734..2b7381350c 100644 --- a/modules-local/aerodyn/src/fmin_fcn.f90 +++ b/modules/aerodyn/src/fmin_fcn.f90 @@ -24,8 +24,7 @@ module fminfcn use BEMTUnCoupled, only: UncoupledErrFn type, public :: fmin_fcnArgs - real(ReKi) :: airDens - real(ReKi) :: mu + real(ReKi) :: nu integer :: numBlades real(ReKi) :: rlocal real(ReKi) :: chord diff --git a/modules-local/aerodyn/src/mod_root1dim.f90 b/modules/aerodyn/src/mod_root1dim.f90 similarity index 100% rename from modules-local/aerodyn/src/mod_root1dim.f90 rename to modules/aerodyn/src/mod_root1dim.f90 diff --git a/modules-local/aerodyn14/CMakeLists.txt b/modules/aerodyn14/CMakeLists.txt similarity index 76% rename from modules-local/aerodyn14/CMakeLists.txt rename to modules/aerodyn14/CMakeLists.txt index 73c56ff312..9cf12ee44c 100644 --- a/modules-local/aerodyn14/CMakeLists.txt +++ b/modules/aerodyn14/CMakeLists.txt @@ -27,7 +27,7 @@ set(AD14_LIBS_SOURCES # Generated files AeroDyn14_Types.f90 DWM_Types.f90 - ) +) add_library(aerodyn14lib ${AD14_LIBS_SOURCES}) target_link_libraries(aerodyn14lib ifwlib nwtclibs) @@ -38,11 +38,16 @@ install(TARGETS aerodyn14lib LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) -# set(DWM_SOURCES -# src/DWM_driver_wind_farm_mod.f90 -# src/DWM_driver_wind_farm_sub.f90 -# src/DWM_driver_wind_farm.f90 -# ) +set(DWM_SOURCES + src/DWM_driver_wind_farm_mod.f90 + src/DWM_driver_wind_farm_sub.f90 + src/DWM_driver_wind_farm.f90 +) -# add_executable(dwm_driver_wind_farm ${DWM_SOURCES}) -# target_link_libraries(dwm_driver_wind_farm aerodyn14lib) +add_executable(dwm_driver_wind_farm ${DWM_SOURCES}) +target_link_libraries(dwm_driver_wind_farm aerodyn14lib) + +install(TARGETS dwm_driver_wind_farm + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) diff --git a/modules/aerodyn14/README.md b/modules/aerodyn14/README.md new file mode 100644 index 0000000000..eb6b856846 --- /dev/null +++ b/modules/aerodyn14/README.md @@ -0,0 +1,14 @@ +# AeroDyn 14 Module +The legacy version of this module and additional documentation are available +at the [NWTC Software Portal](https://nwtc.nrel.gov/AeroDyn14/). + +**DEPRECATED** +AeroDyn 14 will be replaced with DBEMT and FAST.Farm as discussed in +[issue #93](https://github.com/OpenFAST/openfast/issues/93). + +## Overview +AeroDyn 14 is an aerodynamics software library (module) for use by designers of +horizontal-axis wind turbines. It is written to be interfaced with a dynamics +analysis software package for aero-elastic analysis of wind turbine models. +This version of AeroDyn works only with the modularization framework used in +OpenFAST. diff --git a/modules-local/aerodyn14/src/AD_RegistryEntries.xlsx b/modules/aerodyn14/src/AD_RegistryEntries.xlsx similarity index 100% rename from modules-local/aerodyn14/src/AD_RegistryEntries.xlsx rename to modules/aerodyn14/src/AD_RegistryEntries.xlsx diff --git a/modules-local/aerodyn14/src/AeroDyn14.f90 b/modules/aerodyn14/src/AeroDyn14.f90 similarity index 100% rename from modules-local/aerodyn14/src/AeroDyn14.f90 rename to modules/aerodyn14/src/AeroDyn14.f90 diff --git a/modules-local/aerodyn14/src/AeroSubs.f90 b/modules/aerodyn14/src/AeroSubs.f90 similarity index 100% rename from modules-local/aerodyn14/src/AeroSubs.f90 rename to modules/aerodyn14/src/AeroSubs.f90 diff --git a/modules-local/aerodyn14/src/DWM.f90 b/modules/aerodyn14/src/DWM.f90 similarity index 100% rename from modules-local/aerodyn14/src/DWM.f90 rename to modules/aerodyn14/src/DWM.f90 diff --git a/modules-local/aerodyn14/src/DWM_Wake_Sub_ver2.f90 b/modules/aerodyn14/src/DWM_Wake_Sub_ver2.f90 similarity index 100% rename from modules-local/aerodyn14/src/DWM_Wake_Sub_ver2.f90 rename to modules/aerodyn14/src/DWM_Wake_Sub_ver2.f90 diff --git a/modules-local/aerodyn14/src/DWM_driver_wind_farm.f90 b/modules/aerodyn14/src/DWM_driver_wind_farm.f90 similarity index 64% rename from modules-local/aerodyn14/src/DWM_driver_wind_farm.f90 rename to modules/aerodyn14/src/DWM_driver_wind_farm.f90 index 62a6110cab..f59052165f 100644 --- a/modules-local/aerodyn14/src/DWM_driver_wind_farm.f90 +++ b/modules/aerodyn14/src/DWM_driver_wind_farm.f90 @@ -1,47 +1,37 @@ PROGRAM DWM_driver_wind_farm - USE IFPORT - USE DFLIB + USE DWM_driver_wind_farm_sub USE read_wind_farm_parameter_data, ONLY: NumWT, DWM_exe_name - USE IFQWIN USE DWM_init_data, ONLY:InputFile +#ifdef __INTEL_COMPILER + USE IFPORT +#endif IMPLICIT NONE INTEGER :: simulation_index INTEGER :: RESULT REAL :: T1,T2 - + ! pre-processing CALL Driver_Init - CALL read_wind_farm_parameter + CALL read_wind_farm_parameter(InputFile) CALL Check_DWM_parameter CALL write_parameter_to_file ! sort the turbines CALL wind_farm_geometry - - !run the DWM for the very first base turbine to generate the turbine interaction information simulation_index = 0 - !RESULT = system("DWM_Wind_Farm.exe "// TRIM(Int2LStr(simulation_index)) //" V80_2MW.fst") ! 2MW NEW - - !general DWM FAST input - !RESULT = system(TRIM(DWM_exe_name)//".exe "// TRIM(Int2LStr(simulation_index)) //" "//TRIM(InputFile)//".fst") - - ! FAST 8 - RESULT = system(TRIM(DWM_exe_name)//".exe "// TRIM(InputFile)//".fst" // " " //TRIM(Int2LStr(simulation_index)) //" "// "DWM") - - !result = SetExitQQ (QWin$ExitNoPersist) - - - + + ! FAST 8 + RESULT = system("echo "//TRIM(DWM_exe_name)//" "// TRIM(InputFile)//".fst" // " " //TRIM(Int2LStr(simulation_index)) //" "// "DWM") + RESULT = system(TRIM(DWM_exe_name)//" "// TRIM(InputFile)//".fst" // " " //TRIM(Int2LStr(simulation_index)) //" "// "DWM") + ! calculate the wake sector angle and the turbine interaction information CALL cal_wake_sector_angle - - - + ! Run the simulation for all the turbines in the wind farm DO simulation_index = 1,NumWT !RESULT = system("DWM_Wind_Farm.exe "// TRIM(Int2LStr(simulation_index)) //" V80_2MW.fst") ! 2MW NEW @@ -50,15 +40,12 @@ PROGRAM DWM_driver_wind_farm !RESULT = system(TRIM(DWM_exe_name)//".exe "// TRIM(Int2LStr(simulation_index)) //" "//TRIM(InputFile)//".fst") ! FAST 8 - RESULT = system(TRIM(DWM_exe_name)//".exe "// TRIM(InputFile)//".fst" // " " //TRIM(Int2LStr(simulation_index)) //" "// "DWM") + RESULT = system(TRIM(DWM_exe_name)//" "// TRIM(InputFile)//".fst" // " " //TRIM(Int2LStr(simulation_index)) //" "// "DWM") - result = SetExitQQ (QWIN$EXITNOPERSIST) + result = 0 !SetExitQQ (QWIN$EXITNOPERSIST) CALL rename_FAST_output(simulation_index) END DO - - - + CALL delete_temp_files - - + END PROGRAM DWM_driver_wind_farm \ No newline at end of file diff --git a/modules-local/aerodyn14/src/DWM_driver_wind_farm_mod.f90 b/modules/aerodyn14/src/DWM_driver_wind_farm_mod.f90 similarity index 83% rename from modules-local/aerodyn14/src/DWM_driver_wind_farm_mod.f90 rename to modules/aerodyn14/src/DWM_driver_wind_farm_mod.f90 index f9ab933319..75ec54a474 100644 --- a/modules-local/aerodyn14/src/DWM_driver_wind_farm_mod.f90 +++ b/modules/aerodyn14/src/DWM_driver_wind_farm_mod.f90 @@ -14,10 +14,10 @@ MODULE read_wind_farm_parameter_data REAL :: WFLowerBd ! The lower bound height of the wind file (m) REAL :: Winddir ! The ambient wind direction INTEGER :: Tinfluencer ! The max number of upstream turbines that affects a downstream turbine (-) - CHARACTER(20):: DWM_exe_name - - REAL, ALLOCATABLE :: Xcoordinate (:) ! wind turbine x location - REAL, ALLOCATABLE :: Ycoordinate (:) ! wind turbine y location + CHARACTER(1024):: DWM_exe_name + + REAL(8), ALLOCATABLE :: Xcoordinate (:) ! wind turbine x location + REAL(8), ALLOCATABLE :: Ycoordinate (:) ! wind turbine y location END MODULE read_wind_farm_parameter_data @@ -27,8 +27,8 @@ MODULE wind_farm_geometry_data INTEGER,ALLOCATABLE :: turbine_sort(:) ! the array that stores the order of the turbines from upstream to downstream INTEGER,ALLOCATABLE :: TurbineInfluenceData(:,:) REAL,ALLOCATABLE :: wake_sector_angle_array(:) - REAL :: xwind - REAL :: ywind + REAL(8) :: xwind + REAL(8) :: ywind INTEGER :: scale_factor REAL :: Pi REAL,ALLOCATABLE :: length(:) ! projected length on the wind direction vector @@ -39,4 +39,4 @@ END MODULE wind_farm_geometry_data MODULE DWM_init_data CHARACTER(1024) :: OutFileRoot CHARACTER(1024) :: InputFile -END MODULE DWM_init_data \ No newline at end of file +END MODULE DWM_init_data diff --git a/modules-local/aerodyn14/src/DWM_driver_wind_farm_sub.f90 b/modules/aerodyn14/src/DWM_driver_wind_farm_sub.f90 similarity index 86% rename from modules-local/aerodyn14/src/DWM_driver_wind_farm_sub.f90 rename to modules/aerodyn14/src/DWM_driver_wind_farm_sub.f90 index 428d8e5f6b..dae5c1a2da 100644 --- a/modules-local/aerodyn14/src/DWM_driver_wind_farm_sub.f90 +++ b/modules/aerodyn14/src/DWM_driver_wind_farm_sub.f90 @@ -16,7 +16,7 @@ MODULE DWM_driver_wind_farm_sub CONTAINS !------------------------------------------------------------------- -SUBROUTINE read_wind_farm_parameter() +SUBROUTINE read_wind_farm_parameter(PriFile) !................................................................... ! This subroutine is to read the wind farm parameter files ! Including the number of rows of the wind farm, the number of turbine in each row @@ -25,16 +25,16 @@ SUBROUTINE read_wind_farm_parameter() USE read_wind_farm_parameter_data IMPLICIT NONE + CHARACTER(*), INTENT(IN) :: PriFile INTEGER :: UnIn = 0 + INTEGER :: UnEc = -1 INTEGER :: I CHARACTER(1024) :: DWM_Title,comment INTEGER :: ErrStat = 0 - INTEGER(4) :: IOS - CHARACTER:: PriFile = 'DWM-driver\wind_farm.txt' + CHARACTER(ErrMsgLen) :: ErrMsg + INTEGER(4) :: IOS - - !bjj: CALL GetNewUnit(UnIn) - CALL OpenFInpFile ( UnIn, 'DWM-driver\wind_farm.txt', ErrStat ) + CALL OpenFInpFile ( UnIn, PriFile, ErrStat, ErrMsg ) READ (UnIn,'(//,A,/)',IOSTAT=IOS) DWM_Title ! read the words (title) CALL CheckIOS( IOS, PriFile, 'file title', StrType ) @@ -42,66 +42,61 @@ SUBROUTINE read_wind_farm_parameter() READ (UnIn,'(A)',IOSTAT=IOS) Comment ! read the words (comment) CALL CheckIOS( IOS, PriFile, 'simulation control parameters comment', StrType ) - ! Read in the hub height - CALL ReadRVar ( UnIn, PriFile, HubHt, 'HubHt', 'The hub height (m)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, HubHt, 'HubHt', 'The hub height (m)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the rotor radius - CALL ReadRVar ( UnIn, PriFile, RotorR, 'RotorR', 'The Rotor radius (m)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, RotorR, 'RotorR', 'The Rotor radius (m)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the total number of wind turbines - CALL ReadIVar ( UnIn, PriFile, NumWT, 'NumWT', 'The total number of wind turbines (-)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, NumWT, 'NumWT', 'The total number of wind turbines (-)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the ambient wind velocity - CALL ReadRVar ( UnIn, PriFile, Uambient, 'Uambient', 'The ambient wind velocity (m/s)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, Uambient, 'Uambient', 'The ambient wind velocity (m/s)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the ambient TI - CALL ReadRVar ( UnIn, PriFile, TI, 'TI', 'TI for first turbine (%)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, TI, 'TI', 'TI for first turbine (%)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the radial domain size - CALL ReadIVar ( UnIn, PriFile, ppR, 'ppR', 'Point per R resolution (-)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, ppR, 'ppR', 'Point per R resolution (-)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the point per R resolution - CALL ReadRVar ( UnIn, PriFile, Domain_R, 'Domain_R', 'Radial domain size (R)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, Domain_R, 'Domain_R', 'Radial domain size (R)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the point per R resolution - CALL ReadRVar ( UnIn, PriFile, Domain_X, 'Domain_X', 'Longitudinal domain size (R)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, Domain_X, 'Domain_X', 'Longitudinal domain size (R)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the simulation time length of the meandering wake model - CALL ReadIVar ( UnIn, PriFile, Mstl, 'Meandering_simulation_time_length', 'The length of the simulation time in the meandering wake model (-)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, Mstl, 'Meandering_simulation_time_length', 'The length of the simulation time in the meandering wake model (-)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the moving time length of the meandering wake model - CALL ReadIVar ( UnIn, PriFile, Mmt, 'Meandering_Moving_time', 'The length of the moving time in the meandering wake model (-)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, Mmt, 'Meandering_Moving_time', 'The length of the moving time in the meandering wake model (-)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the lower bound height of the wind file - CALL ReadRVar ( UnIn, PriFile, WFLowerBd, 'WFLowerBd', 'The lower bound height of the wind file (m)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, WFLowerBd, 'WFLowerBd', 'The lower bound height of the wind file (m)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the ambient wind direction - CALL ReadRVar ( UnIn, PriFile, Winddir, 'Winddir', 'The ambient wind direction (degree)',ErrStat ) + CALL ReadVar ( UnIn, PriFile, Winddir, 'Winddir', 'The ambient wind direction (degree)', ErrStat, ErrMsg, UnEc ) IF ( ErrStat /= 0 ) RETURN ! Read in the DWM_FAST.exe file rootname - READ (UnIn,*,IOStat=ErrStat) DWM_exe_name - - ! Read in the number of upstream turbines that affects a downstream turbine - !CALL ReadIVar ( UnIn, PriFile, Tinfluencer, 'Tinfluencer', 'The max number of upstream turbines that affects a downstream turbine (-)',ErrStat ) - !IF ( ErrStat /= 0 ) RETURN - + CALL ReadVar ( UnIn, PriFile, DWM_exe_name, 'DWM_exe_name', 'The file rootname of the DWM-FAST program', ErrStat, ErrMsg, UnEc ) + ALLOCATE (Xcoordinate(NumWT)) ALLOCATE (Ycoordinate(NumWT)) - CALL ReadCom( UnIn, PriFile, 'Coordinate table headers', ErrStat) + CALL ReadCom( UnIn, PriFile, 'Coordinate table headers', ErrStat, ErrMsg) IF ( ErrStat /= 0 ) RETURN DO i = 1, NumWT @@ -180,15 +175,15 @@ SUBROUTINE write_parameter_to_file() IMPLICIT NONE integer :: Un - !CALL GetNewUnit(Un) + !CALL GetNewUnit(Un) Un = 10 - OPEN(unit = Un, status='replace',file='DWM-driver\DWM_parameter.bin',form='unformatted') - WRITE(Un) HubHt,RotorR,NumWT,Uambient,TI,Domain_R,Domain_X,ppR,Mstl,Mmt,WFLowerBd,Winddir,Tinfluencer + OPEN(unit = Un, status='replace',file='DWM_parameter.bin',form='unformatted') + WRITE(Un) HubHt,RotorR,NumWT,Uambient,TI,Domain_R,Domain_X,ppR,Mstl,Mmt,WFLowerBd,Winddir,Tinfluencer CLOSE(Un) - OPEN(unit = Un, status='replace',file='DWM-driver\wind_farm_coordinate.bin',form='unformatted') - WRITE(Un) Xcoordinate,Ycoordinate + OPEN(unit = Un, status='replace',file='wind_farm_coordinate.bin',form='unformatted') + WRITE(Un) Xcoordinate,Ycoordinate CLOSE(Un) END SUBROUTINE write_parameter_to_file @@ -285,7 +280,7 @@ SUBROUTINE wind_farm_geometry() !CALL GetNewUnit(Un) Un = 10 - OPEN(unit = Un, status='replace',file='DWM-results\wind_farm_turbine_sort.bin',form='unformatted') + OPEN(unit = Un, status='replace',file='wind_farm_turbine_sort.bin',form='unformatted') WRITE(Un) turbine_sort(:) CLOSE(Un) @@ -319,11 +314,11 @@ SUBROUTINE wind_farm_geometry() !CALL GetNewUnit(Un) Un = 10 - OPEN(unit = Un, status='replace',file='DWM-results\turbine_angles.bin',form='unformatted') + OPEN(unit = Un, status='replace',file='turbine_angles.bin',form='unformatted') WRITE(Un) turbine_angle(:,:) CLOSE(Un) - OPEN(unit = Un, status='replace',file='DWM-results\turbine_distance.bin',form='unformatted') + OPEN(unit = Un, status='replace',file='turbine_distance.bin',form='unformatted') WRITE(Un) length(:) CLOSE(Un) @@ -347,8 +342,8 @@ SUBROUTINE wind_farm_geometry() ! test - OPEN (unit=25,file="DWM-driver\turbine_spacing.txt") - WRITE (25,*), length(:) + OPEN (unit=25,file="turbine_spacing.txt") + WRITE (25,*) length(:) CLOSE(25) END SUBROUTINE wind_farm_geometry @@ -360,7 +355,7 @@ SUBROUTINE cal_wake_sector_angle() ! with respect to the change of the downstream distance !................................................................... USE wind_farm_geometry_data, ONLY: wake_sector_angle_array,scale_factor,Pi,TurbineInfluenceData,length,xwind,ywind,turbine_sort - USE read_wind_farm_parameter_data, ONLY: NumWT, Winddir, Tinfluencer,Mmt,ppR,Xcoordinate, Ycoordinate,Mstl,Domain_X,scale_factor + USE read_wind_farm_parameter_data, ONLY: NumWT, Winddir, Tinfluencer,Mmt,ppR,Xcoordinate, Ycoordinate,Mstl,Domain_X REAL,ALLOCATABLE :: distance_array(:) INTEGER :: I,J @@ -399,11 +394,11 @@ SUBROUTINE cal_wake_sector_angle() Pi = ACOS( -1.0 ) ! read the wake file and wake width - OPEN(unit = 10, status='old',file='DWM-results\Wake_width_Turbine_0.bin',form='unformatted') ! open an existing file + OPEN(unit = 10, status='old',file='Wake_width_Turbine_0.bin',form='unformatted') ! open an existing file READ(10) wake_width(:) CLOSE(10) - OPEN(unit = 10, status='old',file='DWM-results\WC_Turbine_0.bin',form='unformatted') ! open an existing file + OPEN(unit = 10, status='old',file='WC_Turbine_0.bin',form='unformatted') ! open an existing file READ(10) wake_center_position(:,:,:) CLOSE(10) @@ -423,7 +418,7 @@ SUBROUTINE cal_wake_sector_angle() wake_sector_angle_array(I) = Sector_angle(wake_width,wake_center_position,distance_array(I)) END DO - OPEN(unit = 10, status='replace',file='DWM-results\wake_sector_angle.bin',form='unformatted') + OPEN(unit = 10, status='replace',file='wake_sector_angle.bin',form='unformatted') WRITE(10) wake_sector_angle_array(:) CLOSE(10) @@ -472,34 +467,10 @@ SUBROUTINE cal_wake_sector_angle() END DO END DO - !OPEN (unit=25,file="DWM_WIND_FARM\results\turbine_influence.txt") - !WRITE (25,'(I5)'), TurbineInfluenceData(:,:) - !CLOSE(25) - - OPEN(unit = 10, status='replace',file='DWM-results\turbine_interaction.bin',form='unformatted') + OPEN(unit = 10, status='replace',file='turbine_interaction.bin',form='unformatted') WRITE(10) TurbineInfluenceData(:,:) CLOSE(10) - - ! OWEZ WIND FARM TURBINE 7 AND TURBINE 8 - !T7_wake = 0 - !T8_wake = 0 - !DO I = 1,Tinfluencer - !IF (TurbineInfluenceData(7,I) /= 0) THEN - !T7_wake = T7_wake+1 - !END IF - !IF (TurbineInfluenceData(8,I) /= 0) THEN - !T8_wake = T8_wake+1 - !END IF - !END DO - - - !OPEN (unit=25,file="DWM_WIND_FARM\results\OWEZ_T7_T8_num.txt") - !WRITE(25,*),'InflowAngle=',Winddir - !WRITE(25,*),'T7_wake=',T7_wake - !WRITE(25,*),'T8_wake=',T8_wake - !CLOSE(25) - !------------------------------------------------------------ - + END SUBROUTINE cal_wake_sector_angle !------------------------------------------------------------------- @@ -510,11 +481,11 @@ FUNCTION projected_length(ax,ay,bx,by) ! The distance is used to sort the turbines from ipstream to downstream !................................................................... - REAL :: ax ! the x coordinate of the point a (reference point) - REAL :: ay ! the y coordinate of the point a - REAL :: bx ! the x coordinate of the point b - REAL :: by ! the y coordinate of the point b - REAL :: projected_length + REAL(8) :: ax ! the x coordinate of the point a (reference point) + REAL(8) :: ay ! the y coordinate of the point a + REAL(8) :: bx ! the x coordinate of the point b + REAL(8) :: by ! the y coordinate of the point b + REAL :: projected_length REAL :: side_a ! triangle side a length REAL :: side_b ! triangle side b length @@ -646,8 +617,8 @@ FUNCTION turbine_position_LorR(xwind,ywind,x0,y0,x1,y1) ! This function is to see if the downwind turbine is on the left side or right side of the line ! connecting the wind origin and the upwind turbine !................................................................... - REAL :: xwind ! wind origin - REAL :: ywind + REAL(8) :: xwind ! wind origin + REAL(8) :: ywind REAL :: x0 ! investigated origin turbine REAL :: y0 REAL :: x1 ! turbine other than the investigated turbine @@ -737,7 +708,7 @@ SUBROUTINE delete_temp_files() CHARACTER(LEN=10) :: InductionPrefix = 'Induction_' CHARACTER(LEN=6) :: Wakeprefix = 'WakeU_' CHARACTER(LEN=11) :: WWprefix_bin = 'Wake_width_' - CHARACTER(LEN=22) :: Prefix = 'DWM-results\' + CHARACTER(LEN=22) :: Prefix = 'DWM-results/' CHARACTER(LEN=4) :: connectionprefix = '_to_' CHARACTER(LEN=8) :: Turbineprefix = 'Turbine_' INTEGER :: I,J,K @@ -820,25 +791,25 @@ SUBROUTINE delete_temp_files() END DO - OPEN (29, file='DWM-results\turbine_angles.bin') + OPEN (29, file='turbine_angles.bin') CLOSE (29, status='delete') - OPEN (29, file='DWM-results\turbine_distance.bin') + OPEN (29, file='turbine_distance.bin') CLOSE (29, status='delete') - OPEN (29, file='DWM-results\turbine_interaction.bin') + OPEN (29, file='turbine_interaction.bin') CLOSE (29, status='delete') - OPEN (29, file='DWM-results\wake_sector_angle.bin') + OPEN (29, file='wake_sector_angle.bin') CLOSE (29, status='delete') - OPEN (29, file='DWM-results\Wake_width_Turbine_0.bin') + OPEN (29, file='Wake_width_Turbine_0.bin') CLOSE (29, status='delete') - OPEN (29, file='DWM-results\WC_Turbine_0.bin') + OPEN (29, file='WC_Turbine_0.bin') CLOSE (29, status='delete') - OPEN (29, file='DWM-results\wind_farm_turbine_sort.bin') + OPEN (29, file='wind_farm_turbine_sort.bin') CLOSE (29, status='delete') @@ -852,7 +823,6 @@ SUBROUTINE Driver_init() USE DWM_init_data, ONLY:OutFileRoot, InputFile INTEGER :: Stat - !CHARACTER(1024) :: InputFile CHARACTER(1024) :: DirName CALL CheckArgs( InputFile, Stat ) @@ -860,9 +830,6 @@ SUBROUTINE Driver_init() CALL GetRoot( InputFile, OutFileRoot ) CALL Get_CWD ( DirName, Stat ) - - !PRINT*,DirName - END SUBROUTINE Driver_init @@ -871,8 +838,9 @@ SUBROUTINE rename_FAST_output(SimulationOrder_index) !............................................................................ ! This routine is called to rename the fast output !............................................................................ +#ifdef __INTEL_COMPILER USE IFPORT - USE DFLIB +#endif USE wind_farm_geometry_data, ONLY: turbine_sort USE DWM_init_data, ONLY: OutFileRoot @@ -880,7 +848,7 @@ SUBROUTINE rename_FAST_output(SimulationOrder_index) CHARACTER(LEN=11) :: Fastprefix = 'FastOutput_' ! Fast output file CHARACTER(LEN=8) :: FastElmprefix = 'FastElm_' ! Fast Elm output file INTEGER :: RESULT - CHARACTER(LEN=22) :: Prefix = 'DWM-results\' + CHARACTER(LEN=22) :: Prefix = 'DWM-results/' CHARACTER(LEN=8) :: Turbineprefix = 'Turbine_' CHARACTER(LEN=3) :: invetigated_turbine_index_character INTEGER :: WT_index @@ -897,15 +865,11 @@ SUBROUTINE rename_FAST_output(SimulationOrder_index) ELSE write(invetigated_turbine_index_character,'(i3)') WT_index END IF - + ! Rename the FAST output wrt the turbine index filename_FastOutput = trim(Prefix)//trim(Fastprefix)//trim(Turbineprefix)//trim(invetigated_turbine_index_character)//".out" filename_FastElm = trim(Prefix)//trim(FastElmprefix)//trim(Turbineprefix)//trim(invetigated_turbine_index_character)//".AD.out" - - !RESULT =rename('V80_2MW.out',filename_FastOutput) - !RESULT =rename('V80_2MW.elm',filename_FastElm ) - - + RESULT =rename( TRIM(OutFileRoot)//'.out', filename_FastOutput) !bjj: what if I'm using .outb in FAST instead of .out? RESULT =rename( TRIM(OutFileRoot)//'.AD.out',filename_FastElm ) !bjj: *.elm has been renamed *.AD.out in FAST v8. Also, .AD.out files are not always generated. END IF diff --git a/modules-local/aerodyn14/src/GenSubs.f90 b/modules/aerodyn14/src/GenSubs.f90 similarity index 100% rename from modules-local/aerodyn14/src/GenSubs.f90 rename to modules/aerodyn14/src/GenSubs.f90 diff --git a/modules-local/aerodyn14/src/Registry-AD14.txt b/modules/aerodyn14/src/Registry-AD14.txt similarity index 100% rename from modules-local/aerodyn14/src/Registry-AD14.txt rename to modules/aerodyn14/src/Registry-AD14.txt diff --git a/modules-local/aerodyn14/src/Registry-DWM.txt b/modules/aerodyn14/src/Registry-DWM.txt similarity index 100% rename from modules-local/aerodyn14/src/Registry-DWM.txt rename to modules/aerodyn14/src/Registry-DWM.txt diff --git a/modules-local/beamdyn/CMakeLists.txt b/modules/beamdyn/CMakeLists.txt similarity index 93% rename from modules-local/beamdyn/CMakeLists.txt rename to modules/beamdyn/CMakeLists.txt index 5994d9f5ae..6de745b8c4 100644 --- a/modules-local/beamdyn/CMakeLists.txt +++ b/modules/beamdyn/CMakeLists.txt @@ -39,7 +39,7 @@ set(BD_DRIVER_SOURCES src/Driver_Beam_Subs.f90) add_executable(beamdyn_driver ${BD_DRIVER_SOURCES}) -target_link_libraries(beamdyn_driver beamdynlib nwtclibs ${CMAKE_DL_LIBS}) +target_link_libraries(beamdyn_driver beamdynlib nwtclibs versioninfolib ${CMAKE_DL_LIBS}) install(TARGETS beamdyn_driver RUNTIME DESTINATION bin diff --git a/modules-local/beamdyn/README.md b/modules/beamdyn/README.md similarity index 61% rename from modules-local/beamdyn/README.md rename to modules/beamdyn/README.md index bed23ff147..9e1675f38e 100644 --- a/modules-local/beamdyn/README.md +++ b/modules/beamdyn/README.md @@ -1,22 +1,36 @@ # BeamDyn Module +The legacy version of this module and additional documentation are available +the [NWTC Software Portal](https://nwtc.nrel.gov/BeamDyn/). ## Overview - -BeamDyn is a time-domain structural-dynamics module for slender structures. The module has been coupled into the FAST aero-hydro-servo-elastic wind turbine multi-physics engineering tool where it used to model blade structural dynamics. BeamDyn is designed to analyze beams that are made of composite materials, initially curved and twisted, and subject to large displacement and rotation deformations. BeamDyn can also be used for static analysis of beams. - -BeamDyn is based on the geometrically exact beam theory (GEBT) and is implemented using Legendre spectral finite elements (LSFEs). GEBT supports full geometric nonlinearity and large deflection, with bending, torsion, shear, and extensional degree-of-freedom (DOFs); anisotropic composite material couplings (using full 6x6 mass and stiffness matrices, including bend-twist coupling); and a reference axis that permits blades that are not straight (supporting built-in curve, sweep, and sectional offsets). - -BeamDyn was originally developed by Qi Wang, Mike Sprague, and Jason Jonkman under an NREL Laboratory Directed Research and Development (LDRD) Project: High-fidelity computational modeling of wind-turbine structural dynamics (2011-2013; PI: M.A. Sprague). Further development was funded by the DOE Wind Energy Technology Office. NREL gratefully acknowledges the development contributions from the following organizations: +BeamDyn is a time-domain structural-dynamics module for slender structures. +The module has been coupled into the FAST aero-hydro-servo-elastic wind turbine +multi-physics engineering tool where it used to model blade structural +dynamics. BeamDyn is designed to analyze beams that are made of composite +materials, initially curved and twisted, and subject to large displacement and +rotation deformations. BeamDyn can also be used for static analysis of beams. + +BeamDyn is based on the geometrically exact beam theory (GEBT) and is +implemented using Legendre spectral finite elements (LSFEs). GEBT supports full +geometric nonlinearity and large deflection, with bending, torsion, shear, and +extensional degree-of-freedom (DOFs); anisotropic composite material couplings +(using full 6x6 mass and stiffness matrices, including bend-twist coupling); +and a reference axis that permits blades that are not straight (supporting +built-in curve, sweep, and sectional offsets). + +BeamDyn was originally developed by Qi Wang, Mike Sprague, and Jason Jonkman +under an NREL Laboratory Directed Research and Development (LDRD) +Project: High-fidelity computational modeling of wind-turbine structural +dynamics (2011-2013; PI: M.A. Sprague). +Further development was funded by the DOE Wind Energy Technology Office. NREL +gratefully acknowledges the development contributions from the following organizations: * [Envision Energy USA, Ltd](http://www.envision-energy.com) +## Manual +BeamDyn documentation is available on the OpenFAST +[ReadTheDocs](https://openfast.readthedocs.io/en/master/source/user/beamdyn/index.html) site. -## BeamDyn Manual - -We are in the process of creating BeamDyn documentation on . - -The original BeamDyn manual may be found [here](https://wind.nrel.gov/nwtc/docs/BeamDyn_Manual.pdf). - -## Some Relevant Publications +## Relevant Publications * Wang, Q., M.A. Sprague, J. Jonkman, N. Johnson, and B. Jonkman, 2017, BeamDyn: An efficient high-fidelity wind turbine blade solver in the FAST modular framework. *Wind Energy*, [DOI:10.1002/we.2101](http://onlinelibrary.wiley.com/doi/10.1002/we.2101/full). @@ -40,4 +54,3 @@ Proceedings of the *AIAA Science and Technology Forum and Exposition, Legendre spectral finite elements for wind turbine blade dynamics. Proceedings of the *AIAA Science and Technology Forum and Exposition, 32nd ASME Wind Energy Symposium*, National Harbor, MD, January 13--17, 2014. Also published as [NREL/CP-2C00-60759](http://www.nrel.gov/docs/fy14osti/60759.pdf). - diff --git a/modules-local/beamdyn/src/BeamDyn.f90 b/modules/beamdyn/src/BeamDyn.f90 similarity index 96% rename from modules-local/beamdyn/src/BeamDyn.f90 rename to modules/beamdyn/src/BeamDyn.f90 index 6ef6e055aa..e32b4eca4f 100644 --- a/modules-local/beamdyn/src/BeamDyn.f90 +++ b/modules/beamdyn/src/BeamDyn.f90 @@ -181,7 +181,12 @@ SUBROUTINE BD_Init( InitInp, u, p, x, xd, z, OtherState, y, MiscVar, Interval, I return end if - call Initialize_FEweights(p) ! set p%FEweight; needs p%uuN0 and p%uu0 +!FIXME: shift mass stiffness matrices here from the keypoint line to the calculated curvature line in p%uu0 +! CALL BD_KMshift2Ref(p) + + + call Initialize_FEweights(p,GLL_nodes,ErrStat2,ErrMsg2) ! set p%FEweight; needs p%uuN0 and p%uu0 + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! compute blade mass, CG, and IN for summary file: CALL BD_ComputeBladeMassNew( p, ErrStat2, ErrMsg2 ) !computes p%blade_mass,p%blade_CG,p%blade_IN @@ -307,7 +312,7 @@ SUBROUTINE BD_Init( InitInp, u, p, x, xd, z, OtherState, y, MiscVar, Interval, I ! Print the summary file if requested: if (InputFileData%SumPrint) then - call BD_PrintSum( p, x, MiscVar, InitInp%RootName, ErrStat2, ErrMsg2 ) + call BD_PrintSum( p, x, MiscVar, InitInp, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) end if @@ -548,39 +553,102 @@ subroutine InitializeNodalLocations(InputFileData,p,GLL_nodes,ErrStat, ErrMsg) end subroutine InitializeNodalLocations !----------------------------------------------------------------------------------------------------------------------------------- -!> This routine calculates the contributions of quadature points outboard of an FE node. It is used to calculate the internal forces -!! from the Fc and Fd terms. This weighting is used in the integration of those loads. However, this is likely not the most robust -!! or clean approach and may contribute significant error to those calculations. +!> This routine calculates the contributions of the integral of shape functions outboard of an FE node. These weighting values are +!! used as part of the integration scheme for the output of the internal forces from the Fc and Fd terms. This is simply a numerical +!! integration of those shape functions. !! Note from ADP: I don't like this method, but haven't found a better method yet. I think a better approach may be to use the !! inverse H' matrix and inverse shape functions, but I have not tried deriving that yet. -subroutine Initialize_FEweights(p) +subroutine Initialize_FEweights(p,GLL_nodes,ErrStat,ErrMsg) type(BD_ParameterType), intent(inout) :: p !< Parameters + real(BDKi), intent(in ) :: GLL_nodes(:) + 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 ! do-loop counter - INTEGER(IntKi) :: nelem ! do-loop counter over number of elements - INTEGER(IntKi) :: idx_qp !< index of current quadrature point in loop - REAL(BDKi) :: SumShp + integer(IntKi) :: i ! do-loop counter + integer(IntKi) :: nelem ! do-loop counter over number of elements + integer(IntKi) :: IntPtIdx !< index of current quadrature point in loop + real(BDKi) :: SumShp + + real(BDKi), allocatable :: Shp(:,:) !< High resolution of Shp functions + real(BDKi), allocatable :: ShpDer(:,:) !< High resolution of ShpDer functions + integer(IntKi) :: IntPoints !< number of points in the high res + REAL(BDKi), allocatable :: EtaVals(:) !< Integeration points along Z, scaled [-1 1] + REAL(BDKi), allocatable :: DistVals(:) !< Integeration points along Z, actual distance + REAL(BDKi) :: ElemLength + + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'Initialize_FEweights' + + ErrStat = ErrID_None + ErrMsg = "" + + + ! Set number of points for the integrations. Number chosen based on convergence tests + IntPoints=100001 + + + CALL AllocAry(EtaVals,IntPoints,'Distance along blade for high res Shp functions',ErrStat2,ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + CALL AllocAry(DistVals,IntPoints,'Distance along blade for high res Shp functions',ErrStat2,ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + CALL AllocAry(Shp,p%nodes_per_elem,IntPoints,'Shp',ErrStat2,ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + CALL AllocAry(ShpDer,p%nodes_per_elem,IntPoints,'ShpDer',ErrStat2,ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup + return + endif + p%FEweight= 0.0_BDKi - ! First we find which QP points are the first QP to consider for each node in each element - DO nelem=1,p%elem_total - DO i=1,p%nodes_per_elem + + ! Loop over the elements in case we change the number of FE points between elements in the future + do nelem=1,p%elem_total + + ! Find the length of this element (straight line approximation) + ElemLength = TwoNorm(p%uuN0(1:3,p%nodes_per_elem,nelem) - p%uuN0(1:3,1,nelem)) + + ! Setup the corresponding EtaVals for all the integration points + do IntPtIdx=1,IntPoints + EtaVals(IntPtIdx) = REAL(IntPtIdx-1,BDKi)/REAL(IntPoints-1,BDKi) + enddo + + ! Calculate corresponding distances for the integration region + DistVals = EtaVals*ElemLength + + ! Scale the EtaVals to [-1 1] range for the diffmtc routine + EtaVals = 2.0_BDKi*EtaVals - 1.0_BDKi + + ! Get the high resolution Shp functions. We won't use the ShpDer results at all + call BD_diffmtc(p%nodes_per_elem,GLL_nodes,EtaVals,IntPoints,Shp,ShpDer) + + ! Integrate region outboard shape function contributions to this FE node! + do i=1,p%nodes_per_elem SumShp=0.0_BDKi - DO idx_qp=p%nqp,1,-1 ! Step inwards to find the first QP past the FE point - IF ( TwoNorm(p%uu0(1:3,idx_qp,nelem)) >= TwoNorm(p%uuN0(1:3,i,nelem))) THEN - p%FEweight(i,nelem) = p%FEweight(i,nelem) + p%Shp(i,idx_qp) - ENDIF - SumShp=SumShp+p%Shp(i,idx_qp) - ENDDO + do IntPtIdx=IntPoints,1,-1 ! Step inwards and integrate + if ( DistVals(IntPtIdx) > TwoNorm(p%uuN0(1:3,i,nelem)-p%uuN0(1:3,1,nelem))) THEN + p%FEweight(i,nelem) = p%FEweight(i,nelem) + Shp(i,IntPtIdx) + endif + SumShp=SumShp+Shp(i,IntPtIdx) + enddo p%FEweight(i,nelem) = p%FEweight(i,nelem) / SumShp - ENDDO - ! Tip contribution - ! Setting FEWeight at the tip to 1. The contirbution of the tip of each element should be absolute, hence no weighting is required - p%FEweight(p%nodes_per_elem,nelem) = 1.0_BDKi - ENDDO + enddo + enddo + + call Cleanup + + contains + subroutine Cleanup() + if (allocated(EtaVals)) deallocate(EtaVals) + if (allocated(DistVals)) deallocate(DistVals) + if (allocated(EtaVals)) deallocate(Shp) + if (allocated(EtaVals)) deallocate(ShpDer) + end subroutine Cleanup end subroutine Initialize_FEweights !----------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE BD_InitShpDerJaco( GLL_Nodes, p ) @@ -599,7 +667,7 @@ SUBROUTINE BD_InitShpDerJaco( GLL_Nodes, p ) CHARACTER(*), PARAMETER :: RoutineName = 'BD_InitShpDerJaco' - CALL BD_diffmtc(p,GLL_nodes,p%Shp,p%ShpDer) + CALL BD_diffmtc(p%nodes_per_elem,GLL_nodes,p%QPtN,p%nqp,p%Shp,p%ShpDer) DO nelem = 1,p%elem_total DO idx_qp = 1, p%nqp @@ -1392,6 +1460,7 @@ subroutine Init_MiscVars( p, u, y, m, ErrStat, ErrMsg ) CALL AllocAry(m%LP_StifK_LU, p%dof_total-6,p%dof_total-6, 'LP_StifK_LU', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AllocAry(m%LP_StifK, p%dof_total,p%dof_total, 'LP_StifK', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AllocAry(m%LP_MassM, p%dof_total,p%dof_total, 'LP_MassM', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry(m%LP_MassM_LU, p%dof_total-6,p%dof_total-6, 'LP_MassM_LU', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AllocAry(m%LP_indx, p%dof_total, 'LP_indx', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! LAPACK routine outputs converted to dimensionality used in BD. Note the index ordering here is due to reshape functions before calls to LAPACK routines @@ -1414,6 +1483,7 @@ subroutine Init_MiscVars( p, u, y, m, ErrStat, ErrMsg ) CALL AllocAry(m%BldInternalForceFE, p%dof_node,p%node_total, 'Calculated Internal Force at FE', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AllocAry(m%BldInternalForceQP, p%dof_node,y%BldMotion%NNodes, 'Calculated Internal Force at QP', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AllocAry(m%FirstNodeReactionLclForceMoment, p%dof_node, 'Root node reaction force/moment', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + m%FirstNodeReactionLclForceMoment = 0.0_BDKi ! This is set to zero so that first timestep values make sense from driver with static solve. CALL AllocAry(m%Nrrr, (p%dof_node/2),p%nodes_per_elem,p%elem_total,'Nrrr: rotation parameters relative to root', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -1427,7 +1497,7 @@ subroutine Init_MiscVars( p, u, y, m, ErrStat, ErrMsg ) CALL AllocAry(m%elm, p%dof_node,p%nodes_per_elem,p%dof_node,p%nodes_per_elem, 'elm', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Point loads applied to FE nodes from driver code. - CALL AllocAry(m%PointLoadLcl, p%dof_node,p%nodes_per_elem, 'PointLoadLcl', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry(m%PointLoadLcl, p%dof_node,p%node_total, 'PointLoadLcl', ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Distributed load from mesh, on the quadrature points. The ramping copy is for the quasi-static solve CALL AllocAry(m%DistrLoad_QP, p%dof_node,p%nqp,p%elem_total, 'DistrLoad_QP',ErrStat2,ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -1819,28 +1889,21 @@ SUBROUTINE BD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) CALL BD_CalcForceAcc(m%u, p, m, ErrStat2,ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! Transfer the FirstNodeReaction forces to the output ReactionForce - y%ReactionForce%Force(:,1) = MATMUL(p%GlbRot,m%FirstNodeReactionLclForceMoment(1:3)) - y%ReactionForce%Moment(:,1) = MATMUL(p%GlbRot,m%FirstNodeReactionLclForceMoment(4:6)) - - !FIXME: This is not tested for Gauss quadrature we might need to map across to the root position. - CALL BD_InternalForceMoment( x, p, m ) - ELSE - ! Calculate the elastic forces for the static case. DO nelem=1,p%elem_total CALL BD_StaticElementMatrix( nelem, p%gravity, p, m ) ENDDO - !FIXME: This is not tested for Gauss quadrature we might need to map across to the root position. - CALL BD_InternalForceMoment( x, p, m ) - - ! Get the root force from the solution for first finite element node. - y%ReactionForce%Force(:,1) = m%BldInternalForceFE(1:3,1) - y%ReactionForce%Moment(:,1) = m%BldInternalForceFE(4:6,1) ENDIF + ! Calculate internal forces and moments + CALL BD_InternalForceMoment( x, p, m ) + + ! Transfer the FirstNodeReaction forces to the output ReactionForce + y%ReactionForce%Force(:,1) = MATMUL(p%GlbRot,m%FirstNodeReactionLclForceMoment(1:3)) + y%ReactionForce%Moment(:,1) = MATMUL(p%GlbRot,m%FirstNodeReactionLclForceMoment(4:6)) + ! set y%BldMotion fields: CALL Set_BldMotion_Mesh( p, m%u2, x, m, y) @@ -2236,8 +2299,7 @@ SUBROUTINE BD_RotationalInterpQP( nelem, p, x, m ) ! Calculate the rotation parameters relative to the root for each node - m%Nrrr(1:3,elem_start,nelem) = (/ 0.0_BDKi, 0.0_BDKi, 0.0_BDKi /) ! First node has no curvature relative to itself - DO idx_node=2,p%nodes_per_elem + DO idx_node=1,p%nodes_per_elem ! Find resulting rotation parameters R(Nr) = Ri^T(x%q(1)) R(x%q(:)) ! where R(x%q(1))^T is the transpose rotation parameters for the root node CALL BD_CrvCompose(m%Nrrr(1:3,idx_node,nelem),x%q(4:6,elem_start),x%q(4:6,elem_start-1+idx_node),FLAG_R1TR2) ! m%Nrrr(1:3,idx_node,nelem) = x%q(4:6,elem_start)^- composed with x%q(4:6,elem_start-1+idx_node) @@ -2327,7 +2389,10 @@ SUBROUTINE BD_StifAtDeformedQP( nelem, p, m ) INTEGER(IntKi) :: idx_qp !< index counter for quadrature point INTEGER(IntKi) :: temp_id2 !< Index to last node of previous element + INTEGER(IntKi) :: i,j !< generic counters REAL(BDKi) :: tempR6(6,6) + REAL(BDKi) :: tempBeta6(6,6) + ! see Bauchau 2011 Flexible Multibody Dynamics p 692-693, section 17.7.2 @@ -2339,12 +2404,24 @@ SUBROUTINE BD_StifAtDeformedQP( nelem, p, m ) ! Setup the temporary matrix for modifying the stiffness matrix. RR0 is changing with time. tempR6 = 0.0_BDKi + tempBeta6 = 0.0_BDKi tempR6(1:3,1:3) = m%qp%RR0(:,:,idx_qp,nelem) ! upper left -- translation tempR6(4:6,4:6) = m%qp%RR0(:,:,idx_qp,nelem) ! lower right -- rotation -!NOTE: Bauchau has the lower right corner multiplied by H + !NOTE: Bauchau has the lower right corner multiplied by H + + ! Move damping ratio from material frame to the calculation reference frame + ! This is the following: + ! tempBEta6=matmul(tempR6,matmul(diag(p%beta),transpose(tempR6))) + do j=1,6 + do i=1,6 + ! diagonal of p%beta * TRANSPOSE(tempR6) + tempBeta6(i,j) = p%beta(i)*tempR6(j,i) + enddo + enddo + tempBeta6 = matmul(tempR6,tempBeta6) - !> Modify the Mass matrix as + !> Modify the Mass matrix so it is in the calculation reference frame !! \f$ \begin{bmatrix} !! \left(\underline{\underline{R}} \underline{\underline{R}}_0\right) & 0 \\ !! 0 & \left(\underline{\underline{R}} \underline{\underline{R}}_0\right) @@ -2355,6 +2432,9 @@ SUBROUTINE BD_StifAtDeformedQP( nelem, p, m ) !! 0 & \left(\underline{\underline{R}} \underline{\underline{R}}_0\right)^T !! \end{bmatrix} \f$ m%qp%Stif(:,:,idx_qp,nelem) = MATMUL(tempR6,MATMUL(p%Stif0_QP(1:6,1:6,temp_id2+idx_qp),TRANSPOSE(tempR6))) + + ! Now apply the damping + m%qp%betaC(:,:,idx_qp,nelem) = matmul(tempBeta6,m%qp%Stif(:,:,idx_qp,nelem)) ENDDO END SUBROUTINE BD_StifAtDeformedQP @@ -2802,15 +2882,6 @@ SUBROUTINE BD_DissipativeForce( nelem, p, m,fact ) INTEGER(IntKi) :: idx_qp !< index of current quadrature point - DO idx_qp=1,p%nqp - !m%qp%betaC(:,:,idx_qp,nelem) = MATMUL( diag(p%beta(i)), temp_b,m%qp%Stif(:,:,idx_qp,nelem)) - DO j=1,6 - DO i=1,6 - m%qp%betaC(i,j,idx_qp,nelem) = p%beta(i)*m%qp%Stif(i,j,idx_qp,nelem) - END DO - END DO - END DO - IF (.NOT. fact) then ! skip all but Fc and Fd terms @@ -3064,12 +3135,14 @@ END SUBROUTINE BD_GyroForce !----------------------------------------------------------------------------------------------------------------------------------- !> calculate Lagrangian interpolant tensor at ns points where basis !! functions are assumed to be associated with (np+1) GLL points on [-1,1] -SUBROUTINE BD_diffmtc( p,GLL_nodes,Shp,ShpDer ) +SUBROUTINE BD_diffmtc( nodes_per_elem,GLL_nodes,QPtN,nqp,Shp,ShpDer ) ! See Bauchau equations 17.1 - 17.5 - TYPE(BD_ParameterType), INTENT(IN ) :: p !< Parameters + INTEGER(IntKi), INTENT(IN ) :: nodes_per_elem !< Nodes per elemenent REAL(BDKi), INTENT(IN ) :: GLL_nodes(:) !< GLL_nodes(p%nodes_per_elem): location of the (p%nodes_per_elem) p%GLL points + REAL(BDKi), INTENT(IN ) :: QPtN(:) !< Locations of quadrature points ([-1 1]) + INTEGER(IntKi), INTENT(IN ) :: nqp !< number of quadrature points to consider. Should be size of 2nd index of Shp & ShpDer REAL(BDKi), INTENT(INOUT) :: Shp(:,:) !< p%Shp (or another Shp array for when we add outputs at arbitrary locations) REAL(BDKi), INTENT(INOUT) :: ShpDer(:,:) !< p%ShpDer (or another Shp array for when we add outputs at arbitrary locations) @@ -3087,26 +3160,26 @@ SUBROUTINE BD_diffmtc( p,GLL_nodes,Shp,ShpDer ) ShpDer(:,:) = 0.0_BDKi - do j = 1,p%nqp - do l = 1,p%nodes_per_elem + do j = 1,nqp + do l = 1,nodes_per_elem - if ((abs(p%QPtN(j)-1.).LE.eps).AND.(l.EQ.p%nodes_per_elem)) then !adp: FIXME: do we want to compare to eps, or EqualRealNos??? - ShpDer(l,j) = REAL((p%nodes_per_elem)*(p%nodes_per_elem-1), BDKi)/4.0_BDKi - elseif ((abs(p%QPtN(j)+1.).LE.eps).AND.(l.EQ.1)) then - ShpDer(l,j) = -REAL((p%nodes_per_elem)*(p%nodes_per_elem-1), BDKi)/4.0_BDKi - elseif (abs(p%QPtN(j)-GLL_nodes(l)).LE.eps) then + if ((abs(QPtN(j)-1.).LE.eps).AND.(l.EQ.nodes_per_elem)) then !adp: FIXME: do we want to compare to eps, or EqualRealNos??? + ShpDer(l,j) = REAL((nodes_per_elem)*(nodes_per_elem-1), BDKi)/4.0_BDKi + elseif ((abs(QPtN(j)+1.).LE.eps).AND.(l.EQ.1)) then + ShpDer(l,j) = -REAL((nodes_per_elem)*(nodes_per_elem-1), BDKi)/4.0_BDKi + elseif (abs(QPtN(j)-GLL_nodes(l)).LE.eps) then ShpDer(l,j) = 0.0_BDKi else ShpDer(l,j) = 0.0_BDKi den = 1.0_BDKi - do i = 1,p%nodes_per_elem + do i = 1,nodes_per_elem if (i.NE.l) then den = den*(GLL_nodes(l)-GLL_nodes(i)) endif dnum = 1.0_BDKi - do k = 1,p%nodes_per_elem + do k = 1,nodes_per_elem if ((k.NE.l).AND.(k.NE.i).AND.(i.NE.l)) then - dnum = dnum*(p%QPtN(j)-GLL_nodes(k)) + dnum = dnum*(QPtN(j)-GLL_nodes(k)) elseif (i.EQ.l) then dnum = 0.0_BDKi endif @@ -3117,19 +3190,19 @@ SUBROUTINE BD_diffmtc( p,GLL_nodes,Shp,ShpDer ) endif enddo enddo - - do j = 1,p%nqp - do l = 1,p%nodes_per_elem - if(abs(p%QPtN(j)-GLL_nodes(l)).LE.eps) then + do j = 1,nqp + do l = 1,nodes_per_elem + + if(abs(QPtN(j)-GLL_nodes(l)).LE.eps) then Shp(l,j) = 1.0_BDKi else dnum = 1.0_BDKi den = 1.0_BDKi - do k = 1,p%nodes_per_elem + do k = 1,nodes_per_elem if (k.NE.l) then den = den *(GLL_nodes(l) - GLL_nodes(k)) - dnum = dnum*(p%QPtN(j) - GLL_nodes(k)) + dnum = dnum*(QPtN(j) - GLL_nodes(k)) endif enddo Shp(l,j) = dnum/den @@ -3517,6 +3590,10 @@ SUBROUTINE BD_Static(t,u,utimes,p,x,OtherState,m,ErrStat,ErrMsg) ! note that if BD_StaticSolution converges, then piter will .le. p%niter + ! bjj: note that this is not necessarially sufficient: if an error occurred in the loop inside BD_StaticSolution + ! and it exited early, this condition would also hold. Care must be taken inside BD_StaticSolution so that doesn't + ! happen if this convergence condition is used. + if (piter .le. p%niter) then ! save this successfully converged value @@ -3630,14 +3707,22 @@ SUBROUTINE BD_StaticSolution( x, gravity, p, m, piter, ErrStat, ErrMsg ) ! Solve for X in A*X=B to get the displacement of blade under static load. CALL LAPACK_getrf( p%dof_total-p%dof_node, p%dof_total-p%dof_node, m%LP_StifK_LU, m%LP_indx, ErrStat2, ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! if there is a problem with the factorization, we should not continue with this iteration + if (ErrStat >= AbortErrLev) RETURN + CALL LAPACK_getrs( 'N',p%dof_total-p%dof_node, m%LP_StifK_LU, m%LP_indx, m%LP_RHS_LU, ErrStat2, ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! if there is a problem with the solve, we should not continue with this iteration + if (ErrStat >= AbortErrLev) RETURN ! Reshape to BeamDyn arrays m%Solution(:,1) = 0.0_BDKi ! first node is not set below m%Solution(:,2:p%node_total) = RESHAPE( m%LP_RHS_LU, (/ p%dof_node, (p%node_total - 1) /) ) CALL BD_StaticUpdateConfiguration(p,m,x) + + ! Set the first node reaction force / moment + m%FirstNodeReactionLclForceMoment(1:6) = m%RHS(1:6,1) Enorm = abs(DOT_PRODUCT(m%LP_RHS_LU, m%LP_RHS(7:p%dof_total))) ! compute the energy of the current system (note - not a norm!) @@ -4003,7 +4088,11 @@ SUBROUTINE BD_QuasiStatic(u,p,x,OtherState,m,ErrStat,ErrMsg, RampLoad) end if OtherState%Acc = 0.0_BDKi - + + ! Reset the inertial forces (this is for output purposes if we have to start without the quasistatic solve) + m%qp%Fi = 0.0_BDKi ! This could be output before it gets set. + + ! Now proceed only if we are allowed to and have not exceeded the IF ( LoadSteps .EQ. 2**MaxLoadSteps ) THEN !NOTE: if we did not converge to a solution, then we will return now that we have reset the states. @@ -4269,7 +4358,7 @@ SUBROUTINE BD_InternalForceMoment( x, p, m ) TYPE(BD_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(BD_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables - INTEGER(IntKi) :: nelem ! number of current element + INTEGER(IntKi) :: nelem ! number of current element INTEGER(IntKi) :: idx_node_in_elem INTEGER(IntKi) :: idx_node INTEGER(IntKi) :: idx_qp @@ -4286,20 +4375,13 @@ SUBROUTINE BD_InternalForceMoment( x, p, m ) m%BldInternalForceFE(:,:) = 0.0_BDKi m%BldInternalForceQP(:,:) = 0.0_BDKi + ! Integrate quadrature points to get the FE nodes elastic force per length. m%EFint(:,:,:) = 0.0_BDKi - - ! Note from ADP: I expect the FE nodes to be correct with this approach. The QP calculations further down are going to be inexact - ! due to the integration weighting I am using (FEweights). This needs further review. - ! I don't like this method, but haven't found a better method yet. I think a better approach may be to use the - ! inverse H' matrix and inverse shape functions, but I have not tried deriving that yet. - - ! Integrate the elastic force contributions from the tip inwards. We only consider the shape function contributions at each QP beyond the current FE node. - ! Note that FE node contributions at the start of an element should be contained in the last node of the preceeding element. - DO nelem=p%elem_total,1,-1 - DO i=p%nodes_per_elem,1,-1 + DO nelem=1,p%elem_total + DO i=1,p%nodes_per_elem ! Integrate shape functions across the quadrature points to get FE nodes. - DO idx_qp=p%nqp,1,-1 + DO idx_qp=1,p%nqp ! Force contributions from current node m%EFint(1:3,i,nelem) = m%EFint(1:3,i,nelem) & + m%qp%Fc(1:3,idx_qp,nelem)*p%QPtw_ShpDer(idx_qp,i) @@ -4312,6 +4394,10 @@ SUBROUTINE BD_InternalForceMoment( x, p, m ) ENDDO ENDDO + + + ! Now Integerate from the tip inwards to get the internal forces at the FE nodes + ! Calculate the internal forces and moments at the FE nodes. ! NOTE: the elastic force contributions are already calculated and stored, so we merely need to perform the summation. ! NOTE: we are only counting unique points, not overlapping FE points (those are identical as the first node is not a state) @@ -4328,43 +4414,57 @@ SUBROUTINE BD_InternalForceMoment( x, p, m ) ! Keep track of previous node for adding force contributions to moments PrevNodePos = p%uuN0(1:3,p%nodes_per_elem,nelem) + x%q(1:3,nelem*LastNode+1) - DO idx_node_in_elem=LastNode,2,-1 ! Skip first node on element as it corresponds to last node of previous element or the root + DO idx_node_in_elem=LastNode,1,-1 - ! Index to node + ! Index to node in FE array idx_node = p%node_elem_idx(nelem,1)-1 + idx_node_in_elem ! p%node_elem_idx(nelem,1) is the first node in the element ! Force term - m%BldInternalForceFE(1:3,idx_node) = p%FEweight(idx_node_in_elem,nelem) * m%EFint(1:3,idx_node_in_elem,nelem) + m%BldInternalForceFE(1:3,idx_node+1) + (1.0_BDKi - p%FEweight(idx_node_in_elem+1,nelem)) * m%EFint(1:3,idx_node_in_elem+1,nelem) + ! NOTE: the idx_node+1 includes all force contributions up to the previous node tip inwards + m%BldInternalForceFE(1:3,idx_node) = p%FEweight(idx_node_in_elem,nelem) * m%EFint(1:3,idx_node_in_elem,nelem) & + + m%BldInternalForceFE(1:3,idx_node+1) & + + (1.0_BDKi - p%FEweight(idx_node_in_elem+1,nelem)) * m%EFint(1:3,idx_node_in_elem+1,nelem) ! Remaining integral of prior nodes shape functions ! Moment term including forces from next node out projected to this node ! NOTE: this appears like double counting, but the issue is that the Fd and Fc terms are both included in EFint. - ! These terms partially cancel each other. Fd includes part of the force term as well. The exact math - ! is a bit fuzzy to me. It appears to work though. If only Fc is used, then the result is off a very - ! small amount that is unknown to me. + ! These terms partially cancel each other. Fd includes part of the force term as well. Tmp3 = PrevNodePos - (p%uuN0(1:3,idx_node_in_elem,nelem) + x%q(1:3,idx_node)) - m%BldInternalForceFE(4:6,idx_node) = m%EFint(4:6,idx_node_in_elem,nelem) + m%BldInternalForceFE(4:6,idx_node+1) + cross_product( Tmp3, m%BldInternalForceFE(1:3,idx_node+1) ) + m%BldInternalForceFE(4:6,idx_node) = m%EFint(4:6,idx_node_in_elem,nelem) & + + m%BldInternalForceFE(4:6,idx_node+1) & + + cross_product( Tmp3, m%BldInternalForceFE(1:3,idx_node+1) ) & + + cross_product( Tmp3, (1.0_BDKi - p%FEweight(idx_node_in_elem+1,nelem)) * m%EFint(1:3,idx_node_in_elem+1,nelem)) ! remaining integral of prior node shape function ! Keep track of node position next node in. PrevNodePos = p%uuN0(1:3,idx_node_in_elem,nelem) + x%q(1:3,idx_node) ENDDO - ! only skip last node of outer element. So next element towards root needs its last node - ! included as first node of next element is skipped (they overlap) - !LastNode=p%nodes_per_elem + + ENDDO + + + ! The mathematics above ends up setting element boundaries to exactly zero. + DO nelem = p%elem_total,2,-1 + ! if we are at the element boundary, we keep the average value from the tip of the next element in and + ! the negative of the first node of this element. + ! + ! NOTE: the above calculations result in something close to zero otherwise because it is counting both + ! the tip of inner element and first node of outer element, which will almost cancel. + idx_node = p%node_elem_idx(nelem-1,2) ! Last node of next element inboard + m%BldInternalForceFE(1:3,idx_node) = ( m%EFint(1:3,p%nodes_per_elem,nelem-1) - m%EFint(1:3,1,nelem) ) / 2.0_BDKi ENDDO ! Now deal with the root node - IF(p%analysis_type /= BD_STATIC_ANALYSIS) THEN !dynamic analysis: - ! Add root reaction: This includes the mass*acceleration terms for the first node - m%BldInternalForceFE(1:6,1) = m%FirstNodeReactionLclForceMoment(:) - ELSE ! static case: - ! Add root reaction -- This is in the first node for static case and does not need contributions from the outboard sections due - ! to how the solve is performed. - m%BldInternalForceFE(1:3,1) = m%elf(1:3,1) - m%BldInternalForceFE(4:6,1) = m%elf(4:6,1) - ENDIF + ! Add root reaction: For the dynamic solves, this includes the mass*acceleration terms for the first node + ! For the static solve, this is in the first node for static case and does not need + ! contributions from the outboard sections due to how the solve is performed. + m%BldInternalForceFE(1:6,1) = m%FirstNodeReactionLclForceMoment(:) - ! Rotate coords to global reference frame + ! Point force at the tip is not counted at the last point. However, its contribution to the moment, and the tip moment are counted already. + m%BldInternalForceFE(1:3,p%node_total) = m%BldInternalForceFE(1:3,p%node_total) + (1.0_BDKi - p%FEweight(p%nodes_per_elem,p%elem_total))*m%PointLoadLcl(1:3,p%node_total) + + + + ! Rotate coords to global reference frame DO i=1,SIZE(m%BldInternalForceFE,DIM=2) m%BldInternalForceFE(1:3,i) = MATMUL(p%GlbRot,m%BldInternalForceFE(1:3,i)) m%BldInternalForceFE(4:6,i) = MATMUL(p%GlbRot,m%BldInternalForceFE(4:6,i)) @@ -4385,6 +4485,7 @@ SUBROUTINE BD_InternalForceMoment( x, p, m ) ! retrieve the QP data, we take the FE node result with the root reaction, and perform an integration using the pseudo- ! inverse of the ShpDer function to retrieve the QP reaction info. Since the starting info includes the coordinate ! transforms, we do not need to transform again. + ! Note: the FE node information above already has the rotation to the global reference frame, so we do not do that again here. DO idx_node=1,size(p%NdIndx) @@ -4395,7 +4496,7 @@ SUBROUTINE BD_InternalForceMoment( x, p, m ) ! Integrate over the FE point information Tmp6 = 0.0_BDKi - StartNode=p%node_elem_idx(p%elem_total,1) + StartNode=p%node_elem_idx(nelem,1) DO i=1,p%nodes_per_elem Tmp6 = Tmp6 + m%BldInternalForceFE(:,StartNode+i-1)* p%Shp(i,idx_qp) ENDDO @@ -4403,12 +4504,6 @@ SUBROUTINE BD_InternalForceMoment( x, p, m ) m%BldInternalForceQP(:,idx_node) = Tmp6 ENDDO - - ! Rotate coords to global reference frame - DO i=1,SIZE(m%BldInternalForceQP,DIM=2) - m%BldInternalForceQP(1:3,i) = MATMUL(p%GlbRot,m%BldInternalForceQP(1:3,i)) - m%BldInternalForceQP(4:6,i) = MATMUL(p%GlbRot,m%BldInternalForceQP(4:6,i)) - ENDDO END SELECT @@ -4732,7 +4827,7 @@ SUBROUTINE BD_DynamicSolutionGA2( x, OtherState, p, m, ErrStat, ErrMsg) CALL BD_QuadraturePointData( p,x,m ) ! Calculate QP values uuu, uup, RR0, kappa, E1 using current guess at continuous states (displacements and velocities) CALL BD_GenerateDynamicElementGA2( x, OtherState, p, m,fact) - ! Apply additional forces / loads at GLL points (such as aerodynamic loads)? + ! Apply additional forces / loads at GLL points (driver code only -- aero is from DistrLoad) DO j=1,p%node_total m%RHS(1:6,j) = m%RHS(1:6,j) + m%PointLoadLcl(1:6,j) ENDDO diff --git a/modules-local/beamdyn/src/BeamDyn_IO.f90 b/modules/beamdyn/src/BeamDyn_IO.f90 similarity index 99% rename from modules-local/beamdyn/src/BeamDyn_IO.f90 rename to modules/beamdyn/src/BeamDyn_IO.f90 index 138753561e..a4c06bf83c 100644 --- a/modules-local/beamdyn/src/BeamDyn_IO.f90 +++ b/modules/beamdyn/src/BeamDyn_IO.f90 @@ -1852,13 +1852,13 @@ SUBROUTINE Calc_WriteOutput( p, AllOuts, y, m, ErrStat, ErrMsg ) END SUBROUTINE Calc_WriteOutput !---------------------------------------------------------------------------------------------------------------------------------- !> This routine generates the summary file, which contains a regurgitation of the input data and interpolated flexible body data. -SUBROUTINE BD_PrintSum( p, x, m, RootName, ErrStat, ErrMsg ) +SUBROUTINE BD_PrintSum( p, x, m, InitInp, ErrStat, ErrMsg ) ! passed variables TYPE(BD_ParameterType), INTENT(IN) :: p !< Parameters of the structural dynamics module type(BD_ContinuousStateType), intent(in) :: x !< Continuous states TYPE(BD_MiscVarType), INTENT(INout) :: m !< misc/optimization variables - CHARACTER(*), INTENT(IN) :: RootName !< root name of summary file to be generated (will add .sum in this routine) + TYPE(BD_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine INTEGER(IntKi), INTENT(OUT) :: ErrStat !< error status CHARACTER(*), INTENT(OUT) :: ErrMsg !< error message @@ -1877,7 +1877,7 @@ SUBROUTINE BD_PrintSum( p, x, m, RootName, ErrStat, ErrMsg ) ! Open the summary file and give it a heading. CALL GetNewUnit( UnSu, ErrStat, ErrMsg ) - CALL OpenFOutFile ( UnSu, TRIM( RootName )//'.sum', ErrStat, ErrMsg ) + CALL OpenFOutFile ( UnSu, TRIM( InitInp%RootName )//'.sum', ErrStat, ErrMsg ) IF ( ErrStat >= AbortErrLev ) RETURN ! Heading: @@ -1903,6 +1903,11 @@ SUBROUTINE BD_PrintSum( p, x, m, RootName, ErrStat, ErrMsg ) WRITE (UnSu,'(3ES18.5)' ) p%GlbRot(i,:) ENDDO + WRITE (UnSu,'(A)') 'Initial blade orientation tensor (relative to global rotation tensor):' + DO i=1,3 + WRITE (UnSu,'(3ES18.5)' ) InitInp%RootOri(i,:) + ENDDO + WRITE (UnSu,'(A)') 'Global rotation WM parameters (IEC coords):' WRITE (UnSu,'(3ES18.5)' ) p%Glb_crv(:) @@ -2316,8 +2321,8 @@ SUBROUTINE Init_Jacobian_x_z( p, InitOut, ErrStat, ErrMsg) !...................................... ! default perturbations, p%dx: !...................................... - p%dx(1:3) = 0.2_ReKi*D2R * p%blade_length ! deflection states in m and m/s - p%dx(4:6) = 0.2_ReKi*D2R ! deflection states in rad and rad/s + p%dx(1:3) = 0.2_BDKi*D2R_D * p%blade_length ! deflection states in m and m/s + p%dx(4:6) = 0.2_BDKi*D2R_D ! deflection states in rad and rad/s InitOut%RotFrame_x = p%RotStates InitOut%DerivOrder_x = 2 diff --git a/modules-local/beamdyn/src/BeamDyn_Subs.f90 b/modules/beamdyn/src/BeamDyn_Subs.f90 similarity index 100% rename from modules-local/beamdyn/src/BeamDyn_Subs.f90 rename to modules/beamdyn/src/BeamDyn_Subs.f90 diff --git a/modules-local/beamdyn/src/Driver_Beam.f90 b/modules/beamdyn/src/Driver_Beam.f90 similarity index 95% rename from modules-local/beamdyn/src/Driver_Beam.f90 rename to modules/beamdyn/src/Driver_Beam.f90 index 8ba228b0c0..b7ea7f74a4 100644 --- a/modules-local/beamdyn/src/Driver_Beam.f90 +++ b/modules/beamdyn/src/Driver_Beam.f90 @@ -21,6 +21,7 @@ PROGRAM BeamDyn_Driver_Program USE BeamDyn_driver_subs ! all other modules inherited through this one + USE VersionInfo IMPLICIT NONE @@ -97,8 +98,8 @@ PROGRAM BeamDyn_Driver_Program ! initialize the BD_InitInput values not in the driver input file BD_InitInput%RootName = TRIM(BD_Initinput%InputFile) - BD_InitInput%RootDisp = 0.0_R8Ki - BD_InitInput%RootOri = BD_InitInput%GlbRot + BD_InitInput%RootDisp = matmul(transpose(BD_InitInput%RootOri),BD_InitInput%GlbPos) - BD_InitInput%GlbPos + BD_InitInput%RootVel(1:3) = matmul(BD_InitInput%RootOri, Cross_Product( BD_InitInput%RootVel(4:6), BD_InitInput%GlbPos )) ! set translational velocities based on rotation and GlbPos. BD_InitInput%DynamicSolve = DvrData%DynamicSolve ! QuasiStatic options handled within the BD code. t_global = DvrData%t_initial @@ -126,11 +127,15 @@ PROGRAM BeamDyn_Driver_Program ! If the Quasi-Static solve is in use, rerun the initialization with loads at t=0 ! (HACK: set in the driver only because computing Jacobians with this option [as in FAST glue code] is problematic) BD_OtherState%RunQuasiStaticInit = BD_Parameter%analysis_type == BD_DYN_SSS_ANALYSIS + + + ! Set the Initial root orientation + BD_Input(1)%RootMotion%Orientation(1:3,1:3,1) = DvrData%RootRelInit call Init_RotationCenterMesh(DvrData, BD_InitInput, BD_Input(1)%RootMotion, ErrStat, ErrMsg) CALL CheckError() - call CreateMultiPointMeshes(DvrData,BD_InitOutput,BD_Parameter, BD_Output, BD_Input(1), ErrStat, ErrMsg) + call CreateMultiPointMeshes(DvrData,BD_InitInput,BD_InitOutput,BD_Parameter, BD_Output, BD_Input(1), ErrStat, ErrMsg) call Transfer_MultipointLoads(DvrData, BD_Output, BD_Input(1), ErrStat, ErrMsg) CALL Dvr_InitializeOutputFile(DvrOut,BD_InitOutput,RootName,ErrStat,ErrMsg) diff --git a/modules-local/beamdyn/src/Driver_Beam_Subs.f90 b/modules/beamdyn/src/Driver_Beam_Subs.f90 similarity index 95% rename from modules-local/beamdyn/src/Driver_Beam_Subs.f90 rename to modules/beamdyn/src/Driver_Beam_Subs.f90 index 488d07e837..e62a86c66b 100644 --- a/modules-local/beamdyn/src/Driver_Beam_Subs.f90 +++ b/modules/beamdyn/src/Driver_Beam_Subs.f90 @@ -43,6 +43,8 @@ module BeamDyn_driver_subs TYPE(MeshMapType) :: Map_RotationCenter_to_RootMotion LOGICAL :: DynamicSolve + LOGICAL :: GlbRotBladeT0 ! Initial blade root orientation is also the GlbRot reference frame + REAL(DbKi) :: RootRelInit(3,3) ! Initial root orientation relative to GlbRot REAL(DbKi) :: t_initial REAL(DbKi) :: t_final REAL(R8Ki) :: w ! magnitude of rotational velocity vector @@ -148,6 +150,7 @@ SUBROUTINE BD_ReadDvrFile(DvrInputFile,dt,InitInputData,DvrData,& CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) InitInputData%GlbPos(:) = 0.0_ReKi InitInputData%GlbRot(:,:) = 0.0_R8Ki + InitInputData%RootOri(:,:) = 0.0_R8Ki CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(1),"InitInputData%GlbPos(1)", "position vector X",ErrStat2,ErrMsg2,UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(2),"InitInputData%GlbPos(2)", "position vector Y",ErrStat2,ErrMsg2,UnEc) @@ -160,14 +163,41 @@ SUBROUTINE BD_ReadDvrFile(DvrInputFile,dt,InitInputData,DvrData,& CALL ReadCom(UnIn,DvrInputFile,'Comments on DCM',ErrStat2,ErrMsg2,UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) DO i=1,3 - CALL ReadAry(UnIn,DvrInputFile,InitInputData%GlbRot(i,:),3,"InitInputData%GlbPos",& - "Global DCM",ErrStat2,ErrMsg2,UnEc) + CALL ReadAry(UnIn,DvrInputFile,InitInputData%RootOri(i,:),3,"InitInputData%RootOri",& + "Initial root orientation",ErrStat2,ErrMsg2,UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ENDDO + + CALL ReadVar(UnIn,DvrInputFile,DvrData%GlbRotBladeT0,"DvrData%GlbRotBladeT0","Is the blade initial orientation also the GlbRot calculation frame",ErrStat2,ErrMSg2,UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) then call cleanup() return end if + + ! Use the initial blade root orientation as the GlbRot reference orientation for all calculations? + if ( DvrData%GlbRotBladeT0 ) then + + ! Set the GlbRot matrix + InitInputData%GlbRot = InitInputData%RootOri + CALL eye( DvrData%RootRelInit, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + else + + ! Initialize the GlbRot matrix as the identity. Relative rotation for root to GlbRot + DvrData%RootRelInit = InitInputData%RootOri + CALL eye( InitInputData%GlbRot, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + end if + + if (ErrStat >= AbortErrLev) then + call cleanup() + return + end if + !---------------------- INITIAL VELOCITY PARAMETER -------------------------------- CALL ReadCom(UnIn,DvrInputFile,'Section Header: Initial Velocity Parameter',ErrStat2,ErrMsg2,UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -384,9 +414,10 @@ SUBROUTINE Dvr_WriteOutputLine(t,OutUnit, OutFmt, Output) end subroutine Dvr_WriteOutputLine !---------------------------------------------------------------------------------------------------------------------------------- -subroutine CreateMultiPointMeshes(DvrData,BD_InitOutput,BD_Parameter,y, u, ErrStat,ErrMsg) +subroutine CreateMultiPointMeshes(DvrData,BD_InitInput,BD_InitOutput,BD_Parameter,y, u, ErrStat,ErrMsg) TYPE(BD_DriverInternalType), INTENT(INOUT) :: DvrData + TYPE(BD_InitInputType) , INTENT(IN ) :: BD_InitInput TYPE(BD_InitOutputType) , INTENT(IN ) :: BD_InitOutput TYPE(BD_ParameterType) , INTENT(IN ) :: BD_Parameter TYPE(BD_OutputType), INTENT(IN ) :: y @@ -717,7 +748,8 @@ SUBROUTINE BD_InputSolve( t, u, DvrData, ErrStat, ErrMsg) Orientation(2,3) = 0.0_R8Ki Orientation(3,3) = 1.0_R8Ki - DvrData%RotationCenter%Orientation(:,:,1) = matmul(Orientation, DvrData%RotationCenter%RefOrientation(:,:,1)) + DvrData%RotationCenter%Orientation(:,:,1) = matmul(Orientation, matmul(DvrData%RotationCenter%RefOrientation(:,:,1),DvrData%RootRelInit)) + CALL Transfer_Point_to_Point( DvrData%RotationCenter, u%RootMotion, DvrData%Map_RotationCenter_to_RootMotion, ErrStat2, ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) diff --git a/modules-local/beamdyn/src/OutListParameters.xlsx b/modules/beamdyn/src/OutListParameters.xlsx similarity index 100% rename from modules-local/beamdyn/src/OutListParameters.xlsx rename to modules/beamdyn/src/OutListParameters.xlsx diff --git a/modules-local/beamdyn/src/Registry_BeamDyn.txt b/modules/beamdyn/src/Registry_BeamDyn.txt similarity index 100% rename from modules-local/beamdyn/src/Registry_BeamDyn.txt rename to modules/beamdyn/src/Registry_BeamDyn.txt diff --git a/modules-local/beamdyn/tests/test_BD_CheckRotMat.F90 b/modules/beamdyn/tests/test_BD_CheckRotMat.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_CheckRotMat.F90 rename to modules/beamdyn/tests/test_BD_CheckRotMat.F90 diff --git a/modules-local/beamdyn/tests/test_BD_CrvCompose.F90 b/modules/beamdyn/tests/test_BD_CrvCompose.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_CrvCompose.F90 rename to modules/beamdyn/tests/test_BD_CrvCompose.F90 diff --git a/modules-local/beamdyn/tests/test_BD_CrvExtractCrv.F90 b/modules/beamdyn/tests/test_BD_CrvExtractCrv.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_CrvExtractCrv.F90 rename to modules/beamdyn/tests/test_BD_CrvExtractCrv.F90 diff --git a/modules-local/beamdyn/tests/test_BD_CrvMatrixH.F90 b/modules/beamdyn/tests/test_BD_CrvMatrixH.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_CrvMatrixH.F90 rename to modules/beamdyn/tests/test_BD_CrvMatrixH.F90 diff --git a/modules-local/beamdyn/tests/test_BD_CrvMatrixR.F90 b/modules/beamdyn/tests/test_BD_CrvMatrixR.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_CrvMatrixR.F90 rename to modules/beamdyn/tests/test_BD_CrvMatrixR.F90 diff --git a/modules-local/beamdyn/tests/test_BD_DistrLoadCopy.F90 b/modules/beamdyn/tests/test_BD_DistrLoadCopy.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_DistrLoadCopy.F90 rename to modules/beamdyn/tests/test_BD_DistrLoadCopy.F90 diff --git a/modules-local/beamdyn/tests/test_BD_GaussPointWeight.F90 b/modules/beamdyn/tests/test_BD_GaussPointWeight.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_GaussPointWeight.F90 rename to modules/beamdyn/tests/test_BD_GaussPointWeight.F90 diff --git a/modules-local/beamdyn/tests/test_BD_GenerateGLL.F90 b/modules/beamdyn/tests/test_BD_GenerateGLL.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_GenerateGLL.F90 rename to modules/beamdyn/tests/test_BD_GenerateGLL.F90 diff --git a/modules-local/beamdyn/tests/test_BD_GravityForce.F90 b/modules/beamdyn/tests/test_BD_GravityForce.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_GravityForce.F90 rename to modules/beamdyn/tests/test_BD_GravityForce.F90 diff --git a/modules-local/beamdyn/tests/test_BD_InitShpDerJaco.F90 b/modules/beamdyn/tests/test_BD_InitShpDerJaco.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_InitShpDerJaco.F90 rename to modules/beamdyn/tests/test_BD_InitShpDerJaco.F90 diff --git a/modules-local/beamdyn/tests/test_BD_InputGlobalLocal.F90 b/modules/beamdyn/tests/test_BD_InputGlobalLocal.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_InputGlobalLocal.F90 rename to modules/beamdyn/tests/test_BD_InputGlobalLocal.F90 diff --git a/modules-local/beamdyn/tests/test_BD_QPData_mEta_rho.F90 b/modules/beamdyn/tests/test_BD_QPData_mEta_rho.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_BD_QPData_mEta_rho.F90 rename to modules/beamdyn/tests/test_BD_QPData_mEta_rho.F90 diff --git a/modules-local/beamdyn/tests/test_BD_diffmtc.F90 b/modules/beamdyn/tests/test_BD_diffmtc.F90 similarity index 95% rename from modules-local/beamdyn/tests/test_BD_diffmtc.F90 rename to modules/beamdyn/tests/test_BD_diffmtc.F90 index 89edacab4b..7b4bc91889 100644 --- a/modules-local/beamdyn/tests/test_BD_diffmtc.F90 +++ b/modules/beamdyn/tests/test_BD_diffmtc.F90 @@ -63,7 +63,7 @@ subroutine test_BD_diffmtc() call AllocAry(gll_nodes, n, "GLL points array", ErrStat, ErrMsg) gll_nodes = (/ -1.0, 1.0 /) - call BD_diffmtc(parametertype, gll_nodes, test_shape, test_shapederivative) + call BD_diffmtc(parametertype%nodes_per_elem, gll_nodes, parametertype%QPtN, parametertype%nqp, test_shape, test_shapederivative) call AllocAry(baseline_shape, parametertype%nqp, parametertype%nodes_per_elem, "baseline_shape", ErrStat, ErrMsg) call AllocAry(baseline_shapederivative, parametertype%nqp, parametertype%nodes_per_elem, "baseline_shapederivative", ErrStat, ErrMsg) diff --git a/modules-local/beamdyn/tests/test_ExtractRelativeRotation.F90 b/modules/beamdyn/tests/test_ExtractRelativeRotation.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_ExtractRelativeRotation.F90 rename to modules/beamdyn/tests/test_ExtractRelativeRotation.F90 diff --git a/modules-local/beamdyn/tests/test_tools.F90 b/modules/beamdyn/tests/test_tools.F90 similarity index 100% rename from modules-local/beamdyn/tests/test_tools.F90 rename to modules/beamdyn/tests/test_tools.F90 diff --git a/modules-local/elastodyn/CMakeLists.txt b/modules/elastodyn/CMakeLists.txt similarity index 100% rename from modules-local/elastodyn/CMakeLists.txt rename to modules/elastodyn/CMakeLists.txt diff --git a/modules/elastodyn/README.md b/modules/elastodyn/README.md new file mode 100644 index 0000000000..a52f91e435 --- /dev/null +++ b/modules/elastodyn/README.md @@ -0,0 +1,4 @@ +# ElastoDyn Module + +## Overview +ElastoDyn is the structural dynamics module in the OpenFAST framework. diff --git a/modules-local/elastodyn/src/ED_UserSubs.f90 b/modules/elastodyn/src/ED_UserSubs.f90 similarity index 100% rename from modules-local/elastodyn/src/ED_UserSubs.f90 rename to modules/elastodyn/src/ED_UserSubs.f90 diff --git a/modules-local/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 similarity index 99% rename from modules-local/elastodyn/src/ElastoDyn.f90 rename to modules/elastodyn/src/ElastoDyn.f90 index ad3a21b99a..2fd91e734a 100644 --- a/modules-local/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -11699,7 +11699,7 @@ SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, if (.not. EqualRealNos( u%BlPitchCom(1), u%BlPitchCom(k) ) ) then call SetErrStat(ErrID_Info,"Operating point of collective pitch extended input is invalid because "// & "the commanded blade pitch angles are not the same for each blade.", ErrStat, ErrMsg, RoutineName) - return + exit end if end do diff --git a/modules-local/elastodyn/src/ElastoDyn_IO.f90 b/modules/elastodyn/src/ElastoDyn_IO.f90 similarity index 100% rename from modules-local/elastodyn/src/ElastoDyn_IO.f90 rename to modules/elastodyn/src/ElastoDyn_IO.f90 diff --git a/modules-local/elastodyn/src/ElastoDyn_Registry.txt b/modules/elastodyn/src/ElastoDyn_Registry.txt similarity index 100% rename from modules-local/elastodyn/src/ElastoDyn_Registry.txt rename to modules/elastodyn/src/ElastoDyn_Registry.txt diff --git a/modules-local/extptfm/CMakeLists.txt b/modules/extptfm/CMakeLists.txt similarity index 100% rename from modules-local/extptfm/CMakeLists.txt rename to modules/extptfm/CMakeLists.txt diff --git a/modules/extptfm/README.md b/modules/extptfm/README.md new file mode 100644 index 0000000000..a8235e6f1a --- /dev/null +++ b/modules/extptfm/README.md @@ -0,0 +1,4 @@ +# ExtPtfm Module + +## Overview +A module for external platform loading (m, c, k, f) in OpenFAST diff --git a/modules-local/extptfm/src/ExtPtfm_MCKF.f90 b/modules/extptfm/src/ExtPtfm_MCKF.f90 similarity index 100% rename from modules-local/extptfm/src/ExtPtfm_MCKF.f90 rename to modules/extptfm/src/ExtPtfm_MCKF.f90 diff --git a/modules-local/extptfm/src/ExtPtfm_MCKF_Driver.f90 b/modules/extptfm/src/ExtPtfm_MCKF_Driver.f90 similarity index 100% rename from modules-local/extptfm/src/ExtPtfm_MCKF_Driver.f90 rename to modules/extptfm/src/ExtPtfm_MCKF_Driver.f90 diff --git a/modules-local/extptfm/src/ExtPtfm_MCKF_Registry.txt b/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt similarity index 100% rename from modules-local/extptfm/src/ExtPtfm_MCKF_Registry.txt rename to modules/extptfm/src/ExtPtfm_MCKF_Registry.txt diff --git a/modules-ext/feamooring/CMakeLists.txt b/modules/feamooring/CMakeLists.txt similarity index 100% rename from modules-ext/feamooring/CMakeLists.txt rename to modules/feamooring/CMakeLists.txt diff --git a/modules/feamooring/README.md b/modules/feamooring/README.md new file mode 100644 index 0000000000..77b1b0562b --- /dev/null +++ b/modules/feamooring/README.md @@ -0,0 +1,27 @@ +# FEAMooring Module +The legacy version of this module and additional documentation are available +the [NWTC Software Portal](https://nwtc.nrel.gov/FEAMooring/). + +## Overview +A TAMU-led team, in partnership with ABS and NREL, was selected for funding +under topic area 1.3 of DE-FOA-0000415 to develop an open-source +mooring-dynamics module for the analysis of floating offshore wind turbines. +This project led to the development of FEAMooring (or FEAM), a +finite-element-based mooring-dynamics module that has been coupled into +OpenFAST. FEAMooring can also be driven as a standalone code to compute mooring +dynamics uncoupled from OpenFAST. + +FEAMooring calculates the mooring-line reaction forces at the fairlead +positions of the floating platform considering the mooring dynamics, including +inertia and drag forces at each line element. The module can analyze several +kinds of mooring systems, including catenary mooring, taut mooring, vertical +tendons, etc. provided that the proper line geometry and properties are +specified. While powerful, FEAMooring has the following limitations: + +- Only single uniform moorings lines between the fairlead and anchor are + considered; it is not possible to model multi-segmented lines, line + interconnections, or weights/tanks +- Mooring-line bending stiffness is not considered +- Seabed friction is not considered +- Interface does not support coupling to HydroDyn; the added mass, drag, and + buoyancy calculations assume still water diff --git a/modules-ext/feamooring/src/FEAM.f90 b/modules/feamooring/src/FEAM.f90 similarity index 100% rename from modules-ext/feamooring/src/FEAM.f90 rename to modules/feamooring/src/FEAM.f90 diff --git a/modules-ext/feamooring/src/FEAM_Driver.f90 b/modules/feamooring/src/FEAM_Driver.f90 similarity index 100% rename from modules-ext/feamooring/src/FEAM_Driver.f90 rename to modules/feamooring/src/FEAM_Driver.f90 diff --git a/modules-ext/feamooring/src/FEAM_Registry.txt b/modules/feamooring/src/FEAM_Registry.txt similarity index 100% rename from modules-ext/feamooring/src/FEAM_Registry.txt rename to modules/feamooring/src/FEAM_Registry.txt diff --git a/modules-ext/feamooring/test/FE_Mooring.dat b/modules/feamooring/test/FE_Mooring.dat similarity index 100% rename from modules-ext/feamooring/test/FE_Mooring.dat rename to modules/feamooring/test/FE_Mooring.dat diff --git a/modules-ext/feamooring/test/NRELOffshrBsline5MW_ITIBarge4_FEAMooring.dat b/modules/feamooring/test/NRELOffshrBsline5MW_ITIBarge4_FEAMooring.dat similarity index 100% rename from modules-ext/feamooring/test/NRELOffshrBsline5MW_ITIBarge4_FEAMooring.dat rename to modules/feamooring/test/NRELOffshrBsline5MW_ITIBarge4_FEAMooring.dat diff --git a/modules-ext/feamooring/test/NRELOffshrBsline5MW_MIT_NREL_TLP_FEAMooring.dat b/modules/feamooring/test/NRELOffshrBsline5MW_MIT_NREL_TLP_FEAMooring.dat similarity index 100% rename from modules-ext/feamooring/test/NRELOffshrBsline5MW_MIT_NREL_TLP_FEAMooring.dat rename to modules/feamooring/test/NRELOffshrBsline5MW_MIT_NREL_TLP_FEAMooring.dat diff --git a/modules-ext/feamooring/test/NRELOffshrBsline5MW_OC3Hywind_FEAMooring.dat b/modules/feamooring/test/NRELOffshrBsline5MW_OC3Hywind_FEAMooring.dat similarity index 100% rename from modules-ext/feamooring/test/NRELOffshrBsline5MW_OC3Hywind_FEAMooring.dat rename to modules/feamooring/test/NRELOffshrBsline5MW_OC3Hywind_FEAMooring.dat diff --git a/modules-ext/feamooring/test/NRELOffshrBsline5MW_OC4DeepCwindSemi_FEAMooring.dat b/modules/feamooring/test/NRELOffshrBsline5MW_OC4DeepCwindSemi_FEAMooring.dat similarity index 100% rename from modules-ext/feamooring/test/NRELOffshrBsline5MW_OC4DeepCwindSemi_FEAMooring.dat rename to modules/feamooring/test/NRELOffshrBsline5MW_OC4DeepCwindSemi_FEAMooring.dat diff --git a/modules-local/hydrodyn/CMakeLists.txt b/modules/hydrodyn/CMakeLists.txt similarity index 96% rename from modules-local/hydrodyn/CMakeLists.txt rename to modules/hydrodyn/CMakeLists.txt index 72898acb32..203af88232 100644 --- a/modules-local/hydrodyn/CMakeLists.txt +++ b/modules/hydrodyn/CMakeLists.txt @@ -62,7 +62,7 @@ add_library(hydrodynlib ${HYDRODYN_SOURCES}) target_link_libraries(hydrodynlib nwtclibs) add_executable(hydrodyn_driver src/HydroDyn_DriverCode.f90) -target_link_libraries(hydrodyn_driver hydrodynlib nwtclibs) +target_link_libraries(hydrodyn_driver hydrodynlib nwtclibs versioninfolib) #add_executable(ss_radiation # src/SS_Radiation_DriverCode.f90) diff --git a/modules/hydrodyn/README.md b/modules/hydrodyn/README.md new file mode 100644 index 0000000000..4ffa369fad --- /dev/null +++ b/modules/hydrodyn/README.md @@ -0,0 +1,21 @@ +# HydroDyn Module +The legacy version of this module and additional documentation are available +the [NWTC Software Portal](https://nwtc.nrel.gov/HydroDyn/). + +## Overview +HydroDyn is a time-domain hydrodynamics module that has been coupled into the +OpenFAST wind turbine computer-aided engineering (CAE) tool to enable +aero-hydro-servo-elastic simulation of offshore wind turbines. HydroDyn is +applicable to both fixed-bottom and floating offshore substructures. It can +also be driven as a standalone code to compute hydrodynamic loading uncoupled +from OpenFAST. + +HydroDyn allows for multiple approaches for calculating the hydrodynamic loads +on a structure: a potential-flow theory solution, a strip-theory solution, or a +combination of the two. Waves in HydroDyn can be regular (periodic) or +irregular (stochastic) and long-crested (unidirectional) or short-crested (with +wave energy spread across a range of directions). HydroDyn treats waves using +first-order (linear Airy) or first- plus second-order wave theory with the +option to include directional spreading, but no wave stretching or higher order +wave theories are included. To minimize computational expense, Fast Fourier +Transforms are applied in the summation of all wave frequency components. diff --git a/modules-local/hydrodyn/src/Conv_Radiation.f90 b/modules/hydrodyn/src/Conv_Radiation.f90 similarity index 100% rename from modules-local/hydrodyn/src/Conv_Radiation.f90 rename to modules/hydrodyn/src/Conv_Radiation.f90 diff --git a/modules-local/hydrodyn/src/Conv_Radiation.txt b/modules/hydrodyn/src/Conv_Radiation.txt similarity index 100% rename from modules-local/hydrodyn/src/Conv_Radiation.txt rename to modules/hydrodyn/src/Conv_Radiation.txt diff --git a/modules-local/hydrodyn/src/Current.f90 b/modules/hydrodyn/src/Current.f90 similarity index 100% rename from modules-local/hydrodyn/src/Current.f90 rename to modules/hydrodyn/src/Current.f90 diff --git a/modules-local/hydrodyn/src/Current.txt b/modules/hydrodyn/src/Current.txt similarity index 100% rename from modules-local/hydrodyn/src/Current.txt rename to modules/hydrodyn/src/Current.txt diff --git a/modules-local/hydrodyn/src/HydroDyn.f90 b/modules/hydrodyn/src/HydroDyn.f90 similarity index 99% rename from modules-local/hydrodyn/src/HydroDyn.f90 rename to modules/hydrodyn/src/HydroDyn.f90 index 0a92c4f172..748b99024c 100644 --- a/modules-local/hydrodyn/src/HydroDyn.f90 +++ b/modules/hydrodyn/src/HydroDyn.f90 @@ -388,10 +388,10 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I ! Since the Convolution Radiation module is currently the only module which requires knowledge of the time step size, ! we will set Hydrodyn's time step to be that of the Convolution radiation module if it is being used. Otherwise, we ! will set it to be equal to the glue-codes - IF ((Initlocal%PotMod == 1) .AND. (Initlocal%WAMIT%RdtnMod == 1) ) THEN + IF ((Initlocal%PotMod == 1) .AND. (Initlocal%WAMIT%RdtnMod == 1) ) THEN - p%DT = InitLocal%WAMIT%Conv_Rdtn%RdtnDT + p%DT = InitLocal%WAMIT%Conv_Rdtn%RdtnDT #ifdef USE_FIT ELSE IF (Initlocal%PotMod == 2) THEN diff --git a/modules-local/hydrodyn/src/HydroDyn.txt b/modules/hydrodyn/src/HydroDyn.txt similarity index 100% rename from modules-local/hydrodyn/src/HydroDyn.txt rename to modules/hydrodyn/src/HydroDyn.txt diff --git a/modules-local/hydrodyn/src/HydroDyn_DriverCode.f90 b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 similarity index 99% rename from modules-local/hydrodyn/src/HydroDyn_DriverCode.f90 rename to modules/hydrodyn/src/HydroDyn_DriverCode.f90 index fa1af98eb2..bcb8b6e5a7 100644 --- a/modules-local/hydrodyn/src/HydroDyn_DriverCode.f90 +++ b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 @@ -27,6 +27,7 @@ PROGRAM HydroDynDriver USE HydroDyn_Types USE HydroDyn_Output USE ModMesh_Types + USE VersionInfo IMPLICIT NONE @@ -128,6 +129,9 @@ PROGRAM HydroDynDriver CHARACTER(200) :: git_commit ! String containing the current git commit hash TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'HydroDyn Driver', '', '' ) ! The version number of this program. + + ! Variables Init + Time = -99999 !............................................................................................................................... ! Routines called in initialization diff --git a/modules-local/hydrodyn/src/HydroDyn_Input.f90 b/modules/hydrodyn/src/HydroDyn_Input.f90 similarity index 99% rename from modules-local/hydrodyn/src/HydroDyn_Input.f90 rename to modules/hydrodyn/src/HydroDyn_Input.f90 index a5dc8de8d5..556c851e85 100644 --- a/modules-local/hydrodyn/src/HydroDyn_Input.f90 +++ b/modules/hydrodyn/src/HydroDyn_Input.f90 @@ -984,7 +984,7 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) ! SumQTF -- Full Sum-Frequency forces computed with full QTFs from WAMIT file: {0: No Sum-frequency forces, [10, 11, or 12]: WAMIT file to use} - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%SumQTF, 'DiffQTF', 'Full Sum-Frequency forces computed with full QTFs from WAMIT file: {0: No Sum-frequency forces, [10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%SumQTF, 'SumQTF', 'Full Sum-Frequency forces computed with full QTFs from WAMIT file: {0: No Sum-frequency forces, [10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN @@ -2630,7 +2630,6 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) InitInp%Waves%WaveMultiDir = .TRUE. ELSEIF ( (InitInp%Waves%WaveMod < 2 .OR. InitInp%Waves%WaveMod >4) .AND. InitInp%Waves%WaveDirMod == 1 ) THEN CALL SetErrStat( ErrID_Warn,'WaveDirMod unused unless WaveMod == 2, 3, or 4. Ignoring WaveDirMod.',ErrStat,ErrMsg,RoutineName) - InitInp%Waves%WaveMod = 0 ENDIF diff --git a/modules-local/hydrodyn/src/HydroDyn_Output.f90 b/modules/hydrodyn/src/HydroDyn_Output.f90 similarity index 100% rename from modules-local/hydrodyn/src/HydroDyn_Output.f90 rename to modules/hydrodyn/src/HydroDyn_Output.f90 diff --git a/modules-local/hydrodyn/src/Morison.f90 b/modules/hydrodyn/src/Morison.f90 similarity index 98% rename from modules-local/hydrodyn/src/Morison.f90 rename to modules/hydrodyn/src/Morison.f90 index 36de146cd5..18d0c9a53f 100644 --- a/modules-local/hydrodyn/src/Morison.f90 +++ b/modules/hydrodyn/src/Morison.f90 @@ -1194,23 +1194,27 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen ! Attach the external distributed buoyancy loads to the distributed mesh so they can be transferred to the WRP - + + ! Because of wave stretching and user-supplied waves, we may have loads above the still water line (SWL) which will be used + ! in the hydrodynamics for conditions where the wave height is > SWL. So we now need to check that the vertical position + ! is <= SWL for this summary file calculation. + DO J = 1, outDistribMesh%Nnodes - - DO I=1,6 + if ( outDistribMesh%Position(3,J) <= MSL2SWL ) then + DO I=1,6 - IF (I < 4 ) THEN + IF (I < 4 ) THEN - outDistribMesh%Force(I ,J) = D_F_B(I,J) + outDistribMesh%Force(I ,J) = D_F_B(I,J) - ELSE + ELSE - outDistribMesh%Moment(I-3,J) = D_F_B(I,J) + outDistribMesh%Moment(I-3,J) = D_F_B(I,J) - END IF + END IF - END DO ! DO I - + END DO ! DO I + end if ! <= MSL2SWL check END DO ! DO J @@ -1226,23 +1230,27 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen ! Transfer the loads from the lumped mesh to the (0,0,0) point mesh - + + ! Because of wave stretching and user-supplied waves, we may have loads above the still water line (SWL) which will be used + ! in the hydrodynamics for conditions where the wave height is > SWL. So we now need to check that the vertical position + ! is <= SWL for this summary file calculation. + DO J = 1, outLumpedMesh%Nnodes - - DO I=1,6 + if ( outLumpedMesh%Position(3,J) <= MSL2SWL ) then + DO I=1,6 - IF (I < 4 ) THEN + IF (I < 4 ) THEN - outLumpedMesh%Force(I ,J) = L_F_B(I,J) + outLumpedMesh%Force(I ,J) = L_F_B(I,J) - ELSE + ELSE - outLumpedMesh%Moment(I-3,J) = L_F_B(I,J) + outLumpedMesh%Moment(I-3,J) = L_F_B(I,J) - END IF + END IF - END DO ! DO I - + END DO ! DO I + end if ! <= MSL2SWL check END DO ! DO J ! Remap for the lumped to WRP mesh transfer @@ -1272,9 +1280,9 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen DO I=1,6 - IF (I < 4 ) THEN + IF (I < 4 ) THEN - outDistribMesh%Force(I,J ) = D_F_BF(I,J) + outDistribMesh%Force(I,J ) = D_F_BF(I,J) ELSE @@ -1296,9 +1304,9 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen DO I=1,6 - IF (I < 4 ) THEN + IF (I < 4 ) THEN - outLumpedMesh%Force(I,J) = L_F_BF(I,J) + outLumpedMesh%Force(I,J) = L_F_BF(I,J) ELSE @@ -3769,7 +3777,7 @@ SUBROUTINE Morison_ProcessMorisonGeometry( InitInp, ErrStat, ErrMsg ) ! Local variables - INTEGER :: I !, J, j1, j2, tempINT ! generic integer for counting + INTEGER :: I , J! j1, j2, tempINT ! generic integer for counting ! TYPE(Morison_JointType) :: joint1, joint2 ! Real(ReKi) :: z1 ! Real(ReKi) :: z2 @@ -3894,7 +3902,22 @@ SUBROUTINE Morison_ProcessMorisonGeometry( InitInp, ErrStat, ErrMsg ) prop2Indx = temp InitInp%Elements(I)%InpMbrDist1 = 1.0 InitInp%Elements(I)%InpMbrDist2 = 0.0 - + ! --- Swap member coeffs if needed. + ! Fine in this loop since there is a unique CoefMember per Member (otherwise we could swap them several times). + J = InitInp%InpMembers(I)%MmbrCoefIDIndx ! Index in CoefMembers table + IF (J>0) THEN + ! NOTE: SWAP defined at the end of the current subroutine + CALL SWAP(InitInp%CoefMembers(J)%MemberCd1 , InitInp%CoefMembers(J)%MemberCd2) + CALL SWAP(InitInp%CoefMembers(J)%MemberCa1 , InitInp%CoefMembers(J)%MemberCa2) + CALL SWAP(InitInp%CoefMembers(J)%MemberCp1 , InitInp%CoefMembers(J)%MemberCp2) + CALL SWAP(InitInp%CoefMembers(J)%MemberAxCa1 , InitInp%CoefMembers(J)%MemberAxCa2) + CALL SWAP(InitInp%CoefMembers(J)%MemberAxCp1 , InitInp%CoefMembers(J)%MemberAxCp2) + CALL SWAP(InitInp%CoefMembers(J)%MemberCdMG1 , InitInp%CoefMembers(J)%MemberCdMG2) + CALL SWAP(InitInp%CoefMembers(J)%MemberCaMG1 , InitInp%CoefMembers(J)%MemberCaMG2) + CALL SWAP(InitInp%CoefMembers(J)%MemberCpMG1 , InitInp%CoefMembers(J)%MemberCpMG2) + CALL SWAP(InitInp%CoefMembers(J)%MemberAxCaMG1, InitInp%CoefMembers(J)%MemberAxCaMG2) + CALL SWAP(InitInp%CoefMembers(J)%MemberAxCpMG1, InitInp%CoefMembers(J)%MemberAxCpMG2) + END IF END IF propSet = InitInp%MPropSets(prop1Indx) @@ -4019,7 +4042,14 @@ SUBROUTINE Morison_ProcessMorisonGeometry( InitInp, ErrStat, ErrMsg ) ! p%NMorisonElements = 0 END IF - + CONTAINS + SUBROUTINE SWAP(x1,x2) + Real(Reki),intent(inout) :: x1,x2 + Real(Reki) :: tmp + tmp = x1 + x1 = x2 + x2 = tmp + END SUBROUTINE SWAP END SUBROUTINE Morison_ProcessMorisonGeometry !---------------------------------------------------------------------------------------------------------------------------------- @@ -4550,7 +4580,8 @@ SUBROUTINE Morison_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, qdotdot2(1) = elementWaterState *u%DistribMesh%TranslationAcc(1,J) qdotdot2(2) = elementWaterState *u%DistribMesh%TranslationAcc(2,J) qdotdot2(3) = elementWaterState *u%DistribMesh%TranslationAcc(3,J) - m%D_F_AM_M(:,J) = -matmul( p%D_AM_M (:,:,J) , qdotdot2 ) !bjj: these lines take up a lot of time. are the matrices sparse? + ! calculated the added mass forces (moments are zero) + m%D_F_AM_M(1:3,J) = -matmul( p%D_AM_M (:,:,J) , qdotdot2 ) !bjj: these lines take up a lot of time. are the matrices sparse? DO I=1,6 IF (I < 4 ) THEN diff --git a/modules-local/hydrodyn/src/Morison.txt b/modules/hydrodyn/src/Morison.txt similarity index 100% rename from modules-local/hydrodyn/src/Morison.txt rename to modules/hydrodyn/src/Morison.txt diff --git a/modules-local/hydrodyn/src/Morison_Output.f90 b/modules/hydrodyn/src/Morison_Output.f90 similarity index 100% rename from modules-local/hydrodyn/src/Morison_Output.f90 rename to modules/hydrodyn/src/Morison_Output.f90 diff --git a/modules-local/hydrodyn/src/SS_Excitation.f90 b/modules/hydrodyn/src/SS_Excitation.f90 similarity index 100% rename from modules-local/hydrodyn/src/SS_Excitation.f90 rename to modules/hydrodyn/src/SS_Excitation.f90 diff --git a/modules-local/hydrodyn/src/SS_Excitation.txt b/modules/hydrodyn/src/SS_Excitation.txt similarity index 100% rename from modules-local/hydrodyn/src/SS_Excitation.txt rename to modules/hydrodyn/src/SS_Excitation.txt diff --git a/modules-local/hydrodyn/src/SS_Excitation_Driver.f90 b/modules/hydrodyn/src/SS_Excitation_Driver.f90 similarity index 100% rename from modules-local/hydrodyn/src/SS_Excitation_Driver.f90 rename to modules/hydrodyn/src/SS_Excitation_Driver.f90 diff --git a/modules-local/hydrodyn/src/SS_Radiation.f90 b/modules/hydrodyn/src/SS_Radiation.f90 similarity index 100% rename from modules-local/hydrodyn/src/SS_Radiation.f90 rename to modules/hydrodyn/src/SS_Radiation.f90 diff --git a/modules-local/hydrodyn/src/SS_Radiation.txt b/modules/hydrodyn/src/SS_Radiation.txt similarity index 100% rename from modules-local/hydrodyn/src/SS_Radiation.txt rename to modules/hydrodyn/src/SS_Radiation.txt diff --git a/modules-local/hydrodyn/src/SS_Radiation_DriverCode.f90 b/modules/hydrodyn/src/SS_Radiation_DriverCode.f90 similarity index 100% rename from modules-local/hydrodyn/src/SS_Radiation_DriverCode.f90 rename to modules/hydrodyn/src/SS_Radiation_DriverCode.f90 diff --git a/modules-local/hydrodyn/src/UserWaves.f90 b/modules/hydrodyn/src/UserWaves.f90 similarity index 93% rename from modules-local/hydrodyn/src/UserWaves.f90 rename to modules/hydrodyn/src/UserWaves.f90 index f25d1bdbe6..495fb3fe28 100644 --- a/modules-local/hydrodyn/src/UserWaves.f90 +++ b/modules/hydrodyn/src/UserWaves.f90 @@ -756,9 +756,9 @@ SUBROUTINE UserWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) RETURN END IF - Frmt = '('//TRIM(Int2LStr(InitInp%NWaveKin))//'(:,A,A11))' - - + + + ! Read the first file and set the initial values of the CALL GetNewUnit( UnWv ) @@ -782,9 +782,11 @@ SUBROUTINE UserWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) END IF DO i = 0,InitOut%NStepWave-1 - CALL ReadCAry ( UnWv, FileName, WaveDataStr(i,:), InitInp%NWaveKin, 'junk', 'junk', ErrStatTmp, ErrMsgTmp ) - !Read(UnWv,Frmt) ( Delim, WaveDataStr(i,j) , j=1,InitInp%NWaveKin ) - + ! Extract fields from current line + IF (.not. ExtractFields(UnWv, WaveDataStr(i,:), InitInp%NWaveKin)) THEN + call Cleanup() + RETURN + END IF DO j = 1, InitInp%NWaveKin isNumeric = is_numeric(WaveDataStr(i,j), WaveData(i,j)) @@ -826,14 +828,12 @@ SUBROUTINE UserWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) END IF DO i = 0,InitOut%NStepWave-1 - - !Read(UnWv,Frmt) ( Delim, WaveDataStr(i,j) , j=1,InitInp%NWaveKin ) - CALL ReadCAry ( UnWv, FileName, WaveDataStr(i,:), InitInp%NWaveKin, 'junk', 'junk', ErrStatTmp, ErrMsgTmp ) - !CALL ReadAry ( UnF, FileName, WaveDataStr(i,:), InitInp%NWaveKin, 'WaveData', & - ! 'Wave kinematics data for one time step', ErrStatTmp, ErrMsgTmp ) + ! Extract fields from current line + IF (.not. ExtractFields(UnWv, WaveDataStr(i,:), InitInp%NWaveKin)) THEN + call Cleanup() + RETURN + END IF DO j = 1, InitInp%NWaveKin - !CALL ReadVar ( UnF, FileName, WaveData(i,j), 'WaveData', & - ! 'Wave kinematics data for one time step', ErrStatTmp, ErrMsgTmp ) isNumeric = is_numeric(WaveDataStr(i,j), WaveData(i,j)) IF ( ( isNumeric .AND. (InitOut%nodeInWater(i,j) == 0) ) .OR. ( .NOT. isNumeric .AND. ( InitOut%nodeInWater(i,j) == 1 ) ) ) THEN ErrStatTmp = ErrID_Fatal @@ -849,12 +849,6 @@ SUBROUTINE UserWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) ELSE InitOut%nodeInWater(i,j) = 1 END IF - - !CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) - !IF (ErrStat >= AbortErrLev) THEN - ! CALL CleanUp() - ! RETURN - !END IF END DO END DO @@ -919,8 +913,62 @@ SUBROUTINE UserWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) InitOut%WaveElev(InitOut%NStepWave,:) = InitOut%WaveElev(0,:) InitOut%nodeInWater(InitOut%NStepWave,:) = InitOut%nodeInWater(0,:) + + + ! For creating animations of the sea surface, the WaveElevXY array is passed in with a series of x,y coordinates + ! (index 1). The second index corresponds to the number of points passed in. A two dimensional time series + ! is created with the first index corresponding to the timestep, and second index corresponding to the second + ! index of the WaveElevXY array. + IF ( ALLOCATED(InitInp%WaveElevXY)) THEN + ALLOCATE ( InitOut%WaveElevSeries (0:InitOut%NStepWave, 1:SIZE(InitInp%WaveElevXY, DIM=2)) , STAT=ErrStatTmp ) + IF (ErrStatTmp /= 0) THEN + CALL SetErrStat(ErrID_Fatal,'Cannot allocate array InitOut%WaveElevSeries.',ErrStat,ErrMsg,'VariousWaves_Init') + RETURN + END IF + ! Calculate the wave elevation at all points requested in the array WaveElevXY + DO I = 0,InitOut%NStepWave + DO J = 1,SIZE(InitInp%WaveElevXY, DIM=2) + InitOut%WaveElevSeries(I,J) = 0.0_ReKi ! TODO, these values should be interpolated based on inputs + ENDDO + ENDDO + ENDIF + CONTAINS + + !> Sub function to extract n fields on the current line of the file unit FU + FUNCTION ExtractFields(FU, s, n) result(OK) + ! Arguments + INTEGER, INTENT(IN) :: FU !< Unit name + INTEGER, INTENT(IN) :: n !< Number of fields + CHARACTER(*), INTENT(OUT) :: s(n) !< Fields + LOGICAL :: OK + ! Local var + CHARACTER(2048) :: TextLine !< One line of text read from the file + OK=.TRUE. + + ! Read line + READ(FU, FMT='(A)', IOSTAT=ErrStat) TextLine + IF (ErrStat/=0) THEN + ErrStat = ErrID_Fatal + WRITE(ErrMsg,'(A,I0,A,I0,A)') 'Failed to read line ',I+2,' (out of ',InitOut%NStepWave+1,' expected lines) in file '//TRIM(FileName)//& + & '. Check that the number of lines (without header) is equal to WaveTMax/WaveDT. ' + OK=.FALSE. + RETURN + END IF + + ! Extract fields (ReadCAryFromStr is in NWTC_IO) + CALL ReadCAryFromStr ( TextLine, s, n, 'line', 'junk', ErrStat, ErrMsgTmp ) + IF (ErrStat/=0) THEN + ErrStat = ErrID_Fatal + write(ErrMsg,'(A,I0,A,I0,A)') 'Failed to extract fields from line ',I+2,' in file '//TRIM(FileName)//'. '//& + & trim(ErrMsgTmp)//' Check that the number of columns is correct and matches the number of internal HydroDyn nodes.'//& + &' (Typically twice the number of joints).' + OK=.FALSE. + RETURN + END IF + END FUNCTION ExtractFields + SUBROUTINE CleanUp( ) IF (ALLOCATED( WaveDataStr )) DEALLOCATE( WaveDataStr, STAT=ErrStatTmp) diff --git a/modules-local/hydrodyn/src/WAMIT.f90 b/modules/hydrodyn/src/WAMIT.f90 similarity index 100% rename from modules-local/hydrodyn/src/WAMIT.f90 rename to modules/hydrodyn/src/WAMIT.f90 diff --git a/modules-local/hydrodyn/src/WAMIT.txt b/modules/hydrodyn/src/WAMIT.txt similarity index 100% rename from modules-local/hydrodyn/src/WAMIT.txt rename to modules/hydrodyn/src/WAMIT.txt diff --git a/modules-local/hydrodyn/src/WAMIT2.f90 b/modules/hydrodyn/src/WAMIT2.f90 similarity index 100% rename from modules-local/hydrodyn/src/WAMIT2.f90 rename to modules/hydrodyn/src/WAMIT2.f90 diff --git a/modules-local/hydrodyn/src/WAMIT2.txt b/modules/hydrodyn/src/WAMIT2.txt similarity index 100% rename from modules-local/hydrodyn/src/WAMIT2.txt rename to modules/hydrodyn/src/WAMIT2.txt diff --git a/modules-local/hydrodyn/src/WAMIT2_Output.f90 b/modules/hydrodyn/src/WAMIT2_Output.f90 similarity index 100% rename from modules-local/hydrodyn/src/WAMIT2_Output.f90 rename to modules/hydrodyn/src/WAMIT2_Output.f90 diff --git a/modules-local/hydrodyn/src/WAMIT_Interp.f90 b/modules/hydrodyn/src/WAMIT_Interp.f90 similarity index 100% rename from modules-local/hydrodyn/src/WAMIT_Interp.f90 rename to modules/hydrodyn/src/WAMIT_Interp.f90 diff --git a/modules-local/hydrodyn/src/WAMIT_Output.f90 b/modules/hydrodyn/src/WAMIT_Output.f90 similarity index 100% rename from modules-local/hydrodyn/src/WAMIT_Output.f90 rename to modules/hydrodyn/src/WAMIT_Output.f90 diff --git a/modules-local/hydrodyn/src/Waves.f90 b/modules/hydrodyn/src/Waves.f90 similarity index 98% rename from modules-local/hydrodyn/src/Waves.f90 rename to modules/hydrodyn/src/Waves.f90 index 3eaa9d7cb7..44f90bbd01 100644 --- a/modules-local/hydrodyn/src/Waves.f90 +++ b/modules/hydrodyn/src/Waves.f90 @@ -564,11 +564,9 @@ SUBROUTINE StillWaterWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) TYPE(Waves_InitOutputType), INTENT(INOUT) :: InitOut ! Initialization output data INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - ! Local Variables - INTEGER :: J ! Generic index - INTEGER(IntKi) :: ErrStatTmp ! Temporary error status + ! Local Variables + INTEGER :: I, J ! Generic index + INTEGER(IntKi) :: ErrStatTmp ! Temporary error status ! Initialize ErrStat @@ -632,6 +630,24 @@ SUBROUTINE StillWaterWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) InitOut%WaveAcc = 0.0 InitOut%WaveDirArr = 0.0 + ! For creating animations of the sea surface, the WaveElevXY array is passed in with a series of x,y coordinates + ! (index 1). The second index corresponds to the number of points passed in. A two dimensional time series + ! is created with the first index corresponding to the timestep, and second index corresponding to the second + ! index of the WaveElevXY array. + IF ( ALLOCATED(InitInp%WaveElevXY)) THEN + ALLOCATE ( InitOut%WaveElevSeries (0:InitOut%NStepWave, 1:SIZE(InitInp%WaveElevXY, DIM=2)) , STAT=ErrStatTmp ) + IF (ErrStatTmp /= 0) THEN + CALL SetErrStat(ErrID_Fatal,'Cannot allocate array InitOut%WaveElevSeries.',ErrStat,ErrMsg,'VariousWaves_Init') + RETURN + END IF + ! Calculate the wave elevation at all points requested in the array WaveElevXY + DO I = 0,InitOut%NStepWave + DO J = 1,SIZE(InitInp%WaveElevXY, DIM=2) + InitOut%WaveElevSeries(I,J) = 0.0_ReKi + ENDDO + ENDDO + ENDIF + ! Add the current velocities to the wave velocities: @@ -1173,18 +1189,6 @@ SUBROUTINE VariousWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) END IF - ! For creating animations of the sea surface, the WaveElevXY array is passed in with a series of x,y coordinates - ! (index 1). The second index corresponds to the number of points passed in. A two dimensional time series - ! is created with the first index corresponding to the timestep, and second index corresponding to the second - ! index of the WaveElevXY array. - IF ( ALLOCATED(InitInp%WaveElevXY)) THEN - ALLOCATE ( InitOut%WaveElevSeries (0:InitOut%NStepWave, 1:SIZE(InitInp%WaveElevXY, DIM=2)) , STAT=ErrStatTmp ) - IF (ErrStatTmp /= 0) THEN - CALL SetErrStat(ErrID_Fatal,'Cannot allocate array InitOut%WaveElevSeries.',ErrStat,ErrMsg,'VariousWaves_Init') - CALL CleanUp() - RETURN - END IF - ENDIF ! We now need to establish the nodeInWater flag values for all the simulation node for all timesteps, this is an extension which is needed to ! support user input wave data. TODO: THIS ASSUMES NO WAVE STRETCHING!!!!!!!! GJH 18 Mar 2015 @@ -1643,6 +1647,10 @@ SUBROUTINE VariousWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) ENDDO ENDDO + ! Filling last value since it is not reached by the loop above + CALL RANDOM_NUMBER(WvSpreadThetaIdx) + LastInd = MINLOC( WvSpreadThetaIdx, DIM=1 ) + InitOut%WaveDirArr(K) = WvTheta( LastInd ) ! Perform a quick sanity check. We should have assigned all wave frequencies a direction, so K should be ! K = NStepWave2 (K is incrimented afterwards). @@ -1784,8 +1792,18 @@ SUBROUTINE VariousWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) END DO ! J - All points where the incident wave elevations can be output - ! Calculate the wave elevation at all points requested in the array WaveElevXY - IF ( ALLOCATED(InitInp%WaveElevXY) ) THEN + ! For creating animations of the sea surface, the WaveElevXY array is passed in with a series of x,y coordinates + ! (index 1). The second index corresponds to the number of points passed in. A two dimensional time series + ! is created with the first index corresponding to the timestep, and second index corresponding to the second + ! index of the WaveElevXY array. + IF ( ALLOCATED(InitInp%WaveElevXY)) THEN + ALLOCATE ( InitOut%WaveElevSeries (0:InitOut%NStepWave, 1:SIZE(InitInp%WaveElevXY, DIM=2)) , STAT=ErrStatTmp ) + IF (ErrStatTmp /= 0) THEN + CALL SetErrStat(ErrID_Fatal,'Cannot allocate array InitOut%WaveElevSeries.',ErrStat,ErrMsg,'VariousWaves_Init') + CALL CleanUp() + RETURN + END IF + ! Calculate the wave elevation at all points requested in the array WaveElevXY DO J = 1,SIZE(InitInp%WaveElevXY, DIM=2) ! This subroutine call applies the FFT at the correct location. CALL WaveElevTimeSeriesAtXY( InitInp%WaveElevXY(1,J), InitInp%WaveElevXY(2,J), InitOut%WaveElevSeries(0:InitOut%NStepWave,J), ErrStatTmp, ErrMsgTmp ) diff --git a/modules-local/hydrodyn/src/Waves.txt b/modules/hydrodyn/src/Waves.txt similarity index 100% rename from modules-local/hydrodyn/src/Waves.txt rename to modules/hydrodyn/src/Waves.txt diff --git a/modules-local/hydrodyn/src/Waves2.f90 b/modules/hydrodyn/src/Waves2.f90 similarity index 100% rename from modules-local/hydrodyn/src/Waves2.f90 rename to modules/hydrodyn/src/Waves2.f90 diff --git a/modules-local/hydrodyn/src/Waves2.txt b/modules/hydrodyn/src/Waves2.txt similarity index 100% rename from modules-local/hydrodyn/src/Waves2.txt rename to modules/hydrodyn/src/Waves2.txt diff --git a/modules-local/hydrodyn/src/Waves2_Output.f90 b/modules/hydrodyn/src/Waves2_Output.f90 similarity index 100% rename from modules-local/hydrodyn/src/Waves2_Output.f90 rename to modules/hydrodyn/src/Waves2_Output.f90 diff --git a/modules-ext/icedyn/CMakeLists.txt b/modules/icedyn/CMakeLists.txt similarity index 100% rename from modules-ext/icedyn/CMakeLists.txt rename to modules/icedyn/CMakeLists.txt diff --git a/modules/icedyn/README.md b/modules/icedyn/README.md new file mode 100644 index 0000000000..2b02a574ef --- /dev/null +++ b/modules/icedyn/README.md @@ -0,0 +1,23 @@ +# IceDyn Module +The legacy version of this module and additional documentation are available +the [NWTC Software Portal](https://nwtc.nrel.gov/IceDyn/). + +## Overview +The U.S. Department of Energy (DOE) awarded the University of Michigan a +project to create a model for interaction of bottom-fixed offshore wind +turbines with surface ice for use with common simulation tools. The IceDyn +module, which conforms to the standards of the FAST Modularization Framework, +was created from this project. + +The IceDyn module includes 6 ice mechanics models that incorporate ice floe +forcing, deformation and failure and structure geometry. The six models are +- quasi-static ice loading on vertical structure +- dynamic ice loading on vertical structure +- random ice loading on vertical structure +- non-simultaneous ice loading on vertical structure +- ice loading on sloping structure +- large ice floe impact + +## Manual +IceDyn documentation is available +[here](http://wind.nrel.gov/nwtc/docs/IceDyn_Manual.pdf). diff --git a/modules-ext/icedyn/src/Driver_IceDyn.f90 b/modules/icedyn/src/Driver_IceDyn.f90 similarity index 100% rename from modules-ext/icedyn/src/Driver_IceDyn.f90 rename to modules/icedyn/src/Driver_IceDyn.f90 diff --git a/modules-ext/icedyn/src/IceDyn.f90 b/modules/icedyn/src/IceDyn.f90 similarity index 100% rename from modules-ext/icedyn/src/IceDyn.f90 rename to modules/icedyn/src/IceDyn.f90 diff --git a/modules-ext/icedyn/src/Registry_IceDyn.txt b/modules/icedyn/src/Registry_IceDyn.txt similarity index 100% rename from modules-ext/icedyn/src/Registry_IceDyn.txt rename to modules/icedyn/src/Registry_IceDyn.txt diff --git a/modules-ext/icefloe/CMakeLists.txt b/modules/icefloe/CMakeLists.txt similarity index 100% rename from modules-ext/icefloe/CMakeLists.txt rename to modules/icefloe/CMakeLists.txt diff --git a/modules/icefloe/README.md b/modules/icefloe/README.md new file mode 100644 index 0000000000..ca65c3f583 --- /dev/null +++ b/modules/icefloe/README.md @@ -0,0 +1,31 @@ +# IceFloe Module +The legacy version of this module and additional documentation are available +the [NWTC Software Portal](https://nwtc.nrel.gov/IceFloe/). + +## Overview +The U.S. Department of Energy (DOE) awarded DNV GL a project to create a model +for interaction of bottom-fixed offshore wind turbines with surface ice for use +with common simulation tools. The IceFloe module, which conforms to the +standards of the FAST Modularization Framework, was created from this project. + +The IceFloe module includes the option to apply loads from several models +(listed in table below) to a monopole structure or a multi-leg structure of +either three or four legs of the same diameter. For multi-leg support +structures, the ice loads are calculated independently for each leg; however +factors based on sheltering of one leg by another are also used, which can be +automatically applied or user specified. The project's final technical report +provides more details. + +| Ice Load Model in IceFloe | Source | +| ----------------------------- | ---------------------- | +| Continuous random crushing | ISO 19906, Karna | +| Intermittent crushing per ISO | ISO 19906 | +| Lock-in crushing per ISO | ISO 19906 | +| Lock-in crushing per IEC | IEC 61400-3, Korzhavin | +| Coupled crushing | Määtänen | +| Flexural failure per ISO | ISO 19906, Croasdale | +| Flexural failure per IEC | IEC 61400-3, Ralston | + +## Manual +IceFloe documentation is available +[here](https://nwtc.nrel.gov/system/files/DDRP0133-IceLoadFinalReport2014_10_30.pdf). diff --git a/modules-ext/icefloe/src/icefloe/IceFlexBase.F90 b/modules/icefloe/src/icefloe/IceFlexBase.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/IceFlexBase.F90 rename to modules/icefloe/src/icefloe/IceFlexBase.F90 diff --git a/modules-ext/icefloe/src/icefloe/IceFlexIEC.f90 b/modules/icefloe/src/icefloe/IceFlexIEC.f90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/IceFlexIEC.f90 rename to modules/icefloe/src/icefloe/IceFlexIEC.f90 diff --git a/modules-ext/icefloe/src/icefloe/IceFlexISO.f90 b/modules/icefloe/src/icefloe/IceFlexISO.f90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/IceFlexISO.f90 rename to modules/icefloe/src/icefloe/IceFlexISO.f90 diff --git a/modules-ext/icefloe/src/icefloe/IceFloeBase.F90 b/modules/icefloe/src/icefloe/IceFloeBase.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/IceFloeBase.F90 rename to modules/icefloe/src/icefloe/IceFloeBase.F90 diff --git a/modules-ext/icefloe/src/icefloe/IceFloe_Types_notFAST.f90 b/modules/icefloe/src/icefloe/IceFloe_Types_notFAST.f90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/IceFloe_Types_notFAST.f90 rename to modules/icefloe/src/icefloe/IceFloe_Types_notFAST.f90 diff --git a/modules-ext/icefloe/src/icefloe/coupledCrushing.F90 b/modules/icefloe/src/icefloe/coupledCrushing.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/coupledCrushing.F90 rename to modules/icefloe/src/icefloe/coupledCrushing.F90 diff --git a/modules-ext/icefloe/src/icefloe/crushingIEC.F90 b/modules/icefloe/src/icefloe/crushingIEC.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/crushingIEC.F90 rename to modules/icefloe/src/icefloe/crushingIEC.F90 diff --git a/modules-ext/icefloe/src/icefloe/crushingISO.F90 b/modules/icefloe/src/icefloe/crushingISO.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/crushingISO.F90 rename to modules/icefloe/src/icefloe/crushingISO.F90 diff --git a/modules-ext/icefloe/src/icefloe/iceInput.f90 b/modules/icefloe/src/icefloe/iceInput.f90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/iceInput.f90 rename to modules/icefloe/src/icefloe/iceInput.f90 diff --git a/modules-ext/icefloe/src/icefloe/iceLog.F90 b/modules/icefloe/src/icefloe/iceLog.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/iceLog.F90 rename to modules/icefloe/src/icefloe/iceLog.F90 diff --git a/modules-ext/icefloe/src/icefloe/intermittentCrushing.F90 b/modules/icefloe/src/icefloe/intermittentCrushing.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/intermittentCrushing.F90 rename to modules/icefloe/src/icefloe/intermittentCrushing.F90 diff --git a/modules-ext/icefloe/src/icefloe/lockInISO.F90 b/modules/icefloe/src/icefloe/lockInISO.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/lockInISO.F90 rename to modules/icefloe/src/icefloe/lockInISO.F90 diff --git a/modules-ext/icefloe/src/icefloe/randomCrushing.F90 b/modules/icefloe/src/icefloe/randomCrushing.F90 similarity index 100% rename from modules-ext/icefloe/src/icefloe/randomCrushing.F90 rename to modules/icefloe/src/icefloe/randomCrushing.F90 diff --git a/modules-ext/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 b/modules/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 rename to modules/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 diff --git a/modules-ext/icefloe/src/interfaces/Bladed/IceFloeBladed.f90 b/modules/icefloe/src/interfaces/Bladed/IceFloeBladed.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/Bladed/IceFloeBladed.f90 rename to modules/icefloe/src/interfaces/Bladed/IceFloeBladed.f90 diff --git a/modules-ext/icefloe/src/interfaces/Console/IceFloe.f90 b/modules/icefloe/src/interfaces/Console/IceFloe.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/Console/IceFloe.f90 rename to modules/icefloe/src/interfaces/Console/IceFloe.f90 diff --git a/modules-ext/icefloe/src/interfaces/Console/NWTC_Base_reduced.f90 b/modules/icefloe/src/interfaces/Console/NWTC_Base_reduced.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/Console/NWTC_Base_reduced.f90 rename to modules/icefloe/src/interfaces/Console/NWTC_Base_reduced.f90 diff --git a/modules-ext/icefloe/src/interfaces/Console/SysIVF_reduced.f90 b/modules/icefloe/src/interfaces/Console/SysIVF_reduced.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/Console/SysIVF_reduced.f90 rename to modules/icefloe/src/interfaces/Console/SysIVF_reduced.f90 diff --git a/modules-ext/icefloe/src/interfaces/FAST/IceFloe.f90 b/modules/icefloe/src/interfaces/FAST/IceFloe.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/FAST/IceFloe.f90 rename to modules/icefloe/src/interfaces/FAST/IceFloe.f90 diff --git a/modules-ext/icefloe/src/interfaces/FAST/IceFloe_FASTRegistry.inp b/modules/icefloe/src/interfaces/FAST/IceFloe_FASTRegistry.inp similarity index 100% rename from modules-ext/icefloe/src/interfaces/FAST/IceFloe_FASTRegistry.inp rename to modules/icefloe/src/interfaces/FAST/IceFloe_FASTRegistry.inp diff --git a/modules-ext/icefloe/src/interfaces/HAWC2/HAWC2_DLL.f90 b/modules/icefloe/src/interfaces/HAWC2/HAWC2_DLL.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/HAWC2/HAWC2_DLL.f90 rename to modules/icefloe/src/interfaces/HAWC2/HAWC2_DLL.f90 diff --git a/modules-ext/icefloe/src/interfaces/HAWC2/NWTC_IO_reduced.f90 b/modules/icefloe/src/interfaces/HAWC2/NWTC_IO_reduced.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/HAWC2/NWTC_IO_reduced.f90 rename to modules/icefloe/src/interfaces/HAWC2/NWTC_IO_reduced.f90 diff --git a/modules-ext/icefloe/src/interfaces/IceFloe_Test.f90 b/modules/icefloe/src/interfaces/IceFloe_Test.f90 similarity index 100% rename from modules-ext/icefloe/src/interfaces/IceFloe_Test.f90 rename to modules/icefloe/src/interfaces/IceFloe_Test.f90 diff --git a/modules-ext/icefloe/test/GLA_Proto_flex_ISO.inp b/modules/icefloe/test/GLA_Proto_flex_ISO.inp similarity index 100% rename from modules-ext/icefloe/test/GLA_Proto_flex_ISO.inp rename to modules/icefloe/test/GLA_Proto_flex_ISO.inp diff --git a/modules-ext/icefloe/test/GLA_Proto_intercrush_ISO.inp b/modules/icefloe/test/GLA_Proto_intercrush_ISO.inp similarity index 100% rename from modules-ext/icefloe/test/GLA_Proto_intercrush_ISO.inp rename to modules/icefloe/test/GLA_Proto_intercrush_ISO.inp diff --git a/modules-ext/icefloe/test/GLA_Proto_lockin_ISO.inp b/modules/icefloe/test/GLA_Proto_lockin_ISO.inp similarity index 100% rename from modules-ext/icefloe/test/GLA_Proto_lockin_ISO.inp rename to modules/icefloe/test/GLA_Proto_lockin_ISO.inp diff --git a/modules-ext/icefloe/test/GLA_Proto_randomcrush_ISO.inp b/modules/icefloe/test/GLA_Proto_randomcrush_ISO.inp similarity index 100% rename from modules-ext/icefloe/test/GLA_Proto_randomcrush_ISO.inp rename to modules/icefloe/test/GLA_Proto_randomcrush_ISO.inp diff --git a/modules-ext/icefloe/test/GLA_proto_flex_IEC.dat b/modules/icefloe/test/GLA_proto_flex_IEC.dat similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_flex_IEC.dat rename to modules/icefloe/test/GLA_proto_flex_IEC.dat diff --git a/modules-ext/icefloe/test/GLA_proto_flex_IEC.inp b/modules/icefloe/test/GLA_proto_flex_IEC.inp similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_flex_IEC.inp rename to modules/icefloe/test/GLA_proto_flex_IEC.inp diff --git a/modules-ext/icefloe/test/GLA_proto_flex_IEC.log b/modules/icefloe/test/GLA_proto_flex_IEC.log similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_flex_IEC.log rename to modules/icefloe/test/GLA_proto_flex_IEC.log diff --git a/modules-ext/icefloe/test/GLA_proto_flex_ISO.dat b/modules/icefloe/test/GLA_proto_flex_ISO.dat similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_flex_ISO.dat rename to modules/icefloe/test/GLA_proto_flex_ISO.dat diff --git a/modules-ext/icefloe/test/GLA_proto_flex_ISO.log b/modules/icefloe/test/GLA_proto_flex_ISO.log similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_flex_ISO.log rename to modules/icefloe/test/GLA_proto_flex_ISO.log diff --git a/modules-ext/icefloe/test/GLA_proto_interCrush_ISO.dat b/modules/icefloe/test/GLA_proto_interCrush_ISO.dat similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_interCrush_ISO.dat rename to modules/icefloe/test/GLA_proto_interCrush_ISO.dat diff --git a/modules-ext/icefloe/test/GLA_proto_interCrush_ISO.log b/modules/icefloe/test/GLA_proto_interCrush_ISO.log similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_interCrush_ISO.log rename to modules/icefloe/test/GLA_proto_interCrush_ISO.log diff --git a/modules-ext/icefloe/test/GLA_proto_lockin_IEC.dat b/modules/icefloe/test/GLA_proto_lockin_IEC.dat similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_lockin_IEC.dat rename to modules/icefloe/test/GLA_proto_lockin_IEC.dat diff --git a/modules-ext/icefloe/test/GLA_proto_lockin_IEC.inp b/modules/icefloe/test/GLA_proto_lockin_IEC.inp similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_lockin_IEC.inp rename to modules/icefloe/test/GLA_proto_lockin_IEC.inp diff --git a/modules-ext/icefloe/test/GLA_proto_lockin_IEC.log b/modules/icefloe/test/GLA_proto_lockin_IEC.log similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_lockin_IEC.log rename to modules/icefloe/test/GLA_proto_lockin_IEC.log diff --git a/modules-ext/icefloe/test/GLA_proto_lockin_ISO.dat b/modules/icefloe/test/GLA_proto_lockin_ISO.dat similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_lockin_ISO.dat rename to modules/icefloe/test/GLA_proto_lockin_ISO.dat diff --git a/modules-ext/icefloe/test/GLA_proto_lockin_ISO.log b/modules/icefloe/test/GLA_proto_lockin_ISO.log similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_lockin_ISO.log rename to modules/icefloe/test/GLA_proto_lockin_ISO.log diff --git a/modules-ext/icefloe/test/GLA_proto_randomCrush_ISO.dat b/modules/icefloe/test/GLA_proto_randomCrush_ISO.dat similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_randomCrush_ISO.dat rename to modules/icefloe/test/GLA_proto_randomCrush_ISO.dat diff --git a/modules-ext/icefloe/test/GLA_proto_randomCrush_ISO.log b/modules/icefloe/test/GLA_proto_randomCrush_ISO.log similarity index 100% rename from modules-ext/icefloe/test/GLA_proto_randomCrush_ISO.log rename to modules/icefloe/test/GLA_proto_randomCrush_ISO.log diff --git a/modules-ext/icefloe/test/runAll.bat b/modules/icefloe/test/runAll.bat similarity index 100% rename from modules-ext/icefloe/test/runAll.bat rename to modules/icefloe/test/runAll.bat diff --git a/modules-local/inflowwind/CMakeLists.txt b/modules/inflowwind/CMakeLists.txt similarity index 100% rename from modules-local/inflowwind/CMakeLists.txt rename to modules/inflowwind/CMakeLists.txt diff --git a/modules/inflowwind/README.md b/modules/inflowwind/README.md new file mode 100644 index 0000000000..d19b470559 --- /dev/null +++ b/modules/inflowwind/README.md @@ -0,0 +1,9 @@ +# InflowWind Module +The legacy version of this module and additional documentation are available +at the [NWTC Software Portal](https://nwtc.nrel.gov/InflowWind/). + +## Overview +InflowWind is a module for processing wind-inflow data. It has been coupled +into the OpenFAST multi-physics engineering tool to enable aero-elastic +simulation of horizontal-axis wind turbines. InflowWind can also be driven +as a standalone code to process wind-inflow data uncoupled from OpenFAST. diff --git a/modules-local/inflowwind/src/CTWind.f90 b/modules/inflowwind/src/CTWind.f90 similarity index 100% rename from modules-local/inflowwind/src/CTWind.f90 rename to modules/inflowwind/src/CTWind.f90 diff --git a/modules-local/inflowwind/src/FDWind.f90 b/modules/inflowwind/src/FDWind.f90 similarity index 100% rename from modules-local/inflowwind/src/FDWind.f90 rename to modules/inflowwind/src/FDWind.f90 diff --git a/modules-local/inflowwind/src/IfW_4Dext.f90 b/modules/inflowwind/src/IfW_4Dext.f90 similarity index 100% rename from modules-local/inflowwind/src/IfW_4Dext.f90 rename to modules/inflowwind/src/IfW_4Dext.f90 diff --git a/modules-local/inflowwind/src/IfW_4Dext.txt b/modules/inflowwind/src/IfW_4Dext.txt similarity index 100% rename from modules-local/inflowwind/src/IfW_4Dext.txt rename to modules/inflowwind/src/IfW_4Dext.txt diff --git a/modules-local/inflowwind/src/IfW_BladedFFWind.f90 b/modules/inflowwind/src/IfW_BladedFFWind.f90 similarity index 100% rename from modules-local/inflowwind/src/IfW_BladedFFWind.f90 rename to modules/inflowwind/src/IfW_BladedFFWind.f90 diff --git a/modules-local/inflowwind/src/IfW_BladedFFWind.txt b/modules/inflowwind/src/IfW_BladedFFWind.txt similarity index 100% rename from modules-local/inflowwind/src/IfW_BladedFFWind.txt rename to modules/inflowwind/src/IfW_BladedFFWind.txt diff --git a/modules-local/inflowwind/src/IfW_HAWCWind.f90 b/modules/inflowwind/src/IfW_HAWCWind.f90 similarity index 100% rename from modules-local/inflowwind/src/IfW_HAWCWind.f90 rename to modules/inflowwind/src/IfW_HAWCWind.f90 diff --git a/modules-local/inflowwind/src/IfW_HAWCWind.txt b/modules/inflowwind/src/IfW_HAWCWind.txt similarity index 100% rename from modules-local/inflowwind/src/IfW_HAWCWind.txt rename to modules/inflowwind/src/IfW_HAWCWind.txt diff --git a/modules-local/inflowwind/src/IfW_TSFFWind.f90 b/modules/inflowwind/src/IfW_TSFFWind.f90 similarity index 100% rename from modules-local/inflowwind/src/IfW_TSFFWind.f90 rename to modules/inflowwind/src/IfW_TSFFWind.f90 diff --git a/modules-local/inflowwind/src/IfW_TSFFWind.txt b/modules/inflowwind/src/IfW_TSFFWind.txt similarity index 100% rename from modules-local/inflowwind/src/IfW_TSFFWind.txt rename to modules/inflowwind/src/IfW_TSFFWind.txt diff --git a/modules-local/inflowwind/src/IfW_UniformWind.f90 b/modules/inflowwind/src/IfW_UniformWind.f90 similarity index 100% rename from modules-local/inflowwind/src/IfW_UniformWind.f90 rename to modules/inflowwind/src/IfW_UniformWind.f90 diff --git a/modules-local/inflowwind/src/IfW_UniformWind.txt b/modules/inflowwind/src/IfW_UniformWind.txt similarity index 100% rename from modules-local/inflowwind/src/IfW_UniformWind.txt rename to modules/inflowwind/src/IfW_UniformWind.txt diff --git a/modules-local/inflowwind/src/IfW_UserWind.f90 b/modules/inflowwind/src/IfW_UserWind.f90 similarity index 100% rename from modules-local/inflowwind/src/IfW_UserWind.f90 rename to modules/inflowwind/src/IfW_UserWind.f90 diff --git a/modules-local/inflowwind/src/IfW_UserWind.txt b/modules/inflowwind/src/IfW_UserWind.txt similarity index 100% rename from modules-local/inflowwind/src/IfW_UserWind.txt rename to modules/inflowwind/src/IfW_UserWind.txt diff --git a/modules-local/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 similarity index 100% rename from modules-local/inflowwind/src/InflowWind.f90 rename to modules/inflowwind/src/InflowWind.f90 diff --git a/modules-local/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt similarity index 100% rename from modules-local/inflowwind/src/InflowWind.txt rename to modules/inflowwind/src/InflowWind.txt diff --git a/modules-local/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 similarity index 100% rename from modules-local/inflowwind/src/InflowWind_Driver.f90 rename to modules/inflowwind/src/InflowWind_Driver.f90 diff --git a/modules-local/inflowwind/src/InflowWind_Driver_Subs.f90 b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 similarity index 100% rename from modules-local/inflowwind/src/InflowWind_Driver_Subs.f90 rename to modules/inflowwind/src/InflowWind_Driver_Subs.f90 diff --git a/modules-local/inflowwind/src/InflowWind_Driver_Types.f90 b/modules/inflowwind/src/InflowWind_Driver_Types.f90 similarity index 100% rename from modules-local/inflowwind/src/InflowWind_Driver_Types.f90 rename to modules/inflowwind/src/InflowWind_Driver_Types.f90 diff --git a/modules-local/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 similarity index 99% rename from modules-local/inflowwind/src/InflowWind_Subs.f90 rename to modules/inflowwind/src/InflowWind_Subs.f90 index 3d39e46f49..bd39768c73 100644 --- a/modules-local/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -1384,9 +1384,11 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM end if ! Allocate array for AllOuts - CALL AllocAry( m%AllOuts, MaxOutPts, 'AllOuts', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) RETURN + ALLOCATE( m%AllOuts(0:MaxOutPts), Stat=TmpErrStat ) + IF (TmpErrStat/=0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating memory for m%AllOuts.",ErrStat,ErrMsg,RoutineName) + RETURN + END IF m%AllOuts = 0.0_ReKi @@ -1617,7 +1619,8 @@ SUBROUTINE SetOutParamLin( p, ErrStat, ErrMsg ) call AllocAry(p%OutParamLinIndx, 2, p%NumOuts, 'OutParamLinIndx', ErrStat2, ErrMsg2) call setErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return - + + p%OutParamLinIndx = 0 do i = 1,p%NumOuts if (p%OutParam(i)%SignM /= 0 ) then diff --git a/modules-local/inflowwind/src/Lidar.f90 b/modules/inflowwind/src/Lidar.f90 similarity index 100% rename from modules-local/inflowwind/src/Lidar.f90 rename to modules/inflowwind/src/Lidar.f90 diff --git a/modules-local/inflowwind/src/Lidar.txt b/modules/inflowwind/src/Lidar.txt similarity index 100% rename from modules-local/inflowwind/src/Lidar.txt rename to modules/inflowwind/src/Lidar.txt diff --git a/modules-local/inflowwind/src/OutListParameters.xlsx b/modules/inflowwind/src/OutListParameters.xlsx similarity index 100% rename from modules-local/inflowwind/src/OutListParameters.xlsx rename to modules/inflowwind/src/OutListParameters.xlsx diff --git a/modules-ext/map/CMakeLists.txt b/modules/map/CMakeLists.txt similarity index 90% rename from modules-ext/map/CMakeLists.txt rename to modules/map/CMakeLists.txt index 3f5c7bee04..999a2daef8 100644 --- a/modules-ext/map/CMakeLists.txt +++ b/modules/map/CMakeLists.txt @@ -14,8 +14,9 @@ # limitations under the License. # -if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAP_DLL_EXPORTS -DCMINPACK_NO_DLL -DNDEBUG -D_WINDOWS -D_USRDLL") +if(WIN32 OR CYGWIN OR MINGW) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMAP_DLL_EXPORTS -DCMINPACK_NO_DLL -DNDEBUG -D_WINDOWS -D_USRDLL") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAP_DLL_EXPORTS -DCMINPACK_NO_DLL -DNDEBUG -D_WINDOWS -D_USRDLL") endif() generate_f90_types(src/MAP_Registry.txt MAP_Types.f90 -ccode) diff --git a/modules/map/README.md b/modules/map/README.md new file mode 100644 index 0000000000..e5c2b4237e --- /dev/null +++ b/modules/map/README.md @@ -0,0 +1,25 @@ +# Map++ Module +This is an externally developed module with further information +available on the developer's documentation site: +[map++ readthedocs](https://map-plus-plus.readthedocs.io/en/latest). + +The legacy version of FAST's information regarding this module +are available at the [NWTC Software Portal](https://nwtc.nrel.gov/MAP/). + +## Overview +The Mooring Analysis Program (MAP++) is a library designed to be used in +parallel with other CAE tools to model the steady-state forces on a +Multi-Segmented, Quasi-Static (MSQS) mooring line. The MSQS model is developed +based on an extension of conventional single line static solutions. +Conceptually, MAP++'s MSQS module solves the algebraic equations for all +elements simultaneously with the condition that the total force at connection +points sum to zero. Seabed contact, seabed friction, and externally applied +forces can be modeled with this tool. This allows multi-element mooring lines +with arbitrary connection configurations to be analyzed. + +Because MAP++ is compiled as a library, it can be linked with other programs at +run-time. Alternatively, one may use MAP++'s native Python binding routines to +access the program through Python. These features give users the option to +execute MAP++ as a stand-alone design or simulation tool. The entry points into +MAP++ follow the function calling conventions outlined by the NWTC FAST +modularization framework. diff --git a/modules-ext/map/src/MAP_Fortran_Registry.txt b/modules/map/src/MAP_Fortran_Registry.txt similarity index 100% rename from modules-ext/map/src/MAP_Fortran_Registry.txt rename to modules/map/src/MAP_Fortran_Registry.txt diff --git a/modules-ext/map/src/MAP_Registry.txt b/modules/map/src/MAP_Registry.txt similarity index 100% rename from modules-ext/map/src/MAP_Registry.txt rename to modules/map/src/MAP_Registry.txt diff --git a/modules-ext/map/src/bstring/bstraux.c b/modules/map/src/bstring/bstraux.c similarity index 100% rename from modules-ext/map/src/bstring/bstraux.c rename to modules/map/src/bstring/bstraux.c diff --git a/modules-ext/map/src/bstring/bstraux.h b/modules/map/src/bstring/bstraux.h similarity index 100% rename from modules-ext/map/src/bstring/bstraux.h rename to modules/map/src/bstring/bstraux.h diff --git a/modules-ext/map/src/bstring/bstrlib.c b/modules/map/src/bstring/bstrlib.c similarity index 100% rename from modules-ext/map/src/bstring/bstrlib.c rename to modules/map/src/bstring/bstrlib.c diff --git a/modules-ext/map/src/bstring/bstrlib.h b/modules/map/src/bstring/bstrlib.h similarity index 100% rename from modules-ext/map/src/bstring/bstrlib.h rename to modules/map/src/bstring/bstrlib.h diff --git a/modules-ext/map/src/cminpack/cminpack.h b/modules/map/src/cminpack/cminpack.h similarity index 100% rename from modules-ext/map/src/cminpack/cminpack.h rename to modules/map/src/cminpack/cminpack.h diff --git a/modules-ext/map/src/cminpack/cminpackP.h b/modules/map/src/cminpack/cminpackP.h similarity index 100% rename from modules-ext/map/src/cminpack/cminpackP.h rename to modules/map/src/cminpack/cminpackP.h diff --git a/modules-ext/map/src/cminpack/dpmpar.c b/modules/map/src/cminpack/dpmpar.c similarity index 100% rename from modules-ext/map/src/cminpack/dpmpar.c rename to modules/map/src/cminpack/dpmpar.c diff --git a/modules-ext/map/src/cminpack/enorm.c b/modules/map/src/cminpack/enorm.c similarity index 100% rename from modules-ext/map/src/cminpack/enorm.c rename to modules/map/src/cminpack/enorm.c diff --git a/modules-ext/map/src/cminpack/enorm_u.c b/modules/map/src/cminpack/enorm_u.c similarity index 100% rename from modules-ext/map/src/cminpack/enorm_u.c rename to modules/map/src/cminpack/enorm_u.c diff --git a/modules-ext/map/src/cminpack/lmder.c b/modules/map/src/cminpack/lmder.c similarity index 100% rename from modules-ext/map/src/cminpack/lmder.c rename to modules/map/src/cminpack/lmder.c diff --git a/modules-ext/map/src/cminpack/lmpar.c b/modules/map/src/cminpack/lmpar.c similarity index 100% rename from modules-ext/map/src/cminpack/lmpar.c rename to modules/map/src/cminpack/lmpar.c diff --git a/modules-ext/map/src/cminpack/minpack.h b/modules/map/src/cminpack/minpack.h similarity index 100% rename from modules-ext/map/src/cminpack/minpack.h rename to modules/map/src/cminpack/minpack.h diff --git a/modules-ext/map/src/cminpack/qrfac.c b/modules/map/src/cminpack/qrfac.c similarity index 100% rename from modules-ext/map/src/cminpack/qrfac.c rename to modules/map/src/cminpack/qrfac.c diff --git a/modules-ext/map/src/cminpack/qrsolv.c b/modules/map/src/cminpack/qrsolv.c similarity index 100% rename from modules-ext/map/src/cminpack/qrsolv.c rename to modules/map/src/cminpack/qrsolv.c diff --git a/modules-ext/map/src/freedata.c b/modules/map/src/freedata.c similarity index 100% rename from modules-ext/map/src/freedata.c rename to modules/map/src/freedata.c diff --git a/modules-ext/map/src/freedata.h b/modules/map/src/freedata.h similarity index 100% rename from modules-ext/map/src/freedata.h rename to modules/map/src/freedata.h diff --git a/modules-ext/map/src/jacobian.c b/modules/map/src/jacobian.c similarity index 100% rename from modules-ext/map/src/jacobian.c rename to modules/map/src/jacobian.c diff --git a/modules-ext/map/src/jacobian.h b/modules/map/src/jacobian.h similarity index 100% rename from modules-ext/map/src/jacobian.h rename to modules/map/src/jacobian.h diff --git a/modules-ext/map/src/lapack/lapacke.h b/modules/map/src/lapack/lapacke.h similarity index 100% rename from modules-ext/map/src/lapack/lapacke.h rename to modules/map/src/lapack/lapacke.h diff --git a/modules-ext/map/src/lapack/lapacke_mangling.h b/modules/map/src/lapack/lapacke_mangling.h similarity index 100% rename from modules-ext/map/src/lapack/lapacke_mangling.h rename to modules/map/src/lapack/lapacke_mangling.h diff --git a/modules-ext/map/src/lineroutines.c b/modules/map/src/lineroutines.c similarity index 100% rename from modules-ext/map/src/lineroutines.c rename to modules/map/src/lineroutines.c diff --git a/modules-ext/map/src/lineroutines.h b/modules/map/src/lineroutines.h similarity index 100% rename from modules-ext/map/src/lineroutines.h rename to modules/map/src/lineroutines.h diff --git a/modules-ext/map/src/lmroutines.cc b/modules/map/src/lmroutines.cc similarity index 100% rename from modules-ext/map/src/lmroutines.cc rename to modules/map/src/lmroutines.cc diff --git a/modules-ext/map/src/lmroutines.hpp b/modules/map/src/lmroutines.hpp similarity index 100% rename from modules-ext/map/src/lmroutines.hpp rename to modules/map/src/lmroutines.hpp diff --git a/modules-ext/map/src/makefile b/modules/map/src/makefile similarity index 100% rename from modules-ext/map/src/makefile rename to modules/map/src/makefile diff --git a/modules-ext/map/src/map.f90 b/modules/map/src/map.f90 similarity index 100% rename from modules-ext/map/src/map.f90 rename to modules/map/src/map.f90 diff --git a/modules-ext/map/src/map.h b/modules/map/src/map.h similarity index 100% rename from modules-ext/map/src/map.h rename to modules/map/src/map.h diff --git a/modules-ext/map/src/map_glue.f90 b/modules/map/src/map_glue.f90 similarity index 100% rename from modules-ext/map/src/map_glue.f90 rename to modules/map/src/map_glue.f90 diff --git a/modules-ext/map/src/mapapi.c b/modules/map/src/mapapi.c similarity index 100% rename from modules-ext/map/src/mapapi.c rename to modules/map/src/mapapi.c diff --git a/modules-ext/map/src/mapapi.h b/modules/map/src/mapapi.h similarity index 100% rename from modules-ext/map/src/mapapi.h rename to modules/map/src/mapapi.h diff --git a/modules-ext/map/src/maperror.c b/modules/map/src/maperror.c similarity index 100% rename from modules-ext/map/src/maperror.c rename to modules/map/src/maperror.c diff --git a/modules-ext/map/src/maperror.h b/modules/map/src/maperror.h similarity index 100% rename from modules-ext/map/src/maperror.h rename to modules/map/src/maperror.h diff --git a/modules-ext/map/src/mapinit.c b/modules/map/src/mapinit.c similarity index 100% rename from modules-ext/map/src/mapinit.c rename to modules/map/src/mapinit.c diff --git a/modules-ext/map/src/mapinit.h b/modules/map/src/mapinit.h similarity index 100% rename from modules-ext/map/src/mapinit.h rename to modules/map/src/mapinit.h diff --git a/modules-ext/map/src/mapsys.h b/modules/map/src/mapsys.h similarity index 99% rename from modules-ext/map/src/mapsys.h rename to modules/map/src/mapsys.h index 9afc07151f..9dbf89e537 100644 --- a/modules-ext/map/src/mapsys.h +++ b/modules/map/src/mapsys.h @@ -53,7 +53,7 @@ # include # define map_snprintf snprintf # define map_strcat(a,b,c) strncat(a,c,b) -# if defined(_MINGW) +# if defined(__MINGW32__) # define MAP_EXTERNCALL __declspec( dllexport ) # else # define MAP_EXTERNCALL diff --git a/modules-ext/map/src/numeric.c b/modules/map/src/numeric.c similarity index 100% rename from modules-ext/map/src/numeric.c rename to modules/map/src/numeric.c diff --git a/modules-ext/map/src/numeric.h b/modules/map/src/numeric.h similarity index 100% rename from modules-ext/map/src/numeric.h rename to modules/map/src/numeric.h diff --git a/modules-ext/map/src/outputstream.c b/modules/map/src/outputstream.c similarity index 99% rename from modules-ext/map/src/outputstream.c rename to modules/map/src/outputstream.c index ce23367679..b7aae4e815 100644 --- a/modules-ext/map/src/outputstream.c +++ b/modules/map/src/outputstream.c @@ -934,7 +934,7 @@ MAP_ERROR_CODE write_expanded_input_file_to_summary_file(FILE* file, Initializat }; -#if !defined(_MSC_VER) +#if !defined(_MSC_VER) && !defined(__MINGW32__) MAP_ERROR_CODE fopen_s(FILE** f, const char* name, const char* mode) { assert(f); diff --git a/modules-ext/map/src/outputstream.h b/modules/map/src/outputstream.h similarity index 99% rename from modules-ext/map/src/outputstream.h rename to modules/map/src/outputstream.h index 833a590aeb..8ef94a846b 100644 --- a/modules-ext/map/src/outputstream.h +++ b/modules/map/src/outputstream.h @@ -32,7 +32,7 @@ #include "MAP_Types.h" -#if !defined(_MSC_VER) +#if !defined(_MSC_VER) && !defined(__MINGW32__) MAP_ERROR_CODE fopen_s(FILE** f, const char* name, const char* mode); #endif diff --git a/modules-ext/map/src/residual.c b/modules/map/src/residual.c similarity index 100% rename from modules-ext/map/src/residual.c rename to modules/map/src/residual.c diff --git a/modules-ext/map/src/residual.h b/modules/map/src/residual.h similarity index 100% rename from modules-ext/map/src/residual.h rename to modules/map/src/residual.h diff --git a/modules-ext/map/src/simclist/simclist.c b/modules/map/src/simclist/simclist.c similarity index 100% rename from modules-ext/map/src/simclist/simclist.c rename to modules/map/src/simclist/simclist.c diff --git a/modules-ext/map/src/simclist/simclist.h b/modules/map/src/simclist/simclist.h similarity index 100% rename from modules-ext/map/src/simclist/simclist.h rename to modules/map/src/simclist/simclist.h diff --git a/modules-ext/moordyn/CMakeLists.txt b/modules/moordyn/CMakeLists.txt similarity index 100% rename from modules-ext/moordyn/CMakeLists.txt rename to modules/moordyn/CMakeLists.txt diff --git a/modules/moordyn/README.md b/modules/moordyn/README.md new file mode 100644 index 0000000000..af24791e59 --- /dev/null +++ b/modules/moordyn/README.md @@ -0,0 +1,30 @@ +# MoorDyn Module +This is an externally developed module with further information +available on the developer's documentation site: +[Matt Hall](http://www.matt-hall.ca/moordyn.html). + +The legacy version of FAST's information regarding this module +are available at the [NWTC Software Portal](https://nwtc.nrel.gov/MoorDyn/). + +## Overview +MoorDyn is a lumped-mass mooring line model for simulating the dynamics of +moorings connected to floating offshore structures. It accounts for internal +axial stiffness and damping forces, weight and buoyancy forces, hydrodynamic +forces from Morison's equation (assuming quiescent water so far), and vertical +spring-damper forces from contact with the seabed. MoorDyn's input file format +is based on that of MAP. The model supports arbitrary line interconnections, +clump weights and floats, and different line properties. + +The Fortran implementation of MoorDyn, which has been developed +following the FAST Modularization Framework, is included as a module in +OpenFAST. + +For the C++ implementation of MoorDyn, see http://www.matt-hall.ca/moordyn. +"MoorDyn C" can be compiled as a dynamically-linked library and features +simpler functions for easy coupling with models or scripts coded in C/C++, +Fortran, Matlab/Simulink, etc. It has recently been integrated into WEC-Sim. + +Both forms of MoorDyn feature the same underlying mooring model, use similar +input and output conventions, and are being updated and improved in parallel. +They follow the same version numbering, with a "C" or "F" suffix for +differentiation. diff --git a/modules-ext/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 similarity index 100% rename from modules-ext/moordyn/src/MoorDyn.f90 rename to modules/moordyn/src/MoorDyn.f90 diff --git a/modules-ext/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 similarity index 100% rename from modules-ext/moordyn/src/MoorDyn_IO.f90 rename to modules/moordyn/src/MoorDyn_IO.f90 diff --git a/modules-ext/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt similarity index 100% rename from modules-ext/moordyn/src/MoorDyn_Registry.txt rename to modules/moordyn/src/MoorDyn_Registry.txt diff --git a/modules-local/nwtc-library/CMakeLists.txt b/modules/nwtc-library/CMakeLists.txt similarity index 97% rename from modules-local/nwtc-library/CMakeLists.txt rename to modules/nwtc-library/CMakeLists.txt index 127808a7e5..c4f850c6b2 100644 --- a/modules-local/nwtc-library/CMakeLists.txt +++ b/modules/nwtc-library/CMakeLists.txt @@ -42,11 +42,11 @@ set(NWTCLIBS_SOURCES get_filename_component(FCNAME ${CMAKE_Fortran_COMPILER} NAME) if (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU") - if (APPLE OR UNIX) - set(NWTC_SYS_FILE src/SysGnuLinux.f90) - elseif (WIN32) + if (WIN32) set(NWTC_SYS_FILE src/SysGnuWin.f90) - endif (APPLE OR UNIX) + elseif (APPLE OR UNIX OR CYGWIN) + set(NWTC_SYS_FILE src/SysGnuLinux.f90) + endif () elseif (${CMAKE_Fortran_COMPILER_ID} STREQUAL "Intel") if (APPLE OR UNIX) set(NWTC_SYS_FILE src/SysIFL.f90) diff --git a/modules/nwtc-library/README.md b/modules/nwtc-library/README.md new file mode 100644 index 0000000000..9273a9ff87 --- /dev/null +++ b/modules/nwtc-library/README.md @@ -0,0 +1,22 @@ +# NWTC Library Module +The legacy version of this module and additional documentation are available +at the [NWTC Software Portal](https://nwtc.nrel.gov/NWTC_Library/). + +## Overview +Over the years, the researchers at the NWTC have written many general-purpose +routines that we use in many of our software. In the past, we would copy those +needed for any given program from the source of another code. We decided that +doing it that way was just too much work; especially when we wanted to change +one of the routines and have it affect all the packages. So, we decided to +create a central set of routines and include their source files in our Fortran +projects. Thus, the NWTC Subroutine Library was born. + +The NWTC Subroutine Library consists of several modules, each contained in its +own source file. The library is written in standard Fortran 2003, with the +exception of some of the routines and data in the Sys*.f90 files. We currently +have several compiler-specific files available to choose from, including +- SysIVF.f90 for the Intel Visual Fortran compiler for Windows +- SysGnuLinux.f90 for the GNU Fortran compiler for Linux + +If you want to port our programs to a different compiler, you should only have +to modify one of the Sys*.f90 files to get it to compile. diff --git a/modules-local/nwtc-library/src/Generate_NWTC_Library_Types.bat b/modules/nwtc-library/src/Generate_NWTC_Library_Types.bat similarity index 100% rename from modules-local/nwtc-library/src/Generate_NWTC_Library_Types.bat rename to modules/nwtc-library/src/Generate_NWTC_Library_Types.bat diff --git a/modules-local/nwtc-library/src/ModMesh.f90 b/modules/nwtc-library/src/ModMesh.f90 similarity index 100% rename from modules-local/nwtc-library/src/ModMesh.f90 rename to modules/nwtc-library/src/ModMesh.f90 diff --git a/modules-local/nwtc-library/src/ModMesh_Mapping.f90 b/modules/nwtc-library/src/ModMesh_Mapping.f90 similarity index 100% rename from modules-local/nwtc-library/src/ModMesh_Mapping.f90 rename to modules/nwtc-library/src/ModMesh_Mapping.f90 diff --git a/modules-local/nwtc-library/src/ModMesh_Types.f90 b/modules/nwtc-library/src/ModMesh_Types.f90 similarity index 100% rename from modules-local/nwtc-library/src/ModMesh_Types.f90 rename to modules/nwtc-library/src/ModMesh_Types.f90 diff --git a/modules-local/nwtc-library/src/NWTC_Base.f90 b/modules/nwtc-library/src/NWTC_Base.f90 similarity index 100% rename from modules-local/nwtc-library/src/NWTC_Base.f90 rename to modules/nwtc-library/src/NWTC_Base.f90 diff --git a/modules-local/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 similarity index 99% rename from modules-local/nwtc-library/src/NWTC_IO.f90 rename to modules/nwtc-library/src/NWTC_IO.f90 index 3e97b1df98..5109af6c6e 100644 --- a/modules-local/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -175,6 +175,7 @@ MODULE NWTC_IO !> \copydoc nwtc_io::readcary INTERFACE ReadAry MODULE PROCEDURE ReadCAry + MODULE PROCEDURE ReadCAryFromStr MODULE PROCEDURE ReadIAry MODULE PROCEDURE ReadLAry MODULE PROCEDURE ReadR4Ary ! read array of 4-byte reals @@ -1801,8 +1802,6 @@ SUBROUTINE Conv2UC ( Str ) IF ( ( Str(IC:IC) >= 'a' ).AND.( Str(IC:IC) <= 'z' ) ) THEN Str(IC:IC) = CHAR( ICHAR( Str(IC:IC) ) - 32 ) - ELSE - Str(IC:IC) = Str(IC:IC) END IF END DO ! IC @@ -4458,56 +4457,7 @@ SUBROUTINE ProgWarn ( Message ) RETURN END SUBROUTINE ProgWarn - -!======================================================================= -!> This routine outputs the git hash associate with the current codebase. - FUNCTION QueryGitVersion() - - ! Passed variables. - - !INTEGER(IntKi), INTENT(OUT) :: ErrStat ! Error status - !CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message - - ! Function declaration. - - CHARACTER(200) :: QueryGitVersion ! This function. - - ! Local variables. - - INTEGER(IntKi) :: UnIn ! Unit number for reading file - INTEGER(IntKi) :: ErrStat2 ! Temporary Error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Error message - - !ErrStat = ErrID_None - !ErrMsg = '' - - QueryGitVersion = 'unversioned' - - ! VS build method for obtaining the git version info. - ! This requires setting: - ! 1) GIT_INCLUDE_FILE = '$(ProjectDir)\..\gitVersionInfo.h' preprocessor option on this file or the project containing this file. - ! 2) Creating a prebuild event on the project file producing the resulting binary (i.e., FAST.exe) with the following command: ..\CreateGitVersion.bat - ! 3) The bat file, CreateGitVersion.bat, located in the vs-build folder of the openfast repository, which contains the git command used to obtain the git info - ! @ECHO off - ! SET IncludeFile=..\gitVersionInfo.h - ! - ! %IncludeFile% - ! FOR /f %%a IN ('git describe --abbrev^=7 --always --tags --dirty') DO > %IncludeFile% - ! ECHO '>> %IncludeFile% - ! EXIT /B 0 - ! This creates the gitVersionInfo.h file in the vs-build folder - -#ifdef GIT_INCLUDE_FILE -#include GIT_INCLUDE_FILE -#endif -#ifdef GIT_VERSION_INFO -QueryGitVersion = GIT_VERSION_INFO -#endif - - RETURN - END FUNCTION QueryGitVersion - !======================================================================= !> \copydoc nwtc_io::int2lstr FUNCTION R2LStr4 ( Num ) @@ -4646,6 +4596,49 @@ SUBROUTINE ReadCAry ( UnIn, Fil, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg RETURN END SUBROUTINE ReadCAry +!====================================================================== +!> This routine reads a AryLen values separated by whitespace (or other Fortran record delimiters such as commas) +!! into an array (either on same line or multiple lines) from an input string +!! Use ReadAry (nwtc_io::readary) instead of directly calling a specific routine in the generic interface. + SUBROUTINE ReadCAryFromStr ( Str, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) + + ! Argument declarations: + CHARACTER(*), INTENT(IN) :: Str !< String to read from + INTEGER, INTENT(IN) :: AryLen !< Length of the array. + INTEGER, INTENT(IN), OPTIONAL:: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc + INTEGER, INTENT(OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message describing ErrStat + CHARACTER(*), INTENT(OUT) :: Ary(AryLen) !< Array being read. + CHARACTER(*), INTENT(IN) :: AryDescr !< Text string describing the variable. + CHARACTER(*), INTENT(IN) :: AryName !< Text string containing the variable name. + ! Local declarations: + INTEGER :: Ind ! Index into the string array. Assumed to be one digit. + INTEGER :: IOS ! I/O status returned from the read statement. + + ! Init of output + do Ind=1,AryLen + Ary(Ind)='' + end do + ! Reading fields from string + READ (Str,*,IOSTAT=IOS) ( Ary(Ind), Ind=1,AryLen ) + + ! Dedicated "CheckIOS" + IF ( IOS < 0 ) THEN + write(ErrMsg,'(A,I0,A)') 'End of line reached while trying to read ',AryLen,' fields from string.' + ErrStat = ErrID_Fatal + ELSE IF ( IOS > 0 ) THEN + write(ErrMsg,'(A,I0,A)') 'Unexpected error while trying to read ',AryLen,' fields from string.' + ELSE + ErrMsg='' + ErrStat = ErrID_None + END IF + IF (ErrStat >= AbortErrLev) RETURN + IF ( PRESENT(UnEc) ) THEN + IF ( UnEc > 0 ) & + WRITE (UnEc,Ec_StrAryFrmt) TRIM( AryName ), AryDescr, ( TRIM( Ary(Ind) ), Ind=1,MIN(AryLen,NWTC_MaxAryLen) ) + END IF + RETURN + END SUBROUTINE ReadCAryFromStr !======================================================================= !> This routine reads a AryLen values into a real array from the next AryLen lines of the input file (one value per line). !! Use ReadAryLines (nwtc_io::readarylines) instead of directly calling a specific routine in the generic interface. diff --git a/modules-local/nwtc-library/src/NWTC_Library.f90 b/modules/nwtc-library/src/NWTC_Library.f90 similarity index 100% rename from modules-local/nwtc-library/src/NWTC_Library.f90 rename to modules/nwtc-library/src/NWTC_Library.f90 diff --git a/modules-local/nwtc-library/src/NWTC_Library_Types.f90 b/modules/nwtc-library/src/NWTC_Library_Types.f90 similarity index 100% rename from modules-local/nwtc-library/src/NWTC_Library_Types.f90 rename to modules/nwtc-library/src/NWTC_Library_Types.f90 diff --git a/modules-local/nwtc-library/src/NWTC_Num.f90 b/modules/nwtc-library/src/NWTC_Num.f90 similarity index 100% rename from modules-local/nwtc-library/src/NWTC_Num.f90 rename to modules/nwtc-library/src/NWTC_Num.f90 diff --git a/modules-local/nwtc-library/src/NetLib/Dierckx_FitPack/NWTC_FitPack.f90 b/modules/nwtc-library/src/NetLib/Dierckx_FitPack/NWTC_FitPack.f90 similarity index 100% rename from modules-local/nwtc-library/src/NetLib/Dierckx_FitPack/NWTC_FitPack.f90 rename to modules/nwtc-library/src/NetLib/Dierckx_FitPack/NWTC_FitPack.f90 diff --git a/modules-local/nwtc-library/src/NetLib/Dierckx_FitPack/dierckx_fitpack.f b/modules/nwtc-library/src/NetLib/Dierckx_FitPack/dierckx_fitpack.f similarity index 100% rename from modules-local/nwtc-library/src/NetLib/Dierckx_FitPack/dierckx_fitpack.f rename to modules/nwtc-library/src/NetLib/Dierckx_FitPack/dierckx_fitpack.f diff --git a/modules-local/nwtc-library/src/NetLib/Dierckx_FitPack/readme.txt b/modules/nwtc-library/src/NetLib/Dierckx_FitPack/readme.txt similarity index 100% rename from modules-local/nwtc-library/src/NetLib/Dierckx_FitPack/readme.txt rename to modules/nwtc-library/src/NetLib/Dierckx_FitPack/readme.txt diff --git a/modules-local/nwtc-library/src/NetLib/fftpack/NWTC_FFTPACK.f90 b/modules/nwtc-library/src/NetLib/fftpack/NWTC_FFTPACK.f90 similarity index 100% rename from modules-local/nwtc-library/src/NetLib/fftpack/NWTC_FFTPACK.f90 rename to modules/nwtc-library/src/NetLib/fftpack/NWTC_FFTPACK.f90 diff --git a/modules-local/nwtc-library/src/NetLib/fftpack/doc.txt b/modules/nwtc-library/src/NetLib/fftpack/doc.txt similarity index 100% rename from modules-local/nwtc-library/src/NetLib/fftpack/doc.txt rename to modules/nwtc-library/src/NetLib/fftpack/doc.txt diff --git a/modules-local/nwtc-library/src/NetLib/fftpack/fftpack4.1.f b/modules/nwtc-library/src/NetLib/fftpack/fftpack4.1.f similarity index 100% rename from modules-local/nwtc-library/src/NetLib/fftpack/fftpack4.1.f rename to modules/nwtc-library/src/NetLib/fftpack/fftpack4.1.f diff --git a/modules-local/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 b/modules/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 similarity index 99% rename from modules-local/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 rename to modules/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 index 9ab360634e..f82fff275c 100644 --- a/modules-local/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 +++ b/modules/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 @@ -297,7 +297,7 @@ SUBROUTINE LAPACK_DGEMM( TRANSA, TRANSB, ALPHA, A, B, BETA, C, ErrStat, ErrMsg ) END IF - CALL dgemm (TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, M) + CALL DGEMM (TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, M) RETURN @@ -387,7 +387,7 @@ SUBROUTINE LAPACK_SGEMM( TRANSA, TRANSB, ALPHA, A, B, BETA, C, ErrStat, ErrMsg ) END IF - CALL sgemm (TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, M) + CALL SGEMM (TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, M) RETURN diff --git a/modules-local/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 b/modules/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 similarity index 100% rename from modules-local/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 rename to modules/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 diff --git a/modules-local/nwtc-library/src/NetLib/scalapack/dlasrt2.f b/modules/nwtc-library/src/NetLib/scalapack/dlasrt2.f similarity index 100% rename from modules-local/nwtc-library/src/NetLib/scalapack/dlasrt2.f rename to modules/nwtc-library/src/NetLib/scalapack/dlasrt2.f diff --git a/modules-local/nwtc-library/src/NetLib/scalapack/slasrt2.f b/modules/nwtc-library/src/NetLib/scalapack/slasrt2.f similarity index 100% rename from modules-local/nwtc-library/src/NetLib/scalapack/slasrt2.f rename to modules/nwtc-library/src/NetLib/scalapack/slasrt2.f diff --git a/modules-local/nwtc-library/src/Registry_NWTC_Library.txt b/modules/nwtc-library/src/Registry_NWTC_Library.txt similarity index 100% rename from modules-local/nwtc-library/src/Registry_NWTC_Library.txt rename to modules/nwtc-library/src/Registry_NWTC_Library.txt diff --git a/modules-local/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt b/modules/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt similarity index 100% rename from modules-local/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt rename to modules/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt diff --git a/modules-local/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt b/modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt similarity index 100% rename from modules-local/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt rename to modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt diff --git a/modules-local/nwtc-library/src/SingPrec.f90 b/modules/nwtc-library/src/SingPrec.f90 similarity index 100% rename from modules-local/nwtc-library/src/SingPrec.f90 rename to modules/nwtc-library/src/SingPrec.f90 diff --git a/modules-local/nwtc-library/src/SysGnuLinux.f90 b/modules/nwtc-library/src/SysGnuLinux.f90 similarity index 98% rename from modules-local/nwtc-library/src/SysGnuLinux.f90 rename to modules/nwtc-library/src/SysGnuLinux.f90 index c5c011f431..7257e32561 100644 --- a/modules-local/nwtc-library/src/SysGnuLinux.f90 +++ b/modules/nwtc-library/src/SysGnuLinux.f90 @@ -77,8 +77,8 @@ FUNCTION FileSize( Unit ) INTEGER(B8Ki) :: FileSize ! The size of the file in bytes to be returned. INTEGER, INTENT(IN) :: Unit ! The I/O unit number of the pre-opened file. - INTEGER :: StatArray(13) ! An array returned by FSTAT that includes the file size. - INTEGER :: Status ! The status returned by + INTEGER(4) :: StatArray(13) ! An array returned by FSTAT that includes the file size. + INTEGER(4) :: Status ! The status returned by Status = FSTAT( INT( Unit, B4Ki ), StatArray ) @@ -230,10 +230,10 @@ SUBROUTINE OpenCon ! This routine opens the console for standard output. -!bjj: removed for use with CygWin; Because CU = 6 now, this statement is not necessary +!bjj: Because CU = 6 now, this statement is not necessary ! OPEN ( CU , FILE='/dev/stdout' , STATUS='OLD' ) - CALL FlushOut ( CU ) +! CALL FlushOut ( CU ) RETURN END SUBROUTINE OpenCon @@ -379,8 +379,7 @@ SUBROUTINE WriteScr ( Str, Frm ) CHARACTER(*), INTENT(IN) :: Str ! The input string to write to the screen. CHARACTER(*), INTENT(IN) :: Frm ! Format specifier for the output. - INTEGER :: ErrStat ! Error stat - ! This SUBROUTINE is used to dynamically load a DLL.us of write operation (so code doesn't crash) + INTEGER :: ErrStat ! Error status of write operation (so code doesn't crash) IF ( LEN_TRIM(Str) < 1 ) THEN WRITE ( CU, '()', IOSTAT=ErrStat ) @@ -396,6 +395,7 @@ END SUBROUTINE WriteScr ! ( Str ) !======================================================================= SUBROUTINE LoadDynamicLib ( DLL, ErrStat, ErrMsg ) + ! This SUBROUTINE is used to dynamically load a DLL. TYPE (DLL_Type), INTENT(INOUT) :: DLL ! The DLL to be loaded. INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation diff --git a/modules-local/nwtc-library/src/SysGnuWin.f90 b/modules/nwtc-library/src/SysGnuWin.f90 similarity index 98% rename from modules-local/nwtc-library/src/SysGnuWin.f90 rename to modules/nwtc-library/src/SysGnuWin.f90 index 58e78d7c91..e0ca2c1983 100644 --- a/modules-local/nwtc-library/src/SysGnuWin.f90 +++ b/modules/nwtc-library/src/SysGnuWin.f90 @@ -20,7 +20,7 @@ MODULE SysSubs ! This module contains routines with system-specific logic and references, including all references to the console unit, CU. ! It also contains standard (but not system-specific) routines it uses. - ! SysGnu.f90 is specifically for the GNU Fortran (gfortran) compiler on Windows. + ! SysGnuWin.f90 is specifically for the GNU Fortran (gfortran) compiler on Windows. ! It contains the following routines: ! FUNCTION FileSize( Unit ) ! Returns the size (in bytes) of an open file. ! FUNCTION Is_NaN( DblNum ) ! Please use IEEE_IS_NAN() instead @@ -28,6 +28,7 @@ MODULE SysSubs ! FUNCTION NWTC_gamma( x ) ! Returns the gamma value of its argument. ! SUBROUTINE FlushOut ( Unit ) ! SUBROUTINE GET_CWD( DirName, Status ) + ! SUBROUTINE MKDIR( new_directory_path ) ! SUBROUTINE OpenCon ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) ! SUBROUTINE ProgExit ( StatCode ) @@ -38,7 +39,7 @@ MODULE SysSubs ! SUBROUTINE WriteScr ( Str, Frm ) ! SUBROUTINE LoadDynamicLib( DLL, ErrStat, ErrMsg ) ! SUBROUTINE FreeDynamicLib( DLL, ErrStat, ErrMsg ) - + USE NWTC_Base IMPLICIT NONE @@ -68,8 +69,6 @@ MODULE SysSubs CONTAINS - - !======================================================================= FUNCTION FileSize( Unit ) @@ -92,7 +91,7 @@ FUNCTION FileSize( Unit ) RETURN END FUNCTION FileSize ! ( Unit ) !======================================================================= - FUNCTION Is_NaN( DblNum ) +FUNCTION Is_NaN( DblNum ) ! This routine determines if a REAL(DbKi) variable holds a proper number. ! BJJ: this routine is used in CRUNCH. @@ -221,7 +220,7 @@ SUBROUTINE MKDIR ( new_directory_path ) inquire( file=trim(new_directory_path), exist=directory_exists ) if ( .NOT. directory_exists ) then - make_command = 'mkdir -p '//trim(new_directory_path) + make_command = 'mkdir "'//trim(new_directory_path)//'"' call system( make_command ) endif @@ -349,7 +348,7 @@ SUBROUTINE WrNR ( Str ) RETURN END SUBROUTINE WrNR ! ( Str ) !======================================================================= - SUBROUTINE WrOver ( Str ) +SUBROUTINE WrOver ( Str ) ! This routine writes out a string that overwrites the previous line. diff --git a/modules-local/nwtc-library/src/SysIFL.f90 b/modules/nwtc-library/src/SysIFL.f90 similarity index 99% rename from modules-local/nwtc-library/src/SysIFL.f90 rename to modules/nwtc-library/src/SysIFL.f90 index 0405643206..14fc973377 100644 --- a/modules-local/nwtc-library/src/SysIFL.f90 +++ b/modules/nwtc-library/src/SysIFL.f90 @@ -239,7 +239,7 @@ SUBROUTINE OpenCon !bjj: Because CU = 6 now, this statement is not necessary ! OPEN ( CU , FILE='/dev/stdout' , STATUS='UNKNOWN' , CARRIAGECONTROL='FORTRAN', RECL=ConRecL ) - CALL FlushOut ( CU ) +! CALL FlushOut ( CU ) RETURN END SUBROUTINE OpenCon diff --git a/modules-local/nwtc-library/src/SysIVF.f90 b/modules/nwtc-library/src/SysIVF.f90 similarity index 99% rename from modules-local/nwtc-library/src/SysIVF.f90 rename to modules/nwtc-library/src/SysIVF.f90 index d7432e6acc..ac0c2aefdc 100644 --- a/modules-local/nwtc-library/src/SysIVF.f90 +++ b/modules/nwtc-library/src/SysIVF.f90 @@ -228,7 +228,7 @@ SUBROUTINE MKDIR ( new_directory_path ) inquire( directory=trim(new_directory_path), exist=directory_exists ) if ( .NOT. directory_exists ) then - make_command = 'mkdir '//trim(new_directory_path) + make_command = 'mkdir "'//trim(new_directory_path)//'"' call system( make_command ) endif diff --git a/modules-local/nwtc-library/src/SysIVF_Labview.f90 b/modules/nwtc-library/src/SysIVF_Labview.f90 similarity index 100% rename from modules-local/nwtc-library/src/SysIVF_Labview.f90 rename to modules/nwtc-library/src/SysIVF_Labview.f90 diff --git a/modules-local/nwtc-library/src/SysMatlab.f90 b/modules/nwtc-library/src/SysMatlab.f90 similarity index 97% rename from modules-local/nwtc-library/src/SysMatlab.f90 rename to modules/nwtc-library/src/SysMatlab.f90 index c9e88f00c8..56180f0eb4 100644 --- a/modules-local/nwtc-library/src/SysMatlab.f90 +++ b/modules/nwtc-library/src/SysMatlab.f90 @@ -276,6 +276,25 @@ FUNCTION NWTC_GammaR16( x ) NWTC_GammaR16 = gamma( x ) END FUNCTION NWTC_GammaR16 +!======================================================================= +!> This routine creates a given directory if it does not already exist. +SUBROUTINE MKDIR ( new_directory_path ) + + implicit none + + character(*), intent(in) :: new_directory_path + character(1024) :: make_command + logical :: directory_exists + + ! Check if the directory exists first + inquire( directory=trim(new_directory_path), exist=directory_exists ) + + if ( .NOT. directory_exists ) then + make_command = 'mkdir "'//trim(new_directory_path)//'"' + call system( make_command ) + endif + +END SUBROUTINE MKDIR !======================================================================= SUBROUTINE OpenCon diff --git a/modules-local/nwtc-library/src/ranlux/RANLUX.f90 b/modules/nwtc-library/src/ranlux/RANLUX.f90 similarity index 100% rename from modules-local/nwtc-library/src/ranlux/RANLUX.f90 rename to modules/nwtc-library/src/ranlux/RANLUX.f90 diff --git a/modules-local/nwtc-library/src/readme.txt b/modules/nwtc-library/src/readme.txt similarity index 100% rename from modules-local/nwtc-library/src/readme.txt rename to modules/nwtc-library/src/readme.txt diff --git a/modules-local/nwtc-library/test/Compare_LAPACK_MUMPS/Compare_LAPACK_MUMPS.f90 b/modules/nwtc-library/test/Compare_LAPACK_MUMPS/Compare_LAPACK_MUMPS.f90 similarity index 100% rename from modules-local/nwtc-library/test/Compare_LAPACK_MUMPS/Compare_LAPACK_MUMPS.f90 rename to modules/nwtc-library/test/Compare_LAPACK_MUMPS/Compare_LAPACK_MUMPS.f90 diff --git a/modules-local/nwtc-library/test/Test_CheckArgs.f90 b/modules/nwtc-library/test/Test_CheckArgs.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_CheckArgs.f90 rename to modules/nwtc-library/test/Test_CheckArgs.f90 diff --git a/modules-local/nwtc-library/test/Test_ChkRealFmtStr/Test_ChkRealFmtStr.f90 b/modules/nwtc-library/test/Test_ChkRealFmtStr/Test_ChkRealFmtStr.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_ChkRealFmtStr/Test_ChkRealFmtStr.f90 rename to modules/nwtc-library/test/Test_ChkRealFmtStr/Test_ChkRealFmtStr.f90 diff --git a/modules-local/nwtc-library/test/Test_ChkRealFmtStr/makefile b/modules/nwtc-library/test/Test_ChkRealFmtStr/makefile similarity index 100% rename from modules-local/nwtc-library/test/Test_ChkRealFmtStr/makefile rename to modules/nwtc-library/test/Test_ChkRealFmtStr/makefile diff --git a/modules-local/nwtc-library/test/Test_FileSize/Test_FileSize.f90 b/modules/nwtc-library/test/Test_FileSize/Test_FileSize.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_FileSize/Test_FileSize.f90 rename to modules/nwtc-library/test/Test_FileSize/Test_FileSize.f90 diff --git a/modules-local/nwtc-library/test/Test_FileSize/makefile b/modules/nwtc-library/test/Test_FileSize/makefile similarity index 100% rename from modules-local/nwtc-library/test/Test_FileSize/makefile rename to modules/nwtc-library/test/Test_FileSize/makefile diff --git a/modules-local/nwtc-library/test/Test_MeshMapping/Makefile b/modules/nwtc-library/test/Test_MeshMapping/Makefile similarity index 100% rename from modules-local/nwtc-library/test/Test_MeshMapping/Makefile rename to modules/nwtc-library/test/Test_MeshMapping/Makefile diff --git a/modules-local/nwtc-library/test/Test_MeshMapping/Test_MeshMapping.f90 b/modules/nwtc-library/test/Test_MeshMapping/Test_MeshMapping.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_MeshMapping/Test_MeshMapping.f90 rename to modules/nwtc-library/test/Test_MeshMapping/Test_MeshMapping.f90 diff --git a/modules-local/nwtc-library/test/Test_MeshMapping/Test_MeshMapping_Mod.f90 b/modules/nwtc-library/test/Test_MeshMapping/Test_MeshMapping_Mod.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_MeshMapping/Test_MeshMapping_Mod.f90 rename to modules/nwtc-library/test/Test_MeshMapping/Test_MeshMapping_Mod.f90 diff --git a/modules-local/nwtc-library/test/Test_NWTC_Library.f90 b/modules/nwtc-library/test/Test_NWTC_Library.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_NWTC_Library.f90 rename to modules/nwtc-library/test/Test_NWTC_Library.f90 diff --git a/modules-local/nwtc-library/test/Test_OpenCon_GnuWin/Test_OpenCon_GnuWin.f90 b/modules/nwtc-library/test/Test_OpenCon_GnuWin/Test_OpenCon_GnuWin.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_OpenCon_GnuWin/Test_OpenCon_GnuWin.f90 rename to modules/nwtc-library/test/Test_OpenCon_GnuWin/Test_OpenCon_GnuWin.f90 diff --git a/modules-local/nwtc-library/test/Test_OpenCon_GnuWin/makefile b/modules/nwtc-library/test/Test_OpenCon_GnuWin/makefile similarity index 100% rename from modules-local/nwtc-library/test/Test_OpenCon_GnuWin/makefile rename to modules/nwtc-library/test/Test_OpenCon_GnuWin/makefile diff --git a/modules-local/nwtc-library/test/Test_ReadComFile/Test_ReadComFile.f90 b/modules/nwtc-library/test/Test_ReadComFile/Test_ReadComFile.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_ReadComFile/Test_ReadComFile.f90 rename to modules/nwtc-library/test/Test_ReadComFile/Test_ReadComFile.f90 diff --git a/modules-local/nwtc-library/test/Test_ReadComFile/makefile b/modules/nwtc-library/test/Test_ReadComFile/makefile similarity index 100% rename from modules-local/nwtc-library/test/Test_ReadComFile/makefile rename to modules/nwtc-library/test/Test_ReadComFile/makefile diff --git a/modules-local/nwtc-library/test/Test_ReadFASTbin.f90 b/modules/nwtc-library/test/Test_ReadFASTbin.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_ReadFASTbin.f90 rename to modules/nwtc-library/test/Test_ReadFASTbin.f90 diff --git a/modules-local/nwtc-library/test/Test_RegCubicSpline/Test_RegCubicSpline.f90 b/modules/nwtc-library/test/Test_RegCubicSpline/Test_RegCubicSpline.f90 similarity index 100% rename from modules-local/nwtc-library/test/Test_RegCubicSpline/Test_RegCubicSpline.f90 rename to modules/nwtc-library/test/Test_RegCubicSpline/Test_RegCubicSpline.f90 diff --git a/modules-local/openfast-library/CMakeLists.txt b/modules/openfast-library/CMakeLists.txt similarity index 90% rename from modules-local/openfast-library/CMakeLists.txt rename to modules/openfast-library/CMakeLists.txt index 5233766b87..47df96e871 100644 --- a/modules-local/openfast-library/CMakeLists.txt +++ b/modules/openfast-library/CMakeLists.txt @@ -49,12 +49,10 @@ add_library(openfast_postlib src/FAST_Subs.f90 src/FAST_Solver.f90 ) -target_link_libraries(openfast_postlib openfast_prelib scfastlib foamfastlib) +target_link_libraries(openfast_postlib openfast_prelib scfastlib foamfastlib versioninfolib) -add_library(openfastlib - src/FAST_Library.f90) -target_link_libraries(openfastlib - openfast_postlib openfast_prelib scfastlib foamfastlib) +add_library(openfastlib src/FAST_Library.f90) +target_link_libraries(openfastlib openfast_postlib openfast_prelib scfastlib foamfastlib) install(TARGETS openfastlib openfast_prelib openfast_postlib EXPORT ${CMAKE_PROJECT_NAME}Libraries diff --git a/modules/openfast-library/README.md b/modules/openfast-library/README.md new file mode 100644 index 0000000000..9ca65673f9 --- /dev/null +++ b/modules/openfast-library/README.md @@ -0,0 +1,6 @@ +# OpenFAST Library Module + +## Overview +The OpenFAST Library contains all of the subroutines making up the OpenFAST +glue code. These subroutines coordinate the initialization, solving, and +data output for the multiphysics simulation. diff --git a/modules-local/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 similarity index 100% rename from modules-local/openfast-library/src/FAST_Library.f90 rename to modules/openfast-library/src/FAST_Library.f90 diff --git a/modules-local/openfast-library/src/FAST_Library.h b/modules/openfast-library/src/FAST_Library.h similarity index 100% rename from modules-local/openfast-library/src/FAST_Library.h rename to modules/openfast-library/src/FAST_Library.h diff --git a/modules-local/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 similarity index 99% rename from modules-local/openfast-library/src/FAST_Lin.f90 rename to modules/openfast-library/src/FAST_Lin.f90 index d0df4d3354..29bbffda74 100644 --- a/modules-local/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -503,6 +503,7 @@ SUBROUTINE FAST_Linearize_OP(t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD1 ErrStat = ErrID_None ErrMsg = "" + Un = -1 LinRootName = TRIM(p_FAST%OutFileRoot)//'.'//trim(num2lstr(m_FAST%NextLinTimeIndx)) @@ -966,10 +967,13 @@ subroutine cleanup() if (allocated(dYdz)) deallocate(dYdz) if (allocated(dZdz)) deallocate(dZdz) if (allocated(dZdu)) deallocate(dZdu) - if (allocated(ipiv)) deallocate(ipiv) + if (allocated(ipiv)) deallocate(ipiv) if (allocated(dUdu)) deallocate(dUdu) if (allocated(dUdy)) deallocate(dUdy) + + if (Un > 0) close(Un) + end subroutine cleanup END SUBROUTINE FAST_Linearize_OP !---------------------------------------------------------------------------------------------------------------------------------- @@ -1121,7 +1125,7 @@ END SUBROUTINE WrLinFile_txt_Head !> Routine that writes the A,B,C,D matrices from linearization to a text file. SUBROUTINE WrLinFile_txt_End(Un, p_FAST, LinData) - INTEGER(IntKi), INTENT(IN ) :: Un !< unit number + INTEGER(IntKi), INTENT(INOUT) :: Un !< unit number TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< parameters TYPE(FAST_LinType), INTENT(IN ) :: LinData !< Linearization data for individual module or glue (coupled system) @@ -1146,7 +1150,8 @@ SUBROUTINE WrLinFile_txt_End(Un, p_FAST, LinData) if (allocated(LinData%StateRel_x)) call WrPartialMatrix( LinData%StateRel_x, Un, p_FAST%OutFmt, 'State_Rel_x' ) if (allocated(LinData%StateRel_xdot)) call WrPartialMatrix( LinData%StateRel_xdot, Un, p_FAST%OutFmt, 'State_Rel_xdot' ) - close(un) + close(Un) + Un = -1 END SUBROUTINE WrLinFile_txt_End !---------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules-local/openfast-library/src/FAST_Mods.f90 b/modules/openfast-library/src/FAST_Mods.f90 similarity index 100% rename from modules-local/openfast-library/src/FAST_Mods.f90 rename to modules/openfast-library/src/FAST_Mods.f90 diff --git a/modules-local/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt similarity index 100% rename from modules-local/openfast-library/src/FAST_Registry.txt rename to modules/openfast-library/src/FAST_Registry.txt diff --git a/modules-local/openfast-library/src/FAST_Solver.f90 b/modules/openfast-library/src/FAST_Solver.f90 similarity index 99% rename from modules-local/openfast-library/src/FAST_Solver.f90 rename to modules/openfast-library/src/FAST_Solver.f90 index aff4c0299a..adfbecf129 100644 --- a/modules-local/openfast-library/src/FAST_Solver.f90 +++ b/modules/openfast-library/src/FAST_Solver.f90 @@ -2443,13 +2443,19 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & ! HD motion inputs: (from SD and ED) IF (p_FAST%CompHydro == Module_HD ) THEN - ! Make copies of the accelerations we just solved for (so we don't overwrite them) - MeshMapData%u_HD_M_LumpedMesh%RotationAcc = u_HD%Morison%LumpedMesh%RotationAcc - MeshMapData%u_HD_M_LumpedMesh%TranslationAcc = u_HD%Morison%LumpedMesh%TranslationAcc - MeshMapData%u_HD_M_DistribMesh%RotationAcc = u_HD%Morison%DistribMesh%RotationAcc - MeshMapData%u_HD_M_DistribMesh%TranslationAcc = u_HD%Morison%DistribMesh%TranslationAcc - MeshMapData%u_HD_Mesh%RotationAcc = u_HD%Mesh%RotationAcc - MeshMapData%u_HD_Mesh%TranslationAcc = u_HD%Mesh%TranslationAcc + ! Make copies of the accelerations we just solved for (so we don't overwrite them) + IF (MeshMapData%u_HD_M_LumpedMesh%Committed) THEN + MeshMapData%u_HD_M_LumpedMesh%RotationAcc = u_HD%Morison%LumpedMesh%RotationAcc + MeshMapData%u_HD_M_LumpedMesh%TranslationAcc = u_HD%Morison%LumpedMesh%TranslationAcc + ENDIF + IF (MeshMapData%u_HD_M_DistribMesh%Committed) THEN + MeshMapData%u_HD_M_DistribMesh%RotationAcc = u_HD%Morison%DistribMesh%RotationAcc + MeshMapData%u_HD_M_DistribMesh%TranslationAcc = u_HD%Morison%DistribMesh%TranslationAcc + ENDIF + IF (MeshMapData%u_HD_Mesh%Committed) THEN + MeshMapData%u_HD_Mesh%RotationAcc = u_HD%Mesh%RotationAcc + MeshMapData%u_HD_Mesh%TranslationAcc = u_HD%Mesh%TranslationAcc + ENDIF ! transfer the output data to inputs @@ -2472,13 +2478,19 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & END IF - ! put the acceleration data (calucluted in this routine) back - u_HD%Morison%LumpedMesh%RotationAcc = MeshMapData%u_HD_M_LumpedMesh%RotationAcc - u_HD%Morison%LumpedMesh%TranslationAcc = MeshMapData%u_HD_M_LumpedMesh%TranslationAcc - u_HD%Morison%DistribMesh%RotationAcc = MeshMapData%u_HD_M_DistribMesh%RotationAcc - u_HD%Morison%DistribMesh%TranslationAcc = MeshMapData%u_HD_M_DistribMesh%TranslationAcc - u_HD%Mesh%RotationAcc = MeshMapData%u_HD_Mesh%RotationAcc - u_HD%Mesh%TranslationAcc = MeshMapData%u_HD_Mesh%TranslationAcc + ! put the acceleration data (calucluted in this routine) back + IF (MeshMapData%u_HD_M_LumpedMesh%Committed) THEN + u_HD%Morison%LumpedMesh%RotationAcc = MeshMapData%u_HD_M_LumpedMesh%RotationAcc + u_HD%Morison%LumpedMesh%TranslationAcc = MeshMapData%u_HD_M_LumpedMesh%TranslationAcc + ENDIF + IF (MeshMapData%u_HD_M_DistribMesh%Committed) THEN + u_HD%Morison%DistribMesh%RotationAcc = MeshMapData%u_HD_M_DistribMesh%RotationAcc + u_HD%Morison%DistribMesh%TranslationAcc = MeshMapData%u_HD_M_DistribMesh%TranslationAcc + ENDIF + IF (MeshMapData%u_HD_Mesh%Committed) THEN + u_HD%Mesh%RotationAcc = MeshMapData%u_HD_Mesh%RotationAcc + u_HD%Mesh%TranslationAcc = MeshMapData%u_HD_Mesh%TranslationAcc + ENDIF !...... @@ -2771,12 +2783,16 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) ! These are the motions for the lumped point loads associated viscous drag on the WAMIT body and/or filled/flooded lumped forces of the WAMIT body - CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, MeshMapData%u_HD_M_LumpedMesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (MeshMapData%u_HD_M_LumpedMesh%Committed) then + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, MeshMapData%u_HD_M_LumpedMesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + endif ! These are the motions for the line2 (distributed) loads associated viscous drag on the WAMIT body and/or filled/flooded distributed forces of the WAMIT body - CALL Transfer_Point_to_Line2( y_ED2%PlatformPtMesh, MeshMapData%u_HD_M_DistribMesh, MeshMapData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (MeshMapData%u_HD_M_DistribMesh%Committed) then + CALL Transfer_Point_to_Line2( y_ED2%PlatformPtMesh, MeshMapData%u_HD_M_DistribMesh, MeshMapData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + endif !.................. ! Get ED loads input (from HD only) diff --git a/modules-local/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 similarity index 99% rename from modules-local/openfast-library/src/FAST_Subs.f90 rename to modules/openfast-library/src/FAST_Subs.f90 index b21dd1824f..343e65218e 100644 --- a/modules-local/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -23,6 +23,7 @@ MODULE FAST_Subs USE FAST_Solver USE FAST_Linear + USE VersionInfo IMPLICIT NONE @@ -1223,9 +1224,10 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! ------------------------------------------------------------------------- ! Write initialization data to FAST summary file: ! ------------------------------------------------------------------------- - - CALL FAST_WrSum( p_FAST, y_FAST, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (p_FAST%SumPrint) then + CALL FAST_WrSum( p_FAST, y_FAST, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + endif ! ------------------------------------------------------------------------- @@ -1793,6 +1795,11 @@ SUBROUTINE ValidateInputData(p, ErrStat, ErrMsg) end if + + if ( p%TurbineType /= Type_LandBased .and. .not. EqualRealNos(p%TurbinePos(3), 0.0_SiKi) ) then + call SetErrStat(ErrID_Fatal, 'Height of turbine location, TurbinePos(3), must be 0 for offshore turbines.', ErrStat, ErrMsg, RoutineName) + end if + !............................................................................................................................... ! temporary check on p_FAST%DT_out @@ -2940,9 +2947,16 @@ FUNCTION get_vtkdir_path( out_file_root ) CHARACTER(*), INTENT(IN) :: out_file_root INTEGER(IntKi) :: last_separator_index - ! get the directory of the primary input file (i.e. the case directory); PathSep comes from Sys*.f90 - last_separator_index = index(trim(out_file_root), PathSep, back=.true.) - get_vtkdir_path = trim(out_file_root(1 : last_separator_index) // 'vtk') + ! get the directory of the primary input file (i.e. the case directory); Windows can have either forward or backward slashes (compare with GetPath()) + + last_separator_index = index(out_file_root, '/', back=.true.) + last_separator_index = max( index(out_file_root, '\', back=.true.), last_separator_index ) + + if (last_separator_index==0) then + get_vtkdir_path = '.'//PathSep//'vtk' + else + get_vtkdir_path = trim(out_file_root(1 : last_separator_index) // 'vtk') + end if END FUNCTION !---------------------------------------------------------------------------------------------------------------------------------- !> This function builds the path for the vtk root file name based on the output file root @@ -2952,10 +2966,11 @@ FUNCTION get_vtkroot_path( out_file_root ) INTEGER(IntKi) :: last_separator_index INTEGER(IntKi) :: path_length - path_length = len(trim(out_file_root)) - last_separator_index = index(trim(out_file_root), PathSep, back=.true.) + last_separator_index = index(out_file_root, '/', back=.true.) + last_separator_index = max( index(out_file_root, '\', back=.true.), last_separator_index ) + get_vtkroot_path = trim( get_vtkdir_path(out_file_root) ) // PathSep & - // out_file_root( last_separator_index + 1 : path_length) + // out_file_root( last_separator_index + 1 :) END FUNCTION !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets up some of the information needed for plotting VTK surfaces. It initializes only the data needed before @@ -3066,6 +3081,7 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_H if (p_FAST%CompHydro == MODULE_HD) then RefLengths = p_FAST%VTK_Surface%GroundRad*VTK_GroundFactor/2.0_SiKi + ! note that p_FAST%TurbinePos(3) must be 0 for offshore turbines RefPoint(3) = p_FAST%TurbinePos(3) - InitOutData_HD%WtrDpth call WrVTK_Ground ( RefPoint, RefLengths, trim(VTK_path) // '.SeabedSurface', ErrStat2, ErrMsg2 ) @@ -3189,9 +3205,14 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_H call move_alloc( InitInData_HD%WaveElevXY, p_FAST%VTK_Surface%WaveElevXY ) call move_alloc( InitOutData_HD%WaveElevSeries, p_FAST%VTK_Surface%WaveElev ) - p_FAST%VTK_Surface%WaveElevXY(1,:) = p_FAST%VTK_Surface%WaveElevXY(1,:) + p_FAST%TurbinePos(1) - p_FAST%VTK_Surface%WaveElevXY(2,:) = p_FAST%VTK_Surface%WaveElevXY(2,:) + p_FAST%TurbinePos(2) - p_FAST%VTK_Surface%WaveElev = p_FAST%VTK_Surface%WaveElev + p_FAST%TurbinePos(3) ! not sure this is really accurrate if p_FAST%TurbinePos(3) is non-zero + ! put the following lines in loops to avoid stack-size issues: + do k=1,size(p_FAST%VTK_Surface%WaveElevXY,2) + p_FAST%VTK_Surface%WaveElevXY(:,k) = p_FAST%VTK_Surface%WaveElevXY(:,k) + p_FAST%TurbinePos(1:2) + end do + + !do k=1,size(p_FAST%VTK_Surface%WaveElev,2) + ! p_FAST%VTK_Surface%WaveElev(:,k) = p_FAST%VTK_Surface%WaveElev(:,k) + p_FAST%TurbinePos(3) ! not sure this is really accurate if p_FAST%TurbinePos(3) is non-zero + !end do end if @@ -5018,9 +5039,13 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD14, AD, IfW, O CHARACTER(ErrMsgLen) :: ErrMSg2 CHARACTER(*), PARAMETER :: RoutineName = 'WrVTK_AllMeshes' - ! calculate the number of digits in 'y_FAST%NOutSteps' (Maximum number of output steps to be written) - ! this will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK() - Twidth = int(log10(real(y_FAST%NOutSteps))) + 1 + ! Calculate the number of digits for the maximum number of output steps to be written. + ! This will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK() + if ( (p_FAST%n_VTKTime>0) .and. (p_FAST%n_TMax_m1+1>0) ) then + Twidth = CEILING( log10( real(p_FAST%n_TMax_m1+1, ReKi) / p_FAST%n_VTKTime ) ) + 1 + else + Twidth = 1 + endif NumBl = 0 if (allocated(ED%Output)) then @@ -5247,9 +5272,13 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD14, AD, IfW, CHARACTER(ErrMsgLen) :: ErrMSg2 CHARACTER(*), PARAMETER :: RoutineName = 'WrVTK_BasicMeshes' - ! calculate the number of digits in 'y_FAST%NOutSteps' (Maximum number of output steps to be written) - ! this will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK() - Twidth = int(log10(real(y_FAST%NOutSteps))) + 1 + ! Calculate the number of digits for the maximum number of output steps to be written. + ! This will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK() + if ( (p_FAST%n_VTKTime>0) .and. (p_FAST%n_TMax_m1+1>0) ) then + Twidth = CEILING( log10( real(p_FAST%n_TMax_m1+1, ReKi) / p_FAST%n_VTKTime ) ) + 1 + else + Twidth = 1 + endif NumBl = 0 @@ -5356,9 +5385,13 @@ SUBROUTINE WrVTK_Surfaces(t_global, p_FAST, y_FAST, MeshMapData, ED, BD, AD14, A CHARACTER(ErrMsgLen) :: ErrMSg2 CHARACTER(*), PARAMETER :: RoutineName = 'WrVTK_Surfaces' - ! calculate the number of digits in 'y_FAST%NOutSteps' (Maximum number of output steps to be written) - ! this will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK_...() - Twidth = int(log10(real(y_FAST%NOutSteps))) + 1 + ! Calculate the number of digits for the maximum number of output steps to be written. + ! This will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK() + if ( (p_FAST%n_VTKTime>0) .and. (p_FAST%n_TMax_m1+1>0) ) then + Twidth = CEILING( log10( real(p_FAST%n_TMax_m1+1, ReKi) / p_FAST%n_VTKTime ) ) + 1 + else + Twidth = 1 + endif NumBl = 0 @@ -5480,10 +5513,13 @@ SUBROUTINE WrVTK_WaveElev(t_global, p_FAST, y_FAST, HD) !................................................................. ! write the data that potentially changes each time step: !................................................................. - - ! calculate the number of digits in 'y_FAST%NOutSteps' (Maximum number of output steps to be written) - ! this will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK_...() - Twidth = int(log10(real(y_FAST%NOutSteps))) + 1 + ! Calculate the number of digits for the maximum number of output steps to be written. + ! This will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK() + if ( (p_FAST%n_VTKTime>0) .and. (p_FAST%n_TMax_m1+1>0) ) then + Twidth = CEILING( log10( real(p_FAST%n_TMax_m1+1, ReKi) / p_FAST%n_VTKTime ) ) + 1 + else + Twidth = 1 + endif VTK_path = get_vtkroot_path( p_FAST%OutFileRoot ) diff --git a/modules-local/openfast-library/src/OutListParameters.xlsx b/modules/openfast-library/src/OutListParameters.xlsx similarity index 100% rename from modules-local/openfast-library/src/OutListParameters.xlsx rename to modules/openfast-library/src/OutListParameters.xlsx diff --git a/modules-local/openfast-registry/CMakeLists.txt b/modules/openfast-registry/CMakeLists.txt similarity index 84% rename from modules-local/openfast-registry/CMakeLists.txt rename to modules/openfast-registry/CMakeLists.txt index 9865c5232c..8e373eb4ac 100644 --- a/modules-local/openfast-registry/CMakeLists.txt +++ b/modules/openfast-registry/CMakeLists.txt @@ -30,6 +30,6 @@ set(REGISTRY_SOURCES add_executable(openfast_registry ${REGISTRY_SOURCES}) set_target_properties(openfast_registry PROPERTIES - RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/modules-local/openfast-registry - RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/modules-local/openfast-registry + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/modules/openfast-registry + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/modules/openfast-registry ) diff --git a/modules/openfast-registry/README.md b/modules/openfast-registry/README.md new file mode 100644 index 0000000000..985db5770b --- /dev/null +++ b/modules/openfast-registry/README.md @@ -0,0 +1,64 @@ +# OpenFAST Registry Module +The legacy version of this module and additional documentation are available +at the [NWTC Legacy Repository](https://github.com/old-NWTC/FAST_Registry). + +## Overview +The OpenFAST Registry is a utility for generating code for module data types in +the OpenFAST Framework. + +The OpenFAST Registry allows the developer to specify the data types for a +module once and in a single location, automating the time consuming and +error-prone task of generating the code. The tables in the Registry text input +files serve as a data dictionary for improving understandability and +maintainability of the code. + +The FAST Registry is borrowed from a mechanism that was originally developed at +NCAR for the [Weather Research and Forecast (WRF) model software] +(http://www.mmm.ucar.edu/wrf/WG2/software_2.0/registry_schaffer.pdf). It has +been modified for the FAST Modularization Framework to +create *ModuleName*_Types.f90 files along with any necessary C source code or +header files associated with the *ModuleName*_Types.f90 files. + +## Syntax +To create *ModuleName*_Types.f90 from data defined in RegistryFile.txt: +``` + >>> openfast_registry RegistryFile.txt [options] +``` +To create template *ModuleName*_Registry.txt file: +``` + >>> openfast_registry -registry ModuleName ModName +``` +To create template file for *ModuleName*.f90: +``` + >>> openfast_registry -template ModuleName ModName +``` +Summary of options: + +``` + >>> openfast_registry -h + + ----- FAST Registry (v3.01.00, 11-Jan-2016) -------------- + ---------------------------------------------------------- + Usage: Registry_win32.exe registryfile [options] -or- + [-force] [-template|-registry] ModuleName ModName + Options: + -h this summary + -I look for usefrom files in directory "dir" + -O generate types files in directory "dir" + -noextrap do not generate ModName_Input_ExtrapInterp or ModName_Output_ExtrapInterp routines + -D define symbol for conditional evaluation inside registry file + -ccode generate additional code for interfacing with C/C++ + -keep do not delete temporary files from registry program + -shownodes output a listing of the nodes in registry's AST + === alternate usage for generating templates === + -template ModuleName ModName + Generate a template Module file none exists + -registry ModuleName ModName + Generate a template registry file if none exists + -force Force generating of template or registry file + (the / character can be used in place of - when specifying options) +``` + +## Manual +For more information and syntax, please refer to the +[NWTC Programmer's Handbook](https://nwtc.nrel.gov/system/files/ProgrammingHandbook_Mod20130717.pdf). diff --git a/modules-local/openfast-registry/src/FAST_preamble.h b/modules/openfast-registry/src/FAST_preamble.h similarity index 100% rename from modules-local/openfast-registry/src/FAST_preamble.h rename to modules/openfast-registry/src/FAST_preamble.h diff --git a/modules-local/openfast-registry/src/Makefile b/modules/openfast-registry/src/Makefile similarity index 100% rename from modules-local/openfast-registry/src/Makefile rename to modules/openfast-registry/src/Makefile diff --git a/modules-local/openfast-registry/src/Template_data.c b/modules/openfast-registry/src/Template_data.c similarity index 100% rename from modules-local/openfast-registry/src/Template_data.c rename to modules/openfast-registry/src/Template_data.c diff --git a/modules-local/openfast-registry/src/Template_registry.c b/modules/openfast-registry/src/Template_registry.c similarity index 100% rename from modules-local/openfast-registry/src/Template_registry.c rename to modules/openfast-registry/src/Template_registry.c diff --git a/modules-local/openfast-registry/src/data.c b/modules/openfast-registry/src/data.c similarity index 100% rename from modules-local/openfast-registry/src/data.c rename to modules/openfast-registry/src/data.c diff --git a/modules-local/openfast-registry/src/data.h b/modules/openfast-registry/src/data.h similarity index 100% rename from modules-local/openfast-registry/src/data.h rename to modules/openfast-registry/src/data.h diff --git a/modules-local/openfast-registry/src/gen_c_types.c b/modules/openfast-registry/src/gen_c_types.c similarity index 100% rename from modules-local/openfast-registry/src/gen_c_types.c rename to modules/openfast-registry/src/gen_c_types.c diff --git a/modules-local/openfast-registry/src/gen_module_files.c b/modules/openfast-registry/src/gen_module_files.c similarity index 100% rename from modules-local/openfast-registry/src/gen_module_files.c rename to modules/openfast-registry/src/gen_module_files.c diff --git a/modules-local/openfast-registry/src/misc.c b/modules/openfast-registry/src/misc.c similarity index 99% rename from modules-local/openfast-registry/src/misc.c rename to modules/openfast-registry/src/misc.c index 0e76fdd744..628aa05bc4 100644 --- a/modules-local/openfast-registry/src/misc.c +++ b/modules/openfast-registry/src/misc.c @@ -5,6 +5,8 @@ #ifdef _WIN32 # define rindex(X,Y) strrchr(X,Y) # define index(X,Y) strchr(X,Y) +# include +# define getpid _getpid #else # include # include diff --git a/modules-local/openfast-registry/src/my_strtok.c b/modules/openfast-registry/src/my_strtok.c similarity index 100% rename from modules-local/openfast-registry/src/my_strtok.c rename to modules/openfast-registry/src/my_strtok.c diff --git a/modules-local/openfast-registry/src/protos.h b/modules/openfast-registry/src/protos.h similarity index 100% rename from modules-local/openfast-registry/src/protos.h rename to modules/openfast-registry/src/protos.h diff --git a/modules-local/openfast-registry/src/reg_parse.c b/modules/openfast-registry/src/reg_parse.c similarity index 100% rename from modules-local/openfast-registry/src/reg_parse.c rename to modules/openfast-registry/src/reg_parse.c diff --git a/modules-local/openfast-registry/src/registry.c b/modules/openfast-registry/src/registry.c similarity index 99% rename from modules-local/openfast-registry/src/registry.c rename to modules/openfast-registry/src/registry.c index c33b8bc301..2fe9dc566e 100644 --- a/modules-local/openfast-registry/src/registry.c +++ b/modules/openfast-registry/src/registry.c @@ -5,6 +5,8 @@ # include # define rindex(X,Y) strrchr(X,Y) # define index(X,Y) strchr(X,Y) +# include +# define getpid _getpid #else # include # include diff --git a/modules-local/openfast-registry/src/registry.h b/modules/openfast-registry/src/registry.h similarity index 100% rename from modules-local/openfast-registry/src/registry.h rename to modules/openfast-registry/src/registry.h diff --git a/modules-local/openfast-registry/src/sym.c b/modules/openfast-registry/src/sym.c similarity index 100% rename from modules-local/openfast-registry/src/sym.c rename to modules/openfast-registry/src/sym.c diff --git a/modules-local/openfast-registry/src/sym.h b/modules/openfast-registry/src/sym.h similarity index 100% rename from modules-local/openfast-registry/src/sym.h rename to modules/openfast-registry/src/sym.h diff --git a/modules-local/openfast-registry/src/symtab_gen.c b/modules/openfast-registry/src/symtab_gen.c similarity index 100% rename from modules-local/openfast-registry/src/symtab_gen.c rename to modules/openfast-registry/src/symtab_gen.c diff --git a/modules-local/openfast-registry/src/type.c b/modules/openfast-registry/src/type.c similarity index 100% rename from modules-local/openfast-registry/src/type.c rename to modules/openfast-registry/src/type.c diff --git a/modules-local/openfoam/CMakeLists.txt b/modules/openfoam/CMakeLists.txt similarity index 100% rename from modules-local/openfoam/CMakeLists.txt rename to modules/openfoam/CMakeLists.txt diff --git a/modules/openfoam/README.md b/modules/openfoam/README.md new file mode 100644 index 0000000000..0d57400745 --- /dev/null +++ b/modules/openfoam/README.md @@ -0,0 +1,5 @@ +# OpenFOAM Module + +## Overview +This is a pseudo module used to couple OpenFAST with OpenFOAM; +it is considered part of the OpenFAST glue code. diff --git a/modules-local/openfoam/src/OpenFOAM.f90 b/modules/openfoam/src/OpenFOAM.f90 similarity index 98% rename from modules-local/openfoam/src/OpenFOAM.f90 rename to modules/openfoam/src/OpenFOAM.f90 index b63425f816..3523b16028 100644 --- a/modules-local/openfoam/src/OpenFOAM.f90 +++ b/modules/openfoam/src/OpenFOAM.f90 @@ -1024,9 +1024,10 @@ SUBROUTINE CalcForceActuatorPositionsBlade(InitIn_OpFM, p_OpFM, structPositions, ! Now calculate the positions of the force nodes based on interpolation forceNodePositions(:,1) = structPositions(:,1) DO I=2,p_OpFM%NnodesForceBlade-1 ! Calculate the position of the force nodes - jLower=1 - do while ( ( (rStructNodes(jLower) - p_OpFM%forceBldRnodes(I))*(rStructNodes(jLower+1) - p_OpFM%forceBldRnodes(I)) .gt. 0) .and. (jLower .lt. nStructNodes) ) - jLower = jLower + 1 + do jLower = 1, (nStructNodes - 1) + if ((rStructNodes(jLower) - p_OpFM%forceBldRnodes(I))*(rStructNodes(jLower+1) - p_OpFM%forceBldRnodes(I)) .le. 0) then + exit + endif end do rInterp = (p_OpFM%forceBldRnodes(I) - rStructNodes(jLower))/(rStructNodes(jLower+1)-rStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes forceNodePositions(:,I) = structPositions(:,jLower) + rInterp * (structPositions(:,jLower+1) - structPositions(:,jLower)) @@ -1067,10 +1068,11 @@ SUBROUTINE CalcForceActuatorPositionsTower(InitIn_OpFM, p_OpFM, structPositions, ! Now calculate the positions of the force nodes based on interpolation forceNodePositions(:,1) = structPositions(:,1) DO I=2,p_OpFM%NnodesForceTower-1 ! Calculate the position of the force nodes - jLower=1 - do while ( ((hStructNodes(jLower) - p_OpFM%forceTwrHnodes(I))*(hStructNodes(jLower+1) - p_OpFM%forceTwrHnodes(I)) .gt. 0) .and. (jLower .lt. nStructNodes)) - jLower = jLower + 1 - end do + do jLower = 1, (nStructNodes - 1) + if ((hStructNodes(jLower) - p_OpFM%forceTwrHnodes(I))*(hStructNodes(jLower+1) - p_OpFM%forceTwrHnodes(I)) .le. 0) then + exit + endif + enddo hInterp = (p_OpFM%forceTwrHnodes(I) - hStructNodes(jLower))/(hStructNodes(jLower+1)-hStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes forceNodePositions(:,I) = structPositions(:,jLower) + hInterp * (structPositions(:,jLower+1) - structPositions(:,jLower)) END DO @@ -1138,7 +1140,7 @@ SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat, INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None REAL(ReKi) :: rInterp ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes - + ! Set the chord for the hub node to be zero. Ideally, I'd like this to be the hub radius. Will figure this out later. Node = 1 u_OpFM%forceNodesChord(Node) = 0.0_ReKi @@ -1149,10 +1151,11 @@ SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat, nNodesBladeProps = SIZE(InitOut_AD%BladeProps(k)%BlChord) DO I=1,p_OpFM%NnodesForceBlade Node = Node + 1 - jLower=1 - do while ( ( (InitOut_AD%BladeProps(k)%BlSpn(jLower) - p_OpFM%forceBldRnodes(I))*(InitOut_AD%BladeProps(k)%BlSpn(jLower+1) - p_OpFM%forceBldRnodes(I)) .gt. 0 ) .and. (jLower .lt. nNodesBladeProps) )!Determine the closest two nodes at which the blade properties are specified - jLower = jLower + 1 - end do + do jLower = 1, (nNodesBladeProps - 1) + if ( (InitOut_AD%BladeProps(k)%BlSpn(jLower) - p_OpFM%forceBldRnodes(I))*(InitOut_AD%BladeProps(k)%BlSpn(jLower+1) - p_OpFM%forceBldRnodes(I)) .le. 0 ) then + exit + endif + enddo if (jLower .lt. nNodesBladeProps) then rInterp = (p_OpFM%forceBldRnodes(I) - InitOut_AD%BladeProps(k)%BlSpn(jLower))/(InitOut_AD%BladeProps(k)%BlSpn(jLower+1)-InitOut_AD%BladeProps(k)%BlSpn(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes u_OpFM%forceNodesChord(Node) = InitOut_AD%BladeProps(k)%BlChord(jLower) + rInterp * (InitOut_AD%BladeProps(k)%BlChord(jLower+1) - InitOut_AD%BladeProps(k)%BlChord(jLower)) @@ -1171,10 +1174,11 @@ SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat, ! Calculate the chord at the force nodes based on interpolation DO I=1,p_OpFM%NnodesForceTower Node = Node + 1 - jLower=1 - do while ( ( (InitOut_AD%TwrElev(jLower) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight)*(InitOut_AD%TwrElev(jLower+1) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight) .gt. 0) .and. (jLower .lt. nNodesTowerProps) ) !Determine the closest two nodes at which the blade properties are specified - jLower = jLower + 1 - end do + do jLower = 1, (nNodesTowerProps - 1) + if ( (InitOut_AD%TwrElev(jLower) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight)*(InitOut_AD%TwrElev(jLower+1) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight) .le. 0) then + exit + endif + enddo if (jLower .lt. nNodesTowerProps) then rInterp = (p_OpFM%forceTwrHnodes(I)+p_OpFM%TowerBaseHeight - InitOut_AD%TwrElev(jLower))/(InitOut_AD%TwrElev(jLower+1)-InitOut_AD%TwrElev(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes u_OpFM%forceNodesChord(Node) = InitOut_AD%TwrDiam(jLower) + rInterp * (InitOut_AD%TwrDiam(jLower+1) - InitOut_AD%TwrDiam(jLower)) diff --git a/modules-local/openfoam/src/OpenFOAM_Registry.txt b/modules/openfoam/src/OpenFOAM_Registry.txt similarity index 100% rename from modules-local/openfoam/src/OpenFOAM_Registry.txt rename to modules/openfoam/src/OpenFOAM_Registry.txt diff --git a/modules-local/orcaflex-interface/CMakeLists.txt b/modules/orcaflex-interface/CMakeLists.txt similarity index 100% rename from modules-local/orcaflex-interface/CMakeLists.txt rename to modules/orcaflex-interface/CMakeLists.txt diff --git a/modules/orcaflex-interface/README.md b/modules/orcaflex-interface/README.md new file mode 100644 index 0000000000..ccf27b6cdf --- /dev/null +++ b/modules/orcaflex-interface/README.md @@ -0,0 +1,28 @@ +# OrcaFlex Interface Module +The legacy version of this module and additional documentation are available +the [NWTC Software Portal](https://nwtc.nrel.gov/OrcaFlexInterface/). + +## Overview +OrcaFlex is a commercial software package developed by Orcina for the design +and analysis of marine systems. When the OrcaFlexInterface module is used in +OpenFAST, all hydrodynamic and mooring loads will be computed using OrcaFlex, +while the turbine, tower, and floating platform structural dynamics; +aerodynamics; and control and electrical-drive dynamics will be computed by +OpenFAST. + +To use this module with OpenFAST, you will need the following: +- OpenFAST for Windows® +- A valid OrcaFlex license +- FASTlinkDLL.dll; This DLL is compiled by Orcina and is called by OpenFAST + during the simulation to compute the loads on the platform by OrcaFlex. + Both 32- and 64-bit versions of FASTlinkDLL.dll, which are compatible with + the 32- and 64-bit Windows executable versions of OpenFAST, are available + at https://orcina.com/Support/FASTlink.zip. + +## Sample Models +Sample models for OpenFAST and OrcaFlexInterface can be downloaded +[here](https://nwtc.nrel.gov/enduser). + +This self-extracting archive for Windows contains documentation on using the +OpenFAST-OrcaFlex interface as well as several sample models set to call +FASTlinkDLL. diff --git a/modules-local/orcaflex-interface/src/OrcaDriver.f90 b/modules/orcaflex-interface/src/OrcaDriver.f90 similarity index 100% rename from modules-local/orcaflex-interface/src/OrcaDriver.f90 rename to modules/orcaflex-interface/src/OrcaDriver.f90 diff --git a/modules-local/orcaflex-interface/src/OrcaDriver_Subs.f90 b/modules/orcaflex-interface/src/OrcaDriver_Subs.f90 similarity index 100% rename from modules-local/orcaflex-interface/src/OrcaDriver_Subs.f90 rename to modules/orcaflex-interface/src/OrcaDriver_Subs.f90 diff --git a/modules-local/orcaflex-interface/src/OrcaDriver_Types.f90 b/modules/orcaflex-interface/src/OrcaDriver_Types.f90 similarity index 100% rename from modules-local/orcaflex-interface/src/OrcaDriver_Types.f90 rename to modules/orcaflex-interface/src/OrcaDriver_Types.f90 diff --git a/modules-local/orcaflex-interface/src/OrcaFlexInterface.f90 b/modules/orcaflex-interface/src/OrcaFlexInterface.f90 similarity index 100% rename from modules-local/orcaflex-interface/src/OrcaFlexInterface.f90 rename to modules/orcaflex-interface/src/OrcaFlexInterface.f90 diff --git a/modules-local/orcaflex-interface/src/OrcaFlexInterface.txt b/modules/orcaflex-interface/src/OrcaFlexInterface.txt similarity index 100% rename from modules-local/orcaflex-interface/src/OrcaFlexInterface.txt rename to modules/orcaflex-interface/src/OrcaFlexInterface.txt diff --git a/modules-local/orcaflex-interface/src/OutListParameters.xlsx b/modules/orcaflex-interface/src/OutListParameters.xlsx similarity index 100% rename from modules-local/orcaflex-interface/src/OutListParameters.xlsx rename to modules/orcaflex-interface/src/OutListParameters.xlsx diff --git a/modules-local/servodyn/CMakeLists.txt b/modules/servodyn/CMakeLists.txt similarity index 100% rename from modules-local/servodyn/CMakeLists.txt rename to modules/servodyn/CMakeLists.txt diff --git a/modules/servodyn/README.md b/modules/servodyn/README.md new file mode 100644 index 0000000000..e1d6505087 --- /dev/null +++ b/modules/servodyn/README.md @@ -0,0 +1,16 @@ +# ServoDyn Module +The legacy version of TMD and additional documentation are available +at the [NWTC Software Portal](https://nwtc.nrel.gov/TMD/). + +## Overview +ServoDyn is the control and Electrical Drive Dynamics Module for the +OpenFAST framework. + +Included in ServoDyn is the tuned mass damper (TMD) module which adds +functionality to OpenFAST that simulates the addition of TMDs in the +nacelle and/or tower for structural control. The TMDs are two independent, +one-DOF, linear mass-spring-damping elements that act in the fore-aft and +side-side directions or one single omni-directional TMD. They can be placed +relative to the nacelle reference position or base of the undeflected tower +using the options in the input file. The TMD module is added as a sub-module +of ServoDyn. diff --git a/modules-local/servodyn/src/BladedInterface.f90 b/modules/servodyn/src/BladedInterface.f90 similarity index 100% rename from modules-local/servodyn/src/BladedInterface.f90 rename to modules/servodyn/src/BladedInterface.f90 diff --git a/modules-local/servodyn/src/PitchCntrl_ACH.f90 b/modules/servodyn/src/PitchCntrl_ACH.f90 similarity index 100% rename from modules-local/servodyn/src/PitchCntrl_ACH.f90 rename to modules/servodyn/src/PitchCntrl_ACH.f90 diff --git a/modules-local/servodyn/src/ServoDyn.f90 b/modules/servodyn/src/ServoDyn.f90 similarity index 99% rename from modules-local/servodyn/src/ServoDyn.f90 rename to modules/servodyn/src/ServoDyn.f90 index c6dca6970d..a47f726900 100644 --- a/modules-local/servodyn/src/ServoDyn.f90 +++ b/modules/servodyn/src/ServoDyn.f90 @@ -835,20 +835,20 @@ SUBROUTINE SrvD_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState, !............................................................................................................................... ! Torque control - CALL Torque_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2 ) + CALL Torque_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Pitch control: - CALL Pitch_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) + CALL Pitch_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Yaw control: - CALL Yaw_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) + CALL Yaw_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Tip brake control: - CALL TipBrake_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) + CALL TipBrake_UpdateStates( t_next, u_interp, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) !............................................................................................................................... diff --git a/modules-local/servodyn/src/ServoDyn_Driver.f90 b/modules/servodyn/src/ServoDyn_Driver.f90 similarity index 100% rename from modules-local/servodyn/src/ServoDyn_Driver.f90 rename to modules/servodyn/src/ServoDyn_Driver.f90 diff --git a/modules-local/servodyn/src/ServoDyn_Registry.txt b/modules/servodyn/src/ServoDyn_Registry.txt similarity index 100% rename from modules-local/servodyn/src/ServoDyn_Registry.txt rename to modules/servodyn/src/ServoDyn_Registry.txt diff --git a/modules-local/servodyn/src/TMD.f90 b/modules/servodyn/src/TMD.f90 similarity index 99% rename from modules-local/servodyn/src/TMD.f90 rename to modules/servodyn/src/TMD.f90 index 5703076bdf..0481f691f4 100644 --- a/modules-local/servodyn/src/TMD.f90 +++ b/modules/servodyn/src/TMD.f90 @@ -1135,7 +1135,7 @@ SUBROUTINE SpringForceExtrapInterp(x, p, F_table) Nrows = SIZE(p%F_TBL,1) ALLOCATE(TmpRAry(Nrows),STAT=ErrStat2) IF (ErrStat2 /= 0) then - CALL WrScr('Error allocating temp array. TMD stiffness results may be inaccurrate.') + CALL WrScr('Error allocating temp array. TMD stiffness results may be inaccurate.') RETURN END IF diff --git a/modules-local/servodyn/src/TMD_Driver.f90 b/modules/servodyn/src/TMD_Driver.f90 similarity index 100% rename from modules-local/servodyn/src/TMD_Driver.f90 rename to modules/servodyn/src/TMD_Driver.f90 diff --git a/modules-local/servodyn/src/TMD_Registry.txt b/modules/servodyn/src/TMD_Registry.txt similarity index 100% rename from modules-local/servodyn/src/TMD_Registry.txt rename to modules/servodyn/src/TMD_Registry.txt diff --git a/modules-local/servodyn/src/UserSubs.f90 b/modules/servodyn/src/UserSubs.f90 similarity index 100% rename from modules-local/servodyn/src/UserSubs.f90 rename to modules/servodyn/src/UserSubs.f90 diff --git a/modules-local/servodyn/src/UserVSCont_KP.f90 b/modules/servodyn/src/UserVSCont_KP.f90 similarity index 100% rename from modules-local/servodyn/src/UserVSCont_KP.f90 rename to modules/servodyn/src/UserVSCont_KP.f90 diff --git a/modules-local/subdyn/CMakeLists.txt b/modules/subdyn/CMakeLists.txt similarity index 94% rename from modules-local/subdyn/CMakeLists.txt rename to modules/subdyn/CMakeLists.txt index b94e79e806..c5e5c3ae80 100644 --- a/modules-local/subdyn/CMakeLists.txt +++ b/modules/subdyn/CMakeLists.txt @@ -32,7 +32,7 @@ set(SUBDYN_DRIVER_SOURCES src/SubDyn_Driver.f90) add_executable(subdyn_driver ${SUBDYN_DRIVER_SOURCES}) -target_link_libraries(subdyn_driver subdynlib nwtclibs) +target_link_libraries(subdyn_driver subdynlib nwtclibs versioninfolib) install(TARGETS subdynlib subdyn_driver EXPORT "${CMAKE_PROJECT_NAME}Libraries" diff --git a/modules/subdyn/README.md b/modules/subdyn/README.md new file mode 100644 index 0000000000..1e5f84bec7 --- /dev/null +++ b/modules/subdyn/README.md @@ -0,0 +1,25 @@ +# SubDyn Module +The legacy version of this module and additional documentation are available +at the [NWTC Software Portal](https://nwtc.nrel.gov/SubDyn/). + +## Overview +SubDyn is a time-domain structural-dynamics module for multi-member +fixed-bottom substructures that has been coupled into the OpenFAST +aero-hydro-servo-elastic computer-aided engineering (CAE) tool. Substructure +types supported by SubDyn include monopiles, tripods, jackets, and other +lattice-type substructures common for offshore wind installations in shallow +and transitional water depths. SubDyn can also be used to model lattice +support structures for land-based wind turbines. + +SubDyn follows the requirements of the FAST modularization framework and +couples to OpenFAST. It can also be driven as a standalone code to compute +the mode shapes, natural frequencies, and time-domain responses of +substructures, uncoupled from OpenFAST and in the absence of external loading +other than gravity and interface motion. + +SubDyn relies on two main engineering schematizations +1. a linear frame finite-element beam model (LFEB) +2. a dynamics system reduction via Craig-Bampton’s (C-B) method + +together with a Static-Improvement method, greatly reducing the number of modes +needed to obtain an accurate solution. diff --git a/modules-local/subdyn/src/SD_FEM.f90 b/modules/subdyn/src/SD_FEM.f90 similarity index 100% rename from modules-local/subdyn/src/SD_FEM.f90 rename to modules/subdyn/src/SD_FEM.f90 diff --git a/modules-local/subdyn/src/SubDyn.f90 b/modules/subdyn/src/SubDyn.f90 similarity index 98% rename from modules-local/subdyn/src/SubDyn.f90 rename to modules/subdyn/src/SubDyn.f90 index 3a789ac2cc..39830a31a6 100644 --- a/modules-local/subdyn/src/SubDyn.f90 +++ b/modules/subdyn/src/SubDyn.f90 @@ -4153,32 +4153,61 @@ END SUBROUTINE OutSummary !------------------------------------------------------------------------------------------------------ !------------------------------------------------------------------------------------------------------ +!> This function calculates the length of a member FUNCTION MemberLength(MemberID,Init,ErrStat,ErrMsg) -!Function to calculate Member Length - TYPE(SD_InitType), INTENT(IN) :: Init ! Input data for initialization routine, this structure contains many variables needed for summary file - INTEGER(IntKi), INTENT(IN) :: MemberID !Member ID # - REAL(ReKi) :: MemberLength !Member Length - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - !LOCALS - REAL(Reki) :: xyz1(3),xyz2(3) !coordinates of joints in GLOBAL REF SYS - INTEGER(IntKi) ::i !counter -!This function calculates the length of a member !This assumes members + TYPE(SD_InitType), INTENT(IN) :: Init !< Input data for initialization routine, this structure contains many variables needed for summary file + INTEGER(IntKi), INTENT(IN) :: MemberID !< Member ID # + REAL(ReKi) :: MemberLength !< Member Length + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + !Locals + REAL(Reki) :: xyz1(3),xyz2(3) ! Coordinates of joints in GLOBAL REF SYS + INTEGER(IntKi) :: i ! Counter + INTEGER(IntKi) :: Joint1,Joint2 ! JointID + CHARACTER(*), PARAMETER :: RoutineName = 'MemberLength' + ErrStat = ErrID_None + ErrMsg = '' + MemberLength=0.0 + !Find the MemberID in the list - ErrStat = ErrID_Fatal - ErrMsg = 'Error calculating length of Member in Function MemberLength' - MemberLength=0.0 - - DO i=1,SIZE(Init%Members, DIM=1) !tried where here and could not make it scalara - IF (Init%Members(i,1) .EQ. MemberID) THEN - xyz1= Init%Joints(Init%Members(i,2),2:4) - xyz2= Init%Joints(Init%Members(i,3),2:4) - MemberLength=SQRT( SUM((xyz2-xyz1)**2.) ) - ErrStat = ErrID_None - ErrMsg = '' - EXIT - ENDIF + DO i=1,SIZE(Init%Members, DIM=1) + IF (Init%Members(i,1) .EQ. MemberID) THEN + ! Find joints ID for this member + Joint1 = FindNode(i,1); if (Joint1<0) return + Joint2 = FindNode(i,2); if (Joint2<0) return + xyz1= Init%Joints(Joint1,2:4) + xyz2= Init%Joints(Joint2,2:4) + MemberLength=SQRT( SUM((xyz2-xyz1)**2.) ) + if ( EqualRealNos(MemberLength, 0.0_ReKi) ) then + call SetErrStat(ErrID_Fatal,' Member with ID '//trim(Num2LStr(MemberID))//' has zero length!', ErrStat,ErrMsg,RoutineName); + return + endif + return + ENDIF ENDDO + call SetErrStat(ErrID_Fatal,' Member with ID '//trim(Num2LStr(MemberID))//' not found in member list!', ErrStat,ErrMsg,RoutineName); + +contains + !> Find JointID for node `iNode` (1 or 2) or member `iMember` + integer(IntKi) function FindNode(iMember,iNode) result(j) + integer(IntKi), intent(in) :: iMember !< Member index in Init%Members list + integer(IntKi), intent(in) :: iNode !< Node index, 1 or 2 for the member iMember + logical :: found + found = .false. + j=1 + do while ( .not. found .and. j <= Init%NJoints ) + if (Init%Members(iMember, iNode+1) == nint(Init%Joints(j,1))) then ! Columns 2/3 for iNode 1/2 + found = .true. + exit + endif + j = j + 1 + enddo + if (.not.found) then + j=-1 + call SetErrStat(ErrID_Fatal,' Member '//trim(Num2LStr(iMember))//' has JointID'//trim(Num2LStr(iNode))//' = '//& + trim(Num2LStr(Init%Members(iMember,iNode+1)))//' which is not in the node list !', ErrStat,ErrMsg,RoutineName) + endif + end function END FUNCTION MemberLength !------------------------------------------------------------------------------------------------------ diff --git a/modules-local/subdyn/src/SubDyn_Driver.f90 b/modules/subdyn/src/SubDyn_Driver.f90 similarity index 99% rename from modules-local/subdyn/src/SubDyn_Driver.f90 rename to modules/subdyn/src/SubDyn_Driver.f90 index 450911ebb3..cc6c4026ea 100644 --- a/modules-local/subdyn/src/SubDyn_Driver.f90 +++ b/modules/subdyn/src/SubDyn_Driver.f90 @@ -25,6 +25,7 @@ PROGRAM TestSubDyn USE SubDyn USE SubDyn_Types USE SubDyn_Output + USE VersionInfo IMPLICIT NONE diff --git a/modules-local/subdyn/src/SubDyn_Output.f90 b/modules/subdyn/src/SubDyn_Output.f90 similarity index 100% rename from modules-local/subdyn/src/SubDyn_Output.f90 rename to modules/subdyn/src/SubDyn_Output.f90 diff --git a/modules-local/subdyn/src/SubDyn_Registry.txt b/modules/subdyn/src/SubDyn_Registry.txt similarity index 100% rename from modules-local/subdyn/src/SubDyn_Registry.txt rename to modules/subdyn/src/SubDyn_Registry.txt diff --git a/modules-local/subdyn/src/qsort_c_module.f90 b/modules/subdyn/src/qsort_c_module.f90 similarity index 100% rename from modules-local/subdyn/src/qsort_c_module.f90 rename to modules/subdyn/src/qsort_c_module.f90 diff --git a/modules-local/supercontroller/CMakeLists.txt b/modules/supercontroller/CMakeLists.txt similarity index 100% rename from modules-local/supercontroller/CMakeLists.txt rename to modules/supercontroller/CMakeLists.txt diff --git a/modules/supercontroller/README.md b/modules/supercontroller/README.md new file mode 100644 index 0000000000..3d2552ea83 --- /dev/null +++ b/modules/supercontroller/README.md @@ -0,0 +1,5 @@ +# SuperController Module + +## Overview +This is a pseudo module used to couple OpenFAST with SuperController; +it is considered part of the OpenFAST glue code diff --git a/modules-local/supercontroller/src/SuperController.f90 b/modules/supercontroller/src/SuperController.f90 similarity index 100% rename from modules-local/supercontroller/src/SuperController.f90 rename to modules/supercontroller/src/SuperController.f90 diff --git a/modules-local/supercontroller/src/SuperController_Registry.txt b/modules/supercontroller/src/SuperController_Registry.txt similarity index 100% rename from modules-local/supercontroller/src/SuperController_Registry.txt rename to modules/supercontroller/src/SuperController_Registry.txt diff --git a/modules-local/turbsim/CMakeLists.txt b/modules/turbsim/CMakeLists.txt similarity index 94% rename from modules-local/turbsim/CMakeLists.txt rename to modules/turbsim/CMakeLists.txt index d35b37691d..38a1cdb0b0 100644 --- a/modules-local/turbsim/CMakeLists.txt +++ b/modules/turbsim/CMakeLists.txt @@ -28,6 +28,6 @@ set(MODULE_SOURCES ) add_executable(turbsim ${MODULE_SOURCES}) -target_link_libraries(turbsim nwtclibs) +target_link_libraries(turbsim nwtclibs versioninfolib) install(TARGETS turbsim RUNTIME DESTINATION bin) diff --git a/modules/turbsim/README.md b/modules/turbsim/README.md new file mode 100644 index 0000000000..0c79c2c5c5 --- /dev/null +++ b/modules/turbsim/README.md @@ -0,0 +1,16 @@ +# TurbSim Module +The legacy version of this module and additional documentation are available +at the [NWTC Software Portal](https://nwtc.nrel.gov/TurbSim/). + +## Overview +TurbSim is a stochastic, full-field, turbulent-wind simulator primarialy for +use with [InflowWind](https://nwtc.nrel.gov/InflowWind "InflowWind")-based +simulation tools. It uses a statistical model (as opposed to a physics-based +model) to numerically simulate time series of three-component wind-speed +vectors at points in a two-dimensional vertical rectangular grid that is fixed +in space. + +Spectra of velocity components and spatial coherence are defined in the +frequency domain, and an inverse Fourier transform produces time series. The +underlying theory behind this method of simulating time series assumes a +stationary process. diff --git a/modules-local/turbsim/src/BlankModVKM.f90 b/modules/turbsim/src/BlankModVKM.f90 similarity index 100% rename from modules-local/turbsim/src/BlankModVKM.f90 rename to modules/turbsim/src/BlankModVKM.f90 diff --git a/modules-local/turbsim/src/CohStructures.f90 b/modules/turbsim/src/CohStructures.f90 similarity index 100% rename from modules-local/turbsim/src/CohStructures.f90 rename to modules/turbsim/src/CohStructures.f90 diff --git a/modules-local/turbsim/src/Profiles.f90 b/modules/turbsim/src/Profiles.f90 similarity index 99% rename from modules-local/turbsim/src/Profiles.f90 rename to modules/turbsim/src/Profiles.f90 index 3be7dc1d43..7135b92856 100644 --- a/modules-local/turbsim/src/Profiles.f90 +++ b/modules/turbsim/src/Profiles.f90 @@ -393,7 +393,7 @@ SUBROUTINE getDirectionProfile( p, Ht, DirectionProfile, VAngleProfile, ErrStat, ! Calculate the wind direction at this height IF ( Ht(J) <= p%met%USR_Z(1) ) THEN - DirectionProfile(IZ) = p%met%USR_WindDir(1) + DirectionProfile(J) = p%met%USR_WindDir(1) ELSEIF ( Ht(J) >= p%met%USR_Z(p%met%NumUSRz) ) THEN DirectionProfile(J) = p%met%USR_WindDir(p%met%NumUSRz) ELSE diff --git a/modules-local/turbsim/src/RandNum.f90 b/modules/turbsim/src/RandNum.f90 similarity index 100% rename from modules-local/turbsim/src/RandNum.f90 rename to modules/turbsim/src/RandNum.f90 diff --git a/modules-local/turbsim/src/Root_Searching.f90 b/modules/turbsim/src/Root_Searching.f90 similarity index 100% rename from modules-local/turbsim/src/Root_Searching.f90 rename to modules/turbsim/src/Root_Searching.f90 diff --git a/modules-local/turbsim/src/TS_FileIO.f90 b/modules/turbsim/src/TS_FileIO.f90 similarity index 100% rename from modules-local/turbsim/src/TS_FileIO.f90 rename to modules/turbsim/src/TS_FileIO.f90 diff --git a/modules-local/turbsim/src/TSsubs.f90 b/modules/turbsim/src/TSsubs.f90 similarity index 100% rename from modules-local/turbsim/src/TSsubs.f90 rename to modules/turbsim/src/TSsubs.f90 diff --git a/modules-local/turbsim/src/TurbSim.f90 b/modules/turbsim/src/TurbSim.f90 similarity index 99% rename from modules-local/turbsim/src/TurbSim.f90 rename to modules/turbsim/src/TurbSim.f90 index 9f23d8dd07..9cdbf4a573 100644 --- a/modules-local/turbsim/src/TurbSim.f90 +++ b/modules/turbsim/src/TurbSim.f90 @@ -57,7 +57,7 @@ PROGRAM TurbSim USE TS_FileIO USE TS_Profiles use TS_CohStructures - +use VersionInfo IMPLICIT NONE diff --git a/modules-local/turbsim/src/TurbSim_Types.f90 b/modules/turbsim/src/TurbSim_Types.f90 similarity index 100% rename from modules-local/turbsim/src/TurbSim_Types.f90 rename to modules/turbsim/src/TurbSim_Types.f90 diff --git a/modules-local/turbsim/src/VelocitySpectra.f90 b/modules/turbsim/src/VelocitySpectra.f90 similarity index 100% rename from modules-local/turbsim/src/VelocitySpectra.f90 rename to modules/turbsim/src/VelocitySpectra.f90 diff --git a/modules/version/CMakeLists.txt b/modules/version/CMakeLists.txt new file mode 100644 index 0000000000..63e280e001 --- /dev/null +++ b/modules/version/CMakeLists.txt @@ -0,0 +1,27 @@ +# +# 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. +# + +include(GetGitRevisionDescription) +git_describe(GIT_DESCRIBE) +add_definitions(-DGIT_VERSION_INFO="${GIT_DESCRIBE}") + +add_library(versioninfolib src/VersionInfo.f90) + +install(TARGETS versioninfolib + EXPORT "${CMAKE_PROJECT_NAME}Libraries" + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) diff --git a/modules/version/README.md b/modules/version/README.md new file mode 100644 index 0000000000..f2efaabd76 --- /dev/null +++ b/modules/version/README.md @@ -0,0 +1,20 @@ +# Version Module + +## Overview +The Version module provides all driver and glue codes with the version based +on the git status. OpenFAST follows [semantic versioning](https://semver.org). +In summary, this means that with a version number as MAJOR.MINOR.PATCH, the +components will be incremented as follows: + +- MAJOR version when introducing incompatible API changes, +- MINOR version when adding functionality in a backwards-compatible manner, and +- PATCH version when making backwards-compatible bug fixes. + +For example, ``OpenFAST-v1.0.0-123-gabcd1234-dirty`` describes OpenFAST as: + +- v1.0.0 is the MAJOR.MINOR.PATCH numbering system and corresponds to a tagged + commit made by NREL on GitHub +- 123-g is the number of additional commits after the most recent tag for a + build [the ``-g`` is for ``git``] +- abcd1234 is the first 8 characters of the current commit hash +- dirty denotes that local changes have been made but not committed diff --git a/modules/version/src/VersionInfo.f90 b/modules/version/src/VersionInfo.f90 new file mode 100644 index 0000000000..a462697a99 --- /dev/null +++ b/modules/version/src/VersionInfo.f90 @@ -0,0 +1,44 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2015-2016 National Renewable Energy Laboratory +! Copyright (C) 2016-2017 Envision Energy USA, LTD +! +! This file is part of the NWTC Subroutine Library. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +!********************************************************************************************************************************** +MODULE VersionInfo + + implicit none + +contains + +FUNCTION QueryGitVersion() + + CHARACTER(200) :: QueryGitVersion + +#ifdef GIT_INCLUDE_FILE +#include GIT_INCLUDE_FILE +#endif + +#ifdef GIT_VERSION_INFO + QueryGitVersion = GIT_VERSION_INFO +#else + QueryGitVersion = 'unversioned' +#endif + + RETURN +END FUNCTION QueryGitVersion + +END MODULE diff --git a/reg_tests/CMakeLists.txt b/reg_tests/CMakeLists.txt index 842b3fe067..d29d5b5bca 100644 --- a/reg_tests/CMakeLists.txt +++ b/reg_tests/CMakeLists.txt @@ -38,7 +38,7 @@ option(CTEST_PLOT_ERRORS "Generate plots of regression test errors." OFF) set(CTEST_OPENFAST_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast/openfast" CACHE FILEPATH "Specify the OpenFAST executable to use in testing.") # Set the BeamDyn executable configuration option and default -set(CTEST_BEAMDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules-local/beamdyn/beamdyn_driver" CACHE FILEPATH "Specify the BeamDyn driver executable to use in testing.") +set(CTEST_BEAMDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/beamdyn/beamdyn_driver" CACHE FILEPATH "Specify the BeamDyn driver executable to use in testing.") # Set the python executable configuration option and default if(NOT EXISTS ${PYTHON_EXECUTABLE}) @@ -61,7 +61,7 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/r-test") # build and seed the test directories with the data they need to run the tests file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}) -foreach(regTest glue-codes/openfast modules-local/beamdyn) +foreach(regTest glue-codes/openfast modules/beamdyn) file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}/${regTest}) endforeach() diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index ffe7c294f9..b60068525e 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -79,7 +79,7 @@ function(bd_regression TESTNAME LABEL) set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeBeamdynRegressionCase.py") set(BEAMDYN_EXECUTABLE "${CTEST_BEAMDYN_EXECUTABLE}") set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") - set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules-local/beamdyn") + set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/beamdyn") regression(${TEST_SCRIPT} ${BEAMDYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") endfunction(bd_regression) @@ -122,8 +122,10 @@ of_regression_linear("5MW_Land_BD_Linear" "openfast;linear;beamdyn;ser of_regression_linear("5MW_OC4Semi_Linear" "openfast;linear;hydrodyn;servodyn") # BeamDyn regression tests -bd_regression("bd_5MW_dynamic" "beamdyn;dynamic") -bd_regression("bd_curved_beam" "beamdyn;static") -bd_regression("bd_isotropic_rollup" "beamdyn;static") -bd_regression("bd_static_cantilever_beam" "beamdyn;static") -bd_regression("bd_static_twisted_with_k1" "beamdyn;static") +bd_regression("bd_5MW_dynamic" "beamdyn;dynamic") +bd_regression("bd_5MW_dynamic_gravity_Az00" "beamdyn;dynamic") +bd_regression("bd_5MW_dynamic_gravity_Az90" "beamdyn;dynamic") +bd_regression("bd_curved_beam" "beamdyn;static") +bd_regression("bd_isotropic_rollup" "beamdyn;static") +bd_regression("bd_static_cantilever_beam" "beamdyn;static") +bd_regression("bd_static_twisted_with_k1" "beamdyn;static") diff --git a/reg_tests/executeBeamdynRegressionCase.py b/reg_tests/executeBeamdynRegressionCase.py index da3c5edda5..b5c3eda865 100644 --- a/reg_tests/executeBeamdynRegressionCase.py +++ b/reg_tests/executeBeamdynRegressionCase.py @@ -73,7 +73,7 @@ regtests = os.path.join(sourceDirectory, "reg_tests") lib = os.path.join(regtests, "lib") rtest = os.path.join(regtests, "r-test") -moduleDirectory = os.path.join(rtest, "modules-local", "beamdyn") +moduleDirectory = os.path.join(rtest, "modules", "beamdyn") inputsDirectory = os.path.join(moduleDirectory, caseName) targetOutputDirectory = os.path.join(inputsDirectory) testBuildDirectory = os.path.join(buildDirectory, caseName) diff --git a/reg_tests/manualRegressionTest.py b/reg_tests/manualRegressionTest.py index 9d78ed02c3..5223db78f1 100644 --- a/reg_tests/manualRegressionTest.py +++ b/reg_tests/manualRegressionTest.py @@ -72,7 +72,7 @@ def strFormat(string): longestName = max(casenames, key=len) for case in casenames: print(strFormat(prefix).format(prefix), strFormat(longestName+" ").format(case), end="", flush=True) - command = "{} executeOpenfastRegressionCase.py {} {} {} {} {} {} {} {} {}".format(pythonCommand, case, openfast_executable, sourceDirectory, buildDirectory, tolerance, machine, compiler, plotFlag, noExecFlag) + command = "\"{}\" executeOpenfastRegressionCase.py {} {} {} {} {} {} {} {} {}".format(pythonCommand, case, openfast_executable, sourceDirectory, buildDirectory, tolerance, machine, compiler, plotFlag, noExecFlag) returnCode = subprocess.call(command, stdout=outstd, shell=True) resultString = passString if returnCode == 0 else failString results.append((case, resultString)) diff --git a/reg_tests/r-test b/reg_tests/r-test index f380148c2c..8db70cc4ee 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit f380148c2c30c1e9a0a5e96a85dbf13630adc0b7 +Subproject commit 8db70cc4eec2465e0fb4f79fd8c8a872b0ac286b diff --git a/share/discon/CMakeLists.txt b/share/discon/CMakeLists.txt index 4d779cf0df..7ca94e253a 100644 --- a/share/discon/CMakeLists.txt +++ b/share/discon/CMakeLists.txt @@ -14,6 +14,49 @@ # limitations under the License. # +# Helper macros for setting appropriate compiler flags + +# Customizations for GNU Fortran compiler +macro(set_gfortran) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -m64 -ffree-line-length-none -fdefault-real-8 -C") + + # debug flags + if(CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fcheck=all -pedantic -fbacktrace" ) + endif() +endmacro(set_gfortran) + +# Customizations for Intel Fortran Compiler +macro(set_ifort) + if(WIN32) + set_ifort_windows() + else() + set_ifort_posix() + endif() +endmacro(set_ifort) + +# Customizations for Intel Fortran Compiler on posix systems +macro(set_ifort_posix) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -m64 -fpp -real-size 64") + + # debug flags + if(CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -g -check all -traceback" ) + endif() +endmacro(set_ifort_posix) + +# Customizations for Intel Fortran Compiler on Windows systems +macro(set_ifort_windows) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /Qm64 /fpp /real-size:64 /libs:static") + + # debug flags + if(CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} /Z7 /check:all /traceback" ) + endif() +endmacro(set_ifort_windows) + + +# CMake config cmake_minimum_required(VERSION 2.8.12) project(DISCON) enable_language(Fortran) @@ -23,24 +66,23 @@ file(TO_CMAKE_PATH ${SOURCE_PATH} SOURCE_PATH) # set the build type option if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING - "Choose the build type: Debug Release" FORCE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the build type: Debug Release" FORCE) endif (NOT CMAKE_BUILD_TYPE) -# add the build flags +# set the build flags if (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU") - set(CMAKE_Fortran_FLAGS "-m64 -fbacktrace -ffree-line-length-none -fdefault-real-8 -C -DDOUBLE_PRECISION") + set_gfortran() elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "Intel") - set(CMAKE_Fortran_FLAGS "-m64 -g -traceback -132 -r8 -DDOUBLE_PRECISION") + set_ifort() endif() set(CMAKE_SHARE_LINKER_FLAGS "-shared") -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux") +if(APPLE OR UNIX) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DIMPLICIT_DLLEXPORT") endif() # supress the mac runtime path warnings -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +if(APPLE) set(CMAKE_MACOSX_RPATH 1) endif() @@ -52,7 +94,7 @@ if (${CMAKE_CURRENT_LIST_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) set(INSTALL_DEST "${CMAKE_SOURCE_DIR}/..") # otherwise else() - set(INSTALL_DEST "${CMAKE_BINARY_DIR}/reg_tests/glue-codes/fast/5MW_Baseline/ServoData") + set(INSTALL_DEST "${CMAKE_BINARY_DIR}/reg_tests/glue-codes/openfast/5MW_Baseline/ServoData") endif() install(TARGETS DISCON DESTINATION ${INSTALL_DEST}) diff --git a/share/fast-build-cpp-spack.sh b/share/fast-build-cpp-spack.sh index c203af0624..fd5ca9c8ee 100755 --- a/share/fast-build-cpp-spack.sh +++ b/share/fast-build-cpp-spack.sh @@ -28,7 +28,7 @@ libxml2_install_dir=`${SPACK_EXE} location -i libxml2 %${COMPILER}` CC=gcc CXX=g++ FC=gfortran cmake \ -DCMAKE_INSTALL_PREFIX=${OPENFAST_DIR}/install/ \ -DCMAKE_BUILD_TYPE=DEBUG \ - -DBUILD_FAST_CPP_API=ON \ + -DBUILD_OPENFAST_CPP_API=ON \ -DFPE_TRAP_ENABLED:BOOL=ON \ -DYAML_ROOT:PATH=$yaml_install_dir \ -DHDF5_USE_STATIC_LIBRARIES=ON \ diff --git a/share/fast-build-cpp.sh b/share/fast-build-cpp.sh index 09195323cf..5477dac7ea 100755 --- a/share/fast-build-cpp.sh +++ b/share/fast-build-cpp.sh @@ -7,7 +7,7 @@ EXTRA_ARGS=$@ CC=mpicc CXX=mpic++ FC=gfortran cmake \ -DCMAKE_INSTALL_PREFIX=$openfast_dir/install/ \ -DCMAKE_BUILD_TYPE=RELEASE \ - -DBUILD_FAST_CPP_API=ON \ + -DBUILD_OPENFAST_CPP_API=ON \ -DYAML_ROOT:PATH=$yaml_install_dir \ -DHDF5_USE_STATIC_LIBRARIES=ON \ -DHDF5_ROOT:PATH=$hdf5_install_dir \ diff --git a/share/fast-install.sh b/share/fast-install.sh index 8e409e205e..14b20efceb 100755 --- a/share/fast-install.sh +++ b/share/fast-install.sh @@ -22,8 +22,8 @@ prepInstall() { compileLapack() { #Registry echo -n "Compiling Lapack" - [ -d modules-ext/lapack ] || mkdir modules-ext/lapack - cd modules-ext/lapack + [ -d modules/lapack ] || mkdir modules/lapack + cd modules/lapack curl -k -o lapack-3.6.0.tgz http://www.netlib.org/lapack/lapack-3.6.0.tgz &> log.wget tar -zxf lapack-3.6.0.tgz &> log.untar [ -d build ] || mkdir build @@ -43,8 +43,8 @@ compileYAMLcpp() { #yaml-cpp echo "Compiling yaml-cpp" echo -n " Setting up build directory" - [ -d modules-ext/yaml-cpp ] || mkdir modules-ext/yaml-cpp - cd modules-ext/yaml-cpp + [ -d modules/yaml-cpp ] || mkdir modules/yaml-cpp + cd modules/yaml-cpp git clone https://github.com/jbeder/yaml-cpp.git &> /dev/null [ -d build ] || mkdir build cd build @@ -67,8 +67,8 @@ compileYAMLcpp() { compileHDF5() { echo "Compiling hdf5" echo -n " Getting source" - [ -d modules-ext/hdf5 ] || mkdir modules-ext/hdf5 - cd modules-ext/hdf5 + [ -d modules/hdf5 ] || mkdir modules/hdf5 + cd modules/hdf5 wget --no-check-certificate https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.1/src/hdf5-1.10.1.tar.bz2 &> log.wget passFail $? echo -n " Setting up build directory" diff --git a/share/spack/package.py b/share/spack/package.py index a00ee76c1a..fa95189d5f 100644 --- a/share/spack/package.py +++ b/share/spack/package.py @@ -81,7 +81,7 @@ def cmake_args(self): 'ON' if '+double-precision' in spec else 'OFF'), '-DUSE_DLL_INTERFACE:BOOL=%s' % ( 'ON' if '+dll-interface' in spec else 'OFF'), - '-DBUILD_FAST_CPP_API:BOOL=%s' % ( + '-DBUILD_OPENFAST_CPP_API:BOOL=%s' % ( 'ON' if '+cxx' in spec else 'OFF'), ]) diff --git a/utilities/template-module/ChangeLog.txt b/share/template-module/ChangeLog.txt similarity index 100% rename from utilities/template-module/ChangeLog.txt rename to share/template-module/ChangeLog.txt diff --git a/utilities/template-module/README.md b/share/template-module/README.md similarity index 100% rename from utilities/template-module/README.md rename to share/template-module/README.md diff --git a/utilities/template-module/src/ModuleName.f90 b/share/template-module/src/ModuleName.f90 similarity index 100% rename from utilities/template-module/src/ModuleName.f90 rename to share/template-module/src/ModuleName.f90 diff --git a/utilities/template-module/src/ModuleName_Registry.txt b/share/template-module/src/ModuleName_Registry.txt similarity index 100% rename from utilities/template-module/src/ModuleName_Registry.txt rename to share/template-module/src/ModuleName_Registry.txt diff --git a/utilities/template-module/src/ModuleName_Types.f90 b/share/template-module/src/ModuleName_Types.f90 similarity index 100% rename from utilities/template-module/src/ModuleName_Types.f90 rename to share/template-module/src/ModuleName_Types.f90 diff --git a/utilities/template-module/src/drivers/ModName_Driver.f90 b/share/template-module/src/drivers/ModName_Driver.f90 similarity index 100% rename from utilities/template-module/src/drivers/ModName_Driver.f90 rename to share/template-module/src/drivers/ModName_Driver.f90 diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt index 4a370650b2..2bad689266 100644 --- a/unit_tests/CMakeLists.txt +++ b/unit_tests/CMakeLists.txt @@ -51,7 +51,7 @@ ExternalProject_Add(pfunit include_directories(${PROJECT_BINARY_DIR}/pfunit/mod) set(pfunit_directory ${PFUNIT_INSTALL}) -set(source_modulesdirectory ${PROJECT_SOURCE_DIR}/../modules-local) +set(source_modulesdirectory ${PROJECT_SOURCE_DIR}/../modules) set(build_testdirectory ${PROJECT_BINARY_DIR}/tests) file(MAKE_DIRECTORY ${build_testdirectory}) @@ -64,10 +64,9 @@ include_directories( ) set_source_files_properties(${pfunit_directory}/include/driver.F90 PROPERTIES GENERATED 1) -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux") +if(APPLE OR UNIX OR CYGWIN OR MINGW) set(pfunit_lib "/lib/libpfunit.a") -else() - # Windows +else() # Windows set(pfunit_lib "/lib/pfunit.lib") endif() diff --git a/vs-build/AeroDyn/AeroDyn_Driver.vfproj b/vs-build/AeroDyn/AeroDyn_Driver.vfproj index 2c81f03c83..647f5fb94a 100644 --- a/vs-build/AeroDyn/AeroDyn_Driver.vfproj +++ b/vs-build/AeroDyn/AeroDyn_Driver.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 @@ - + @@ -90,7 +90,7 @@ - + @@ -116,11 +116,11 @@ - - + + - + @@ -146,11 +146,11 @@ - - + + - + @@ -176,10 +176,10 @@ - + - + @@ -205,13 +205,13 @@ - - - - + + + + - + @@ -237,11 +237,11 @@ - + - + @@ -258,7 +258,7 @@ - + @@ -267,14 +267,14 @@ - - - - - - - - + + + + + + + + @@ -283,12 +283,12 @@ - - - + + + - + @@ -306,5 +306,6 @@ - + + diff --git a/vs-build/BeamDyn/BeamDyn.vfproj b/vs-build/BeamDyn/BeamDyn.vfproj index 750636d68a..7236c70820 100644 --- a/vs-build/BeamDyn/BeamDyn.vfproj +++ b/vs-build/BeamDyn/BeamDyn.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 @@ - + @@ -95,7 +95,7 @@ - + @@ -112,15 +112,15 @@ - - - - - + + + + + - + - + @@ -137,7 +137,7 @@ - + @@ -154,7 +154,7 @@ - + @@ -171,7 +171,7 @@ - + @@ -188,7 +188,7 @@ - + @@ -205,7 +205,7 @@ - + @@ -222,7 +222,7 @@ - + @@ -239,7 +239,7 @@ - + @@ -256,7 +256,7 @@ - + @@ -273,7 +273,7 @@ - + @@ -289,5 +289,6 @@ - + + diff --git a/vs-build/CreateGitVersion.bat b/vs-build/CreateGitVersion.bat index 15b2147b8f..91647f8e93 100644 --- a/vs-build/CreateGitVersion.bat +++ b/vs-build/CreateGitVersion.bat @@ -3,5 +3,7 @@ SET IncludeFile=..\gitVersionInfo.h %IncludeFile% FOR /f %%a IN ('git describe --abbrev^=8 --always --tags --dirty') DO > %IncludeFile% -ECHO '>> %IncludeFile% +git describe --abbrev^=8 --always --tags --dirty > NUL +IF %ERRORLEVEL%==0 ( ECHO '>> %IncludeFile% ) else ( ECHO Unversioned from $Format:%H$ '>> %IncludeFile% ) + EXIT /B 0 \ No newline at end of file diff --git a/vs-build/Discon/Discon.sln b/vs-build/Discon/Discon.sln index 06867c12e7..7c5b5beb58 100644 --- a/vs-build/Discon/Discon.sln +++ b/vs-build/Discon/Discon.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.40629.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2043 MinimumVisualStudioVersion = 10.0.40219.1 Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = "Discon", "Discon.vfproj", "{183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}" EndProject @@ -19,10 +19,10 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Debug|Win32.ActiveCfg = Debug|Win32 {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Debug|Win32.Build.0 = Debug|Win32 - {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Debug|x64.ActiveCfg = Debug|Win32 - {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Debug|x64.Build.0 = Debug|Win32 - {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Release|Win32.ActiveCfg = Release|x64 - {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Release|Win32.Build.0 = Release|x64 + {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Debug|x64.ActiveCfg = Debug|x64 + {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Debug|x64.Build.0 = Debug|x64 + {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Release|Win32.ActiveCfg = Release|Win32 + {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Release|Win32.Build.0 = Release|Win32 {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Release|x64.ActiveCfg = Release|x64 {183CC593-AD4C-4A15-81C1-7D6D20A9A5ED}.Release|x64.Build.0 = Release|x64 {11A28263-1385-47DF-9122-30BF9C0DF013}.Debug|Win32.ActiveCfg = Debug|Win32 @@ -45,4 +45,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A4EE85D3-EA0C-4285-B446-0E8D70945A10} + EndGlobalSection EndGlobal diff --git a/vs-build/Discon/Discon.vfproj b/vs-build/Discon/Discon.vfproj index d388f55667..30d07a9dc4 100644 --- a/vs-build/Discon/Discon.vfproj +++ b/vs-build/Discon/Discon.vfproj @@ -5,7 +5,7 @@ - + @@ -15,8 +15,8 @@ - - + + @@ -25,7 +25,7 @@ - + @@ -35,8 +35,8 @@ - - + + diff --git a/vs-build/Discon/Discon_ITIBarge.vfproj b/vs-build/Discon/Discon_ITIBarge.vfproj index e0027b486f..d263c96c12 100644 --- a/vs-build/Discon/Discon_ITIBarge.vfproj +++ b/vs-build/Discon/Discon_ITIBarge.vfproj @@ -5,7 +5,7 @@ - + @@ -15,8 +15,8 @@ - - + + @@ -25,7 +25,7 @@ - + @@ -35,8 +35,8 @@ - - + + diff --git a/vs-build/Discon/Discon_OC3Hywind.vfproj b/vs-build/Discon/Discon_OC3Hywind.vfproj index e3f5119f3a..f821f3dcfc 100644 --- a/vs-build/Discon/Discon_OC3Hywind.vfproj +++ b/vs-build/Discon/Discon_OC3Hywind.vfproj @@ -5,7 +5,7 @@ - + @@ -15,8 +15,8 @@ - - + + @@ -25,7 +25,7 @@ - + @@ -35,8 +35,8 @@ - - + + diff --git a/vs-build/FAST-Types/FAST-Types.vfproj b/vs-build/FAST-Types/FAST-Types.vfproj index 0045a41882..5ae84e3efd 100644 --- a/vs-build/FAST-Types/FAST-Types.vfproj +++ b/vs-build/FAST-Types/FAST-Types.vfproj @@ -5,7 +5,7 @@ - + @@ -92,7 +92,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -126,7 +126,7 @@ - + @@ -143,7 +143,7 @@ - + @@ -160,7 +160,7 @@ - + @@ -180,7 +180,7 @@ - + @@ -198,7 +198,7 @@ - + @@ -217,7 +217,7 @@ - + @@ -236,7 +236,7 @@ - + @@ -255,7 +255,7 @@ - + @@ -274,7 +274,7 @@ - + @@ -293,7 +293,7 @@ - + @@ -310,7 +310,7 @@ - + @@ -327,7 +327,7 @@ - + @@ -344,7 +344,7 @@ - + @@ -361,7 +361,7 @@ - + @@ -378,7 +378,7 @@ - + @@ -395,7 +395,7 @@ - + @@ -412,7 +412,7 @@ - + @@ -429,7 +429,7 @@ - + @@ -449,7 +449,7 @@ - + @@ -469,7 +469,7 @@ - + @@ -488,7 +488,7 @@ - + @@ -505,7 +505,7 @@ - + @@ -522,7 +522,7 @@ - + @@ -539,7 +539,7 @@ - + @@ -556,7 +556,7 @@ - + @@ -573,7 +573,7 @@ - + @@ -590,24 +590,24 @@ - + - + - + - + - + - + - + - + - - + + @@ -627,7 +627,7 @@ - + @@ -646,7 +646,7 @@ - + @@ -665,7 +665,7 @@ - + @@ -684,7 +684,7 @@ - + @@ -703,7 +703,7 @@ - + @@ -722,7 +722,7 @@ - + @@ -741,7 +741,7 @@ - + @@ -758,7 +758,7 @@ - + @@ -777,7 +777,7 @@ - + diff --git a/vs-build/FASTlib/FASTlib.vfproj b/vs-build/FASTlib/FASTlib.vfproj index eb2369d05c..fff39a2413 100644 --- a/vs-build/FASTlib/FASTlib.vfproj +++ b/vs-build/FASTlib/FASTlib.vfproj @@ -5,7 +5,7 @@ - + @@ -14,7 +14,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -41,7 +41,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -59,7 +59,7 @@ - + @@ -68,7 +68,7 @@ - + @@ -77,7 +77,7 @@ - + @@ -86,7 +86,7 @@ - + @@ -95,7 +95,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -132,7 +132,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -188,7 +188,7 @@ - + @@ -214,7 +214,7 @@ - + @@ -238,7 +238,7 @@ - + @@ -264,20 +264,20 @@ - - - - - - - - - + + + + + + + + + - + @@ -302,11 +302,11 @@ - - + + - + @@ -331,13 +331,13 @@ - - - + + + - + @@ -362,12 +362,12 @@ - - - + + + - + @@ -393,12 +393,12 @@ - - - + + + - + @@ -424,10 +424,10 @@ - + - + @@ -453,13 +453,13 @@ - - - - + + + + - + @@ -485,7 +485,7 @@ - + @@ -511,7 +511,7 @@ - + @@ -537,7 +537,7 @@ - + @@ -563,7 +563,7 @@ - + @@ -589,7 +589,7 @@ - + @@ -615,7 +615,7 @@ - + @@ -640,7 +640,7 @@ - + @@ -667,7 +667,7 @@ - + @@ -692,7 +692,7 @@ - + @@ -719,29 +719,29 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + @@ -766,10 +766,10 @@ - + - + @@ -795,22 +795,22 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - + @@ -836,7 +836,7 @@ - + @@ -862,7 +862,7 @@ - + @@ -888,7 +888,7 @@ - + @@ -914,7 +914,7 @@ - + @@ -940,7 +940,7 @@ - + @@ -966,33 +966,33 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1018,19 +1018,19 @@ - - - - - - - - - + + + + + + + + + - + @@ -1056,12 +1056,12 @@ - + - + - + @@ -1101,10 +1101,10 @@ - + - + @@ -1131,14 +1131,14 @@ - + - - - + + + - + @@ -1164,11 +1164,11 @@ - + - + @@ -1194,7 +1194,7 @@ - + @@ -1220,7 +1220,7 @@ - + @@ -1245,7 +1245,7 @@ - + @@ -1270,29 +1270,29 @@ - - - - + + + + - + - - - - - - - - - - - + + + + + + + + + + + - + @@ -1303,7 +1303,7 @@ - + @@ -1329,10 +1329,10 @@ - + - + @@ -1358,7 +1358,7 @@ - + @@ -1384,15 +1384,15 @@ - - - - - - + + + + + + - + @@ -1418,13 +1418,13 @@ - - - - + + + + - + @@ -1450,5 +1450,6 @@ - + + diff --git a/vs-build/HydroDyn/HydroDynDriver.vfproj b/vs-build/HydroDyn/HydroDynDriver.vfproj index a25aae931c..8447d96adc 100644 --- a/vs-build/HydroDyn/HydroDynDriver.vfproj +++ b/vs-build/HydroDyn/HydroDynDriver.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -58,7 +58,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + @@ -92,7 +92,7 @@ - + @@ -100,12 +100,12 @@ - + - + @@ -116,12 +116,12 @@ - + - + @@ -132,27 +132,27 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - + @@ -161,10 +161,10 @@ - - + + - + @@ -173,7 +173,7 @@ - + @@ -182,7 +182,7 @@ - + @@ -191,7 +191,7 @@ - + @@ -200,7 +200,7 @@ - + @@ -209,7 +209,7 @@ - + @@ -218,7 +218,7 @@ - + @@ -227,7 +227,7 @@ - + @@ -236,7 +236,7 @@ - + @@ -245,7 +245,7 @@ - + @@ -253,5 +253,6 @@ - + + diff --git a/vs-build/MAPlib/MAP_dll.vcxproj b/vs-build/MAPlib/MAP_dll.vcxproj index 63e49b940a..bacec60a01 100644 --- a/vs-build/MAPlib/MAP_dll.vcxproj +++ b/vs-build/MAPlib/MAP_dll.vcxproj @@ -305,53 +305,53 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + + + - + CALL ..\RunRegistry.bat MAP CALL ..\RunRegistry.bat MAP ..\..\build\types-files\MAP_Types.h diff --git a/vs-build/Registry/FAST_Registry.vcxproj b/vs-build/Registry/FAST_Registry.vcxproj index a1b8453775..c127deeebf 100644 --- a/vs-build/Registry/FAST_Registry.vcxproj +++ b/vs-build/Registry/FAST_Registry.vcxproj @@ -439,23 +439,23 @@ - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + diff --git a/vs-build/RunRegistry.bat b/vs-build/RunRegistry.bat index 4e930cd1a7..f3901eeba7 100644 --- a/vs-build/RunRegistry.bat +++ b/vs-build/RunRegistry.bat @@ -21,8 +21,8 @@ REM ---------------------------------------------------------------------------- SET Root_Loc=..\.. IF not "%2"=="" SET Root_Loc=%2 -SET Local_Modules_Loc=%Root_Loc%\modules-local -SET Ext_Modules_Loc=%Root_Loc%\modules-ext +SET Local_Modules_Loc=%Root_Loc%\modules +SET Ext_Modules_Loc=%Root_Loc%\modules SET Registry=..\..\build\bin\Registry.exe SET Output_Loc=..\..\build\types-files SET FAST_Loc=%Local_Modules_Loc%\openfast-library\src diff --git a/vs-build/SubDyn/SubDyn.vfproj b/vs-build/SubDyn/SubDyn.vfproj index 7a6f60baac..b64ee1af19 100644 --- a/vs-build/SubDyn/SubDyn.vfproj +++ b/vs-build/SubDyn/SubDyn.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -49,7 +49,7 @@ - + @@ -58,9 +58,9 @@ - - - + + + @@ -70,7 +70,7 @@ - + @@ -79,7 +79,7 @@ - + @@ -88,7 +88,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -115,7 +115,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -133,7 +133,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -151,7 +151,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -174,9 +174,10 @@ - - - - - + + + + + + diff --git a/vs-build/TurbSim/TurbSim.vfproj b/vs-build/TurbSim/TurbSim.vfproj index b89ed43802..e11bffc343 100644 --- a/vs-build/TurbSim/TurbSim.vfproj +++ b/vs-build/TurbSim/TurbSim.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -50,30 +50,31 @@ - - - + + + - - - - - - - - - + + + + + + + + + - + - - - - - - - - - - + + + + + + + + + + + diff --git a/vs-build/UnsteadyAero/UnsteadyAero.vfproj b/vs-build/UnsteadyAero/UnsteadyAero.vfproj index 49d448e13c..b367af64b3 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 @@ - + @@ -89,12 +89,12 @@ - + - + @@ -113,7 +113,7 @@ - + @@ -122,10 +122,10 @@ - - + + - + @@ -142,7 +142,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -176,7 +176,7 @@ - + @@ -193,7 +193,7 @@ - + @@ -210,7 +210,7 @@ - + @@ -227,7 +227,7 @@ - + @@ -244,7 +244,7 @@ - + @@ -261,7 +261,7 @@ - + @@ -278,7 +278,7 @@ - + @@ -297,7 +297,7 @@ - + @@ -319,7 +319,8 @@ - - - + + + +