diff --git a/.github/scripts/build_windows_executables.bat b/.github/scripts/build_windows_executables.bat index 70257fcb69..3d4efe2846 100644 --- a/.github/scripts/build_windows_executables.bat +++ b/.github/scripts/build_windows_executables.bat @@ -28,6 +28,7 @@ devenv vs-build/MoorDyn/MoorDynDriver.sln /Build "Release|x64" devenv vs-build/MoorDyn_c_binding/MoorDyn_c_binding.sln /Build "Release|x64" devenv vs-build/FAST/FAST.sln /Build "Release|x64" devenv vs-build/SeaState/SeaStateDriver.sln /Build "Release|x64" +devenv vs-build/SeaState_c_binding/SeaState_c_binding.sln /Build "Release|x64" devenv vs-build/SimpleElastoDyn/SimpleElastoDyn_Driver.sln /Build "Release|x64" devenv vs-build/SubDyn/SubDyn.sln /Build "Release|x64" devenv vs-build/TurbSim/TurbSim.vfproj /Build "Release|x64" diff --git a/.github/scripts/windows_devenv_test.bat b/.github/scripts/windows_devenv_test.bat new file mode 100644 index 0000000000..494a6edfbe --- /dev/null +++ b/.github/scripts/windows_devenv_test.bat @@ -0,0 +1,13 @@ +@REM Check if devenv actually works +for /f "usebackq tokens=1* delims=: " %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest`) do ( + if /i "%%i"=="productPath" set devenv=%%j +) + +@REM above command finds devenv.exe, but that opens the VS instance. We need the devenv.com version +set devenv=%devenv:devenv.exe=devenv.com% + +echo Using Visual Studio: %devenv% + +"%devenv%" /? + +exit /b %ERRORLEVEL% diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index cb68200c34..401d57bd23 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -21,68 +21,13 @@ env: C_COMPILER: gcc-12 GCOV_EXE: gcov-12 CMAKE_BUILD_PARALLEL_LEVEL: 8 - CTEST_PARALLEL_LEVEL: 2 - + CTEST_PARALLEL_LEVEL: 4 jobs: - ### BUILD JOBS - - - build-all-debug: - # Tests compiling in debug mode. - # Also compiles the Registry and generates new types files. - # Debug more speeds up the build. - runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Set up MATLAB - uses: matlab-actions/setup-matlab@v2 - with: - products: Simulink - - name: Install dependencies - run: | - pip install -r requirements.txt - pip install glue-codes/python/. # Installs the interface library - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - - name: Setup workspace - run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ - -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ - -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ - -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - -DBLA_VENDOR:STRING=OpenBLAS \ - -DCMAKE_BUILD_TYPE:STRING=DEBUG \ - -DBUILD_SHARED_LIBS:BOOL=OFF \ - -DGENERATE_TYPES=ON \ - -DVARIABLE_TRACKING=OFF \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ - -DBUILD_OPENFAST_SIMULINK_API=ON \ - ${GITHUB_WORKSPACE} - # -DDOUBLE_PRECISION=OFF \ - - name: Build all - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake --build . --target all - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-all-debug-${{ github.sha }} + #----------------------------------------------------------------------------- + # BUILD JOBS + #----------------------------------------------------------------------------- build-all-debug-single: # Tests compiling in debug mode with single precision. @@ -92,37 +37,37 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - with: - submodules: recursive - name: Install dependencies run: | sudo apt-get update -y - sudo apt-get install -y libopenblas-dev + sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Setup workspace - run: cmake -E make_directory ${{runner.workspace}}/openfast/build + run: cmake -E make_directory ${{github.workspace}}/build - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ + -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}}/install \ -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBLA_VENDOR:STRING=OpenBLAS \ -DCMAKE_BUILD_TYPE:STRING=DEBUG \ - -DBUILD_SHARED_LIBS:BOOL=OFF \ - -DVARIABLE_TRACKING=OFF \ + -DVARIABLE_TRACKING:BOOL=OFF \ -DDOUBLE_PRECISION:BOOL=OFF \ + -DBUILD_OPENFAST_CPP_API:BOOL=ON \ + -DBUILD_OPENFAST_LIB_DRIVER:BOOL=ON \ + -DBUILD_OPENFAST_CPP_DRIVER:BOOL=ON \ + -DBUILD_FASTFARM:BOOL=ON \ ${GITHUB_WORKSPACE} - name: Build all - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake --build . --target all - - build-drivers-release: + build-all-release: runs-on: ubuntu-22.04 steps: - name: Checkout @@ -133,40 +78,60 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.11' + - name: List files in workspace + run: ls ${{github.workspace}} - name: Install dependencies run: | - pip install -r requirements.txt sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev + sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Setup workspace - run: cmake -E make_directory ${{runner.workspace}}/openfast/build + run: cmake -E make_directory ${{github.workspace}}/build - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ + -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}}/install \ -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ + -DBUILD_SHARED_LIBS:BOOL=OFF \ -DBLA_VENDOR:STRING=OpenBLAS \ -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ - -DVARIABLE_TRACKING=OFF \ + -DVARIABLE_TRACKING:BOOL=OFF \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ + -DOPENMP:BOOL=ON \ + -DDOUBLE_PRECISION=ON \ + -DBUILD_OPENFAST_CPP_API:BOOL=ON \ + -DBUILD_OPENFAST_LIB_DRIVER:BOOL=ON \ + -DBUILD_OPENFAST_CPP_DRIVER:BOOL=ON \ + -DBUILD_FASTFARM:BOOL=ON \ ${GITHUB_WORKSPACE} - - name: Build module drivers - working-directory: ${{runner.workspace}}/openfast/build + - name: Build all + working-directory: ${{github.workspace}}/build + run: | + cmake --build . --target all + - name: Archive files run: | - cmake --build . --target regression_test_module_drivers - - name: Cache the workspace - uses: actions/cache@v4 + tar -cvf workspace.tar -C ${{github.workspace}} \ + --exclude='*.a' --exclude='*.o' --exclude='build/ftnmods' \ + --exclude='.git' --exclude='docs' --exclude='vs-build' \ + . + - name: Save workspace for other jobs + uses: actions/upload-artifact@v4 with: - path: ${{runner.workspace}} - key: build-drivers-release-${{ github.sha }} + name: build-all-release + path: workspace.tar + #----------------------------------------------------------------------------- + # BUILD AND TEST JOBS + #----------------------------------------------------------------------------- - build-postlib-release: + build-all-test-modules-debug: + # Tests compiling in debug mode. + # Also compiles the Registry and generates new types files. + # Debug more speeds up the build. runs-on: ubuntu-22.04 steps: - name: Checkout @@ -177,235 +142,139 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.11' - - name: Set up MATLAB - uses: matlab-actions/setup-matlab@v2 - with: - products: Simulink - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt + pip install glue-codes/python/. # Installs the interface library sudo apt-get update -y sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev # gcovr - name: Setup workspace - run: cmake -E make_directory ${{runner.workspace}}/openfast/build + run: cmake -E make_directory ${{github.workspace}}/build - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ + -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}}/install \ -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBLA_VENDOR:STRING=OpenBLAS \ - -DCMAKE_BUILD_TYPE:STRING=RELWITHDEBINFO \ - -DOPENMP:BOOL=ON \ - -DDOUBLE_PRECISION=ON \ - -DVARIABLE_TRACKING=OFF \ - -DBUILD_FASTFARM:BOOL=ON \ - -DBUILD_OPENFAST_CPP_API:BOOL=ON \ - -DBUILD_OPENFAST_LIB_DRIVER:BOOL=ON \ - -DBUILD_OPENFAST_CPP_DRIVER:BOOL=ON \ - -DBUILD_SHARED_LIBS:BOOL=OFF \ + -DCMAKE_BUILD_TYPE:STRING=DEBUG \ + -DGENERATE_TYPES:BOOL=ON \ + -DVARIABLE_TRACKING:BOOL=OFF \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ - -DBUILD_OPENFAST_SIMULINK_API=ON \ - ${GITHUB_WORKSPACE} - - name: Build openfast-postlib - working-directory: ${{runner.workspace}}/openfast/build - run: cmake --build . --target openfast_postlib - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-postlib-release-${{ github.sha }} - - - build-interfaces-release: - runs-on: ubuntu-22.04 - needs: build-postlib-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-postlib-release-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies - run: | - pip install -r requirements.txt - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ ${GITHUB_WORKSPACE} - - name: Build OpenFAST C-Interfaces - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake --build . --target openfastlib openfast_lib_driver openfastcpp aerodyn_inflow_c_binding moordyn_c_binding ifw_c_binding hydrodyn_c_binding regression_test_controllers - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-interfaces-release-${{ github.sha }} - - - build-openfast-release: - runs-on: ubuntu-22.04 - needs: build-postlib-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-postlib-release-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies - run: | - pip install -r requirements.txt - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build + # -DDOUBLE_PRECISION=OFF \ + - name: Build all + working-directory: ${{github.workspace}}/build run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - ${GITHUB_WORKSPACE} - - name: Build OpenFAST glue-code - working-directory: ${{runner.workspace}}/openfast/build + cmake --build . --target all + - name: Run UnsteadyAero tests + working-directory: ${{github.workspace}}/build + shell: bash run: | - cmake --build . --target openfast - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} - - - build-fastfarm-release: - runs-on: ubuntu-22.04 - needs: build-postlib-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-postlib-release-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 + ctest -VV -R "^ua_" + - name: Run AeroDyn tests + uses: ./.github/actions/tests-module-aerodyn with: - python-version: '3.11' - - name: Install dependencies - run: | - pip install -r requirements.txt - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - ${GITHUB_WORKSPACE} - - name: Build FAST.Farm - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake --build . --target FAST.Farm - - name: Cache the workspace - uses: actions/cache@v4 + # Don't run regression tests here since they currently fail inconsistently + test-target: unit + - name: Run BeamDyn tests + uses: ./.github/actions/tests-module-beamdyn + - name: Run HydroDyn tests + uses: ./.github/actions/tests-module-hydrodyn + - name: Run InflowWind tests + uses: ./.github/actions/tests-module-inflowwind + - name: Run MoorDyn tests + uses: ./.github/actions/tests-module-moordyn + - name: Run NWTC Library tests + uses: ./.github/actions/tests-module-nwtclibrary + - name: Run SeaState tests + uses: ./.github/actions/tests-module-seastate + - name: Run SubDyn tests + uses: ./.github/actions/tests-module-subdyn + - name: Run VersionInfo tests + uses: ./.github/actions/tests-module-version + - name: Failing test artifacts + uses: actions/upload-artifact@v4 + if: failure() with: - path: ${{runner.workspace}} - key: build-fastfarm-release-${{ github.sha }} - - + name: rtest-modules-debug + path: | + ${{github.workspace}}/build/reg_tests/modules + ${{github.workspace}}/build/unit_tests - ### BUILD AND TEST JOBS - build-test-uadriver-debug: - # UA driver used to require -DUA_OUTS + build-test-OF-simulink: runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v4 with: submodules: recursive - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - name: Install dependencies run: | - pip install -r requirements.txt - pip install glue-codes/python/. # Installs the interface library sudo apt-get update -y sudo apt-get install -y libopenblas-dev + - name: Set up MATLAB + uses: matlab-actions/setup-matlab@v2 + with: + products: Simulink - name: Setup workspace - run: cmake -E make_directory ${{runner.workspace}}/openfast/build + run: cmake -E make_directory ${{github.workspace}}/build - name: Configure build - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ + -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}}/install \ -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ + -DBUILD_OPENFAST_SIMULINK_API:BOOL=ON \ + -DUSE_LOCAL_STATIC_LAPACK:BOOL=ON \ -DCMAKE_BUILD_TYPE:STRING=DEBUG \ - -DBUILD_SHARED_LIBS:BOOL=OFF \ - -DGENERATE_TYPES=ON \ - -DVARIABLE_TRACKING=OFF \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ + -DGENERATE_TYPES:BOOL=ON \ + -DVARIABLE_TRACKING:BOOL=OFF \ ${GITHUB_WORKSPACE} - - name: Build all - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake --build . --target unsteadyaero_driver - - - name: Run UnsteadyAero tests - working-directory: ${{runner.workspace}}/openfast/build - shell: bash + - name: Build FAST_SFunc + working-directory: ${{github.workspace}}/build run: | - ctest -VV -R "^ua_" - - - name: Failing test artifacts - uses: actions/upload-artifact@v4 - if: failure() + cmake --build . --target FAST_SFunc + - name: Run MATLAB tests and generate artifacts + uses: matlab-actions/run-tests@v2 with: - name: rtest-uadriver - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules/unsteadyaero - - + source-folder: ${{github.workspace}}/build/glue-codes/simulink; ${{github.workspace}}/glue-codes/simulink/examples + test-results-junit: test-results/results.xml + code-coverage-cobertura: code-coverage/coverage.xml - ### TEST JOBS + #----------------------------------------------------------------------------- + # TEST JOBS + #----------------------------------------------------------------------------- rtest-module-drivers: runs-on: ubuntu-22.04 - needs: build-drivers-release + needs: build-all-release steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-drivers-release-${{ github.sha }} + name: build-all-release + - name: Untar workspace + run: | + tar -xf workspace.tar -C ${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library @@ -413,10 +282,10 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} @@ -446,83 +315,31 @@ jobs: with: name: rtest-module-drivers path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - - - rtest-modules-debug: - runs-on: ubuntu-22.04 - needs: build-all-debug - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-all-debug-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies - run: | - pip install -r requirements.txt - pip install glue-codes/python/. # Installs the interface library - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ - ${GITHUB_WORKSPACE} - cmake --build . --target regression_test_controllers - - name: Run AeroDyn tests - uses: ./.github/actions/tests-module-aerodyn - with: - # Don't run regression tests here since they currently fail inconsistently - test-target: unit - - name: Run BeamDyn tests - uses: ./.github/actions/tests-module-beamdyn - - name: Run HydroDyn tests - uses: ./.github/actions/tests-module-hydrodyn - - name: Run InflowWind tests - uses: ./.github/actions/tests-module-inflowwind - - name: Run MoorDyn tests - uses: ./.github/actions/tests-module-moordyn - - name: Run NWTC Library tests - uses: ./.github/actions/tests-module-nwtclibrary - - name: Run SeaState tests - uses: ./.github/actions/tests-module-seastate - - name: Run SubDyn tests - uses: ./.github/actions/tests-module-subdyn - - name: Run VersionInfo tests - uses: ./.github/actions/tests-module-version - - name: Failing test artifacts - uses: actions/upload-artifact@v4 - if: failure() - with: - name: rtest-modules-debug - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/unit_tests + ${{github.workspace}}/build/reg_tests/modules rtest-interfaces: runs-on: ubuntu-22.04 - needs: build-interfaces-release + needs: build-all-release + env: + OMP_NUM_THREADS: 1 steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-interfaces-release-${{ github.sha }} + name: build-all-release + - name: Untar workspace + run: | + tar -xf workspace.tar -C ${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library @@ -530,17 +347,18 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} - name: Run Interface / API tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | - ctest -VV -L "cpp|python|fastlib" \ + ctest -VV \ + -L "cpp|python|fastlib" \ -LE "openfast_io" - name: Failing test artifacts uses: actions/upload-artifact@v4 @@ -548,29 +366,37 @@ jobs: with: name: rtest-interfaces path: | - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast-cpp - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/python - ${{runner.workspace}}/openfast/build/reg_tests/modules/aerodyn - ${{runner.workspace}}/openfast/build/reg_tests/modules/moordyn - ${{runner.workspace}}/openfast/build/reg_tests/modules/inflowwind - ${{runner.workspace}}/openfast/build/reg_tests/modules/hydrodyn - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast-cpp/5MW_Baseline + ${{github.workspace}}/build/reg_tests/glue-codes/openfast-cpp + ${{github.workspace}}/build/reg_tests/glue-codes/python + ${{github.workspace}}/build/reg_tests/modules/aerodyn + ${{github.workspace}}/build/reg_tests/modules/moordyn + ${{github.workspace}}/build/reg_tests/modules/inflowwind + ${{github.workspace}}/build/reg_tests/modules/hydrodyn + !${{github.workspace}}/build/reg_tests/glue-codes/openfast-cpp/5MW_Baseline rtest-OF: runs-on: ubuntu-22.04 - needs: build-openfast-release + needs: build-all-release + env: + OMP_NUM_THREADS: 1 steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} + name: build-all-release + - name: Untar workspace + run: | + tar -xf workspace.tar -C${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library @@ -578,178 +404,55 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} cmake --build . --target regression_test_controllers - name: Run 5MW tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | - ctest -VV -j4 \ + ctest -VV \ -L openfast \ - -LE "cpp|linear|python|fastlib|aeromap" \ - -E "5MW_OC4Semi_WSt_WavesWN|5MW_OC3Mnpl_DLL_WTurb_WavesIrr|5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth|5MW_OC3Trpd_DLL_WSt_WavesReg|5MW_Land_BD_DLL_WTurb" + -LE "cpp|linear|python|fastlib|offshore" - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() with: name: rtest-OF path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - rtest-openfast_io: - runs-on: ubuntu-22.04 - needs: build-openfast-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies - run: | - pip install -r requirements.txt - pip install glue-codes/python/. # Installs the interface library - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - - name: Install openfast_io - working-directory: ${{runner.workspace}}/openfast/openfast_io - run: | - pip install -e . - - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ - ${GITHUB_WORKSPACE} - cmake --build . --target regression_test_controllers - - name: Run openfast_io tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - ctest -VV -j4 \ - -L openfast_io - - name: Failing test artifacts - uses: actions/upload-artifact@v4 - if: failure() - with: - name: rtest-openfast_io - path: | - ${{runner.workspace}}/openfast/build/reg_tests/openfast_io + ${{github.workspace}}/build/reg_tests/glue-codes/openfast + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AOC + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AWT27 + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/SWRT + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/UAE_VI + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/WP_Baseline - rtest-OF-simulink: + rtest-OF-offshore: runs-on: ubuntu-22.04 - needs: build-openfast-release + needs: build-all-release steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} - - name: Install dependencies + name: build-all-release + - name: Untar workspace run: | - sudo apt-get update -y - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev libopenblas-dev libopenblas-openmp-dev - - name: Set up MATLAB - uses: matlab-actions/setup-matlab@v2 - with: - products: Simulink - - name: Build FAST_SFunc - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DUSE_LOCAL_STATIC_LAPACK:BOOL=ON \ - ${GITHUB_WORKSPACE} - cmake --build . --target FAST_SFunc - - name: Run MATLAB tests and generate artifacts - uses: matlab-actions/run-tests@v2 - with: - source-folder: ${{runner.workspace}}/openfast/build/glue-codes/simulink; ${{runner.workspace}}/openfast/glue-codes/simulink/examples - test-results-junit: test-results/results.xml - code-coverage-cobertura: code-coverage/coverage.xml - - - rtest-OF-5MW_Land_AeroMap: - runs-on: ubuntu-22.04 - needs: build-openfast-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} + tar -xf workspace.tar -C${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install glue-codes/python/. # Installs the interface library - pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev - - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ - ${GITHUB_WORKSPACE} - - name: Run 5MW aero map tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - ctest -VV -L aeromap -LE "cpp|linear|python" -R 5MW_Land_AeroMap - - name: Failing test artifacts - uses: actions/upload-artifact@v4 - if: failure() - with: - name: rtest-OF-5MW_Land_AeroMap - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - - rtest-OF-5MW_OC4Semi_WSt_WavesWN: - runs-on: ubuntu-22.04 - needs: build-openfast-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library @@ -757,97 +460,57 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} cmake --build . --target regression_test_controllers - name: Run 5MW tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | - ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC4Semi_WSt_WavesWN + ctest -VV \ + -L openfast -L offshore \ + -LE "cpp|linear|python|fastlib" - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() with: - name: rtest-OF-5MW_OC4Semi_WSt_WavesWN + name: rtest-OF-offshore path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - - rtest-OF-5MW_OC3Mnpl_DLL_WTurb_WavesIrr: + ${{github.workspace}}/build/reg_tests/glue-codes/openfast + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AOC + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AWT27 + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/SWRT + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/UAE_VI + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/WP_Baseline + + + rtest-OF-linearization: runs-on: ubuntu-22.04 - needs: build-openfast-release + needs: build-all-release + env: + OMP_NUM_THREADS: 1 steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies - run: | - pip install -r requirements.txt - pip install glue-codes/python/. # Installs the interface library - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ - ${GITHUB_WORKSPACE} - cmake --build . --target regression_test_controllers - - name: Run 5MW tests - working-directory: ${{runner.workspace}}/openfast/build + name: build-all-release + - name: Untar workspace run: | - ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC3Mnpl_DLL_WTurb_WavesIrr -j1 - - name: Failing test artifacts - uses: actions/upload-artifact@v4 - if: failure() - with: - name: rtest-OF-5MW_OC3Mnpl_DLL_WTurb_WavesIrr - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - - rtest-OF-5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth: - runs-on: ubuntu-22.04 - needs: build-openfast-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} + tar -xf workspace.tar -C${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library @@ -855,97 +518,53 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} - cmake --build . --target regression_test_controllers - - name: Run 5MW tests - working-directory: ${{runner.workspace}}/openfast/build + - name: Run OpenFAST linearization tests + working-directory: ${{github.workspace}}/build run: | - ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth + ctest -VV -L linear - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() with: - name: rtest-OF-5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth + name: rtest-OF-linearization path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - - rtest-OF-5MW_OC3Trpd_DLL_WSt_WavesReg: + ${{github.workspace}}/build/reg_tests/glue-codes/openfast + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AOC + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AWT27 + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/SWRT + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/UAE_VI + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/WP_Baseline + + rtest-OF-aeromap: runs-on: ubuntu-22.04 - needs: build-openfast-release + needs: build-all-release + env: + OMP_NUM_THREADS: 1 steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies + name: build-all-release + - name: Untar workspace run: | - pip install -r requirements.txt - pip install glue-codes/python/. # Installs the interface library - sudo apt-get update -y - sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev - sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ - ${GITHUB_WORKSPACE} - cmake --build . --target regression_test_controllers - - name: Run 5MW tests - working-directory: ${{runner.workspace}}/openfast/build - run: | - ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC3Trpd_DLL_WSt_WavesReg - - name: Failing test artifacts - uses: actions/upload-artifact@v4 - if: failure() - with: - name: rtest-OF-5MW_OC3Trpd_DLL_WSt_WavesReg - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - - rtest-OF-5MW_Land_BD_DLL_WTurb: - runs-on: ubuntu-22.04 - needs: build-openfast-release - steps: - - name: Cache the workspace - uses: actions/cache@v4 - with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} + tar -xf workspace.tar -C${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library @@ -953,96 +572,108 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} - cmake --build . --target regression_test_controllers - - name: Run 5MW tests - working-directory: ${{runner.workspace}}/openfast/build + - name: Run aero map tests + working-directory: ${{github.workspace}}/build run: | - ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_Land_BD_DLL_WTurb + ctest -VV -L aeromap -LE "cpp|linear|python" - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() with: - name: rtest-OF-5MW_Land_BD_DLL_WTurb + name: rtest-OF-aeromap path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline + ${{github.workspace}}/build/reg_tests/glue-codes/openfast + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AOC + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/AWT27 + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/SWRT + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/UAE_VI + !${{github.workspace}}/build/reg_tests/glue-codes/openfast/WP_Baseline - rtest-OF-linearization: + rtest-openfast_io: runs-on: ubuntu-22.04 - needs: build-openfast-release + needs: build-all-release + env: + OMP_NUM_THREADS: 1 steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-openfast-release-${{ github.sha }} + name: build-all-release + - name: Untar workspace + run: | + tar -xf workspace.tar -C${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library sudo apt-get update -y sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev + - name: Install openfast_io + working-directory: ${{github.workspace}}/openfast_io + run: | + pip install -e . - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} - - name: Run OpenFAST linearization tests - working-directory: ${{runner.workspace}}/openfast/build + cmake --build . --target regression_test_controllers + - name: Run openfast_io tests + working-directory: ${{github.workspace}}/build run: | - ctest -VV -L linear + ctest -VV -L openfast_io - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() with: - name: rtest-OF-linearization + name: rtest-openfast_io path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline + ${{github.workspace}}/build/reg_tests/openfast_io rtest-FF: runs-on: ubuntu-22.04 - needs: build-fastfarm-release + needs: build-all-release + env: + OMP_NUM_THREADS: 2 steps: - - name: Cache the workspace - uses: actions/cache@v4 + - name: Restore workspace from artifact + uses: actions/download-artifact@v4 with: - path: ${{runner.workspace}} - key: build-fastfarm-release-${{ github.sha }} + name: build-all-release + - name: Untar workspace + run: | + tar -xf workspace.tar -C${{github.workspace}} + rm workspace.tar + - name: List files in workspace + run: ls - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies + working-directory: ${{github.workspace}} run: | pip install -r requirements.txt pip install glue-codes/python/. # Installs the interface library @@ -1050,24 +681,23 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Configure Tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build run: | cmake \ - -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DPython_ROOT_DIR:PATH=${{env.pythonLocation}} \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} cmake --build . --target regression_test_controllers - name: Run FAST.Farm tests - working-directory: ${{runner.workspace}}/openfast/build + working-directory: ${{github.workspace}}/build shell: bash run: | - set OMP_NUM_THREADS=2 - ctest -VV -L fastfarm --verbose + ctest -VV -j1 -L fastfarm --verbose - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() with: name: rtest-FF path: | - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/fast-farm + ${{github.workspace}}/build/reg_tests/glue-codes/fast-farm diff --git a/.github/workflows/conda-deploy.yml b/.github/workflows/conda-deploy.yml index 78083fc763..7e721419a7 100644 --- a/.github/workflows/conda-deploy.yml +++ b/.github/workflows/conda-deploy.yml @@ -15,7 +15,7 @@ on: jobs: update-dev: if: github.repository_owner == 'OpenFAST' - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: # - name: Echo path # run: | diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index adf3513704..a7819ab029 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -145,6 +145,10 @@ jobs: submodules: true fetch-depth: 0 + - name: Test devenv actually works + shell: cmd + run: .github/scripts/windows_devenv_test.bat + - name: Install Intel oneAPI BaseKit (Windows) shell: cmd env: diff --git a/README.rst b/README.rst index dff299384a..f63e070680 100644 --- a/README.rst +++ b/README.rst @@ -25,6 +25,18 @@ tag. **OpenFAST is under active development**. + + +Part of the WETO Stack +---------------------- + +OpenFAST is primarily developed with the support of the U.S. Department of Energy and is part of the `WETO Software Stack `_. For more information and other integrated modeling software, see: + +* `Portfolio Overview `_ +* `Entry Guide `_ +* `OpenFAST Workshop `_ + + FAST v8 - OpenFAST ------------------ The transition from FAST v8 to OpenFAST represents the effort to better diff --git a/docs/OtherSupporting/OutListParameters.xlsx b/docs/OtherSupporting/OutListParameters.xlsx index a480f6c047..784d6e06b8 100644 Binary files a/docs/OtherSupporting/OutListParameters.xlsx and b/docs/OtherSupporting/OutListParameters.xlsx differ diff --git a/docs/changelogs/ReleaseProcess.md b/docs/changelogs/ReleaseProcess.md index 6c38317907..27048c779f 100644 --- a/docs/changelogs/ReleaseProcess.md +++ b/docs/changelogs/ReleaseProcess.md @@ -13,6 +13,7 @@ 3. Update the versions in docs/source/user/api_change.rst 4. Verify readthedocs builds correctly 5. Update `openfast_io/pyproject.toml` +6. Update `glue-codes/python/pyproject.toml` (for `pyOpenFAST`) **** @@ -45,7 +46,7 @@ After posting and tagging release git update-index --assume-unchanged vs-build/MAPlib/MAP_dll.vcxproj vs-uild/Registry/FAST_Registry.vcxproj ``` -4. Compile executables for Windows builds +4. Compile executables for Windows builds (manual process - use GH actions `deploy` if possible) * Run one of the executables and check the version info. Muck about with VS if there is an issue. * Also run `dumpbin.exe /dependents .exe` to check static linking * NOTE: build the simulink last -- it messes up some things otherwise @@ -71,6 +72,7 @@ After posting and tagging release - [ ] `OpenFAST-Simulink_x64.dll` -- change `additional dependencies` in the `OpenFAST-Simulink` project in `FAST` to point to correct install of MATLAB - [ ] `openfast_x64.exe` - [ ] `SeaStateDriver_x64.exe` + - [ ] `SeaState_c_binding_x64.dll` - [ ] `SimpleElastoDyn_x64.exe` - [ ] `SubDyn_x64.exe` - [ ] `Turbsim_x64.exe` @@ -82,6 +84,6 @@ After posting and tagging release ``` ## Post-release ### Docker Image push to ghcr.io -1. Build latest `OpenFAST/main` image locally. +1. Build latest `OpenFAST/main` image locally (GH actions fails due to memory usage) 2. Push image to ghcr.io/openfast/openfast using tags `latest` and `` diff --git a/docs/changelogs/v4.0.4.md b/docs/changelogs/v4.0.4.md new file mode 100644 index 0000000000..6dcc91776b --- /dev/null +++ b/docs/changelogs/v4.0.4.md @@ -0,0 +1,94 @@ +**Feature or improvement description** +Pull request to merge `rc-4.0.4` into `main` and create a tagged release for v4.0.4 + +See the milestone and project pages for additional information + + https://github.com/OpenFAST/openfast/milestone/20 + +Test results, if applicable +See GitHub Actions + +### Release checklist: +- [ ] Update the documentation version in docs/conf.py +- [ ] Update the versions in docs/source/user/api\_change.rst +- [ ] Update version info in openfast\_io/pyproject.toml +- [ ] Verify readthedocs builds correctly +- [ ] Create an annotated tag in OpenFAST during merge (mark as most recent if necessary) +- [ ] Create a merge commit in r-test and add a corresponding annotated tag +- [ ] Upload Docker image +- [ ] Compile executables for Windows builds + - [ ] `AeroDisk_Driver_x64.exe` + - [ ] `AeroDyn_Driver_x64.exe` + - [ ] `AeroDyn_Driver_x64_OpenMP.exe` + - [ ] `AeroDyn_Inflow_c_binding_x64.dll` + - [ ] `AeroDyn_Inflow_c_binding_x64_OpenMP.dll` + - [ ] `BeamDyn_Driver_x64.exe` + - [ ] `DISCON.dll (x64)` + - [ ] `DISCON_ITIBarge.dll (x64)` + - [ ] `DISCON_OC3Hywind.dll (x64)` + - [ ] `DISCON_SC.dll (x64)` + - [ ] `FAST.Farm_x64.exe` + - [ ] `FAST.Farm_x64_OMP.exe` + - [ ] `FAST_SFunc.mexw64` + - [ ] `HydroDynDriver_x64.exe` + - [ ] `HydroDyn_C_Binding_x64.dll` + - [ ] `IinflowWind_c_binding_x64.dll` + - [ ] `InflowWind_Driver_x64.exe` + - [ ] `InflowWind_Driver_x64_OpenMP.exe` + - [ ] `MoorDyn_Driver_x64.exe` + - [ ] `MoorDyn_c_binding_x64.dll` + - [ ] `OpenFAST-Simulink_x64.dll` + - [ ] `openfast_x64.exe` + - [ ] `SeaStateDriver_x64.exe` + - [ ] `SimpleElastoDyn_x64.exe` + - [ ] `SubDyn_x64.exe` + - [ ] `Turbsim_x64.exe` + - [ ] `UnsteadyAero_x64.exe` + +# Changelog + +## Overview + +This release includes several bug fixes and improvements for _OpenFAST_, GitHub actions, and _openfast\_io_. + +## General + +### CMake build system + +### GitHub actions + +#2778 Backport of GitHub Action to build windows executables on release (@deslaughter) -- backport of #2636 + + +### openfast_io + +#2779 MD: Backport of PR #2658 -- openfast\_IO MoorDyn compatibility (@RyanDavies19) + +#2777 bug fix #2762 (@mayankchetan) + +#2658 openfast\_IO MoorDyn compatibilityModule (@RyanDavies19) + + + +## Solvers + +### Simulink + +#2785 Avoid ending program when called as a shared library (@bjonkman) -- backport of #2671 + + + +## Module changes + +### OpenFAST library + +#2780 backport of #2760: bug-fix: Adjust steady-state solver small angle assumptions (@bjonkman) + +#2776 Fix FAST\_ExtInfw\_Restart APIC++ API (@marchdf) + + + +## Input file changes + +No input file changes since v4.0.0 + diff --git a/docs/changelogs/v4.0.5.md b/docs/changelogs/v4.0.5.md new file mode 100644 index 0000000000..11173b3121 --- /dev/null +++ b/docs/changelogs/v4.0.5.md @@ -0,0 +1,116 @@ +**Feature or improvement description** +Pull request to merge `rc-4.0.5` into `main` and create a tagged release for v4.0.5 + +See the milestone and project pages for additional information + + https://github.com/OpenFAST/openfast/milestone/22 + +Test results, if applicable +See GitHub Actions + +### Release checklist: +- [ ] Update the documentation version in docs/conf.py +- [ ] Update the versions in docs/source/user/api\_change.rst +- [ ] Update version info in openfast\_io/pyproject.toml +- [ ] Verify readthedocs builds correctly +- [ ] Create an annotated tag in OpenFAST during merge (mark as most recent if necessary) +- [ ] Create a merge commit in r-test and add a corresponding annotated tag +- [ ] Upload Docker image +- [ ] Compile executables for Windows builds + - [ ] `AeroDisk_Driver_x64.exe` + - [ ] `AeroDyn_Driver_x64.exe` + - [ ] `AeroDyn_Driver_x64_OpenMP.exe` + - [ ] `AeroDyn_Inflow_c_binding_x64.dll` + - [ ] `AeroDyn_Inflow_c_binding_x64_OpenMP.dll` + - [ ] `BeamDyn_Driver_x64.exe` + - [ ] `DISCON.dll (x64)` + - [ ] `DISCON_ITIBarge.dll (x64)` + - [ ] `DISCON_OC3Hywind.dll (x64)` + - [ ] `DISCON_SC.dll (x64)` + - [ ] `FAST.Farm_x64.exe` + - [ ] `FAST.Farm_x64_OMP.exe` + - [ ] `FAST_SFunc.mexw64` + - [ ] `HydroDynDriver_x64.exe` + - [ ] `HydroDyn_C_Binding_x64.dll` + - [ ] `IinflowWind_c_binding_x64.dll` + - [ ] `InflowWind_Driver_x64.exe` + - [ ] `InflowWind_Driver_x64_OpenMP.exe` + - [ ] `MoorDyn_Driver_x64.exe` + - [ ] `MoorDyn_c_binding_x64.dll` + - [ ] `OpenFAST-Simulink_x64.dll` + - [ ] `openfast_x64.exe` + - [ ] `SeaStateDriver_x64.exe` + - [ ] `SimpleElastoDyn_x64.exe` + - [ ] `SubDyn_x64.exe` + - [ ] `Turbsim_x64.exe` + - [ ] `UnsteadyAero_x64.exe` + +# Changelog + +## Overview + +This release includes several bug fixes and improvements for _OpenFAST_, GitHub actions, and _openfast\_io_. + +## General + +### CMake build system + +### GitHub actions + +#2825 Simplify GitHub Action for regression tests (backport from dev-tc) (@deslaughter) + + +### openfast_io + +#2828 updated outlist reading in openfast\_io (@mayankchetan) + +#2818 OpenFAST IO updates: MoorDyn and StC (@dzalkind) + + + +## Solvers + +### OpenFAST + +#2831 [BugFix] WrVTK with VTK\_fps fails (@andrew-platt) + + +## Interfaces + +### cpp interface + +#2792 Fix openfastcpp restart parsing of file name (@marchdf) + +#2804 Add a checkError in openfast cpp (@marchdf) + +#2815 Fix restart parsing of file name (backport of #2792 and #2793) (@marchdf) + + +## Module changes + +### AeroDyn + +#2853 Backport #2848 (@bjonkman) + + +### BeamDyn + +#2811 BD: new output - aero only loads mapped to the root (@andrew-platt) + + +### IceFlow + +#2855 Fix Typo in "interpolation" in Ice Crushing Modules (@leopardracer) + + +### SubDyn + +#2821 bugfix: SD maximum number of output channels was incorrectly set (@andrew-platt) + + +## Input file changes + +No input file changes since v4.0.0 + +#2829 FF: typo in SeaState names in `MD_Shared` .fst files - this is not an API change (@andrew-platt) + diff --git a/docs/changelogs/v4.1.0.md b/docs/changelogs/v4.1.0.md new file mode 100644 index 0000000000..1d5ac864ba --- /dev/null +++ b/docs/changelogs/v4.1.0.md @@ -0,0 +1,240 @@ +**Feature or improvement description** +Pull request to merge `rc-4.1.0` into `main` and create a tagged release for v4.1.0 + +See the milestone and project pages for additional information + + https://github.com/OpenFAST/openfast/milestone/17 + +Test results, if applicable +See GitHub Actions + +### Release checklist: +- [ ] Update the documentation version in docs/conf.py +- [ ] Update the versions in docs/source/user/api\_change.rst +- [ ] Update version info in openfast\_io/pyproject.toml (`openfast_io` package) +- [ ] Update version info in glue-codes/python/pyproject.toml (`pyOpenFAST` package for testing) +- [ ] Verify readthedocs builds correctly +- [ ] Create an annotated tag in OpenFAST during merge (mark as most recent if necessary) +- [ ] Create a merge commit in r-test and add a corresponding annotated tag +- [ ] Upload Docker image +- [ ] Compile executables for Windows builds + - [ ] `AeroDisk_Driver_x64.exe` + - [ ] `AeroDyn_Driver_x64.exe` + - [ ] `AeroDyn_Driver_x64_OpenMP.exe` + - [ ] `AeroDyn_Inflow_c_binding_x64.dll` + - [ ] `AeroDyn_Inflow_c_binding_x64_OpenMP.dll` + - [ ] `BeamDyn_Driver_x64.exe` + - [ ] `DISCON.dll (x64)` + - [ ] `DISCON_ITIBarge.dll (x64)` + - [ ] `DISCON_OC3Hywind.dll (x64)` + - [ ] `DISCON_SC.dll (x64)` + - [ ] `FAST.Farm_x64.exe` + - [ ] `FAST.Farm_x64_OMP.exe` + - [ ] `FAST_SFunc.mexw64` + - [ ] `HydroDynDriver_x64.exe` + - [ ] `HydroDyn_C_Binding_x64.dll` + - [ ] `IinflowWind_c_binding_x64.dll` + - [ ] `InflowWind_Driver_x64.exe` + - [ ] `InflowWind_Driver_x64_OpenMP.exe` + - [ ] `MoorDyn_Driver_x64.exe` + - [ ] `MoorDyn_c_binding_x64.dll` + - [ ] `OpenFAST-Simulink_x64.dll` + - [ ] `openfast_x64.exe` + - [ ] `SeaStateDriver_x64.exe` + - [ ] `SeaState_c_binding_x64.dll` + - [ ] `SimpleElastoDyn_x64.exe` + - [ ] `SubDyn_x64.exe` + - [ ] `Turbsim_x64.exe` + - [ ] `UnsteadyAero_x64.exe` + +# Changelog (from 4.0.5) + +## Overview + +This release removes the SuperController from _FAST.Farm_ in favor of ZeroMQ communication between ROSCO controllers. +This release also adds several new features including direct coupling of _MoorDyn_ to _SeaState_, rectangular members in _HydroDyn_ and _SubDyn_, vortex-induced vibration (VIV) capabilities in _MoorDyn_, and a new _pyOpenFAST_ module for calling c-binding libraries directly from Python. +This release also includes several bug fixes and improvements for _AeroDyn_, _BeamDyn_, _MoorDyn_, _OpenFAST_, several various c-binding libary interfaces, and GitHub actions. + + +## General + +### CMake build system + +#2632 Reduce optimization level for `FAST*_Types.f90` with gcc (@andrew-platt) + +### GitHub actions + +#2636 Add job to build Windows executables to deploy.yml (@deslaughter) + +#2771 Update GH conda-deploy action to use Ubuntu 24.04 (@andrew-platt) + + +### Visual Studio build system + +#2866 VS build: fix MD, add `SeaStateS_c_binding` and update GH `deploy` action (@andrew-platt) + + + +## Python packages + +### openfast_io + +#2658 `openfast_IO` MoorDyn compatibility (@RyanDavies19) + + +### pyOpenFAST +This is a new python package that interfaces the c-bindings library versions of _OpenFAST_ with Python. Users who want to call standalone _OpenFAST_ modules from Python will want to look into using this package. Note that the documentation is limited at this time. + +This package is also used in testing (see [documentation on testing environments]([https://openfast.readthedocs.io/en/main/source/testing/regression_test.html#testing-environment)) + +#2680 Refactor the Aerodyn/Inflowwind Python interface to the C-bindings interface (@faisal-bhuiyan) + +#2719 Python infrastructure improvements (new pyOpenFAST package) (@rafmudaf) + + + +## Solvers + +### FAST.Farm + +#2729 Remove supercontroller from FAST.Farm (@abhineet-gupta) + + +### OpenFAST + +#2671 Avoid ending program when called as a shared library (@bjonkman) + +#2705 MoorDyn-SeaState Coupling (OpenFAST and FAST.Farm) (@RyanDavies19) + +#2760 bug fix: Adjust steady-state solver small angle assumptions (@bjonkman) + + + +## Module changes + +### multiple modules + +#2770 Bug fix for Failed0 error checking functions (@rafmudaf) + + +### AeroDyn + +#2848 Bug fix: remove spaces in OLAF's UA summary file name (@bjonkman) + + +### BeamDyn + +#2642 [BugFix] BD: variable passing in `Calc_RR0mEta_rho` (@bjonkman, @andrew-platt) + + +### HydroDyn + +#2646 Implementation of rectangular members in HD and SD (@luwang00) + +#2663 HydroDyn C-binding: Added mass matrix (@luwang00) + +#2787 HD-cbind: Add HydroDyn input files handle (@wenchaoyu, @andrew-platt) + +#2865 Reduce memory requirement in HydroDyn initialization (@bjonkman) + + +### MoorDyn + +#2746 MoorDyn bugfixes (@RyanDavies19) + +#2650 MoorDyn: VIV and Rk4 solver (@RyanDavies19 ) + +#2791 MD cbind: correction to description of mesh point mapping (@andrew-platt) + +#2794 MoorDyn wave directional spreading and custom current profile if no SeaState current (@RyanDavies19) + + +### SeaState + +#2720 Adds first pass SeaState C Binding interface (@rafmudaf) + + +### ServoDyn + +#2798 Docs: correct Bladed Interface channel 63 description (@andrew-platt) + + +### SubDyn + +#2646 (see above in HydroDyn) + +### TurbSim + +#2808 [BugFix] TurbSim calculating grid bottom location (@ptrbortolotti) + + +## Documentation + +#2867 Docs: update info on testing (with `pyOpenFAST` module) (@andrew-platt) + +#2850 Docs Update for the New Rectangular Members in HydroDyn and SubDyn (@luwang00) + + +## Typo fixes in code comments +There have been several "fluff" pull requests with only typo fixes and no code changes. + +#2858 Fix Typos in Comments and Log Messages for Flexural and Crushing Ice Failure Initialization (@kilavvy) + + +## Regression Testing + +#2765 MHK RM1: reduce HD resolution (@andrew-platt) + +## Code API changes +The SuperController has been removed. This changes the interfaces for some files: + +#### CPP interface +- `glue-codes/openfast-cpp/src/OpenFAST.H` + - `class fastInputs {` + - `class OpenFAST {` +- `glue-codes/openfast-cpp/src/OpenFAST.cpp` + - `class fastInputs ` + - `fast::fastInputs::fastInputs():` + +#### OpenFAST library interface +- `modules/openfast-library/src/FAST_Library.h` + - `FAST_ExtLoads_Restart` - removal of SuperController arguments + - `FAST_ExtLoads_Init` - removal of SuperController arguments + - ` FAST_ExtInfw_Restart` - removal of SuperController arguments + - ` FAST_ExtInfw_Init` -removal of SuperController arguments +- `modules/openfast-library/src/FAST_Library.f90` + - `FAST_ExtLoads_Restart` - removal of SuperController arguments + - `FAST_ExtLoads_Init` - removal of SuperController arguments + - ` FAST_ExtInfw_Restart` - removal of SuperController arguments + - ` FAST_ExtInfw_Init` -removal of SuperController arguments + +### HydroDyn c-binding library interface +- `modules/hydrodyn/src/HydroDyn_C_Binding.f90` + - `HydroDyn_C_Init` - arguments + - `HydroDyn_C_CalcOutput_and_AddedMass` - new routine + +### MoorDyn c-bindings libarary interface +- `modules/moordyn/src/MoorDyn_C_Binding.f90` + - `MD_C_Init` - new argument + + +## Input file changes +This release brings several input file changes including the FAST.Farm (removal of supercontroller sections), HydroDyn (new sections for rectangular members, revised members table), SubDyn (new rectangular cross-section table, and additional columns in other tables). +A list of changes can be found here: https://openfast.readthedocs.io/en/main/source/user/api_change.html. However, we recommend that if you start by comparing to the complete set of input files found in the regression tests: https://github.com/OpenFAST/r-test/tree/v4.1.0 (example input files from the regression testing) + + +## Known issues +There are several issues that have not been addressed in this release due to time constraints, but will be addressed in future releases. These include: + +- No visualization of rectangular members from _HydroDyn_ or _SubDyn_ through the VTK output options +- Missing and broken features from several c-binding library interfaces: + - the _AeroDyn\_Inflow\_c-binding_ library interface does not allow for coupling to the tower. This will require an interface update. + - the _HydroDyn\_c-binding_ library interface does not currently support vizualization. This will require an interface update. + - the `InitNodePositions` input to _HydroDyn\_c-binding_ library interface does not currently work with any non-zero `x` or `y` coordinates (non-zero `z` is ok) + - the _MoorDyn\_c-binding_ library interface does not currently support vizualization. This will require an interface update. + - error messages from c-binding library interfaces will get truncated to 1024 characters. A fix is nearly ready, but will have to wait until the next release. +- There are leftover unused and incomplete files from development in the `glue-codes/python` directory. These will be removed later. +- A `glue-codes/labview/src/WaveTank.f90` file is included in this release, but it is incomplete and untested. This is a placeholder for internal development work that may be released in complete form at a later date. +- The GitHub `deploy` action to build Windows executables does not currently catch failed builds. This might be addressed at a later date. We are manually checking these builds for now. +- Documentation on the new _pyOpenFAST_ module is incomplete. Partial documentation exists on how to use it in regression testing, but no documentation or examples exist on using it to call c-bindings modules from Python. +- Documentation is incomplete for _HydroDyn_, _SubDyn_, and a few other modules. diff --git a/docs/conf.py b/docs/conf.py index bb9d65f674..b8073a76b5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -136,9 +136,9 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # built documents. # # The short X.Y version. -version = u'4.0' +version = u'4.1' # The full version, including alpha/beta/rc tags. -release = u'v4.0.3' +release = u'v4.1.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/dev/index.rst b/docs/source/dev/index.rst index dd833c8ef6..96ef271719 100644 --- a/docs/source/dev/index.rst +++ b/docs/source/dev/index.rst @@ -61,7 +61,7 @@ with the NREL OpenFAST team to define the scope of the work and coordinate development efforts. This is particularly important since many groups work on OpenFAST simultaneously. By engaging early, all developers can stay up to date and minimize conflicts during the code merge. -The prefered method of communication is `GitHub Issues `_. +The preferred method of communication is `GitHub Issues `_. An initial post should contain all relevant information about the planned development work, the areas of the software that will be impacted, and any model validation materials. See :ref:`development_plan` diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst index 643fa0fc38..932a15d2be 100644 --- a/docs/source/install/index.rst +++ b/docs/source/install/index.rst @@ -478,7 +478,7 @@ The CMake options specific to OpenFAST and their default settings are: ORCA_DLL_LOAD - Enable OrcaFlex library load (Default: ON) USE_DLL_INTERFACE - Enable runtime loading of dynamic libraries (Default: ON) USE_LOCAL_STATIC_LAPACK - Enable downloading and building static LAPACK and BLAS libs (Default: OFF) - VARIABLE_TRACKING - Enables variable tracking for better runtime debugging output. May increase compile time. Valid only for GNU. (Defualt: ON) + VARIABLE_TRACKING - Enables variable tracking for better runtime debugging output. May increase compile time. Valid only for GNU. (Default: ON) Additional system-specific options may exist for a given system, but those diff --git a/docs/source/testing/regression_test.rst b/docs/source/testing/regression_test.rst index 0e975b055d..099a581564 100644 --- a/docs/source/testing/regression_test.rst +++ b/docs/source/testing/regression_test.rst @@ -13,19 +13,21 @@ tests: - :ref:`regression_test_windows` Each locally computed result is compared to a static set of baseline -results. To account for system, hardware, and compiler -differences, the regression test attempts to match the current machine and -compiler type to the appropriate solution set from these combinations: +results. The results are computed using the following OS, compiler, and hardware +combination: ================== ============== ============================ Operating System Compiler Hardware ================== ============== ============================ - macOS 10.15 GNU 10.2 2020 MacbookPro - Ubuntu 20.04 Intel oneAPI Docker - Ubuntu 20.04 GNU 10.2 Docker - Windows 10 Intel oneAPI Dell Precision 3530 + Ubuntu 22.04 GNU 12.3.0 GitHub actions ================== ============== ============================ +Note that if you run the regression tests locally, there may small numerical +differences due to your compiler and hardware combination that may cause a few +tests to fail. If you use the ``bokeh`` package while running the tests, you +will see a resulting *html* file with plots showing the differences for any +tests that fail (these differences should be small). + The compiler versions, specific math libraries, and more info on hardware used to generate the baseline solutions are documented in the `r-test repository documentation `__. Currently, @@ -62,17 +64,56 @@ reported as failed. The failure criteria is outlined below. else: pass = False + +Testing Environment +------------------- +We recommend using ``conda`` to create a local environment to install the +required packages for *OpenFAST* testing. You can use the following process as a +rough guide for setting up the necessary environment on Linux/MacOS based +systems. + +1. create a new ``conda`` environment for *OpenFAST* testing and install python: + + - ``conda install python`` + +2. from the ``/build`` directory, setup the environment with the +following commands: + + - ``pip install ../requirements.txt`` + + Installs basic dependencies for testing. + + - ``pip install -e ../glue-codes/python/.`` + + Installs the ``pyOpenFAST`` package from *OpenFAST* repository + + - ``pip install -e ../openfast_io/.`` + Installs the ``openfast_io`` package from *OpenFAST* repository + + Dependencies ------------ The following packages are required for regression testing (see also the ``requirements.txt`` file in the root directory for the python modules): -- CMake and CTest (Optional) -- Python >=3.7,<=3.11 +- CMake and CTest +- Python >=3.7 - numpy - vtk - bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3 (Optional) +In addition to the above packages, two packages from the *OpenFAST* repository +are required. We recommend installing these in a ``conda`` enviroment as +described in the above section so that it will not interfere with your system +Python installation. Using the ``pip install -e`` command will install using +the local directory instead placing them within the system Python directories. + +- ``pyOpenFAST`` is a package for interfacing Python to the c-bindings libraries + of *OpenFAST* modules. This is used in some testing at the module level. +- ``openfast_io`` is a package for reading and writing *OpenFAST* input files. + This is used in some of the testing. + + .. _python_driver: Executing with Python driver diff --git a/docs/source/user/aerodyn-olaf/OLAFTheory.rst b/docs/source/user/aerodyn-olaf/OLAFTheory.rst index 7bde8f6587..ac21622da4 100644 --- a/docs/source/user/aerodyn-olaf/OLAFTheory.rst +++ b/docs/source/user/aerodyn-olaf/OLAFTheory.rst @@ -94,7 +94,7 @@ a line of varying circulation. The line follows the motion of the blade and is referred to as “bound” circulation. The bound circulation does not follow the same dynamic equation as the free vorticity of the wake. Instead, the intensity is linked to airfoil lift via the Kutta-Joukowski theorem. Spanwise variation of -the bound circulation results in vorticity being emitted into the the wake. This +the bound circulation results in vorticity being emitted into the wake. This is referred to as “trailed vorticity”. Time changes of the bound circulation are also emitted in the wake, referred to as “shed” vorticity. The subsequent paragraphs describe the representation of the bound vorticity. diff --git a/docs/source/user/aerodyn/input.rst b/docs/source/user/aerodyn/input.rst index 000fc089fe..5013abbad5 100644 --- a/docs/source/user/aerodyn/input.rst +++ b/docs/source/user/aerodyn/input.rst @@ -187,7 +187,7 @@ Determines the kind of BEM algorithm to use. .. warning:: - ``BEM_Mod`` currently governs the coordinate system used for "ill-defined" outputs (outputs that don't have a specified coordinate system) such as the ones that ends with "x" and "y". Other ill-defined outputs are the typical BEM quantities such as "AxInd", "TnInd", "Phi", etc. These are defined in a different coordinate system depending on `BEM_Mod`. For consistency accross differents `Wake_Mod` (even when `Wake_Mod/=1`), we use `BEM_Mod` to determine the coordinate system of the ill-defined outputs. + ``BEM_Mod`` currently governs the coordinate system used for "ill-defined" outputs (outputs that don't have a specified coordinate system) such as the ones that ends with "x" and "y". Other ill-defined outputs are the typical BEM quantities such as "AxInd", "TnInd", "Phi", etc. These are defined in a different coordinate system depending on `BEM_Mod`. For consistency across differents `Wake_Mod` (even when `Wake_Mod/=1`), we use `BEM_Mod` to determine the coordinate system of the ill-defined outputs. The following inputs in this section are only used when ``Wake_Mod = 1``. diff --git a/docs/source/user/aerodyn/theory.rst b/docs/source/user/aerodyn/theory.rst index 8043c51cfe..edd4aa2f1f 100644 --- a/docs/source/user/aerodyn/theory.rst +++ b/docs/source/user/aerodyn/theory.rst @@ -4,7 +4,7 @@ AeroDyn Theory ============== -This theory manual is work in progress, please refer to the AeroDyn 14 manual for more details :cite:`ad-AeroDyn:manual`. Many changes have occured since AeroDyn 14 (e.g. BEM formulation, coordinate system used in the BEM equations, dynamic stall, dynamic BEM), but these changes are not yet documented here. +This theory manual is work in progress, please refer to the AeroDyn 14 manual for more details :cite:`ad-AeroDyn:manual`. Many changes have occurred since AeroDyn 14 (e.g. BEM formulation, coordinate system used in the BEM equations, dynamic stall, dynamic BEM), but these changes are not yet documented here. diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 96b0137dd1..48b5bb0086 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -9,19 +9,86 @@ The changes are tabulated according to the module input file, line number, and f The line number corresponds to the resulting line number after all changes are implemented. Thus, be sure to implement each in order so that subsequent line numbers are correct. -OpenFAST v4.0.3 to OpenFAST v4.1.0 +OpenFAST v4.0.5 to OpenFAST v4.1.0 ---------------------------------- Supercontroller module has been removed from FAST.Farm. -============================================= ==== =============== ======================================================================================================================================================================================================== +============================================= ==== ================== =============================================================================================================================================================================================================================================================================================================================================================================================================================================================== Removed in OpenFAST `v4.1.0` ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -Module Line Flag Name Example Value -============================================= ==== =============== ======================================================================================================================================================================================================== -FAST.Farm 7 UseSC False UseSC - Use a super controller? (flag) -FAST.Farm 11 na --- SUPER CONTROLLER --- [used only for UseSC=True] -FAST.Farm 12 SC_FileName "SC_DLL.dll" SC_FileName Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms (quoted string) -============================================= ==== =============== ======================================================================================================================================================================================================== +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== ================== =============================================================================================================================================================================================================================================================================================================================================================================================================================================================== +FAST.Farm 7 UseSC False UseSC - Use a super controller? (flag) +FAST.Farm 11 na --- SUPER CONTROLLER --- [used only for UseSC=True] +FAST.Farm 12 SC_FileName "SC_DLL.dll" SC_FileName Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms (quoted string) +============================================= ==== ================== =============================================================================================================================================================================================================================================================================================================================================================================================================================================================== + +Line numbers are not provided in the table below because the line numbers can change depending on the number of entries in the input files. Please refer to the User Documentation on the input files for examples. + +============================================= ========= ================== =============================================================================================================================================================================================================================================================================================================================================================================================================================================================== +Added/Modified in OpenFAST `v4.1.0` +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +Module Change Flag Name Example Value +============================================= ========= ================== =============================================================================================================================================================================================================================================================================================================================================================================================================================================================== +HydroDyn Modified na ---------------- CYLINDRICAL MEMBER CROSS-SECTION PROPERTIES ------------------- +HydroDyn Modified NPropSetsCyl 1 NPropSetsCyl - Number of cylindrical member property sets (-) +HydroDyn Added na ---------------- RECTANGULAR MEMBER CROSS-SECTION PROPERTIES ------------------- +HydroDyn Added NPropSetsRec 1 NPropSetsRec - Number of rectangular member property sets (-) +HydroDyn Added na PropSetID PropA PropB PropThck +HydroDyn Added na (-) (m) (m) (m) +HydroDyn Modified na -------- SIMPLE CYLINDRICAL-MEMBER HYDRODYNAMIC COEFFICIENTS (model 1) --------- +HydroDyn Added na -------- SIMPLE RECTANGULAR-MEMBER HYDRODYNAMIC COEFFICIENTS (model 1) --------- +HydroDyn Added na SimplCdA SimplCdAMG SimplCdB SimplCdBMG SimplCaA SimplCaAMG SimplCaB SimplCaBMG SimplCp SimplCpMG SimplAxCd SimplAxCdMG SimplAxCa SimplAxCaMG SimplAxCp SimplAxCpMG SimplCb SimplCbMG +HydroDyn Added na (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) +HydroDyn Modified na ------ DEPTH-BASED CYLINDRICAL-MEMBER HYDRODYNAMIC COEFFICIENTS (model 2) ------- +HydroDyn Modified NCoefDpthCyl 0 NCoefDpthCyl - Number of depth-dependent cylindrical member coefficients (-) +HydroDyn Added na ------ DEPTH-BASED RECTANGULAR-MEMBER HYDRODYNAMIC COEFFICIENTS (model 2) ------- +HydroDyn Added NCoefDpthRec 0 NCoefDpthRec - Number of depth-dependent rectangular member coefficients (-) +HydroDyn Added na Dpth DpthCdA DpthCdAMG DpthCdB DpthCdBMG DpthCaA DpthCaAMG DpthCaB DpthCaBMG DpthCp DpthCpMG DpthAxCd DpthAxCdMG DpthAxCa DpthAxCaMG DpthAxCp DpthAxCpMG DpthCb DpthCbMG +HydroDyn Added na `(m)` (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) +HydroDyn Modified na ------ MEMBER-BASED CYLINDRICAL-MEMBER HYDRODYNAMIC COEFFICIENTS (model 3) ------ +HydroDyn Modified NCoefMembersCyl 0 NCoefMembersCyl - Number of member-based cylindrical member coefficients (-) +HydroDyn Added na ------ MEMBER-BASED RECTANGULAR-MEMBER HYDRODYNAMIC COEFFICIENTS (model 3) ------ +HydroDyn Added NCoefMembersRec 0 NCoefMembersRec - Number of member-based rectangular member coefficients (-) +HydroDyn Added na MemberID MemberCdA1 MemberCdA2 MemberCdAMG1 MemberCdAMG2 MemberCdB1 MemberCdB2 MemberCdBMG1 MemberCdBMG2 MemberCaA1 MemberCaA2 MemberCaAMG1 MemberCaAMG2 MemberCaB1 MemberCaB2 MemberCaBMG1 MemberCaBMG2 MemberCp1 MemberCp2 MemberCpMG1 MemberCpMG2 MemberAxCd1 MemberAxCd2 MemberAxCdMG1 MemberAxCdMG2 MemberAxCa1 MemberAxCa2 MemberAxCaMG1 MemberAxCaMG2 MemberAxCp1 MemberAxCp2 MemberAxCpMG1 MemberAxCpMG2 MemberCb1 MemberCb2 MemberCbMG1 MemberCbMG2 +HydroDyn Added na (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) +HydroDyn Modified na MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MSecGeom MSpinOrient MDivSize MCoefMod MHstLMod PropPot [MCoefMod=1: use simple coeff table, 2: use depth-based coeff table, 3: use member-based coeff table] [PropPot/=0 if member is modeled with potential-flow theory] +HydroDyn Modified na (-) (-) (-) (-) (-) (switch) (deg) (m) (switch) (switch) (flag) +MoorDyn Optional na +SubDyn Modified na MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType MSpin/COSMID ![MType={1c:beam circ., 1r:beam rect., 2:cable, 3:rigid, 4:beam arb., 5:spring}. COMSID={-1:none}] +SubDyn Modified na (-) (-) (-) (-) (-) (-) (deg/-) +SubDyn Added na ----------------- RECTANGULAR BEAM CROSS-SECTION PROPERTIES --------------------------- +SubDyn Added na 0 NPropSets - Number of structurally unique cross-sections (if 0 the following table is ignored) +SubDyn Added na PropSetID YoungE ShearG MatDens XsecSa XsecSb XsecT +SubDyn Added na (-) (N/m2) (N/m2) (kg/m3) (m) (m) (m) +SubDyn Modified na PropSetID YoungE ShearG MatDens XsecA XsecAsx XsecAsy XsecJxx XsecJyy XsecJ0 XsecJt +SubDyn Modified na (-) (N/m2) (N/m2) (kg/m3) (m2) (m2) (m2) (m4) (m4) (m4) (m4) +============================================= ========= ================== =============================================================================================================================================================================================================================================================================================================================================================================================================================================================== + +MoorDyn changes +~~~~~~~~~~~~~~~ + +The *MoorDyn* input file now includes additional optional inputs, but is fully +backwards compatible. For further information on the new inputs: + +- coupling with the *SeaState* module for wave information, see example files: + + - `https://github.com/OpenFAST/r-test/tree/main/modules/moordyn/md_waterkin3 `_ - full wave information from *SeaState* module + - `https://github.com/OpenFAST/r-test/tree/main/modules/moordyn/md_waterkin2 `_ - hybrid wave kinematics coupling with *SeaState* module + +- vortex-induced vibration (VIV) - see `https://moordyn.readthedocs.io/en/latest/inputs.html#id2 `_ + + +OpenFAST v4.0.4 to OpenFAST v4.0.5 +---------------------------------- + +No input file changes were made. + + +OpenFAST v4.0.3 to OpenFAST v4.0.4 +---------------------------------- + +No input file changes were made. OpenFAST v4.0.2 to OpenFAST v4.0.3 diff --git a/docs/source/user/beamdyn/theory.rst b/docs/source/user/beamdyn/theory.rst index f8a80e1e1f..78d14e6936 100644 --- a/docs/source/user/beamdyn/theory.rst +++ b/docs/source/user/beamdyn/theory.rst @@ -82,7 +82,7 @@ Local blade coordinate system The local blade coordinate system is used for some input and output quantities, for example, the cross-sectional mass and stiffness matrices -and the the sectional force and moment resultants. This coordinate +and the sectional force and moment resultants. This coordinate system is different from the blade reference coordinate system in that its :math:`Z_l` axis is always tangent to the blade axis as the blade deflects. Note that a subscript :math:`l` denotes the local blade diff --git a/docs/source/user/cppapi/files/cDriver.i b/docs/source/user/cppapi/files/cDriver.i index 917208c312..f62e9725eb 100644 --- a/docs/source/user/cppapi/files/cDriver.i +++ b/docs/source/user/cppapi/files/cDriver.i @@ -27,7 +27,7 @@ n_substeps: 1 # Number of substeps per timestep of the glue-code n_checkpoint: 160 # Restart files will be written every so many time steps -set_exp_law_wind: false # Set velocity at the the turbine using an exponential law profile. +set_exp_law_wind: false # Set velocity at the turbine using an exponential law profile. Turbine0: diff --git a/docs/source/user/elastodyn/theory.rst b/docs/source/user/elastodyn/theory.rst index d4756dd0cd..09f2eec1e6 100644 --- a/docs/source/user/elastodyn/theory.rst +++ b/docs/source/user/elastodyn/theory.rst @@ -5,7 +5,7 @@ ElastoDyn Theory ================ Note this document is work in progress and is greatly incomplete. -This documentation was started to document some code changes to the the tail furl and rotor furl part of ElastoDyn. +This documentation was started to document some code changes to the tail furl and rotor furl part of ElastoDyn. Please refer to the different ressources provided in :numref:`ed_intro` for additional documents. diff --git a/docs/source/user/fast.farm/FFarmTheory.rst b/docs/source/user/fast.farm/FFarmTheory.rst index 6d0fd4b42a..3f58c3a53e 100644 --- a/docs/source/user/fast.farm/FFarmTheory.rst +++ b/docs/source/user/fast.farm/FFarmTheory.rst @@ -1278,7 +1278,7 @@ where :math:`D` is a reference diameter, and :math:`\bar{U}` is the mean velocity taken as the filtered velocity at the turbine location normal to the rotor disk. The coordinates :math:`x,y,z` and :math:`r,\theta` are taken in the meandering frame of reference. The parameters :math:`k_\text{def}^\text{WAT}` -and :math:`k_\text{grad}^\text{WAT}` are tuning paramters of the model +and :math:`k_\text{grad}^\text{WAT}` are tuning parameters of the model respectively multiplying the quasi-steady wake deficit and the gradient of the wake deficit. These are based on an eddy-viscosity filter with five calibrated parameters to give a more realistic dependence on downstream position. The diff --git a/docs/source/user/fast.farm/OutputFiles.rst b/docs/source/user/fast.farm/OutputFiles.rst index 683820605f..4e65e3accf 100644 --- a/docs/source/user/fast.farm/OutputFiles.rst +++ b/docs/source/user/fast.farm/OutputFiles.rst @@ -138,5 +138,5 @@ module levels, as specified within the OpenFAST input files) are described in the OpenFAST documentation and include summary (*.sum*) files, time-series results (ASCI *.out* or binary *.outb*) files, visualization (*.vtk*) files, etc. FAST.Farm simulations will generate -these same files, but with the the path/rootname changed to *.T*. diff --git a/docs/source/user/hydrodyn/appendix.rst b/docs/source/user/hydrodyn/appendix.rst index b58c4717b9..558914dbaf 100644 --- a/docs/source/user/hydrodyn/appendix.rst +++ b/docs/source/user/hydrodyn/appendix.rst @@ -120,24 +120,36 @@ structure:: 42 14.43376 25.00000 -19.94000 1 0 43 -28.86751 0.00000 -19.94000 1 0 44 14.43376 -25.00000 -19.94000 1 0 - ---------------------- MEMBER CROSS-SECTION PROPERTIES ------------------------- - 4 NPropSets - Number of member property sets (-) + ---------------- CYLINDRICAL MEMBER CROSS-SECTION PROPERTIES ------------------- + 4 NPropSetsCyl - Number of cylindrical member property sets (-) PropSetID PropD PropThck (-) (m) (m) 1 6.50000 0.03000 ! Main Column 2 12.00000 0.06000 ! Upper Columns 3 24.00000 0.06000 ! Base Columns 4 1.60000 0.01750 ! Pontoons - ---------------------- SIMPLE HYDRODYNAMIC COEFFICIENTS (model 1) -------------- + ---------------- RECTANGULAR MEMBER CROSS-SECTION PROPERTIES ------------------- + 0 NPropSetsRec - Number of rectangular member property sets (-) + MPropSetID PropA PropB PropThck + (-) (m) (m) (m) + -------- SIMPLE CYLINDRICAL-MEMBER HYDRODYNAMIC COEFFICIENTS (model 1) --------- SimplCd SimplCdMG SimplCa SimplCaMG SimplCp SimplCpMG SimplAxCd SimplAxCdMG SimplAxCa SimplAxCaMG SimplAxCp SimplAxCpMG SimplCb SimplCbMG (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) 0.00 0.00 0.00 0.00 1.00 1.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00 - ---------------------- DEPTH-BASED HYDRODYNAMIC COEFFICIENTS (model 2) --------- - 0 NCoefDpth - Number of depth-dependent coefficients (-) + -------- SIMPLE RECTANGULAR-MEMBER HYDRODYNAMIC COEFFICIENTS (model 1) --------- + SimplCdA SimplCdAMG SimplCdB SimplCdBMG SimplCaA SimplCaAMG SimplCaB SimplCaBMG SimplCp SimplCpMG SimplAxCd SimplAxCdMG SimplAxCa SimplAxCaMG SimplAxCp SimplAxCpMG SimplCb SimplCbMG + (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 + ------ DEPTH-BASED CYLINDRICAL-MEMBER HYDRODYNAMIC COEFFICIENTS (model 2) ------- + 0 NCoefDpthCyl - Number of depth-dependent cylindrical member coefficients (-) Dpth DpthCd DpthCdMG DpthCa DpthCaMG DpthCp DpthCpMG DpthAxCd DpthAxCdMG DpthAxCa DpthAxCaMG DpthAxCp DpthAxCpMG DpthCb DpthCbMG (m) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) - ---------------------- MEMBER-BASED HYDRODYNAMIC COEFFICIENTS (model 3) -------- - 25 NCoefMembers - Number of member-based coefficients (-) + ------ DEPTH-BASED RECTANGULAR-MEMBER HYDRODYNAMIC COEFFICIENTS (model 2) ------- + 0 NCoefDpthRec - Number of depth-dependent rectangular member coefficients (-) + Dpth DpthCdA DpthCdAMG DpthCdB DpthCdBMG DpthCaA DpthCaAMG DpthCaB DpthCaBMG DpthCp DpthCpMG DpthAxCd DpthAxCdMG DpthAxCa DpthAxCaMG DpthAxCp DpthAxCpMG DpthCb DpthCbMG + (m) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) + ------ MEMBER-BASED CYLINDRICAL-MEMBER HYDRODYNAMIC COEFFICIENTS (model 3) ------ + 25 NCoefMembersCyl - Number of member-based cylindrical member coefficients (-) MemberID MemberCd1 MemberCd2 MemberCdMG1 MemberCdMG2 MemberCa1 MemberCa2 MemberCaMG1 MemberCaMG2 MemberCp1 MemberCp2 MemberCpMG1 MemberCpMG2 MemberAxCd1 MemberAxCd2 MemberAxCdMG1 MemberAxCdMG2 MemberAxCa1 MemberAxCa2 MemberAxCaMG1 MemberAxCaMG2 MemberAxCp1 MemberAxCp2 MemberAxCpMG1 MemberAxCpMG2 MemberCb1 MemberCb2 MemberCbMG1 MemberCbMG2 (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) 1 0.56 0.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00 ! Main Column @@ -165,35 +177,39 @@ structure:: 20 0.63 0.63 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00 ! Cross Brace 1 21 0.63 0.63 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00 ! Cross Brace 2 22 0.63 0.63 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00 ! Cross Brace 3 + ------ MEMBER-BASED RECTANGULAR-MEMBER HYDRODYNAMIC COEFFICIENTS (model 3) ------ + 0 NCoefMembersRec - Number of member-based rectangular member coefficients (-) + MemberID MemberCdA1 MemberCdA2 MemberCdAMG1 MemberCdAMG2 MemberCdB1 MemberCdB2 MemberCdBMG1 MemberCdBMG2 MemberCaA1 MemberCaA2 MemberCaAMG1 MemberCaAMG2 MemberCaB1 MemberCaB2 MemberCaBMG1 MemberCaBMG2 MemberCp1 MemberCp2 MemberCpMG1 MemberCpMG2 MemberAxCd1 MemberAxCd2 MemberAxCdMG1 MemberAxCdMG2 MemberAxCa1 MemberAxCa2 MemberAxCaMG1 MemberAxCaMG2 MemberAxCp1 MemberAxCp2 MemberAxCpMG1 MemberAxCpMG2 MemberCb1 MemberCb2 MemberCbMG1 MemberCbMG2 + (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) -------------------- MEMBERS ------------------------------------------------- 25 NMembers - Number of members (-) - MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MDivSize MCoefMod MHstLMod PropPot [MCoefMod=1: use simple coeff table, 2: use depth-based coeff table, 3: use member-based coeff table] [ PropPot/=0 if member is modeled with potential-flow theory] - (-) (-) (-) (-) (-) (m) (switch) (switch) (flag) - 1 1 2 1 1 1.0000 3 1 TRUE ! Main Column - 2 3 4 2 2 1.0000 3 1 TRUE ! Upper Column 1 - 3 5 6 2 2 1.0000 3 1 TRUE ! Upper Column 2 - 4 7 8 2 2 1.0000 3 1 TRUE ! Upper Column 3 - 5 42 3 3 3 1.0000 3 1 TRUE ! Base Column 1 - 6 43 5 3 3 1.0000 3 1 TRUE ! Base Column 2 - 7 44 7 3 3 1.0000 3 1 TRUE ! Base Column 3 - 23 9 42 3 3 1.0000 3 1 TRUE ! Base column cap 1 - 24 10 43 3 3 1.0000 3 1 TRUE ! Base column cap 2 - 25 11 44 3 3 1.0000 3 1 TRUE ! Base column cap 3 - 8 12 13 4 4 1.0000 3 1 TRUE ! Delta Pontoon, Upper 1 - 9 14 15 4 4 1.0000 3 1 TRUE ! Delta Pontoon, Upper 2 - 10 16 17 4 4 1.0000 3 1 TRUE ! Delta Pontoon, Upper 3 - 11 18 19 4 4 1.0000 3 1 TRUE ! Delta Pontoon, Lower 1 - 12 20 21 4 4 1.0000 3 1 TRUE ! Delta Pontoon, Lower 2 - 13 22 23 4 4 1.0000 3 1 TRUE ! Delta Pontoon, Lower 3 - 14 24 25 4 4 1.0000 3 1 TRUE ! Y Pontoon, Upper 1 - 15 26 27 4 4 1.0000 3 1 TRUE ! Y Pontoon, Upper 2 - 16 28 29 4 4 1.0000 3 1 TRUE ! Y Pontoon, Upper 3 - 17 30 31 4 4 1.0000 3 1 TRUE ! Y Pontoon, Lower 1 - 18 32 33 4 4 1.0000 3 1 TRUE ! Y Pontoon, Lower 2 - 19 34 35 4 4 1.0000 3 1 TRUE ! Y Pontoon, Lower 3 - 20 36 37 4 4 1.0000 3 1 TRUE ! Cross Brace 1 - 21 38 39 4 4 1.0000 3 1 TRUE ! Cross Brace 2 - 22 40 41 4 4 1.0000 3 1 TRUE ! Cross Brace 3 + MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MSecGeom MSpinOrient MDivSize MCoefMod MHstLMod PropPot [MCoefMod=1: use simple coeff table, 2: use depth-based coeff table, 3: use member-based coeff table] [ PropPot/=0 if member is modeled with potential-flow theory] + (-) (-) (-) (-) (-) (switch) (deg) (m) (switch) (switch) (flag) + 1 1 2 1 1 1 0 1.0000 3 1 TRUE ! Main Column + 2 3 4 2 2 1 0 1.0000 3 1 TRUE ! Upper Column 1 + 3 5 6 2 2 1 0 1.0000 3 1 TRUE ! Upper Column 2 + 4 7 8 2 2 1 0 1.0000 3 1 TRUE ! Upper Column 3 + 5 42 3 3 3 1 0 1.0000 3 1 TRUE ! Base Column 1 + 6 43 5 3 3 1 0 1.0000 3 1 TRUE ! Base Column 2 + 7 44 7 3 3 1 0 1.0000 3 1 TRUE ! Base Column 3 + 23 9 42 3 3 1 0 1.0000 3 1 TRUE ! Base column cap 1 + 24 10 43 3 3 1 0 1.0000 3 1 TRUE ! Base column cap 2 + 25 11 44 3 3 1 0 1.0000 3 1 TRUE ! Base column cap 3 + 8 12 13 4 4 1 0 1.0000 3 1 TRUE ! Delta Pontoon, Upper 1 + 9 14 15 4 4 1 0 1.0000 3 1 TRUE ! Delta Pontoon, Upper 2 + 10 16 17 4 4 1 0 1.0000 3 1 TRUE ! Delta Pontoon, Upper 3 + 11 18 19 4 4 1 0 1.0000 3 1 TRUE ! Delta Pontoon, Lower 1 + 12 20 21 4 4 1 0 1.0000 3 1 TRUE ! Delta Pontoon, Lower 2 + 13 22 23 4 4 1 0 1.0000 3 1 TRUE ! Delta Pontoon, Lower 3 + 14 24 25 4 4 1 0 1.0000 3 1 TRUE ! Y Pontoon, Upper 1 + 15 26 27 4 4 1 0 1.0000 3 1 TRUE ! Y Pontoon, Upper 2 + 16 28 29 4 4 1 0 1.0000 3 1 TRUE ! Y Pontoon, Upper 3 + 17 30 31 4 4 1 0 1.0000 3 1 TRUE ! Y Pontoon, Lower 1 + 18 32 33 4 4 1 0 1.0000 3 1 TRUE ! Y Pontoon, Lower 2 + 19 34 35 4 4 1 0 1.0000 3 1 TRUE ! Y Pontoon, Lower 3 + 20 36 37 4 4 1 0 1.0000 3 1 TRUE ! Cross Brace 1 + 21 38 39 4 4 1 0 1.0000 3 1 TRUE ! Cross Brace 2 + 22 40 41 4 4 1 0 1.0000 3 1 TRUE ! Cross Brace 3 ---------------------- FILLED MEMBERS ------------------------------------------ 2 NFillGroups - Number of filled member groups (-) [If FillDens = DEFAULT, then FillDens = WtrDens; FillFSLoc is related to MSL2SWL] FillNumM FillMList FillFSLoc FillDens diff --git a/docs/source/user/hydrodyn/input_files.rst b/docs/source/user/hydrodyn/input_files.rst index 49c0593d60..b93aaa8035 100644 --- a/docs/source/user/hydrodyn/input_files.rst +++ b/docs/source/user/hydrodyn/input_files.rst @@ -618,103 +618,52 @@ water depth results in static pressure loads being applied. Member Cross-Sections --------------------- -Members in HydroDyn are assumed to be straight circular (and possibly -tapered) cylinders. Apart from the hydrodynamic coefficients, the -circular cross-section properties needed for the hydrodynamic load -calculations are member outer diameter, **PropD**, and member thickness, -**PropThck**. You will need to create an entry in this table, -distinguished by **PropSetID**, for each unique combination of these two -properties. The member property-set table contains **NPropSets** rows. -The member property sets are referred to by their **PropSetID** in the -MEMBERS table, as described in :numref:`hd-members` below. **PropD** -determines the static buoyancy loads exterior to a member, as well as -the area used in the viscous-drag calculation and the volume used in the -added-mass and fluid-inertia calculations. **PropThck** determines the -interior volume for fluid-filled (flooded/ballasted) members. +Members in HydroDyn are assumed to be straight with either a circular cross section or a rectangular cross section. In either case, tapering is allowed, including independent tapering of the two sides of a member with rectangular cross sections. However, twisting of rectangular members is not allowed, and the four side walls of the member must remain planar. + +The HydroDyn primary input file contains two separate sections for member cross-section properties. The first section is for circular sections, and the second one is for rectangular sections. + +In the first section labeled CYLINDRICAL MEMBER CROSS-SECTION PROPERTIES, **NPropSetsCyl** different section defintions can be entered, with each section definition on a separate line identified by its **PropSetID**. The **PropSetID** is used in the MEMBERS table, as described in :numref:`hd-members` below. For each section definition, the user needs to provide the member outer diameter, **PropD**, and member wall thickness, **PropThck**. **PropD** determines the static buoyancy loads exterior to a member, as well as the area used in the viscous-drag calculation and the volume used in the added-mass and fluid-inertia load calculations. **PropThck** determines the interior volume for fluid-filled (flooded/ballasted) members. + +In the second section labeled RECTANGULAR MEMBER CROSS-SECTION PROPERTIES, **NPropSetsRec** different section definitions can be entered, with each section definition on a separate line identified by its **PropSetID**. The **PropSetID** is referenced in the MEMBERS table, as described in :numref:`hd-members` below. For each section definition, the user needs to provide the member outer side lengths of the rectangular section. **PropA** is the outer length of Side A, and **PropB** is the outer length of Side B (see :numref:`hd-members` on how the two sides are identified). **PropThck** is again the section wall thickness. Currently, we assume the four side walls of each rectangular section have the same uniform wall thickness, so only one **PropThck** can be specified for each rectangular section. + +Note that the **PropSetID** for circular and rectangular sections are independent. For instance, it is allowed to have a circular section and a rectangular section both having the same **PropSetID**. Depending on the section shape specified for each member, HydroDyn will look up the correct section properties. Hydrodynamic Coefficients ------------------------- -HydroDyn computes distributed viscous-drag, added-mass, fluid-inertia, -and static buoyancy loads along members. - -The hydrodynamic coefficients for the distributed strip-theory loads are -specified using any of three models, which we refer to as the simple -model, a depth-based model, and a member-based model. All of these -models require the specification of both transverse and axial -hydrodynamic coefficients for viscous drag, added mass, and dynamic -pressure. The added-mass -coefficient influences both the added-mass loads and the scattering -component of the fluid-inertia loads. There are separate set of -hydrodynamic coefficients both with and without marine growth. A given -element will either use the marine growth or the standard version of a -coefficient, but never both. Note that input members are split into -elements, one of the splitting rules guarantees the -previous statement is true. Which members have marine growth is defined -by the MARINE GROWTH table of :numref:`hd-marine-growth`. You can specify only one -model type, **MCoefMod**, for any given member in the MEMBERS table. -However, different members can specify different coefficient models. +HydroDyn computes distributed viscous-drag, added-mass, fluid-inertia, and static buoyancy loads along members. + +The hydrodynamic coefficients for the distributed strip-theory loads are specified using any of the three available models, which we refer to as the simple model (model 1), a depth-based model (model 2), and a member-based model (model 3). All of these models require the specification of both transverse and axial hydrodynamic coefficients for viscous drag, added mass, and dynamic pressure. The added-mass coefficient influences both the added-mass loads and the scattering component of the fluid-inertia loads. There are two separate sets of hydrodynamic coefficients with one set for the part of a member with marine growth and the other for the part without. Which members have marine growth is defined by the MARINE GROWTH table of :numref:`hd-marine-growth`. You can specify only one model type (**MCoefMod** = 1, 2, or 3) for any given member in the MEMBERS table. However, different members can use different coefficient models. .. elements per Section 7.5.2, one of the splitting rules guarantees the .. TODO 7.5.2 is the theory section which does not yet exist. -In the hydrodynamic coefficient input parameters, **Cd**, **Ca**, and -**Cp** refer to the viscous-drag, added-mass, and dynamic-pressure -coefficients, respectively. **MG** identifies the coefficients to be -applied for members with marine growth (the standard values are -identified without **MG**), and **Ax** identifies the axial coefficients -to be applied for tapered members (the transverse coefficients are -identified without **Ax**). The **Cb** coefficients allow the user to -scale the hydrostatic load for, e.g., non-circular member cross sections. -To avoid unphysical hydrostatic loads, the **Cb** coefficients are not -used to directly scale the distributed hydrostatic load. Instead, the -local member diameter (with marine growth if specified) is scaled by -the square root of **Cb** when computing the hydrostatic load. This -scaling also affects the hydrostatic load on member endplates for -consistency. - -While the strip-theory solution assumes circular cross sections, the -hydrodynamic coefficients can include shape corrections; however, there -is no distinction made in HydroDyn between different transverse -directions. - -Simple Model -++++++++++++ -This table consists of a single complete set of hydrodynamic -coefficients as follows: **SimplCd**, **SimplCdMG**, **SimplCa**, -**SimplCaMG**, **SimplCp**, **SimplCpMG**, **SimplAxCa**, -**SimplAxCaMG**, **SimplAxCp**, and **SimplAxCpMG**. These hydrodynamic -coefficients are referenced in the members table of :numref:`hd-members` by -selecting **MCoefMod** = 1. - -Depth-Based Model -+++++++++++++++++ -The depth-based coefficient model allows you to specify a series of -depth-dependent coefficients. **NCoefDpth** is the user-specified number -of depths and determines the number of rows in the subsequent table. -Currently, this table requires that the rows are ordered by increasing -depth, **Dpth**; this is equivalent to a decreasing global -*Z*-coordinate. The hydrodynamic coefficients at each depth are as -follows: **DpthCd**, **DpthCdMG**, **DpthCa**, **DpthCaMG**, **DpthCp**, -**DpthCpMG**, **DpthAxCa**, **DpthAxCaMG**, **DpthAxCp**, and -**DpthAxCpMG**. Members use these hydrodynamic coefficients by setting -**MCoefMod** = 2. The HydroDyn module will interpolate coefficients for -a node whose *Z*-coordinate lies between table *Z*-coordinates. - -Member-Based Model -++++++++++++++++++ -The member-based coefficient model allows you to specify a hydrodynamic -coefficients for each particular member. **NCoefMembers** is the -user-specified number of members with member-based coefficients and -determines the number of rows in the subsequent table. The hydrodynamic -coefficients for a member distinguished by **MemberID** are as follows: -**MemberCd1**, **MemberCd2**, **MemberCdMG1**, **MemberCdMG2**, -**MemberCa1**, **MemberCa2**, **MemberCaMG1**, **MemberCaMG2**, -**MemberCp1**, **MemberCp2**, **MemberCpMG1**, **MemberCpMG2**, -**MemberAxCa1**, **MemberAxCa2**, **MemberAxCaMG1**, **MemberAxCaMG2**, -**MemberAxCp1**, **MemberAxCp2**, **MemberAxCpMG1**, and -**MemberAxCpMG2**, where *1* and *2* identify the starting and ending -joint of the member, respectively. Members use these hydrodynamic -coefficients by setting **MCoefMod** = 3. +In the hydrodynamic coefficient tables, **Cd**, **Ca**, and **Cp** refer to the viscous-drag, added-mass, and dynamic-pressure coefficients, respectively. For circular sections, these coefficients apply to loads in any radial direction due to axisymmetry. For rectangular sections, two sets of transverse **Cd** and **Ca** coefficients must be provided, with one set having the letter "A" appended for load components normal to Side A of the section (e.g., **CdA**) and the other with the letter "B" appended for load components normal to Side B of the section (e.g., **CaB**). Note that only the transverse **Cd** and **Ca** (with and without marine growth) make a distinction between the two transverse directions of rectangular sections. None of the other coefficients make this distinction. **MG** identifies the coefficients to be applied on member sections with marine growth (the standard values are identified without **MG**), and **Ax** identifies the axial coefficients to be applied for tapered members (the transverse coefficients are identified without **Ax**). The **Cb** coefficients allow the user to scale the hydrostatic load for, e.g., non-circular and non-rectangular member cross sections. To avoid unphysical hydrostatic loads, the **Cb** coefficients are not used to directly scale the distributed hydrostatic load. Instead, the local member diameter or side lengths (with marine growth if specified) are scaled by the square root of **Cb** when computing the hydrostatic loads. This scaling also affects the hydrostatic loads on member endplates for consistency. While the strip-theory solution assumes either a circular or a rectangular cross section, the hydrodynamic coefficients can include shape corrections. + +For each of the three available coefficient models, there are two separate input sections with the first one for circular sections and the second for rectangular sections. These are explained below. + +Simple Model for Circular Sections +++++++++++++++++++++++++++++++++++ +This table consists of a single complete set of hydrodynamic coefficients for circular sections as follows: **SimplCd**, **SimplCdMG**, **SimplCa**, **SimplCaMG**, **SimplCp**, **SimplCpMG**, **SimplAxCd**, **SimplAxCdMG**, **SimplAxCa**, **SimplAxCaMG**, **SimplAxCp**, **SimplAxCpMG**, **SimplCb**, and **SimplCbMG**. These hydrodynamic coefficients are referenced in the MEMBERS table of :numref:`hd-members` by selecting **MCoefMod** = 1. + +Simple Model for Rectangular Sections ++++++++++++++++++++++++++++++++++++++ +This table consists of a single complete set of hydrodynamic coefficients for rectangular sections as follows: **SimplCdA**, **SimplCdAMG**, **SimplCdB**, **SimplCdBMG**, **SimplCaA**, **SimplCaAMG**, **SimplCaB**, **SimplCaBMG**, **SimplCp**, **SimplCpMG**, **SimplAxCd**, **SimplAxCdMG**, **SimplAxCa**, **SimplAxCaMG**, **SimplAxCp**, **SimplAxCpMG**, **SimplCb**, and **SimplCbMG**. These hydrodynamic coefficients are referenced in the MEMBERS table of :numref:`hd-members` by selecting **MCoefMod** = 1. + +Depth-Based Model for Circular Sections ++++++++++++++++++++++++++++++++++++++++ +The depth-based coefficient model allows you to specify a series of depth-dependent coefficients for circular sections. **NCoefDpthCyl** is the user-specified number of depths and determines the number of rows in the subsequent table. Currently, this table requires that the rows are ordered by increasing depth, **Dpth**; this is equivalent to a decreasing global *Z*-coordinate. The hydrodynamic coefficients at each depth are as follows: **DpthCd**, **DpthCdMG**, **DpthCa**, **DpthCaMG**, **DpthCp**, **DpthCpMG**, **DpthAxCd**, **DpthAxCdMG**, **DpthAxCa**, **DpthAxCaMG**, **DpthAxCp**, **DpthAxCpMG**, **DpthCb**, and **DpthCbMG**. Members use these hydrodynamic coefficients by setting **MCoefMod** = 2. The HydroDyn module will linearly interpolate coefficients for a node whose *Z*-coordinate lies between table *Z*-coordinates. + +Depth-Based Model for Rectangular Sections +++++++++++++++++++++++++++++++++++++++++++ +The depth-based coefficient model allows you to specify a series of depth-dependent coefficients for rectangular sections. **NCoefDpthRec** is the user-specified number of depths and determines the number of rows in the subsequent table. Currently, this table requires that the rows are ordered by increasing depth, **Dpth**; this is equivalent to a decreasing global *Z*-coordinate. The hydrodynamic coefficients at each depth are as follows: **DpthCdA**, **DpthCdAMG**, **DpthCdB**, **DpthCdBMG**, **DpthCaA**, **DpthCaAMG**, **DpthCaB**, **DpthCaBMG**, **DpthCp**, **DpthCpMG**, **DpthAxCd**, **DpthAxCdMG**, **DpthAxCa**, **DpthAxCaMG**, **DpthAxCp**, **DpthAxCpMG**, **DpthCb**, and **DpthCbMG**. Members use these hydrodynamic coefficients by setting **MCoefMod** = 2. The HydroDyn module will linearly interpolate coefficients for a node whose *Z*-coordinate lies between table *Z*-coordinates. + +Member-Based Model for Circular Sections +++++++++++++++++++++++++++++++++++++++++ +The member-based coefficient model allows you to specify a set of hydrodynamic coefficients for each member. **NCoefMembersCyl** is the user-specified number of members with member-based coefficients and determines the number of rows in the subsequent table. The hydrodynamic coefficients for a member distinguished by **MemberID** are as follows: **MemberCd1**, **MemberCd2**, **MemberCdMG1**, **MemberCdMG2**, **MemberCa1**, **MemberCa2**, **MemberCaMG1**, **MemberCaMG2**, **MemberCp1**, **MemberCp2**, **MemberCpMG1**, **MemberCpMG2**, **MemberAxCd1**, **MemberAxCd2**, **MemberAxCdMG1**, **MemberAxCdMG2**, **MemberAxCa1**, **MemberAxCa2**, **MemberAxCaMG1**, **MemberAxCaMG2**, **MemberAxCp1**, **MemberAxCp2**, **MemberAxCpMG1**, **MemberAxCpMG2**, **MemberCb1**, **MemberCb2**, **MemberCbMG1**, and **MemberCbMG2**, where *1* and *2* identify the starting and ending joint of the member, respectively. Members use these hydrodynamic coefficients by setting **MCoefMod** = 3. + +Member-Based Model for Rectangular Sections ++++++++++++++++++++++++++++++++++++++++++++ +The member-based coefficient model allows you to specify a set of hydrodynamic coefficients for each member. **NCoefMembersRec** is the user-specified number of members with member-based coefficients and determines the number of rows in the subsequent table. The hydrodynamic coefficients for a member distinguished by **MemberID** are as follows: **MemberCdA1**, **MemberCdA2**, **MemberCdAMG1**, **MemberCdAMG2**, **MemberCdB1**, **MemberCdB2**, **MemberCdBMG1**, **MemberCdBMG2**, **MemberCaA1**, **MemberCaA2**, **MemberCaAMG1**, **MemberCaAMG2**, **MemberCaB1**, **MemberCaB2**, **MemberCaBMG1**, **MemberCaBMG2**, **MemberCp1**, **MemberCp2**, **MemberCpMG1**, **MemberCpMG2**, **MemberAxCd1**, **MemberAxCd2**, **MemberAxCdMG1**, **MemberAxCdMG2**, **MemberAxCa1**, **MemberAxCa2**, **MemberAxCaMG1**, **MemberAxCaMG2**, **MemberAxCp1**, **MemberAxCp2**, **MemberAxCpMG1**, **MemberAxCpMG2**, **MemberCb1**, **MemberCb2**, **MemberCbMG1**, and **MemberCbMG2**, where *1* and *2* identify the starting and ending joint of the member, respectively. Members use these hydrodynamic coefficients by setting **MCoefMod** = 3. MacCamy-Fuchs diffraction load model ++++++++++++++++++++++++++++++++++++ @@ -741,6 +690,8 @@ diameter. To ensure it is approximately applicable while still allowing for some flexibility, some constraints are placed on members when applying the MacCamy-Fuchs model: +* The member must have a circular cross section. + * The member must be surface-piercing at least when the structure is undisplaced in calm water. * The member must be nearly vertical with an inclination from vertical less than 10 deg. @@ -760,61 +711,22 @@ the available wave-stretching models. Members ------- -**NMembers** is the user-specified number of members and determines the -number of rows in the subsequent table. For each member distinguished by -**MemberID**, **MJointID1** specifies the starting joint and -**MJointID2** specifies the ending joint, corresponding to an identifier -(**JointID**) from the MEMBER JOINTS table. Likewise, **MPropSetID1** -corresponds to the starting cross-section properties and **MProSetID2** -specify the ending cross-section properties, allowing for tapered -members. **MDivSize** determines the maximum spacing (in meters) between -simulation nodes where the distributed loads are actually computed; the -smaller the number, the finer the resolution and longer the -computational time. Each member in your model will have hydrodynamic -coefficients, which are specified using one of the three models (**MCoefMod**). -Model 1 uses a single set of coefficients found in the SIMPLE HYDRODYNAMIC -COEFFICIENTS section. Model 2 is depth-based, and is determined via the table found -in the DEPTH-BASED HYDRODYNAMIC COEFFICIENTS section. Model 3 specifies -coefficients for a particular member, by referring to the MEMBER-BASED -HYDRODYNAMIC COEFFICIENTS section. The **MHstLMod** switch controls the -computation of hydrostatic loads on strip-theory members when **PropPot** -= FALSE. Setting **MHstLMod** to 0 disables hydrostatic load. If set to 1, -hydrostatic loads will be computed analytically. This approach is efficient, -but it only works for fully submerged or surface-piercing members -that are far from horizontal without partially wetted endplates. -For nearly horizontal members close to the free surface or members that experience -partially wetted endplates, a semi-numerical approach for hydrostatic load -can be selected by setting **MHstLMod** to 2. This approach works with any -member positioning in relation to the free surface at the cost of slightly -longer computing time. The **PropPot** flag indicates whether the corresponding -member coincides with the body represented by the potential-flow solution. -When **PropPot** = TRUE, only viscous-drag loads and ballasting loads will -be computed for that member. +**NMembers** is the user-specified number of members and determines the number of rows in the subsequent table. For each member distinguished by **MemberID**, **MJointID1** specifies the starting joint, and **MJointID2** specifies the ending joint, corresponding to an identifier (**JointID**) from the MEMBER JOINTS table. Likewise, **MPropSetID1** corresponds to the starting cross-section properties, and **MProSetID2** specify the ending cross-section properties, allowing for tapered members. **MSecGeom** indicates the cross-section shape of the member. It can be set to either 1 for circular cross section or 2 for rectangular cross section. Depending on **MSecGeom**, **MPropSetID1** and **MPropSetID2** either refer to entries in the CYLINDRICAL MEMBER CROSS-SECTION PROPERTIES table or the RECTANGULAR MEMBER CROSS-SECTION PROPERTIES table. **MSpinOrient** is an angle in degrees that specifies the spin orientation of each member, i.e., the rotation about the member axis. When **MSpinOrient** = 0, Side A of a rectangular section referenced in previous sections is parallel to the horizontal plane. If the member is perfectly vertical, Side A is parallel to the global *X*-axis when **MSpinOrient** = 0. Setting **MSpinOrient** to a nonzero value will rotate the member about its axis (pointing from the starting joint to the ending joint) following the right-hand convention by the prescribed angle. **MSpinOrient** should be specified for both members with rectangular cross sections and members with circular cross sections; however, it has no effect on the latter. **MDivSize** determines the maximum spacing (in meters) between simulation nodes where the distributed loads are actually computed; the smaller the number, the finer the resolution and longer the computational time. + +Each member in your model will have hydrodynamic coefficients, which are specified using one of the three models (**MCoefMod**). Model 1 uses a single set of coefficients found in the SIMPLE HYDRODYNAMIC COEFFICIENTS sections. Model 2 is depth-based, and is determined via the table found in the DEPTH-BASED HYDRODYNAMIC COEFFICIENTS sections. Model 3 specifies coefficients for a particular member, by referring to the MEMBER-BASED HYDRODYNAMIC COEFFICIENTS sections. Depending on **MSecGeom**, HydroDyn will either use the hydrodynamic coefficients from the input tables for circular sections or rectangular sections as appropriate. The **MHstLMod** switch controls the computation of hydrostatic loads on strip-theory members when **PropPot** = FALSE. Setting **MHstLMod** to 0 disables hydrostatic load. If set to 1, hydrostatic loads will be computed analytically. This approach is efficient, but it only works for fully submerged or surface-piercing members that are far from horizontal without partially wetted endplates. For nearly horizontal members close to the free surface or members that experience partially wetted endplates, a semi-numerical approach for hydrostatic load can be selected by setting **MHstLMod** to 2. This approach works with any member positioning in relation to the free surface at the cost of slightly longer computing time. Note that for members with rectangular cross sections, **MHstLMod** must be either 0 or 2. The analytical approach with **MHstLMod** set to 1 is not available for rectangular members. The **PropPot** flag indicates whether the corresponding member is included in the potential-flow solution. When **PropPot** = TRUE, only viscous-drag loads and ballasting loads will be computed for that member, with the assumption that all other load components are already included in the potential-flow solution. .. TODO 7.5.2 is the theory section which does not yet exist. .. Section 7.5.2 discusses the difference between the user-supplied discretization and the simulation discretization. Filled Members -------------- -Members—whether they are also modeled with potential-flow or not—may be -fluid-filled, meaning that they are flooded and/or ballasted. -Fluid-filled members introduce interior buoyancy that subtracts from the -exterior buoyancy and a mass. Both distributed loads along a member and -lumped loads at joints are applied. The volume of fluid in the member is -derived from the outer diameter and thickness of the member and a -fluid-filled free-surface level. The fluid in the member is assumed to -be compartmentalized such that it does not slosh. Rotational inertia of -the fluid in the member is ignored. A member’s filled configuration is -defined by the filled-fluid density and the free-surface level. Filled -members that have the same configuration are collected into fill groups. - -**NFillGroups** specifies the number of fluid-filled member groups and -determines the number of rows in the subsequent table. **FillNumM** -specifies the number of members in the fill group. **FillMList** is a -list of **FillNumM** whitespace-separated **MemberID**\ s. **FillFSLoc** -specifies the *Z*-height of the free-surface (0 for MSL). **FillDens** -is the density of the fluid. If **FillDens** = DEFAULT, then -**FillDens** = **WtrDens**. +Members—whether they are also modeled with potential-flow or not—may be fluid-filled, meaning that they are flooded and/or ballasted. The internal fluid introduces hydrostatic pressure on the inner wall(s) of a flooded/ballasted member. It also adds mass and moment of inertia to the member. Both distributed loads along a member and lumped loads at joints/endplates are applied. + +The volume of fluid in a flooded member is derived from the outer diameter/side lengths and the wall thickness of the member and a fluid-filled level. The member is either partially flooded from the lower end joint to the fluid-filled level, if the fluid-filled level is in the middle of the member, or fully flooded, if the fluid-filled level is above the top end joint of the member. In either case, a watertight bulkhead normal to the member centerline is assumed to bound the filled section of a member on either end, so there is no internal free surface nor sloshing. Furthermore, the fluid in the member is assumed to be compartmentalized such that it moves with the member in a rigid-body fashion for the purpose of computing inertial loads on the member. However, when computing the internal hydrostatic pressure, we do not assume the compartmentalization to be watertight. Therefore, the entire filled volume of a member share a single contiguous hydrostatic pressure field. As an example, a consequence of this modeling assumption is that the weight of all ballast water inside a perfectly vertical untapered spar will rest solely on the bottom endplate of the spar instead of being distributed along the spar. + +Furthermore, we introduce the concept of filled member groups with each group potentially containing multiple members. The internal flooded volumes of all members belonging to the same filled member group are treated as interconnected and, therefore, share the same contiguous hydrostatic pressure field. Each filled member groups is classed as either open or closed. If at least one member in a given filled member group is partially buried in the seabed, such as a monopile, we treat this group as open to the external body of sea water through the bottom opening of the partially buried member and the porous seabed. In this case, the hydrostatic pressure of the internal fluid is in equilibrium with the external body of water with zero hydrostatic pressure at the external still water level. Furthermore, the filled level of an open filled member group cannot be higher than the external still water level, and the density of the internal fluid must exactly match the external water density. Note that any member partially buried in the seabed is considered to have an open bottom, so that there is neither external nor internal hydrostatic pressure on the bottom end of the member. If none of the members of a filled member group crosses the seabed, the filled member group is considered to be closed off from the external body of water, such as the ballast chamber of a floating platform. In this case, the internal hydrostatic pressure is zero at the instantaneous highest point of the internal fluid-filled volumes of all members belonging to this group at each time step. + +In this input section, **NFillGroups** specifies the number of fluid-filled member groups and determines the number of rows in the subsequent table. **FillNumM** specifies the number of members in the filled group. **FillMList** is a list of **FillNumM** whitespace-separated **MemberID**\ s. **FillFSLoc** specifies the *Z*-height of the filled level (0 for MSL). **FillDens** is the density of the fluid. If **FillDens** = DEFAULT, then **FillDens** = **WtrDens**. This option is convenient for open filled member groups, which requires the internal fluid density to match the external water density exactly. .. _hd-marine-growth: diff --git a/docs/source/user/servodyn/SrvD--Ex.sum b/docs/source/user/servodyn/SrvD--Ex.sum index 1ff9fb6191..83efae8dbc 100644 --- a/docs/source/user/servodyn/SrvD--Ex.sum +++ b/docs/source/user/servodyn/SrvD--Ex.sum @@ -56,7 +56,7 @@ 60 --> Rotor azimuth angle (rad) [SrvD input] 61 --> Number of blades (-) [SrvD NumBl parameter] 62 --> Maximum number of values which can be returned for logging (-) [set to 300] - 63 <-- Number logging channels + 63 --> Record number for start of logging output (-) [set to ###] 64 --> Maximum number of characters which can be returned in "OUTNAME" (-) [set to 12601 (including the C NULL CHARACTER)] 65 <-- Number of variables returned for logging [anything greater than MaxLoggingChannels is an error] 69 --> Blade 1 root in-plane bending moment (Nm) [SrvD input] diff --git a/docs/source/user/subdyn/appendixD.rst b/docs/source/user/subdyn/appendixD.rst index 3cf6bcef2c..2da791afe9 100644 --- a/docs/source/user/subdyn/appendixD.rst +++ b/docs/source/user/subdyn/appendixD.rst @@ -51,54 +51,54 @@ Table C-1. List of Output Channels. +---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ | *Node Kinematics* | | +---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| :math:`{M \alpha N \beta}` TDxss, | (m) | Nodal translational displacements of :math:`M \alpha N \beta` | -| | | | -| :math:`M \alpha N \beta` TDyss, | | | -| | | (up to 81 designated locations) in SS coordinate system | -| :math:`M \alpha N \beta` TDzss, | | | -+---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| :math:`{M \alpha N \beta}` RDxe, | (rad) | Nodal rotational displacements of :math:`M \alpha N \beta` | -| | | | -| :math:`{M \alpha N \beta}` RDye, | | | +| :math:`{M \alpha N \beta}` TDxss, | (m) | Nodal total translational displacements of :math:`M \alpha N \beta` | +| | | | +| :math:`M \alpha N \beta` TDyss, | | | +| | | (up to 81 designated locations) in SS coordinate system | +| :math:`M \alpha N \beta` TDzss, | | | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| :math:`{M \alpha N \beta}` RDxe, | (rad) | Nodal rotational elastic deflection of :math:`M \alpha N \beta` relative to the rigid-body configuration | +| | | | +| :math:`{M \alpha N \beta}` RDye, | | | | | | (up to 81 designated locations) in member local coordinate system | -| :math:`{M \alpha N \beta}` RDze | | | +| :math:`{M \alpha N \beta}` RDze | | | +---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| :math:`{M \alpha N \beta}` TAxe, | (:math:`{m/s^2}`) | Nodal translational accelerations of :math:`M \alpha N \beta` | -| | | | -| :math:`{M \alpha N \beta}` TAye, | | | -| | | (up to 81 designated locations) in member local coordinate system | -| :math:`{M \alpha N \beta}` TAze | | | +| :math:`{M \alpha N \beta}` TAxe, | (:math:`{m/s^2}`) | Nodal translational accelerations of :math:`M \alpha N \beta` | +| | | | +| :math:`{M \alpha N \beta}` TAye, | | | +| | | (up to 81 designated locations) in member local coordinate system | +| :math:`{M \alpha N \beta}` TAze | | | +---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| :math:`{M \alpha N \beta}` RAxe, | (:math:`{rad/s^2}`) | Nodal rotational accelerations of :math:`M \alpha N \beta` | -| | | | -| :math:`{M \alpha N \beta}` RAye, | | | -| | | (up to 81 designated locations) in member local coordinate system | -| :math:`{M \alpha N \beta}` RAze | | | +| :math:`{M \alpha N \beta}` RAxe, | (:math:`{rad/s^2}`) | Nodal rotational accelerations of :math:`M \alpha N \beta` | +| | | | +| :math:`{M \alpha N \beta}` RAye, | | | +| | | (up to 81 designated locations) in member local coordinate system | +| :math:`{M \alpha N \beta}` RAze | | | +---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ | *Node Forces and Moments* | | +---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| :math:`{M \alpha N \beta}` FKxe, | (N), | Static (elastic) component of reaction forces and moments | -| | | | -| :math:`{M \alpha N \beta}` FKye, | (N), | at :math:`M \alpha N \beta` along local member coordinate system | -| | | | -| :math:`{M \alpha N \beta}` FKze | (N), | | -| | | | -| :math:`{M \alpha N \beta}` MKxe, | (Nm), | | -| | | | -| :math:`{M \alpha N \beta}` MKye, | (Nm), | | -| | | | -| :math:`{M \alpha N \beta}` MKze | (Nm) | | -+---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| :math:`{M \alpha N \beta}` FMxe, | (N), | Dynamic (inertial) component of reaction forces and moments | -| | | | -| :math:`{M \alpha N \beta}` FMye, | (N), | at :math:`M \alpha N \beta` along local member coordinate system | -| | | | -| :math:`{M \alpha N \beta}` FMze | (N), | | -| | | | -| :math:`{M \alpha N \beta}` MMxe, | (Nm), | | -| | | | -| :math:`{M \alpha N \beta}` MMye, | (Nm), | | -| | | | -| :math:`{M \alpha N \beta}` MMze | (Nm) | | +| :math:`{M \alpha N \beta}` FKxe, | (N), | Static (elastic) component of reaction forces and moments | +| | | | +| :math:`{M \alpha N \beta}` FKye, | (N), | at :math:`M \alpha N \beta` along local member coordinate system | +| | | | +| :math:`{M \alpha N \beta}` FKze | (N), | | +| | | | +| :math:`{M \alpha N \beta}` MKxe, | (Nm), | | +| | | | +| :math:`{M \alpha N \beta}` MKye, | (Nm), | | +| | | | +| :math:`{M \alpha N \beta}` MKze | (Nm) | | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| :math:`{M \alpha N \beta}` FMxe, | (N), | Dynamic (inertial) component of reaction forces and moments | +| | | | +| :math:`{M \alpha N \beta}` FMye, | (N), | at :math:`M \alpha N \beta` along local member coordinate system | +| | | | +| :math:`{M \alpha N \beta}` FMze | (N), | | +| | | | +| :math:`{M \alpha N \beta}` MMxe, | (Nm), | | +| | | | +| :math:`{M \alpha N \beta}` MMye, | (Nm), | | +| | | | +| :math:`{M \alpha N \beta}` MMze | (Nm) | | +---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat index 2c7cf3dcfe..174470d517 100644 --- a/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat +++ b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat @@ -5,12 +5,10 @@ False Echo - Echo input data to ".SD.ech" (flag) "DEFAULT" SDdeltaT - Local Integration Step. If "default", the glue-code integration step will be used. 3 IntMethod - Integration Method [1/2/3/4 = RK4/AB4/ABM4/AM2]. True SttcSolve - Solve dynamics about static equilibrium point -True GuyanLoadCorrection - Include extra moment from lever arm at interface and rotate FEM for floating. -------------------- FEA and CRAIG-BAMPTON PARAMETERS --------------------------------- 3 FEMMod - FEM switch: element model in the FEM. [1= Euler-Bernoulli(E-B); 2=Tapered E-B (unavailable); 3= 2-node Timoshenko; 4= 2-node tapered Timoshenko (unavailable)] 2 NDiv - Number of sub-elements per member -True CBMod - [T/F] If True perform C-B reduction, else full FEM dofs will be retained. If True, select Nmodes to retain in C-B reduced system. - 8 Nmodes - Number of internal modes to retain (ignored if CBMod=False). If Nmodes=0 --> Guyan Reduction. + 8 Nmodes - Number of internal modes to retain. If Nmodes=0 --> Guyan Reduction. If Nmodes<0 --> retain all modes. 1 JDampings - Damping Ratios for each retained mode (% of critical) If Nmodes>0, list Nmodes structural damping ratios for each retained mode (% of critical), or a single damping ratio to be applied to all retained modes. (last entered value will be used for all remaining modes). 0 GuyanDampMod - Guyan damping {0=none, 1=Rayleigh Damping, 2=user specified 6x6 matrix} 0.000, 0.000 RayleighDamp - Mass and stiffness proportional damping coefficients (Rayleigh Damping) [only if GuyanDampMod=1] @@ -111,120 +109,120 @@ IJointID ItfTDXss ItfTDYss ItfTDZss ItfRDXss ItfRDYss ItfRDZss 56 1 1 1 1 1 1 ----------------------------------- MEMBERS ------------------------------------------- 112 NMembers - Number of members (-) -MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType COSMID ![MType={1:beam circ., 2:cable, 3:rigid, 4:beam arb., 5:spring}. COMSID={-1:none}] - (-) (-) (-) (-) (-) (-) (-) - 1 1 2 2 2 1 -1 - 2 2 3 2 2 1 -1 - 3 3 4 2 2 1 -1 - 4 4 5 2 2 1 -1 - 5 6 7 2 2 1 -1 - 6 7 8 2 2 1 -1 - 7 8 9 2 2 1 -1 - 8 9 10 2 2 1 -1 - 9 11 12 2 2 1 -1 - 10 12 13 2 2 1 -1 - 11 13 14 2 2 1 -1 - 12 14 15 2 2 1 -1 - 13 16 17 2 2 1 -1 - 14 17 18 2 2 1 -1 - 15 18 19 2 2 1 -1 - 16 19 20 2 2 1 -1 - 17 5 21 3 3 1 -1 - 18 21 22 3 3 1 -1 - 19 22 23 3 3 1 -1 - 20 23 24 3 3 1 -1 - 21 10 25 3 3 1 -1 - 22 25 26 3 3 1 -1 - 23 26 27 3 3 1 -1 - 24 27 28 3 3 1 -1 - 25 15 29 3 3 1 -1 - 26 29 30 3 3 1 -1 - 27 30 31 3 3 1 -1 - 28 31 32 3 3 1 -1 - 29 20 33 3 3 1 -1 - 30 33 34 3 3 1 -1 - 31 34 35 3 3 1 -1 - 32 35 36 3 3 1 -1 - 33 8 3 1 1 1 -1 - 34 13 8 1 1 1 -1 - 35 13 18 1 1 1 -1 - 36 18 3 1 1 1 -1 - 37 4 37 1 1 1 -1 - 38 37 20 1 1 1 -1 - 39 19 37 1 1 1 -1 - 40 37 5 1 1 1 -1 - 41 9 38 1 1 1 -1 - 42 38 15 1 1 1 -1 - 43 14 38 1 1 1 -1 - 44 38 10 1 1 1 -1 - 45 4 39 1 1 1 -1 - 46 39 10 1 1 1 -1 - 47 9 39 1 1 1 -1 - 48 39 5 1 1 1 -1 - 49 19 40 1 1 1 -1 - 50 40 15 1 1 1 -1 - 51 14 40 1 1 1 -1 - 52 40 20 1 1 1 -1 - 53 5 41 1 1 1 -1 - 54 41 33 1 1 1 -1 - 55 20 41 1 1 1 -1 - 56 41 21 1 1 1 -1 - 57 10 42 1 1 1 -1 - 58 42 29 1 1 1 -1 - 59 15 42 1 1 1 -1 - 60 42 25 1 1 1 -1 - 61 5 43 1 1 1 -1 - 62 43 25 1 1 1 -1 - 63 10 43 1 1 1 -1 - 64 43 21 1 1 1 -1 - 65 20 44 1 1 1 -1 - 66 44 29 1 1 1 -1 - 67 15 44 1 1 1 -1 - 68 44 33 1 1 1 -1 - 69 21 45 1 1 1 -1 - 70 45 34 1 1 1 -1 - 71 33 45 1 1 1 -1 - 72 45 22 1 1 1 -1 - 73 25 46 1 1 1 -1 - 74 46 30 1 1 1 -1 - 75 29 46 1 1 1 -1 - 76 46 26 1 1 1 -1 - 77 21 47 1 1 1 -1 - 78 47 26 1 1 1 -1 - 79 25 47 1 1 1 -1 - 80 47 22 1 1 1 -1 - 81 33 48 1 1 1 -1 - 82 48 30 1 1 1 -1 - 83 29 48 1 1 1 -1 - 84 48 34 1 1 1 -1 - 85 22 49 1 1 1 -1 - 86 49 35 1 1 1 -1 - 87 34 49 1 1 1 -1 - 88 49 23 1 1 1 -1 - 89 26 50 1 1 1 -1 - 90 50 31 1 1 1 -1 - 91 30 50 1 1 1 -1 - 92 50 27 1 1 1 -1 - 93 22 51 1 1 1 -1 - 94 51 27 1 1 1 -1 - 95 26 51 1 1 1 -1 - 96 51 23 1 1 1 -1 - 97 34 52 1 1 1 -1 - 98 52 31 1 1 1 -1 - 99 30 52 1 1 1 -1 - 100 52 35 1 1 1 -1 - 101 24 53 4 4 1 -1 - 102 28 54 4 4 1 -1 - 103 32 56 4 4 1 -1 - 104 36 55 4 4 1 -1 - 105 58 1 5 5 1 -1 - 106 57 16 5 5 1 -1 - 107 60 6 5 5 1 -1 - 108 59 11 5 5 1 -1 - 109 62 58 6 6 1 -1 - 110 61 57 6 6 1 -1 - 111 64 60 6 6 1 -1 - 112 63 59 6 6 1 -1 +MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType MSpin/COSMID ![MType={1c:beam circ., 1r:beam rect., 2:cable, 3:rigid, 4:beam arb., 5:spring}. COMSID={-1:none}] + (-) (-) (-) (-) (-) (-) (deg/-) + 1 1 2 2 2 1c 0 + 2 2 3 2 2 1c 0 + 3 3 4 2 2 1c 0 + 4 4 5 2 2 1c 0 + 5 6 7 2 2 1c 0 + 6 7 8 2 2 1c 0 + 7 8 9 2 2 1c 0 + 8 9 10 2 2 1c 0 + 9 11 12 2 2 1c 0 + 10 12 13 2 2 1c 0 + 11 13 14 2 2 1c 0 + 12 14 15 2 2 1c 0 + 13 16 17 2 2 1c 0 + 14 17 18 2 2 1c 0 + 15 18 19 2 2 1c 0 + 16 19 20 2 2 1c 0 + 17 5 21 3 3 1c 0 + 18 21 22 3 3 1c 0 + 19 22 23 3 3 1c 0 + 20 23 24 3 3 1c 0 + 21 10 25 3 3 1c 0 + 22 25 26 3 3 1c 0 + 23 26 27 3 3 1c 0 + 24 27 28 3 3 1c 0 + 25 15 29 3 3 1c 0 + 26 29 30 3 3 1c 0 + 27 30 31 3 3 1c 0 + 28 31 32 3 3 1c 0 + 29 20 33 3 3 1c 0 + 30 33 34 3 3 1c 0 + 31 34 35 3 3 1c 0 + 32 35 36 3 3 1c 0 + 33 8 3 1 1 1c 0 + 34 13 8 1 1 1c 0 + 35 13 18 1 1 1c 0 + 36 18 3 1 1 1c 0 + 37 4 37 1 1 1c 0 + 38 37 20 1 1 1c 0 + 39 19 37 1 1 1c 0 + 40 37 5 1 1 1c 0 + 41 9 38 1 1 1c 0 + 42 38 15 1 1 1c 0 + 43 14 38 1 1 1c 0 + 44 38 10 1 1 1c 0 + 45 4 39 1 1 1c 0 + 46 39 10 1 1 1c 0 + 47 9 39 1 1 1c 0 + 48 39 5 1 1 1c 0 + 49 19 40 1 1 1c 0 + 50 40 15 1 1 1c 0 + 51 14 40 1 1 1c 0 + 52 40 20 1 1 1c 0 + 53 5 41 1 1 1c 0 + 54 41 33 1 1 1c 0 + 55 20 41 1 1 1c 0 + 56 41 21 1 1 1c 0 + 57 10 42 1 1 1c 0 + 58 42 29 1 1 1c 0 + 59 15 42 1 1 1c 0 + 60 42 25 1 1 1c 0 + 61 5 43 1 1 1c 0 + 62 43 25 1 1 1c 0 + 63 10 43 1 1 1c 0 + 64 43 21 1 1 1c 0 + 65 20 44 1 1 1c 0 + 66 44 29 1 1 1c 0 + 67 15 44 1 1 1c 0 + 68 44 33 1 1 1c 0 + 69 21 45 1 1 1c 0 + 70 45 34 1 1 1c 0 + 71 33 45 1 1 1c 0 + 72 45 22 1 1 1c 0 + 73 25 46 1 1 1c 0 + 74 46 30 1 1 1c 0 + 75 29 46 1 1 1c 0 + 76 46 26 1 1 1c 0 + 77 21 47 1 1 1c 0 + 78 47 26 1 1 1c 0 + 79 25 47 1 1 1c 0 + 80 47 22 1 1 1c 0 + 81 33 48 1 1 1c 0 + 82 48 30 1 1 1c 0 + 83 29 48 1 1 1c 0 + 84 48 34 1 1 1c 0 + 85 22 49 1 1 1c 0 + 86 49 35 1 1 1c 0 + 87 34 49 1 1 1c 0 + 88 49 23 1 1 1c 0 + 89 26 50 1 1 1c 0 + 90 50 31 1 1 1c 0 + 91 30 50 1 1 1c 0 + 92 50 27 1 1 1c 0 + 93 22 51 1 1 1c 0 + 94 51 27 1 1 1c 0 + 95 26 51 1 1 1c 0 + 96 51 23 1 1 1c 0 + 97 34 52 1 1 1c 0 + 98 52 31 1 1 1c 0 + 99 30 52 1 1 1c 0 + 100 52 35 1 1 1c 0 + 101 24 53 4 4 1c 0 + 102 28 54 4 4 1c 0 + 103 32 56 4 4 1c 0 + 104 36 55 4 4 1c 0 + 105 58 1 5 5 1c 0 + 106 57 16 5 5 1c 0 + 107 60 6 5 5 1c 0 + 108 59 11 5 5 1c 0 + 109 62 58 6 6 1c 0 + 110 61 57 6 6 1c 0 + 111 64 60 6 6 1c 0 + 112 63 59 6 6 1c 0 ------------------ CIRCULAR BEAM CROSS-SECTION PROPERTIES ----------------------------- 6 NPropSets - Number of structurally unique circular cross-sections PropSetID YoungE ShearG MatDens XsecD XsecT @@ -235,10 +233,14 @@ PropSetID YoungE ShearG MatDens XsecD X 4 2.10000e+11 8.07690e+10 7850.00 1.200000 0.040000 5 2.10000e+11 8.07690e+10 3339.12 2.082000 0.491000 6 2.10000e+11 8.07690e+10 7850.00 2.082000 0.060000 +----------------- RECTANGULAR BEAM CROSS-SECTION PROPERTIES --------------------------- + 0 NPropSets - Number of structurally unique cross-sections (if 0 the following table is ignored) +PropSetID YoungE ShearG MatDens XsecSa XsecSb XsecT + (-) (N/m2) (N/m2) (kg/m3) (m) (m) (m) ----------------- ARBITRARY BEAM CROSS-SECTION PROPERTIES ----------------------------- 0 NXPropSets - Number of structurally unique non-circular cross-sections (if 0 the following table is ignored) -PropSetID YoungE ShearG MatDens XsecA XsecAsx XsecAsy XsecJxx XsecJyy XsecJ0 - (-) (N/m2) (N/m2) (kg/m3) (m2) (m2) (m2) (m4) (m4) (m4) +PropSetID YoungE ShearG MatDens XsecA XsecAsx XsecAsy XsecJxx XsecJyy XsecJ0 XsecJt + (-) (N/m2) (N/m2) (kg/m3) (m2) (m2) (m2) (m4) (m4) (m4) (m4) -------------------------- CABLE PROPERTIES ------------------------------------------- 0 NCablePropSets - Number of cable cable properties PropSetID EA MatDens T0 CtrlChannel diff --git a/docs/source/user/subdyn/input_files.rst b/docs/source/user/subdyn/input_files.rst index 8e7f5a3ae5..d417fc3d85 100644 --- a/docs/source/user/subdyn/input_files.rst +++ b/docs/source/user/subdyn/input_files.rst @@ -404,33 +404,35 @@ specifies the ending joint, corresponding to an identifier **MPropSetID1** corresponds to the identifier **PropSetID** from the MEMBER X-SECTION PROPERTY table (discussed next) for starting cross-section properties and **MPropSetID2** specifies the identifier -for ending cross-section properties, allowing for tapered members. +for ending cross-section properties, allowing for tapered members. +Note that tapering is not allowed with user-defined generic beams (*MType=4*) below. +Therefore, **MPropSetID1** and **MPropSetID2** must be the same for this beam type. The sixth column specify the member type **MType**. A member is one of the four following types (see :numref:`SD_FEM`): -- Beams (*MType=1*), Euler-Bernoulli (*FEMMod=1*) or Timoshenko (*FEMMod=3*) +- Beams with circular cross sections (*MType=1c* or *MType=1*), Euler-Bernoulli (*FEMMod=1*) or Timoshenko (*FEMMod=3*) + +- Beams with rectangular cross sections (*MType=1r*), Euler-Bernoulli (*FEMMod=1*) or Timoshenko (*FEMMod=3*) - Pretension cables (*MType=2*) - Rigid link (*MType=3*) -- Spring element (*MType=5*) +- Beam with arbitrary user-defined cross-section properties (*MType=4*), Euler-Bernoulli (*FEMMod=1*) or Timoshenko (*FEMMod=3*) -**COSMID** refers to the IDs of the members' cosine matrices for noncircular -members and spring elements; the current release uses SubDyn's default direction cosine convention -if it's not present or when COSMID values are -1. Spring elements are defined between joints that -are coincident in the space and the direction cosine must be provided. +- Spring element (*MType=5*) +The required input for **MSpin/COSMID** depends on the member type. For all beam types (*MType=1c*, *1r*, or *4*), users can specify a spin angle **MSpin** in degrees. This is a rotation of the beam member about its axis (pointing from the starting joint to the ending joint) following the right-hand convention. When **MSpin** = 0, the default SubDyn member orientation is used with the element local *x_e* axis parallel to the global *XY* plane. (If the beam is perfectly vertical, the element local *x_e* axis is parallel to the global *X* axis.) A nonzero **MSpin** effectively rotates the element local coordinate system about the member axis. For a beam with a rectangular cross section, Side A of the rectangular section is always parallel to the *x_e* axis, and setting **MSpin** allows the rectangular section to be reoriented as needed. Note that this convention is consistent with how HydroDyn defines rectangular members. Using the same member spin angle in SubDyn and HydroDyn ensures consistency across the two modules. With *MType=4*, the user-defined cross-section properties are also about the element local axes. Again, setting **MSpin** allows the cross section to be reoriented as needed. Finally, for beams with cylindrical cross sections, **MSpin** has no physical effect, but it does influence output channels based on the element local coordinate system. Setting **MSpin** allows these outputs to be given in a more convenient coordinate system orientation. For spring elements (*MType=5*), users can provide the IDs of user-defined member cosine matrices (**COSMID**\ ); the current release uses SubDyn's default direction cosine convention if **COSMID** is -1. Spring elements are defined between joints that are coincident in space and the direction cosine must be provided. An example of member table is given below .. code:: 2 NMembers - Number of frame members - MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType COSMID - (-) (-) (-) (-) (-) (-) (-) - 10 101 102 2 2 1 - 11 102 103 2 2 1 + MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType MSpin/COSMID + (-) (-) (-) (-) (-) (-) (deg/-) + 10 101 102 2 2 1c 0 + 11 102 103 2 2 1c 0 @@ -438,38 +440,51 @@ An example of member table is given below Member Cross-Section Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Members in SubDyn are assumed to be straight, circular, possibly -tapered, and hollow cylinders. Future releases will allow for generic -cross-sections to be employed. These special cross-section members will -be defined in the second of two tables in the input file (Member -X-Section Property data 2/2), which is currently ignored. +Beam members in SubDyn are assumed to be straight, possibly +tapered, and hollow, with circular, rectangular, or user-defined generic +cross sections. These beam cross-section properties are defined in three +separate tables. -For the circular cross-section members, properties needed by SubDyn are +Properties of circular beam cross sections needed by SubDyn are material Young’s modulus, **YoungE**, shear modulus, **ShearG**, and -density, **MatDens**, member outer diameter, **XsecD**, and member -thickness, **XsecT**. Users will need to create an entry in the first -table within this section of the input file distinguished by +density, **MatDens**, member outer diameter, **XsecD**, and member wall +thickness, **XsecT**. Note that setting **XsecT** to a value less than +or equal to zero implies a solid section. Users will need to create an +entry in the first table within this section of the input file identified by **PropSetID**, for each unique combination of these five properties. The member property-set table contains **NPropSets** rows. The member property sets are referred to by their **PropSetID** in the MEMBERS -table, as described in Section . Note, however, that although diameter -and thickness will be linearly interpolated within an individual member, -SubDyn will not allow *material* properties to change within an -individual member. - -The second table in this section of the input file (not to be used in -this release) will have **NXPropSets** rows (assumed to be zero for -this release), and have additional entries when compared to the previous +table above. Note, however, that although diameter and thickness will +be linearly interpolated within an individual member, SubDyn will not +allow *material* properties to change within an individual member. + +Properties of rectangular beam cross sections needed by SubDyn are the +same as those for circular beam cross sections, except that the section +diameter **XsecD** is replaced with the lengths of the two sides of the +rectangular section **XsecSa** (length of Side A) and **XsecSb** (length of +Side B). Side A is parallel to the element local *x_e* axis and Side B is +parallel to the element local *y_e* axis. Again, setting **XsecT** to a +value less than or equal to zero implies a solid section. Note that SubDyn +can automatically compute the shear areas and torsion constant for solid +rectangular sections and thin-walled rectangular sections. For sections +of intermediate wall thickness, the thin-walled approximation will be used, +which might not be accurate. This is different from circular sections for +which the shear area and torsion constant can be automatically computed by +SubDyn for arbitrary wall thickness. The properties of unique rectangular +beam sections are entered on separate rows of the second table of this input +file section. Again, the table should have **NPropSets** rows. + +The third table in this section of the input file have **NXPropSets** +rows and have additional entries when compared to the previous table, including: cross-sectional area (**XsecA**), cross-sectional shear area along the local principal axes *x* and *y* (**XsecAsx**, **XsecAsy**), cross-sectional area second moment of inertia about *x* -and *y* (**XsecJxx**, **XsecJyy**), and cross-sectional area polar -moment of inertia (**XsecJ0**). The member cosine matrix section (see -Section ) will help determine the correct orientation of the members -within the assembly. - - - +and *y* (**XsecJxx**, **XsecJyy**), cross-sectional polar area +moment of inertia (**XsecJ0**), and the cross-sectional torsion constant +(**XsecJt**). The cross-section properties defined in this section can be +used with the arbitrary beam type with *MType=4* in the MEMBERS table. +The cross section can be reoriented through the **MSpin** input in the MEMBERS +section, similar to rectangular members. Cable Properties diff --git a/docs/source/user/subdyn/theory.rst b/docs/source/user/subdyn/theory.rst index 06bdea0790..8fb686c6f3 100755 --- a/docs/source/user/subdyn/theory.rst +++ b/docs/source/user/subdyn/theory.rst @@ -1879,7 +1879,7 @@ This applies e.g.: to :math:`F_{R,e}, F_{L,e}, F_{R,g}, F_{L,g}`, where the foll The dependency of the load vectors on :math:`U_{TP}` introduces some complications for the state space representation, where for instance the :math:`B` and :math:`F_X` matrices should be modified to account for the dependency in :math:`U_{TP}` in Eq. :eq:`ABFx`. -The equation remains valid even if :math:`F_{L,e}` and :math:`F_{L,g}` contains a dependency in :math:`U_{TP}`, but the matrix :math:`B` shouldn't be used for the linearization (numerical differentiation is then prefered for simplicity). +The equation remains valid even if :math:`F_{L,e}` and :math:`F_{L,g}` contains a dependency in :math:`U_{TP}`, but the matrix :math:`B` shouldn't be used for the linearization (numerical differentiation is then preferred for simplicity). Similar considerations apply for Eq. :eq:`bigY2`. diff --git a/glue-codes/fast-farm/src/FAST_Farm.f90 b/glue-codes/fast-farm/src/FAST_Farm.f90 index bbc9ad94bd..6d2a8c141b 100644 --- a/glue-codes/fast-farm/src/FAST_Farm.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm.f90 @@ -49,8 +49,8 @@ PROGRAM FAST_Farm REAL(ReKi) :: PrevClockTime !< Previous clock time in seconds past midnight INTEGER :: SimStrtTime (8) !< An array containing the elements of the start time (after initialization). INTEGER :: ProgStrtTime (8) !< An array containing the elements of the program start time (before initialization). -REAL(ReKi) :: SimStrtCPU !< User CPU time for simulation (without intialization) -REAL(ReKi) :: ProgStrtCPU !< User CPU time for program (with intialization) +REAL(ReKi) :: SimStrtCPU !< User CPU time for simulation (without initialization) +REAL(ReKi) :: ProgStrtCPU !< User CPU time for program (with initialization) ! these should probably go in the FAST.Farm registry: type(All_FastFarm_Data) :: farm diff --git a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 index 9526de9903..555a6169a1 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 @@ -341,7 +341,7 @@ SUBROUTINE WAT_init( p, WAT_IfW, AWAE_InitInput, ErrStat, ErrMsg ) HAWC_InitInput%WindFileName(3) = trim(BoxFileRoot)//trim(FileEnding(3)) ! HAWC spatial grid - if (p%WAT == Mod_WAT_PreDef) then ! from libary of WAT files, set the NxNyNz and DxDyDz terms + if (p%WAT == Mod_WAT_PreDef) then ! from library of WAT files, set the NxNyNz and DxDyDz terms call MannLibDims(BoxFileRoot, p%RotorDiamRef, p%WAT_NxNyNz, p%WAT_DxDyDz, ErrStat2, ErrMsg2); if (Failed()) return write(sDummy, '(3(I8,1X))') p%WAT_NxNyNz call WrScr(' WAT: NxNyNz set to: '//trim(sDummy)//' (inferred from filename)') diff --git a/glue-codes/labview/CMakeLists.txt b/glue-codes/labview/CMakeLists.txt index b14ef7ae4b..dbea6e2775 100644 --- a/glue-codes/labview/CMakeLists.txt +++ b/glue-codes/labview/CMakeLists.txt @@ -17,7 +17,14 @@ add_library(wavetanktestinglib SHARED src/WaveTank.f90 ) -target_link_libraries(wavetanktestinglib aerodyn_inflow_c_binding moordyn_c_binding seastate_c_binding nwtclibs versioninfolib) +target_link_libraries( + wavetanktestinglib + aerodyn_inflow_c_binding + moordyn_c_binding + seastate_c_binding + nwtclibs + versioninfolib +) if(APPLE OR UNIX) target_compile_definitions(wavetanktestinglib PRIVATE IMPLICIT_DLLEXPORT) endif() diff --git a/glue-codes/labview/src/WaveTank.f90 b/glue-codes/labview/src/WaveTank.f90 index 21f2a6e63f..29de4434f6 100644 --- a/glue-codes/labview/src/WaveTank.f90 +++ b/glue-codes/labview/src/WaveTank.f90 @@ -3,212 +3,740 @@ MODULE WaveTankTesting USE ISO_C_BINDING USE NWTC_Library - ! USE Precision - USE MoorDyn_C - USE SeaState_C_Binding - USE NWTC_C_Binding, ONLY: IntfStrLen, SetErrStat_C + USE NWTC_IO + USE SeaState_C_Binding, ONLY: SeaSt_C_Init, SeaSt_C_CalcOutput, SeaSt_C_End, MaxOutPts, SeaSt_GetWaveFieldPointer_C + USE SeaSt_WaveField_Types, ONLY: SeaSt_WaveFieldType + USE AeroDyn_Inflow_C_BINDING, ONLY: ADI_C_PreInit, ADI_C_SetupRotor, ADI_C_Init, ADI_C_End, MaxADIOutputs, ADI_C_SetRotorMotion, ADI_C_UpdateStates, ADI_C_CalcOutput, ADI_C_GetRotorLoads + USE MoorDyn_C, ONLY: MD_C_Init, MD_C_End, MD_C_SetWaveFieldData, MD_C_UpdateStates, MD_C_CalcOutput + USE NWTC_C_Binding, ONLY: IntfStrLen, SetErrStat_C, SetErrStat_F2C, ErrMsgLen_C, StringConvert_F2C, FileNameFromCString IMPLICIT NONE SAVE PUBLIC :: WaveTank_Init + PUBLIC :: WaveTank_CalcOutput + PUBLIC :: WaveTank_End + PUBLIC :: WaveTank_SetWaveFieldPointer + PUBLIC :: WaveTank_Sizes - REAL(C_DOUBLE) :: dt_c = 0.01_C_DOUBLE ! 100 hertz - REAL(C_FLOAT) :: g_c = 9.8065_C_FLOAT - REAL(C_FLOAT) :: rho_c = 1025.0_C_FLOAT - REAL(C_FLOAT) :: depth_c = 200.0_C_FLOAT - REAL(C_FLOAT), DIMENSION(6) :: ptfminit_c = 0.0_C_FLOAT - INTEGER(C_INT) :: interporder_c = 2 ! 1: linear (uses two time steps) or 2: quadratic (uses three time steps) - - INTEGER(C_INT) :: N_CAMERA_POINTS + INTEGER(C_INT) :: SS_NumChannels_C + INTEGER(C_INT) :: MD_NumChannels_C + INTEGER(C_INT) :: ADI_NumChannels_C + + INTEGER(C_INT) :: iWT_C + INTEGER(C_INT) :: NumBlades_C + INTEGER(C_INT) :: NumMeshPts_C + + REAL(C_DOUBLE) :: DT + + REAL(C_FLOAT), DIMENSION(3,3) :: FloaterPositions = 0.0_C_FLOAT + REAL(C_FLOAT), DIMENSION(2,6) :: FloaterVelocities = 0.0_C_FLOAT + REAL(C_FLOAT), DIMENSION(1,6) :: FloaterAccelerations = 0.0_C_FLOAT + + REAL(C_FLOAT), DIMENSION(3,3) :: NacellePositions = 0.0_C_FLOAT + REAL(C_FLOAT), DIMENSION(2,6) :: NacelleVelocities = 0.0_C_FLOAT + REAL(C_FLOAT), DIMENSION(1,6) :: NacelleAccelerations = 0.0_C_FLOAT + + REAL(C_FLOAT), ALLOCATABLE :: BladeRootPositions(:,:) + REAL(C_FLOAT), ALLOCATABLE :: BladeRootVelocities(:,:) + REAL(C_FLOAT), ALLOCATABLE :: BladeRootAccelerations(:,:) - INTEGER(C_INT) :: load_period = 20 ! seconds + REAL(C_FLOAT), ALLOCATABLE :: BladeMeshPositions(:,:) + REAL(C_FLOAT), ALLOCATABLE :: BladeMeshVelocities(:,:) + REAL(C_FLOAT), ALLOCATABLE :: BladeMeshAccelerations(:,:) + + TYPE WaveTank_InitInput + REAL(C_DOUBLE) :: DT + + ! SeaState variables + TYPE(C_PTR) :: SS_OutRootName_C + REAL(C_FLOAT) :: SS_Gravity_C + REAL(C_FLOAT) :: SS_WtrDens_C + REAL(C_FLOAT) :: SS_WtrDpth_C + REAL(C_FLOAT) :: SS_MSL2SWL_C + INTEGER(C_INT) :: SS_NSteps_C + REAL(C_FLOAT) :: SS_TimeInterval_C + INTEGER(C_INT) :: SS_WaveElevSeriesFlag_C + INTEGER(C_INT) :: SS_WrWvKinMod_C + + ! MD variables + ! REAL(C_DOUBLE) :: MD_DT_C !< Using global DT + REAL(C_FLOAT) :: MD_G_C + REAL(C_FLOAT) :: MD_RHO_C + REAL(C_FLOAT) :: MD_DEPTH_C + REAL(C_FLOAT) :: MD_PtfmInit_C(6) + INTEGER(C_INT) :: MD_InterpOrder_C + + ! ADI variables + ! Preinit + INTEGER(C_INT) :: NumTurbines_C + INTEGER(C_INT) :: TransposeDCM + INTEGER(C_INT) :: PointLoadOutput + REAL(C_FLOAT) :: ADI_gravity_C + REAL(C_FLOAT) :: ADI_defFldDens_C + REAL(C_FLOAT) :: ADI_defKinVisc_C + REAL(C_FLOAT) :: ADI_defSpdSound_C + REAL(C_FLOAT) :: ADI_defPatm_C + REAL(C_FLOAT) :: ADI_defPvap_C + REAL(C_FLOAT) :: ADI_WtrDpth_C + REAL(C_FLOAT) :: ADI_MSL2SWL_C + INTEGER(C_INT) :: MHK + INTEGER(C_INT) :: DebugLevel + ! SetupRotor + INTEGER(C_INT) :: iWT_c !< Wind turbine / rotor number + INTEGER(C_INT) :: TurbineIsHAWT_c !< true for HAWT, false for VAWT + REAL(C_FLOAT) :: TurbOrigin_C(3) !< turbine origin (tower base). Gets added to all meshes to shift turbine position. + REAL(C_FLOAT) :: HubPos_C( 3 ) !< Hub position + REAL(C_DOUBLE) :: HubOri_C( 9 ) !< Hub orientation + REAL(C_FLOAT) :: NacPos_C( 3 ) !< Nacelle position + REAL(C_DOUBLE) :: NacOri_C( 9 ) !< Nacelle orientation + INTEGER(C_INT) :: NumBlades_C + REAL(C_FLOAT), DIMENSION(:), ALLOCATABLE :: BldRootPos_C !< Blade root positions; 3xNumBlades_C + REAL(C_DOUBLE), DIMENSION(:), ALLOCATABLE :: BldRootOri_C !< Blade root orientations; 9xNumBlades_C + ! Initial nodes + INTEGER(C_INT) :: NumMeshPts_C !< Number of mesh points we are transferring motions and outputting loads to + REAL(C_FLOAT), DIMENSION(:), ALLOCATABLE :: InitMeshPos_C !< A 3xNumMeshPts_C array [x,y,z] + REAL(C_DOUBLE), DIMENSION(:), ALLOCATABLE :: InitMeshOri_C !< A 9xNumMeshPts_C array [r11,r12,r13,r21,r22,r23,r31,r32,r33] + INTEGER(C_INT), DIMENSION(:), ALLOCATABLE :: MeshPtToBladeNum_C !< A NumMeshPts_C array of blade numbers associated with each mesh point + ! Init + CHARACTER(KIND=C_CHAR) :: ADI_OutRootName_C(IntfStrLen) !< Root name to use for echo files and other + CHARACTER(KIND=C_CHAR) :: ADI_OutVTKDir_C(IntfStrLen) !< Directory to put all vtk output + ! Interpolation + INTEGER(C_INT) :: ADI_InterpOrder_C !< Interpolation order to use (must be 1 or 2) + ! Time + ! REAL(C_DOUBLE) :: ADI_DT_C !< Timestep used with AD for stepping forward from t to t+dt. Must be constant.; Using global DT + REAL(C_DOUBLE) :: ADI_TMax_C !< Maximum time for simulation + ! Flags + INTEGER(C_INT) :: ADI_storeHHVel !< Store hub height time series from IfW + ! VTK + INTEGER(C_INT) :: ADI_WrVTK_in + INTEGER(C_INT) :: ADI_WrVTK_inType + REAL(C_DOUBLE) :: ADI_WrVTK_inDT + REAL(C_FLOAT) :: ADI_VTKNacDim_in(6) + REAL(C_FLOAT) :: ADI_VTKHubrad_in + INTEGER(C_INT) :: ADI_wrOuts_C + REAL(C_DOUBLE) :: ADI_DT_Outs_C + END TYPE WaveTank_InitInput CONTAINS +SUBROUTINE ReadInput(InputFilePath, InitInp, ErrStat, ErrMsg) + + CHARACTER(*), INTENT(IN ) :: InputFilePath + TYPE(WaveTank_InitInput), INTENT( OUT) :: InitInp + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + + ! Local variables + INTEGER :: UnIn = -1 + ! CHARACTER(1024) :: Line ! String to temporarially hold value of read line + CHARACTER(1024), target :: TmpPath + CHARACTER(1024), pointer :: TmpPointer + ! CHARACTER(1024) :: TmpFmt ! Temporary storage for format statement + CHARACTER(1024) :: FileName + + integer(IntKi) :: ErrStat2 ! local status of error message + character(ErrMsgLen) :: ErrMsg2 ! local error message if errStat /= ErrID_None + + ErrStat = ErrID_None + ErrMsg = " " + + FileName = TRIM(InputFilePath) + CALL GetNewUnit( UnIn ) + CALL OpenFInpFile( UnIn, FileName, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + IF (ErrStat >= AbortErrLev) RETURN + + CALL ReadCom( UnIn, FileName, 'Init comment', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%DT, 'DT', 'DT', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadCom( UnIn, FileName, 'SeaState Init comment', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + IF (ErrStat >= AbortErrLev) RETURN + + CALL ReadVar( UnIn, FileName, TmpPath, 'SS_OutRootName_C', 'SS_OutRootName_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + TmpPointer => TmpPath + InitInp%SS_OutRootName_C = C_LOC(TmpPointer) + CALL ReadVar( UnIn, FileName, InitInp%SS_Gravity_C, 'SS_Gravity_C', 'SS_Gravity_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%SS_WtrDens_C, 'SS_WtrDens_C', 'SS_WtrDens_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%SS_WtrDpth_C, 'SS_WtrDpth_C', 'SS_WtrDpth_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%SS_MSL2SWL_C, 'SS_MSL2SWL_C', 'SS_MSL2SWL_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%SS_NSteps_C, 'SS_NSteps_C', 'SS_NSteps_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%SS_TimeInterval_C, 'SS_TimeInterval_C', 'SS_TimeInterval_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%SS_WaveElevSeriesFlag_C, 'SS_WaveElevSeriesFlag_C', 'SS_WaveElevSeriesFlag_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%SS_WrWvKinMod_C, 'SS_WrWvKinMod_C', 'SS_WrWvKinMod_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + IF (ErrStat >= AbortErrLev) RETURN + + CALL ReadCom( UnIn, FileName, 'MoorDyn Init comment', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%MD_G_C, 'MD_G_C', 'MD_G_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%MD_RHO_C, 'MD_RHO_C', 'MD_RHO_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%MD_DEPTH_C, 'MD_DEPTH_C', 'MD_DEPTH_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%MD_PtfmInit_C, 6, 'MD_PtfmInit_C', 'MD_PtfmInit_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%MD_InterpOrder_C, 'MD_InterpOrder_C', 'MD_InterpOrder_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + IF (ErrStat >= AbortErrLev) RETURN + + CALL ReadCom( UnIn, FileName, 'ADI Init comment', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%NumTurbines_C, 'NumTurbines_C', 'NumTurbines_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%TransposeDCM, 'TransposeDCM', 'TransposeDCM', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%PointLoadOutput, 'PointLoadOutput', 'PointLoadOutput', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_gravity_C, 'ADI_gravity_C', 'ADI_gravity_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_defFldDens_C, 'ADI_defFldDens_C', 'ADI_defFldDens_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_defKinVisc_C, 'ADI_defKinVisc_C', 'ADI_defKinVisc_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_defSpdSound_C, 'ADI_defSpdSound_C', 'ADI_defSpdSound_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_defPatm_C, 'ADI_defPatm_C', 'ADI_defPatm_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_defPvap_C, 'ADI_defPvap_C', 'ADI_defPvap_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_WtrDpth_C, 'ADI_WtrDpth_C', 'ADI_WtrDpth_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_MSL2SWL_C, 'ADI_MSL2SWL_C', 'ADI_MSL2SWL_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%MHK, 'MHK', 'MHK', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%DebugLevel, 'DebugLevel', 'DebugLevel', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + IF (ErrStat >= AbortErrLev) RETURN + + CALL ReadVar( UnIn, FileName, InitInp%iWT_c, 'iWT_c', 'iWT_c', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%TurbineIsHAWT_c, 'TurbineIsHAWT_c', 'TurbineIsHAWT_c', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%TurbOrigin_C, 3, 'TurbOrigin_C', 'TurbOrigin_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%HubPos_C, 3, 'HubPos_C', 'HubPos_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%HubOri_C, 9, 'HubOri_C', 'HubOri_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%NacPos_C, 3, 'NacPos_C', 'NacPos_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%NacOri_C, 9, 'NacOri_C', 'NacOri_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%NumBlades_C, 'NumBlades_C', 'NumBlades_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL AllocAry(InitInp%BldRootPos_C, 3*InitInp%NumBlades_C, 'BldRootPos_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL AllocAry(InitInp%BldRootOri_C, 9*InitInp%NumBlades_C, 'BldRootPos_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%BldRootPos_C, 3*InitInp%NumBlades_C, 'BldRootPos_C', 'BldRootPos_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%BldRootOri_C, 9*InitInp%NumBlades_C, 'BldRootOri_C', 'BldRootOri_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%NumMeshPts_C, 'NumMeshPts_C', 'NumMeshPts_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL AllocAry(InitInp%InitMeshPos_C, 3*InitInp%NumMeshPts_C, 'InitMeshPos_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL AllocAry(InitInp%InitMeshOri_C, 9*InitInp%NumMeshPts_C, 'InitMeshOri_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL AllocAry(InitInp%MeshPtToBladeNum_C, InitInp%NumMeshPts_C, 'MeshPtToBladeNum_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%InitMeshPos_C, 3*InitInp%NumMeshPts_C, 'InitMeshPos_C', 'InitMeshPos_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%InitMeshOri_C, 9*InitInp%NumMeshPts_C, 'InitMeshOri_C', 'InitMeshOri_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%MeshPtToBladeNum_C, InitInp%NumMeshPts_C, 'MeshPtToBladeNum_C', 'MeshPtToBladeNum_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + IF (ErrStat >= AbortErrLev) RETURN + + CALL ReadVar( UnIn, FileName, TmpPath, 'ADI_OutRootName_C', 'ADI_OutRootName_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL StringConvert_F2C(TmpPath, InitInp%ADI_OutRootName_C) + CALL ReadVar( UnIn, FileName, TmpPath, 'ADI_OutVTKDir_C', 'ADI_OutVTKDir_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL StringConvert_F2C(TmpPath, InitInp%ADI_OutVTKDir_C) + CALL ReadVar( UnIn, FileName, InitInp%ADI_InterpOrder_C, 'ADI_InterpOrder_C', 'ADI_InterpOrder_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_TMax_C, 'ADI_TMax_C', 'ADI_TMax_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_storeHHVel, 'ADI_storeHHVel', 'ADI_storeHHVel', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_WrVTK_in, 'ADI_WrVTK_in', 'ADI_WrVTK_in', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_WrVTK_inType, 'ADI_WrVTK_inType', 'ADI_WrVTK_inType', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_WrVTK_inDT, 'ADI_WrVTK_inDT', 'ADI_WrVTK_inDT', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadAry( UnIn, FileName, InitInp%ADI_VTKNacDim_in, 6, 'ADI_VTKNacDim_in', 'ADI_VTKNacDim_in', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_VTKHubrad_in, 'ADI_VTKHubrad_in', 'ADI_VTKHubrad_in', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_wrOuts_C, 'ADI_wrOuts_C', 'ADI_wrOuts_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + CALL ReadVar( UnIn, FileName, InitInp%ADI_DT_Outs_C, 'ADI_DT_Outs_C', 'ADI_DT_Outs_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WaveTankTesting.ReadInput') + IF (ErrStat >= AbortErrLev) RETURN + + if(UnIn>0) CLOSE( UnIn ) +END SUBROUTINE SUBROUTINE WaveTank_Init( & - MD_InputFile_c, & - SS_InputFile_c, & - AD_InputFile_c, & - IfW_InputFile_c, & - n_camera_points_c, & - ErrStat_c, & - ErrMsg_c & + WT_InputFile_C, & + MD_InputFile_C, & + SS_InputFile_C, & + AD_InputFile_C, & + IfW_InputFile_C, & + ErrStat_C, & + ErrMsg_C & ) BIND (C, NAME='WaveTank_Init') #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: WaveTank_Init !GCC$ ATTRIBUTES DLLEXPORT :: WaveTank_Init #endif -IMPLICIT NONE - -CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: MD_InputFile_c(IntfStrLen) -CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: SS_InputFile_c(IntfStrLen) -CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: AD_InputFile_c(IntfStrLen) -CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: IfW_InputFile_c(IntfStrLen) -INTEGER(C_INT), INTENT(IN ) :: n_camera_points_c -INTEGER(C_INT), INTENT( OUT) :: ErrStat_C -CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) - -! Local variables -integer(c_int) :: numchannels_c -character(kind=c_char) :: outputchannelnames_c(100000) -character(kind=c_char) :: outputchannelunits_c(100000) -integer(c_int) :: input_file_passed = 0 ! We're passing paths to input files rather than input strings for all modules -! character(kind=c_char), pointer :: filestring_c(IntfStrLen) ! Point to input file path input argument - -print *, MD_InputFile_c -print *, SS_InputFile_c -print *, AD_InputFile_c -print *, IfW_InputFile_c - -N_CAMERA_POINTS = n_camera_points_c - -! filestring_c => MD_InputFile_c -! call MD_C_Init( & -! input_file_passed, & -! filestring_c, & -! IntfStrLen, & -! dt_c, & -! g_c, & -! rho_c, & -! depth_c, & -! ptfminit_c, & -! interporder_c, & -! numchannels_c, & -! outputchannelnames_c, & -! outputchannelunits_c, & -! ErrStat_C, ErrMsg_C & -! ) - -! call ADI_C_Init( & -! ADinputFilePassed, & ! integer(c_int), intent(in ) :: ADinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] -! ADinputFileString_C, & ! type(c_ptr), intent(in ) :: ADinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR -! ADinputFileStringLength_C, & ! integer(c_int), intent(in ) :: ADinputFileStringLength_C !< lenght of the input file string -! IfWinputFilePassed, & ! integer(c_int), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] -! IfWinputFileString_C, & ! type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR -! IfWinputFileStringLength_C, & ! integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string -! OutRootName_C, & ! character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other -! OutVTKDir_C, & ! character(kind=c_char), intent(in ) :: OutVTKDir_C(IntfStrLen) !< Directory to put all vtk output -! gravity_C, & ! real(c_float), intent(in ) :: gravity_C !< Gravitational acceleration (m/s^2) -! defFldDens_C, & ! real(c_float), intent(in ) :: defFldDens_C !< Air density (kg/m^3) -! defKinVisc_C, & ! real(c_float), intent(in ) :: defKinVisc_C !< Kinematic viscosity of working fluid (m^2/s) -! defSpdSound_C, & ! real(c_float), intent(in ) :: defSpdSound_C !< Speed of sound in working fluid (m/s) -! defPatm_C, & ! real(c_float), intent(in ) :: defPatm_C !< Atmospheric pressure (Pa) [used only for an MHK turbine cavitation check] -! defPvap_C, & ! real(c_float), intent(in ) :: defPvap_C !< Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] -! WtrDpth_C, & ! real(c_float), intent(in ) :: WtrDpth_C !< Water depth (m) -! MSL2SWL_C, & ! real(c_float), intent(in ) :: MSL2SWL_C !< Offset between still-water level and mean sea level (m) [positive upward] -! InterpOrder_C, & ! integer(c_int), intent(in ) :: InterpOrder_C !< Interpolation order to use (must be 1 or 2) -! DT_C, & ! real(c_double), intent(in ) :: DT_C !< Timestep used with AD for stepping forward from t to t+dt. Must be constant. -! TMax_C, & ! real(c_double), intent(in ) :: TMax_C !< Maximum time for simulation -! storeHHVel, & ! integer(c_int), intent(in ) :: storeHHVel !< Store hub height time series from IfW -! WrVTK_in, & ! integer(c_int), intent(in ) :: WrVTK_in !< Write VTK outputs [0: none, 1: init only, 2: animation] -! WrVTK_inType, & ! integer(c_int), intent(in ) :: WrVTK_inType !< Write VTK outputs as [1: surface, 2: lines, 3: both] -! WrVTK_inDT, & ! real(c_double), intent(in ) :: WrVTK_inDT !< Timestep between VTK writes -! VTKNacDim_in, & ! real(c_float), intent(in ) :: VTKNacDim_in(6) !< Nacelle dimension passed in for VTK surface rendering [0,y0,z0,Lx,Ly,Lz] (m) -! VTKHubRad_in, & ! real(c_float), intent(in ) :: VTKHubrad_in !< Hub radius for VTK surface rendering -! wrOuts_C, & -! DT_Outs_C, & -! NumChannels_C, & -! OutputChannelNames_C, & -! OutputChannelUnits_C, & -! ErrStat_C, ErrMsg_C & -! ) - - -! ! Input file info -! integer(c_int), intent(in ) :: ADinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] -! type(c_ptr), intent(in ) :: ADinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR -! integer(c_int), intent(in ) :: ADinputFileStringLength_C !< lenght of the input file string -! integer(c_int), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] -! type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR -! integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string -! character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other -! character(kind=c_char), intent(in ) :: OutVTKDir_C(IntfStrLen) !< Directory to put all vtk output -! ! Environmental -! real(c_float), intent(in ) :: gravity_C !< Gravitational acceleration (m/s^2) -! real(c_float), intent(in ) :: defFldDens_C !< Air density (kg/m^3) -! real(c_float), intent(in ) :: defKinVisc_C !< Kinematic viscosity of working fluid (m^2/s) -! real(c_float), intent(in ) :: defSpdSound_C !< Speed of sound in working fluid (m/s) -! real(c_float), intent(in ) :: defPatm_C !< Atmospheric pressure (Pa) [used only for an MHK turbine cavitation check] -! real(c_float), intent(in ) :: defPvap_C !< Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] -! real(c_float), intent(in ) :: WtrDpth_C !< Water depth (m) -! real(c_float), intent(in ) :: MSL2SWL_C !< Offset between still-water level and mean sea level (m) [positive upward] -! ! Interpolation -! integer(c_int), intent(in ) :: InterpOrder_C !< Interpolation order to use (must be 1 or 2) -! ! Time -! real(c_double), intent(in ) :: DT_C !< Timestep used with AD for stepping forward from t to t+dt. Must be constant. -! real(c_double), intent(in ) :: TMax_C !< Maximum time for simulation -! ! Flags -! integer(c_int), intent(in ) :: storeHHVel !< Store hub height time series from IfW -! ! VTK -! integer(c_int), intent(in ) :: WrVTK_in !< Write VTK outputs [0: none, 1: init only, 2: animation] -! integer(c_int), intent(in ) :: WrVTK_inType !< Write VTK outputs as [1: surface, 2: lines, 3: both] -! real(c_double), intent(in ) :: WrVTK_inDT !< Timestep between VTK writes -! real(c_float), intent(in ) :: VTKNacDim_in(6) !< Nacelle dimension passed in for VTK surface rendering [0,y0,z0,Lx,Ly,Lz] (m) -! real(c_float), intent(in ) :: VTKHubrad_in !< Hub radius for VTK surface rendering -! integer(c_int), intent(in ) :: wrOuts_C !< Write ADI output file -! real(c_double), intent(in ) :: DT_Outs_C !< Timestep to write output file from ADI -! ! Output -! integer(c_int), intent( out) :: NumChannels_C !< Number of output channels requested from the input file -! character(kind=c_char), intent( out) :: OutputChannelNames_C(ChanLen*MaxADIOutputs+1) !< NOTE: if MaxADIOutputs is sufficiently large, we may overrun the buffer on the Python side. -! character(kind=c_char), intent( out) :: OutputChannelUnits_C(ChanLen*MaxADIOutputs+1) -! integer(c_int), intent( out) :: ErrStat_C !< Error status -! character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) !< Error message (C_NULL_CHAR terminated) - -! Set compiler flag for Labview -! Cmpl4LV = .TRUE. + TYPE(C_PTR), INTENT(IN ) :: WT_InputFile_C + TYPE(C_PTR), INTENT(IN ) :: MD_InputFile_C + TYPE(C_PTR), INTENT(IN ) :: SS_InputFile_C + TYPE(C_PTR), INTENT(IN ) :: AD_InputFile_C + TYPE(C_PTR), INTENT(IN ) :: IfW_InputFile_C + INTEGER(C_INT), INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + INTEGER(C_INT) :: ErrStat_C2 + CHARACTER(KIND=C_CHAR, LEN=ErrMsgLen_C) :: ErrMsg_C2 + INTEGER(IntKi) :: ErrStat_F2 + CHARACTER(ErrMsgLen) :: ErrMsg_F2 + TYPE(WaveTank_InitInput) :: WT_InitInp + CHARACTER(1024), POINTER :: WT_InputFilePath + + ! The length of these arrays much match what is set in the corresponding C binding modules + CHARACTER(KIND=C_CHAR) :: SS_OutputChannelNames_C(ChanLen*MaxOutPts+1) + CHARACTER(KIND=C_CHAR) :: SS_OutputChannelUnits_C(ChanLen*MaxOutPts+1) + CHARACTER(KIND=C_CHAR) :: MD_OutputChannelNames_C(100000) + CHARACTER(KIND=C_CHAR) :: MD_OutputChannelUnits_C(100000) + CHARACTER(KIND=C_CHAR) :: ADI_OutputChannelNames_C(ChanLen*MaxADIOutputs+1) + CHARACTER(KIND=C_CHAR) :: ADI_OutputChannelUnits_C(ChanLen*MaxADIOutputs+1) + + ! Initialize error handling + ErrStat_C = ErrID_None + ErrMsg_C = " "//C_NULL_CHAR + + CALL C_F_POINTER(WT_InputFile_C, WT_InputFilePath) + CALL ReadInput(WT_InputFilePath, WT_InitInp, ErrStat_F2, ErrMsg_F2) + CALL SetErrStat_F2C(ErrStat_F2, ErrMsg_F2, ErrStat_C, ErrMsg_C) !, 'WaveTank_Init') + IF (ErrStat_C >= AbortErrLev) RETURN + + ! Store to global variable for use in other routines + DT = WT_InitInp%DT + iWT_C = WT_InitInp%iWT_C + NumBlades_C = WT_InitInp%NumBlades_C + NumMeshPts_C = WT_InitInp%NumMeshPts_C + + ! Initialize hub and nacelle position to input HubPos_C and NacPos_C + DO I=1,3 + FloaterPositions(I,:) = WT_InitInp%HubPos_C + NacellePositions(I,:) = WT_InitInp%NacPos_C + END DO + + ! Allocate the blade root and blade mesh arrays since they're based on the number of blades and mesh points + IF (.NOT. ALLOCATED(BladeRootPositions)) THEN + ALLOCATE( BladeRootPositions(3,3*NumBlades_C) ) + ENDIF + IF (.NOT. ALLOCATED(BladeRootVelocities)) THEN + ALLOCATE( BladeRootVelocities(2,6*NumBlades_C) ) + ENDIF + IF (.NOT. ALLOCATED(BladeRootAccelerations)) THEN + ALLOCATE( BladeRootAccelerations(1,6*NumBlades_C) ) + ENDIF + DO I=1,3 + BladeRootPositions(I,:) = WT_InitInp%BldRootPos_C + END DO + BladeRootVelocities = 0.0_C_FLOAT + BladeRootAccelerations = 0.0_C_FLOAT + + IF (.NOT. ALLOCATED(BladeMeshPositions)) THEN + ALLOCATE( BladeMeshPositions(3,3*NumMeshPts_C) ) + ENDIF + + IF (.NOT. ALLOCATED(BladeMeshVelocities)) THEN + ALLOCATE( BladeMeshVelocities(2,6*NumMeshPts_C) ) + ENDIF + + IF (.NOT. ALLOCATED(BladeMeshAccelerations)) THEN + ALLOCATE( BladeMeshAccelerations(1,6*NumMeshPts_C) ) + ENDIF + DO I=1,3 + BladeMeshPositions(I,:) = WT_InitInp%InitMeshPos_C + END DO + BladeMeshVelocities = 0.0_C_FLOAT + BladeMeshAccelerations = 0.0_C_FLOAT + + CALL SeaSt_C_Init( & + SS_InputFile_C, & + WT_InitInp%SS_OutRootName_C, & + WT_InitInp%SS_Gravity_C, & + WT_InitInp%SS_WtrDens_C, & + WT_InitInp%SS_WtrDpth_C, & + WT_InitInp%SS_MSL2SWL_C, & + WT_InitInp%SS_NSteps_C, & + WT_InitInp%SS_TimeInterval_C, & + WT_InitInp%SS_WaveElevSeriesFlag_C, & + WT_InitInp%SS_WrWvKinMod_C, & + SS_NumChannels_C, & + SS_OutputChannelNames_C, & + SS_OutputChannelUnits_C, & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'SeaSt_C_Init') + IF (ErrStat_C >= AbortErrLev) RETURN + + ! Set the SeaState Wave Field pointer onto MoorDyn + CALL WaveTank_SetWaveFieldPointer(ErrStat_C2, ErrMsg_C2) + + CALL MD_C_Init( & + 0, & !< InputFilePassed: 0 for file, 1 for string + MD_InputFile_C, & + IntfStrLen, & !< InputFileStringLength_C + DT, & + WT_InitInp%MD_G_C, & + WT_InitInp%MD_RHO_C, & + WT_InitInp%MD_DEPTH_C, & + WT_InitInp%MD_PtfmInit_C, & + WT_InitInp%MD_InterpOrder_C, & + MD_NumChannels_C, & + MD_OutputChannelNames_C, & + MD_OutputChannelUnits_C, & + ErrStat_C2, & + ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'MD_C_Init') + IF (ErrStat_C >= AbortErrLev) RETURN + + CALL ADI_C_PreInit( & + WT_InitInp%NumTurbines_C, & + WT_InitInp%TransposeDCM, & + WT_InitInp%PointLoadOutput, & + WT_InitInp%ADI_gravity_C, & + WT_InitInp%ADI_defFldDens_C, & + WT_InitInp%ADI_defKinVisc_C, & + WT_InitInp%ADI_defSpdSound_C, & + WT_InitInp%ADI_defPatm_C, & + WT_InitInp%ADI_defPvap_C, & + WT_InitInp%ADI_WtrDpth_C, & + WT_InitInp%ADI_MSL2SWL_C, & + WT_InitInp%MHK, & + WT_InitInp%DebugLevel, & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_PreInit') + IF (ErrStat_C >= AbortErrLev) RETURN + + CALL ADI_C_SetupRotor( & + WT_InitInp%iWT_c, & + WT_InitInp%TurbineIsHAWT_c, & + WT_InitInp%TurbOrigin_C, & + WT_InitInp%HubPos_C, & + WT_InitInp%HubOri_C, & + WT_InitInp%NacPos_C, & + WT_InitInp%NacOri_C, & + WT_InitInp%NumBlades_C, & + WT_InitInp%BldRootPos_C, & + WT_InitInp%BldRootOri_C, & + WT_InitInp%NumMeshPts_C, & + WT_InitInp%InitMeshPos_C, & + WT_InitInp%InitMeshOri_C, & + WT_InitInp%MeshPtToBladeNum_C, & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_SetupRotor') + IF (ErrStat_C >= AbortErrLev) RETURN + + CALL ADI_C_Init( & + 0, & !< ADinputFilePassed; 0 for file, 1 for string + AD_InputFile_C, & !< ADinputFileString_C; Input file as a single string with lines delineated by C_NULL_CHAR + IntfStrLen, & !< ADinputFileStringLength_C; length of the input file string + 0, & !< IfWinputFilePassed; 0 for file, 1 for string + IfW_InputFile_C, & !< IfWinputFileString_C; Input file as a single string with lines delineated by C_NULL_CHAR + IntfStrLen, & !< IfWinputFileStringLength_C; length of the input file string + WT_InitInp%ADI_OutRootName_C, & !< Root name to use for echo files and other + WT_InitInp%ADI_OutVTKDir_C, & !< Directory to put all vtk output + WT_InitInp%ADI_InterpOrder_C, & !< Interpolation order to use (must be 1 or 2) + DT, & !< Timestep used with AD for stepping forward from t to t+dt. Must be constant. + WT_InitInp%ADI_TMax_C, & !< Maximum time for simulation + WT_InitInp%ADI_storeHHVel, & !< Store hub height time series from IfW + WT_InitInp%ADI_WrVTK_in, & !< Write VTK outputs [0: none, 1: init only, 2: animation] + WT_InitInp%ADI_WrVTK_inType, & !< Write VTK outputs as [1: surface, 2: lines, 3: both] + WT_InitInp%ADI_WrVTK_inDT, & !< Timestep between VTK writes + WT_InitInp%ADI_VTKNacDim_in, & !< Nacelle dimension passed in for VTK surface rendering [0,y0,z0,Lx,Ly,Lz] (m) + WT_InitInp%ADI_VTKHubRad_in, & !< Hub radius for VTK surface rendering + WT_InitInp%ADI_wrOuts_C, & + WT_InitInp%ADI_DT_Outs_C, & + ADI_NumChannels_C, & + ADI_OutputChannelNames_C, & + ADI_OutputChannelUnits_C, & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_Init') + IF (ErrStat_C >= AbortErrLev) RETURN END SUBROUTINE WaveTank_Init -! delta_time, & SUBROUTINE WaveTank_CalcOutput( & - frame_number, & + time, & positions_x, & positions_y, & positions_z, & - rotation_matrix, & - loads, & - ErrStat_c, & - ErrMsg_c & + floater_rotation_matrix, & + blade_rotation_matrix, & + MD_Forces_C, & + ADI_MeshFrc_C, & + ADI_HHVel_C, & + md_outputs, & + adi_outputs, & + ErrStat_C, & + ErrMsg_C & ) BIND (C, NAME='WaveTank_CalcOutput') #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: WaveTank_CalcOutput !GCC$ ATTRIBUTES DLLEXPORT :: WaveTank_CalcOutput #endif -IMPLICIT NONE + REAL(C_DOUBLE), INTENT(IN ) :: time + REAL(C_FLOAT), INTENT(IN ) :: positions_x + REAL(C_FLOAT), INTENT(IN ) :: positions_y + REAL(C_FLOAT), INTENT(IN ) :: positions_z + REAL(C_FLOAT), INTENT(IN ) :: floater_rotation_matrix(9) + REAL(C_FLOAT), INTENT(IN ) :: blade_rotation_matrix(NumBlades_C*9) !< Rotation matrix for each blade, (/ 1x9 flat R for blade 1, 1x9 flat R for blade 2 /) + + ! Outputs + REAL(C_FLOAT), INTENT( OUT) :: MD_Forces_C( 6 ) + REAL(C_FLOAT), INTENT( OUT) :: ADI_MeshFrc_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [Fx,Fy,Fz,Mx,My,Mz] -- forces and moments (global) + REAL(C_FLOAT), INTENT( OUT) :: ADI_HHVel_C(3) !< Wind speed array [Vx,Vy,Vz] -- (m/s) (global) + REAL(C_FLOAT), INTENT( OUT) :: md_outputs(MD_NumChannels_C) + REAL(C_FLOAT), INTENT( OUT) :: adi_outputs(ADI_NumChannels_C) + INTEGER(C_INT), INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + INTEGER(C_INT) :: ErrStat_C2 + CHARACTER(KIND=C_CHAR, LEN=ErrMsgLen_C) :: ErrMsg_C2 + REAL(C_FLOAT) :: DeltaS(3) !< Change in position from previous time step + INTEGER :: I, I0, I1 + + ! ! ADI + ! ! SetRotorMotion + REAL(C_FLOAT) :: ADI_HubPos_C( 3 ) !< Hub position + REAL(C_DOUBLE) :: ADI_HubOri_C( 9 ) !< Hub orientation + REAL(C_FLOAT) :: ADI_HubVel_C( 6 ) !< Hub velocity + REAL(C_FLOAT) :: ADI_HubAcc_C( 6 ) !< Hub acceleration + REAL(C_FLOAT) :: ADI_NacPos_C( 3 ) !< Nacelle position + REAL(C_DOUBLE) :: ADI_NacOri_C( 9 ) !< Nacelle orientation + REAL(C_FLOAT) :: ADI_NacVel_C( 6 ) !< Nacelle velocity + REAL(C_FLOAT) :: ADI_NacAcc_C( 6 ) !< Nacelle acceleration + REAL(C_FLOAT) :: ADI_BldRootPos_C( 3*NumBlades_C ) !< Blade root positions + REAL(C_DOUBLE) :: ADI_BldRootOri_C( 9*NumBlades_C ) !< Blade root orientations + REAL(C_FLOAT) :: ADI_BldRootVel_C( 6*NumBlades_C ) !< Blade root velocities + REAL(C_FLOAT) :: ADI_BldRootAcc_C( 6*NumBlades_C ) !< Blade root accelerations + ! Blade mesh nodes + REAL(C_FLOAT) :: ADI_MeshPos_C( 3*NumMeshPts_C ) !< A 3xNumMeshPts_C array [x,y,z] + REAL(C_DOUBLE) :: ADI_MeshOri_C( 9*NumMeshPts_C ) !< A 9xNumMeshPts_C array [r11,r12,r13,r21,r22,r23,r31,r32,r33] + REAL(C_FLOAT) :: ADI_MeshVel_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [x,y,z] + REAL(C_FLOAT) :: ADI_MeshAcc_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [x,y,z] + + ! Initialize error handling + ErrStat_C = ErrID_None + ErrMsg_C = " "//C_NULL_CHAR + + ! Shift the positions and velocities over one index + FloaterPositions(1,:) = FloaterPositions(2,:) + FloaterPositions(2,:) = FloaterPositions(3,:) + NacellePositions(1,:) = NacellePositions(2,:) + NacellePositions(2,:) = NacellePositions(3,:) + BladeRootPositions(1,:) = BladeRootPositions(2,:) + BladeRootPositions(2,:) = BladeRootPositions(3,:) + BladeMeshPositions(1,:) = BladeMeshPositions(2,:) + BladeMeshPositions(2,:) = BladeMeshPositions(3,:) + FloaterVelocities(1,:) = FloaterVelocities(2,:) + NacelleVelocities(1,:) = NacelleVelocities(2,:) + BladeRootVelocities(1,:) = BladeRootVelocities(2,:) + BladeMeshVelocities(1,:) = BladeMeshVelocities(2,:) + + ! Load the new positions + FloaterPositions(3,:) = (/ positions_x, positions_y, positions_z /) + DeltaS = FloaterPositions(3,:) - FloaterPositions(2,:) + NacellePositions(3,:) = NacellePositions(2,:) + DeltaS + + ! Stride + ! Lower bound: (I-1)*3+1 is the first of the three position components for the current blade + ! +1 is because Fortran starts indexing at 1 + ! Upper bound: (I-1)*3+1+2 is the last of the three position components for the current blade + ! +2 is because Fortran includes the last index in the range + DO I=1,NumBlades_C + I0 = (I-1)*3+1 + I1 = (I-1)*3+1+2 + BladeRootPositions(3,I0:I1) = BladeRootPositions(2,I0:I1) + DeltaS + END DO + DO I=1,NumMeshPts_C + I0 = (I-1)*3+1 + I1 = (I-1)*3+1+2 + BladeMeshPositions(3,I0:I1) = BladeMeshPositions(2,I0:I1) + DeltaS + END DO + + ! Calculate velocities and acceleration + FloaterVelocities(1,:) = (/ (FloaterPositions(2,:) - FloaterPositions(1,:)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + FloaterVelocities(2,:) = (/ (FloaterPositions(3,:) - FloaterPositions(2,:)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + FloaterAccelerations(1,:) = (/ (FloaterVelocities(2,:) - FloaterVelocities(1,:)) / REAL(DT, C_FLOAT) /) + + NacelleVelocities(1,:) = (/ (NacellePositions(2,:) - NacellePositions(1,:)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + NacelleVelocities(2,:) = (/ (NacellePositions(3,:) - NacellePositions(2,:)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + NacelleAccelerations(1,:) = (/ (NacelleVelocities(2,:) - NacelleVelocities(1,:)) / REAL(DT, C_FLOAT) /) + + DO I=1,NumBlades_C + I0 = (I-1)*6+1 + I1 = (I-1)*6+1+5 + BladeRootVelocities(1,I0:I1) = (/ (BladeRootPositions(2,(I-1)*3+1:(I-1)*3+1+2) - BladeRootPositions(1,(I-1)*3+1:(I-1)*3+1+2)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + BladeRootVelocities(2,I0:I1) = (/ (BladeRootPositions(3,(I-1)*3+1:(I-1)*3+1+2) - BladeRootPositions(2,(I-1)*3+1:(I-1)*3+1+2)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + BladeRootAccelerations(1,I0:I1) = (BladeRootVelocities(2,I0:I1) - BladeRootVelocities(1,I0:I1)) / REAL(DT, C_FLOAT) + END DO + + DO I=1,NumMeshPts_C + I0 = (I-1)*6+1 + I1 = (I-1)*6+1+5 + BladeMeshVelocities(1,I0:I1) = (/ (BladeMeshPositions(2,(I-1)*3+1:(I-1)*3+1+2) - BladeMeshPositions(1,(I-1)*3+1:(I-1)*3+1+2)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + BladeMeshVelocities(2,I0:I1) = (/ (BladeMeshPositions(3,(I-1)*3+1:(I-1)*3+1+2) - BladeMeshPositions(2,(I-1)*3+1:(I-1)*3+1+2)) / REAL(DT, C_FLOAT), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /) + BladeMeshAccelerations(1,I0:I1) = (BladeMeshVelocities(2,I0:I1) - BladeMeshVelocities(1,I0:I1)) / REAL(DT, C_FLOAT) + END DO + + ! Get loads from MoorDyn + ! NOTE: MD_C_UpdateStates and MD_C_CalcOutput do not use the positions, velocities, and accelerations. + ! They're passed here just for consistency, but we should not let that interface drive + ! the design of this module. + CALL MD_C_UpdateStates( & + time, & + REAL(time + DT, C_DOUBLE), & + (/ FloaterPositions(3,:), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /), & + (/ FloaterVelocities(2,:) /), & + (/ FloaterAccelerations(1,:) /), & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'MD_C_UpdateStates') + IF (ErrStat_C >= AbortErrLev) RETURN + + CALL MD_C_CalcOutput( & + time, & + (/ FloaterPositions(3,:), 0.0_C_FLOAT, 0.0_C_FLOAT, 0.0_C_FLOAT /), & + (/ FloaterVelocities(2,:) /), & + (/ FloaterAccelerations(1,:) /), & + MD_Forces_C, & + md_outputs, & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'MD_C_CalcOutput') + IF (ErrStat_C >= AbortErrLev) RETURN + + ! Get loads from ADI + + ! All components are rigidly connected so they share velocities, accelerations, and orientation + ! Positions are set by the input file geometry and the calling code + ADI_HubPos_C = FloaterPositions(3,:) + ADI_HubOri_C = floater_rotation_matrix + ADI_HubVel_C = FloaterVelocities(2,:) + ADI_HubAcc_C = FloaterAccelerations(1,:) + + ADI_NacPos_C = NacellePositions(3,:) + ADI_NacOri_C = floater_rotation_matrix + ADI_NacVel_C = NacelleVelocities(2,:) + ADI_NacAcc_C = NacelleAccelerations(1,:) + + ADI_BldRootPos_C = BladeRootPositions(3,:) + ADI_BldRootOri_C = blade_rotation_matrix + ADI_BldRootVel_C = BladeRootVelocities(2,:) + ADI_BldRootAcc_C = BladeRootAccelerations(1,:) + + ADI_MeshPos_C = BladeMeshPositions(3,:) + ADI_MeshOri_C = blade_rotation_matrix + ADI_MeshVel_C = BladeMeshVelocities(2,:) + ADI_MeshAcc_C = BladeMeshAccelerations(1,:) + + CALL ADI_C_SetRotorMotion( & + iWT_c, & !< Wind turbine / rotor number + ADI_HubPos_C, & !< Hub position + ADI_HubOri_C, & !< Hub orientation + ADI_HubVel_C, & !< Hub velocity + ADI_HubAcc_C, & !< Hub acceleration + ADI_NacPos_C, & !< Nacelle position + ADI_NacOri_C, & !< Nacelle orientation + ADI_NacVel_C, & !< Nacelle velocity + ADI_NacAcc_C, & !< Nacelle acceleration + ADI_BldRootPos_C, & !< Blade root positions, 3xNumBlades_C + ADI_BldRootOri_C, & !< Blade root orientations, 9xNumBlades_C + ADI_BldRootVel_C, & !< Blade root velocities, 6xNumBlades_C + ADI_BldRootAcc_C, & !< Blade root accelerations, 6xNumBlades_C + NumMeshPts_C, & !< Number of mesh points we are transferring motions to and output loads to + ADI_MeshPos_C, & !< A 3xNumMeshPts_C array [x,y,z] + ADI_MeshOri_C, & !< A 9xNumMeshPts_C array [r11,r12,r13,r21,r22,r23,r31,r32,r33] + ADI_MeshVel_C, & !< A 6xNumMeshPts_C array [x,y,z] + ADI_MeshAcc_C, & !< A 6xNumMeshPts_C array [x,y,z] + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_SetRotorMotion') + IF (ErrStat_C >= AbortErrLev) RETURN + + CALL ADI_C_UpdateStates( & + time, & + REAL(time + DT, C_DOUBLE), & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_UpdateStates') + IF (ErrStat_C >= AbortErrLev) RETURN + + CALL ADI_C_CalcOutput( & + time, & + adi_outputs, & + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_CalcOutput') + IF (ErrStat_C >= AbortErrLev) RETURN + + CALL ADI_C_GetRotorLoads( & + iWT_c, & !< Wind turbine / rotor number + NumMeshPts_C, & !< Number of mesh points we are transfering motions to and output loads to + ADI_MeshFrc_C, & !< A 6xNumMeshPts_C array [Fx,Fy,Fz,Mx,My,Mz] -- forces and moments (global) + ADI_HHVel_C, & !< Wind speed array [Vx,Vy,Vz] -- (m/s) (global) + ErrStat_C2, ErrMsg_C2 & + ) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_GetRotorLoads') + IF (ErrStat_C >= AbortErrLev) RETURN + +END SUBROUTINE + +SUBROUTINE WaveTank_End(ErrStat_C, ErrMsg_C) bind (C, NAME="WaveTank_End") +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: WaveTank_End +!GCC$ ATTRIBUTES DLLEXPORT :: WaveTank_End +#endif + + INTEGER(C_INT), INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + INTEGER(C_INT) :: ErrStat_C2 + CHARACTER(KIND=C_CHAR, LEN=ErrMsgLen_C) :: ErrMsg_C2 -! INTEGER(C_INT) :: delta_time -INTEGER(C_INT) :: frame_number -REAL(C_FLOAT), INTENT(IN ) :: positions_x(N_CAMERA_POINTS) -REAL(C_FLOAT), INTENT(IN ) :: positions_y(N_CAMERA_POINTS) -REAL(C_FLOAT), INTENT(IN ) :: positions_z(N_CAMERA_POINTS) -REAL(C_FLOAT), INTENT(IN ) :: rotation_matrix(9) -REAL(C_FLOAT), INTENT( OUT) :: loads(N_CAMERA_POINTS) -INTEGER(C_INT), INTENT( OUT) :: ErrStat_C -CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + CALL MD_C_END(ErrStat_C, ErrMsg_C) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'MD_C_END') + IF (ErrStat_C >= AbortErrLev) RETURN -INTEGER :: i + CALL SeaSt_C_END(ErrStat_C, ErrMsg_C) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'SeaSt_C_END') + IF (ErrStat_C >= AbortErrLev) RETURN -IF ( MOD(frame_number / load_period, 2) == 0 ) THEN - loads = -1.0 -ELSE - loads = 1.0 -ENDIF + CALL ADI_C_END(ErrStat_C, ErrMsg_C) + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'ADI_C_END') + IF (ErrStat_C >= AbortErrLev) RETURN END SUBROUTINE -SUBROUTINE WaveTank_End() bind (C, NAME="WaveTank_End") +SUBROUTINE WaveTank_SetWaveFieldPointer(ErrStat_C, ErrMsg_C) bind (C, NAME="WaveTank_SetWaveFieldPointer") +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: WaveTank_SetWaveFieldPointer +!GCC$ ATTRIBUTES DLLEXPORT :: WaveTank_SetWaveFieldPointer +#endif + + INTEGER(C_INT), INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + INTEGER(C_INT) :: ErrStat_C2 + CHARACTER(KIND=C_CHAR, LEN=ErrMsgLen_C) :: ErrMsg_C2 + ! Set the SeaState FlowField pointer onto MoorDyn + TYPE(C_PTR) :: WaveFieldPointer + TYPE(SeaSt_WaveFieldType), POINTER :: WaveFieldPointer_F -IMPLICIT NONE + ! Initialize error handling + ErrStat_C = ErrID_None + ErrMsg_C = " "//C_NULL_CHAR + WaveFieldPointer = SeaSt_GetWaveFieldPointer_C() + CALL C_F_POINTER(WaveFieldPointer, WaveFieldPointer_F) + ! Verify that the data in the WaveField pointer has been set + IF (WaveFieldPointer_F%WtrDpth == 0) THEN + ErrStat_C2 = ErrID_Fatal + ErrMsg_C2 = "SeaState WaveFieldPointer is WtrDpth is 0.0, so it it probably not initialized." + CALL SetErrStat_C(ErrStat_C2, ErrMsg_C2, ErrStat_C, ErrMsg_C, 'WaveTank_SetWaveFieldPointer') + RETURN + END IF + + CALL MD_C_SetWaveFieldData(WaveFieldPointer) + +END SUBROUTINE + +SUBROUTINE WaveTank_Sizes(SS_NumOuts, MD_NumOuts, ADI_NumOuts) bind (C, NAME="WaveTank_Sizes") +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: WaveTank_Sizes +!GCC$ ATTRIBUTES DLLEXPORT :: WaveTank_Sizes +#endif + INTEGER(C_INT), INTENT( OUT) :: SS_NumOuts + INTEGER(C_INT), INTENT( OUT) :: MD_NumOuts + INTEGER(C_INT), INTENT( OUT) :: ADI_NumOuts + SS_NumOuts = SS_NumChannels_C + MD_NumOuts = MD_NumChannels_C + ADI_NumOuts = ADI_NumChannels_C END SUBROUTINE -end module WaveTankTesting +END MODULE WaveTankTesting diff --git a/glue-codes/labview/src/libwavetanktestinglib.h b/glue-codes/labview/src/libwavetanktestinglib.h new file mode 100644 index 0000000000..00ce5f13a6 --- /dev/null +++ b/glue-codes/labview/src/libwavetanktestinglib.h @@ -0,0 +1,14 @@ +#ifndef WAVETANKTESTING_H +#define WAVETANKTESTING_H + +#ifdef __cplusplus +extern "C" { +#endif + +void WaveTank_NoOp(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/glue-codes/openfast-cpp/src/OpenFAST.H b/glue-codes/openfast-cpp/src/OpenFAST.H index ab656344da..8b28d086bf 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.H +++ b/glue-codes/openfast-cpp/src/OpenFAST.H @@ -81,7 +81,7 @@ struct turbineDataType { int nBRfsiPtsTwr; //! The mean azimuth at which the loads are blended between AeroDyn and CFD double azBlendMean; - //! The delta azimuth over which the the loads are blended between AeroDyn and CFD + //! The delta azimuth over which the loads are blended between AeroDyn and CFD double azBlendDelta; //! Mean velocity at reference height double velMean; @@ -708,7 +708,7 @@ private: //! Allocate memory for data structures for all turbines on this processor void allocateMemory_preInit(); - //! Allocate more memory for each turbine after intialization/restart + //! Allocate more memory for each turbine after initialization/restart void allocateMemory_postInit(int iTurbLoc); //! Get the nacelle drag coefficient of local turbine number 'iTurbLoc' diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 140b1dec87..b51aebf674 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -90,8 +90,15 @@ void fast::OpenFAST::findRestartFile(int iTurbLoc) { check_nc_error(ierr, "nc_get_vara_double - getting latest time"); tStart = latest_time; - char tmpOutFileRoot[INTERFACE_STRING_LENGTH]; + char *tmpOutFileRoot; + size_t len; + ierr = nc_inq_attlen(ncid, NC_GLOBAL, "out_file_root", &len); + check_nc_error(ierr, "nc_inq_attlen - getting out_file_root length"); + + tmpOutFileRoot = (char*) malloc(len + 1); ierr = nc_get_att_text(ncid, NC_GLOBAL, "out_file_root", tmpOutFileRoot); + check_nc_error(ierr, "nc_get_att_text - getting out_file_root"); + tmpOutFileRoot[len] = '\0'; turbineData[iTurbLoc].outFileRoot.assign(tmpOutFileRoot); ierr = nc_get_att_double(ncid, NC_GLOBAL, "dt_fast", &dtFAST); @@ -115,7 +122,7 @@ void fast::OpenFAST::findRestartFile(int iTurbLoc) { std::cout << "Restarting from time " << latest_time << " at time step " << tstep << " from file name " << turbineData[iTurbLoc].FASTRestartFileName << std::endl ; nc_close(ncid); - + free(tmpOutFileRoot); } void fast::OpenFAST::prepareRestartFile(int iTurbLoc) { @@ -638,7 +645,6 @@ void fast::OpenFAST::init() { tmpRstFileRoot, &AbortErrLev, &turbineData[iTurb].dt, - &turbineData[iTurb].inflowType, &turbineData[iTurb].numBlades, &turbineData[iTurb].numVelPtsBlade, &turbineData[iTurb].numVelPtsTwr, @@ -661,6 +667,7 @@ void fast::OpenFAST::init() { &extld_o_t_FAST[iTurb], &ErrStat, ErrMsg); + checkError(ErrStat, ErrMsg); turbineData[iTurb].inflowType = 0; } diff --git a/glue-codes/openfast/CMakeLists.txt b/glue-codes/openfast/CMakeLists.txt index a742b5972a..08fde158b7 100644 --- a/glue-codes/openfast/CMakeLists.txt +++ b/glue-codes/openfast/CMakeLists.txt @@ -40,5 +40,3 @@ if(BUILD_OPENFAST_LIB_DRIVER) install(TARGETS openfast_lib_driver RUNTIME DESTINATION bin) endif() - - diff --git a/glue-codes/python/Full_10N_Wrench_1.tdms b/glue-codes/python/Full_10N_Wrench_1.tdms new file mode 100644 index 0000000000..b95f096c24 Binary files /dev/null and b/glue-codes/python/Full_10N_Wrench_1.tdms differ diff --git a/glue-codes/python/WaveTankDriver.py b/glue-codes/python/WaveTankDriver.py index 3a8ec07db8..9e3afc6050 100644 --- a/glue-codes/python/WaveTankDriver.py +++ b/glue-codes/python/WaveTankDriver.py @@ -14,8 +14,10 @@ ) import numpy as np from pathlib import Path +from scipy.spatial.transform import Rotation -from OpynFAST.interface_abc import OpenFASTInterfaceType +from pyOpenFAST.interface_abc import OpenFASTInterfaceType +from pyOpenFAST.tdmslib import parse_tdms project_root = '/Users/rmudafor/Development/openfast' library_path = project_root + '/build/glue-codes/labview/libwavetanktestinglib.dylib' @@ -24,11 +26,11 @@ class WaveTankLib(OpenFASTInterfaceType): def __init__(self, library_path: str, input_file_names: dict): """ - _summary_ Args: library_path (str): Path to the compile wavetank interface shared library input_file_names (dict): Map of file names for each included module: + - WT_InputFile - MD_InputFile - SS_InputFile - AD_InputFile @@ -37,162 +39,231 @@ def __init__(self, library_path: str, input_file_names: dict): super().__init__(library_path) self.input_file_names = { - k: create_string_buffer(str(Path(v).absolute() ).encode('utf-8')) - for k,v in input_file_names.items() + k: str(Path(v).absolute()).encode('utf-8') for k,v in input_file_names.items() } self._initialize_routines() - # Create buffers for class data self.ended = False # For error handling at end + self.print_error_level = 1 + + # Create buffers for class data + # These will generally be overwritten by the Fortran code + # self.ss_output_channel_names = [] + # self.ss_output_channel_units = [] + # self.ss_output_values = None - # This buffer for the channel names and units is set arbitrarily large - # to start. Channel name and unit lengths are currently hard - # coded to 20 (this must match ChanLen in NWTC_Base.f90). - # self._channel_names_c = create_string_buffer(20 * 4000 + 1) - # self._channel_units_c = create_string_buffer(20 * 4000 + 1) + self.md_output_channel_names = [] + self.md_output_channel_units = [] + self.md_output_values = None - self.dt = c_double(0) - self.total_time = c_double(0) - self.numTimeSteps = c_int(0) + self.adi_output_channel_names = [] + self.adi_output_channel_units = [] + self.adi_output_values = None def _initialize_routines(self): self.WaveTank_Init.argtypes = [ - POINTER(c_char), # intent(in ) :: MD_InputFile_c(IntfStrLen) - POINTER(c_char), # intent(in ) :: SS_InputFile_c(IntfStrLen) - POINTER(c_char), # intent(in ) :: AD_InputFile_c(IntfStrLen) - POINTER(c_char), # intent(in ) :: IfW_InputFile_c(IntfStrLen) - POINTER(c_int), # intent(in ) :: IfW_InputFile_c(IntfStrLen) - POINTER(c_int), # intent(in ) :: n_camera_points_c + POINTER(c_char_p), # intent(in ) :: WT_InputFile_c(IntfStrLen) + POINTER(c_char_p), # intent(in ) :: MD_InputFile_c(IntfStrLen) + POINTER(c_char_p), # intent(in ) :: SS_InputFile_c(IntfStrLen) + POINTER(c_char_p), # intent(in ) :: AD_InputFile_c(IntfStrLen) + POINTER(c_char_p), # intent(in ) :: IfW_InputFile_c(IntfStrLen) + POINTER(c_int), # intent( out) :: ErrStat_C POINTER(c_char), # intent( out) :: ErrMsg_C(ErrMsgLen_C) ] self.WaveTank_Init.restype = c_int self.WaveTank_CalcOutput.argtypes = [ - POINTER(c_int), # integer(c_int) :: frame_number - POINTER(c_float), # real(c_float), intent(in ) :: positions_x(N_CAMERA_POINTS) - POINTER(c_float), # real(c_float), intent(in ) :: positions_y(N_CAMERA_POINTS) - POINTER(c_float), # real(c_float), intent(in ) :: positions_z(N_CAMERA_POINTS) - POINTER(c_float), # real(c_float), intent(in ) :: rotation_matrix(9) - POINTER(c_float), # real(c_float), intent( out) :: loads(N_CAMERA_POINTS) + POINTER(c_double), # real(c_double) :: time + POINTER(c_float), # real(c_float), intent(in ) :: positions_x + POINTER(c_float), # real(c_float), intent(in ) :: positions_y + POINTER(c_float), # real(c_float), intent(in ) :: positions_z + POINTER(c_float), # real(c_float), intent(in ) :: floater_rotation_matrix(9) + POINTER(c_float), # real(c_float), intent(in ) :: blade_rotation_matrix(9) + POINTER(c_float), # real(c_float), intent( out) :: MD_Forces_C(1,6) + POINTER(c_float), # real(c_float), intent( out) :: ADI_MeshFrc_C(NumMeshPts,6) + POINTER(c_float), # real(c_float), intent( out) :: ADI_HHVel_C(3) + POINTER(c_float), # real(c_float), intent( out) :: md_outputs(MD_NumChannels_C) + POINTER(c_float), # real(c_float), intent( out) :: adi_outputs(ADI_NumChannels_C) POINTER(c_int), # integer(c_int), intent( out) :: ErrStat_C POINTER(c_char), # character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) ] self.WaveTank_CalcOutput.restype = c_int + self.WaveTank_End.argtypes = [ + POINTER(c_int), # integer(c_int), intent( out) :: ErrStat_C + POINTER(c_char), # character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + ] + self.WaveTank_End.restype = c_int + + self.WaveTank_SetWaveFieldPointer.argtypes = [ + POINTER(c_int), # integer(c_int), intent( out) :: ErrStat_C + POINTER(c_char), # character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + ] + self.WaveTank_SetWaveFieldPointer.restype = c_int + + self.WaveTank_Sizes.argtypes = [ + POINTER(c_int), + POINTER(c_int), + POINTER(c_int), + ] + self.WaveTank_Sizes.restype = c_int - def init(self, n_camera_points): + def init(self): _error_status = c_int(0) _error_message = create_string_buffer(self.ERROR_MSG_C_LEN) - # Convert the string into a c_char byte array - # input_string = '\x00'.join(input_string_array) - # input_string = input_string.encode('utf-8') - # input_string_length = len(input_string) - # # Convert the initial positions array into c_float array # init_positions_c = (c_float * 6)(0.0, ) # for i, p in enumerate(platform_init_pos): # init_positions_c[i] = c_float(p) - # self._numChannels = c_int(0) - - # gravity = c_float(9.80665) - # water_density = c_float(1025) - # water_depth = c_float(200) - # msl2swl = c_float(0) - # outrootname = "./seastate.SeaSt".encode('utf-8') - # wave_kinematics_mode = c_int(0) - # n_steps = c_int(801) - # time_interval = c_float(0.125) - # wave_elevation_series_flag = c_int(0) self.WaveTank_Init( - self.input_file_names["MoorDyn"], - self.input_file_names["SeaState"], - self.input_file_names["AeroDyn"], - self.input_file_names["InflowWind"], - byref(c_int(n_camera_points)), - # create_string_buffer(outrootname), - # byref(gravity), - # byref(water_density), - # byref(water_depth), - # byref(msl2swl), - # byref(n_steps), - # byref(time_interval), - # byref(wave_elevation_series_flag), - # byref(wave_kinematics_mode), + c_char_p(self.input_file_names["WaveTank"]), + c_char_p(self.input_file_names["MoorDyn"]), + c_char_p(self.input_file_names["SeaState"]), + c_char_p(self.input_file_names["AeroDyn"]), + c_char_p(self.input_file_names["InflowWind"]), byref(_error_status), _error_message, ) + if self.print_messages(_error_status): + print(f"WaveTank_Init:\n{_error_status.value}:\n{_error_message.value.decode('cp437')}") if self.fatal_error(_error_status): - raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}") + raise RuntimeError(f"Error Status: {_error_status.value}:\n{_error_message.value.decode('cp437')}") + + # self.output_channel_names = [n.decode('UTF-8') for n in _channel_names.value.split()] + # self.output_channel_units = [n.decode('UTF-8') for n in _channel_units.value.split()] + # self.output_values = np.zeros( self.num_outs_c.value, dtype=c_float, order='C' ) def calc_output( self, - frame_number: int, - positions_x: np.ndarray, - positions_y: np.ndarray, - positions_z: np.ndarray, - rotation_matrix: np.ndarray, - loads: np.ndarray, + time: float, + positions_x: float, + positions_y: float, + positions_z: float, + floater_rotation_matrix: np.ndarray, + blade_rotation_matrix: np.ndarray, + md_loads: np.ndarray, + ad_loads: np.ndarray, + hub_height_velocities: np.ndarray, ): _error_status = c_int(0) _error_message = create_string_buffer(self.ERROR_MSG_C_LEN) self.WaveTank_CalcOutput( - byref(c_int(frame_number)), - positions_x.ctypes.data_as(POINTER(c_float)), - positions_y.ctypes.data_as(POINTER(c_float)), - positions_z.ctypes.data_as(POINTER(c_float)), - rotation_matrix.ctypes.data_as(POINTER(c_float)), - loads.ctypes.data_as(POINTER(c_float)), + byref(c_double(time)), + byref(c_float(positions_x)), + byref(c_float(positions_y)), + byref(c_float(positions_z)), + floater_rotation_matrix.ctypes.data_as(POINTER(c_float)), + blade_rotation_matrix.ctypes.data_as(POINTER(c_float)), + md_loads.ctypes.data_as(POINTER(c_float)), + ad_loads.ctypes.data_as(POINTER(c_float)), + hub_height_velocities.ctypes.data_as(POINTER(c_float)), + self.md_output_values.ctypes.data_as(POINTER(c_float)), + self.adi_output_values.ctypes.data_as(POINTER(c_float)), byref(_error_status), _error_message, ) + if self.print_messages(_error_status): + print(f"WaveTank_CalcOutput:\n{_error_status.value}:\n{_error_message.value.decode('cp437')}") if self.fatal_error(_error_status): raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}") - @property - def output_channel_names(self): - if len(self._channel_names.value.split()) == 0: - return [] - output_channel_names = self._channel_names.value.split() - output_channel_names = [n.decode('UTF-8') for n in output_channel_names] - return output_channel_names + def end(self): + _error_status = c_int(0) + _error_message = create_string_buffer(self.ERROR_MSG_C_LEN) - @property - def output_channel_units(self): - if len(self._channel_units.value.split()) == 0: - return [] - output_channel_units = self._channel_units.value.split() - output_channel_units = [n.decode('UTF-8') for n in output_channel_units] - return output_channel_units + self.WaveTank_End( + byref(_error_status), + _error_message, + ) + if self.print_messages(_error_status): + print(f"WaveTank_End:\n{_error_status.value}:\n{_error_message.value.decode('cp437')}") + if self.fatal_error(_error_status): + raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}") + def allocate_outputs(self): + ss_numouts = c_int(0) + md_numouts = c_int(0) + adi_numouts = c_int(0) + self.WaveTank_Sizes( + byref(ss_numouts), + byref(md_numouts), + byref(adi_numouts), + ) + + # self.ss_output_values = np.zeros(ss_numouts.value, dtype=np.float32, order='C') + self.md_output_values = np.zeros(md_numouts.value, dtype=np.float32, order='C') + self.adi_output_values = np.zeros(adi_numouts.value, dtype=np.float32, order='C') + # self.ss_output_channel_names = [b""] * ss_numouts.value + # self.ss_output_channel_units = [b""] * ss_numouts.value + # self.md_output_channel_names = [b""] * md_numouts.value + # self.md_output_channel_units = [b""] * md_numouts.value + # self.adi_output_channel_names = [b""] * adi_numouts.value + # self.adi_output_channel_units = [b""] * adi_numouts.value + + + def print_messages(self, error_status): + return error_status.value >= self.print_error_level if __name__=="__main__": + + floater_motions = parse_tdms("Full_10N_Wrench_1.tdms") + n_timesteps = len(floater_motions["x"]) + wavetanklib = WaveTankLib( library_path, { - "MoorDyn": "/Users/rmudafor/Development/openfast/reg_tests/r-test/modules/moordyn/py_md_5MW_OC4Semi/md_primary.inp", - "SeaState": "/Users/rmudafor/Development/openfast/reg_tests/r-test/modules/seastate/seastate_1/NRELOffshrBsline5MW_OC4DeepCwindSemi_SeaState.dat", - "AeroDyn": "/Users/rmudafor/Development/openfast/reg_tests/r-test/modules/aerodyn/ad_MHK_RM1_Floating/MHK_RM1_Floating_AeroDyn.dat", - "InflowWind": "/Users/rmudafor/Development/openfast/reg_tests/r-test/modules/inflowwind/py_ifw_turbsimff/ifw_primary.inp", + "WaveTank": "/Users/rmudafor/Development/openfast/glue-codes/python/wavetankconfig.in", + "MoorDyn": "/Users/rmudafor/Development/openfast/reg_tests/r-test/glue-codes/openfast/MHK_RM1_Floating/MHK_RM1_Floating_MoorDyn.dat", + "SeaState": "/Users/rmudafor/Development/openfast/reg_tests/r-test/glue-codes/openfast/MHK_RM1_Floating/SeaState.dat", + "AeroDyn": "/Users/rmudafor/Development/openfast/reg_tests/r-test/glue-codes/openfast/MHK_RM1_Floating/MHK_RM1_Floating_AeroDyn.dat", + "InflowWind": "/Users/rmudafor/Development/openfast/reg_tests/r-test/glue-codes/openfast/MHK_RM1_Floating/MHK_RM1_Floating_InflowWind.dat", }, ) - wavetanklib.init(n_camera_points=3) + wavetanklib.init() + + rotation_matrix = np.eye(3, 3, dtype=np.float32) + md_loads = np.zeros((1,6), dtype=np.float32, order='C') + ad_loads = np.zeros((2,6), dtype=np.float32, order='C') + hub_height_velocities = np.zeros((3,1), dtype=np.float32, order='C') + + wavetanklib.allocate_outputs() + + blade_dcm = np.zeros((2*9), dtype=np.float32, order='C') - positions_x = np.zeros(1, dtype=np.float32) - positions_y = np.zeros(1, dtype=np.float32) - positions_z = np.zeros(1, dtype=np.float32) - rotation_matrix = np.zeros(9, dtype=np.float32) - loads = np.zeros(6, dtype=np.float32) + for i in range(n_timesteps): + R = Rotation.from_euler( + "xyz", + ( + floater_motions["phi"][i], # roll + floater_motions["theta"][i], # pitch + floater_motions["psi"][i], # yaw + ) + ) + floater_dcm = R.as_matrix().flatten() + + # Create the rotation matrix for the blades using the loop index as a rotation angle + # The second blade is rotated 180 degrees from the first + blade_dcm[0:9] = Rotation.from_euler("xyz", (np.deg2rad(i), 0.0, 0.0)).as_matrix().flatten() + blade_dcm[9:18] = Rotation.from_euler("xyz", (np.deg2rad(i + 180), 0.0, 0.0)).as_matrix().flatten() - for i in range(50): wavetanklib.calc_output( - frame_number=i, - positions_x=positions_x, - positions_y=positions_y, - positions_z=positions_z, - rotation_matrix=rotation_matrix, - loads=loads, + time=i, + positions_x=floater_motions["x"][i], + positions_y=floater_motions["y"][i], + positions_z=floater_motions["z"][i], + floater_rotation_matrix=floater_dcm, + blade_rotation_matrix=blade_dcm, + md_loads=md_loads, + ad_loads=ad_loads, + hub_height_velocities=hub_height_velocities ) + # print(hub_height_velocities) + + # print(wavetanklib.md_output_values) + # print(wavetanklib.md_output_values) + + wavetanklib.end() diff --git a/glue-codes/python/pyOpenFAST/tdmslib.py b/glue-codes/python/pyOpenFAST/tdmslib.py new file mode 100644 index 0000000000..5758ef21ea --- /dev/null +++ b/glue-codes/python/pyOpenFAST/tdmslib.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 5 11:26:52 2024 + +@author: schamot + +Description: + Code takes a .tdms file path as input and outputs the data as a dictionary. + + Parameters + ---------- + path : str + path to the .tdms file. + + Returns + ------- + pyDict : dict + Python dictionary of the tdms file. + +""" + +import nptdms + +def parse_tdms(filename: str): + output = TdmsToDict(filename)["Winch System"] + x = output["x"] + y = output["y"] + z = output["z"] + phi = output["phi"] + theta = output["theta"] + psi = output["psi"] + return { + "x": x, + "y": y, + "z": z, + "phi": phi, + "theta": theta, + "psi": psi, + } + +def TdmsToDict(path): + ''' + Code takes a .tdms file path as input and outputs the data as a dictionary. + + Parameters + ---------- + path : str + path to the .tdms file. + + Returns + ------- + pyDict : dict + Python dictionary of the tdms file. + + ''' + # open/read the tdms file + tdms_file = nptdms.TdmsFile.read(path) + + # Set up python dictionary + pyDict = {} + # Get group names + for group in tdms_file.groups(): + #print(f'''Group: {group.name}''') + # Create group dictionary key + pyDict[group.name] = {} + # Get channel names per group + for channel in group.channels(): + #print(f'''\tChannel: {channel.name}''') + pyDict[group.name][channel.name] = channel[:] + # if the data has properties add them + if channel.properties != {}: + pyDict[group.name][channel.name + "_properties"] = channel.properties + + return pyDict + +if __name__ == "__main__": + parse_tdms("Full_10N_Wrench_1.tdms") diff --git a/glue-codes/python/pyproject.toml b/glue-codes/python/pyproject.toml index 8c3e15e83c..6fcc2391e7 100644 --- a/glue-codes/python/pyproject.toml +++ b/glue-codes/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pyOpenFAST" -version = "0.1" +version = "4.1.0" description = "Python interface to OpenFAST FAST Library and physics modules." readme = "README.md" requires-python = ">=3.9" diff --git a/glue-codes/python/wavetankconfig.in b/glue-codes/python/wavetankconfig.in new file mode 100644 index 0000000000..faa90e8a39 --- /dev/null +++ b/glue-codes/python/wavetankconfig.in @@ -0,0 +1,58 @@ +! ----------------- Init --------------- +0.1 DT, time step +! --------------- SeaState ------------- +seastate SS_OutRootName_C +9.80665 SS_Gravity_C +1025 SS_WtrDens_C +200.0 SS_WtrDpth_C +0.0 SS_MSL2SWL_C +801 SS_NSteps_C +0.125 SS_TimeInterval_C +0 SS_WaveElevSeriesFlag_C +0 SS_WrWvKinMod_C +! --------------- MoorDyn ------------- +9.80665 MD_G_C +1025 MD_RHO_C +200 MD_DEPTH_C +0.0 0.0 0.0 0.0 0.0 0.0 MD_PtfmInit_C +1 MD_InterpOrder_C +! ------------------ ADI -------------- +1 NumTurbines_C +1 TransposeDCM +1 PointLoadOutput +9.80655 ADI_gravity_C +1025 ADI_defFldDens_C +1.06E-06 ADI_defKinVisc_C +1500 ADI_defSpdSound_C +101325 ADI_defPatm_C +2500 ADI_defPvap_C +50 ADI_WtrDpth_C +0.0 ADI_MSL2SWL_C +2 MHK +0 DebugLevel +1 iWT_c +1 TurbineIsHAWT_c +0.0 0.0 -24.0 TurbOrigin_C +-10.0 0.0 -24.0 HubPos_C +1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 HubOri_C +0.0 0.0 -24.0 NacPos_C +1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 NacOri_C +2 NumBlades_C +-10.0 0.0 -24.0 -10.0 0.0 -24.0 BldRootPos_C +1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 -1.0 BldRootOri_C +2 NumMeshPts_C +-10.0 0.0 -24.0 -10.0 0.0 -24.0 InitMeshPos_C +1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 -1.0 InitMeshOri_C +1 2 MeshPtToBladeNum_C +adi ADI_OutRootName_C +vtk ADI_OutVTKDir_C +2 ADI_InterpOrder_C +60.0 ADI_TMax_C +1 ADI_storeHHVel +2 ADI_WrVTK_in +2 ADI_WrVTK_inType +0.01 ADI_WrVTK_inDT +0.0 0.0 0.0 0.0 0.0 0.0 ADI_VTKNacDim_in +12.0 ADI_VTKHubrad_in +1 ADI_wrOuts_C +0.1 ADI_DT_Outs_C \ No newline at end of file diff --git a/modules/aerodyn/src/AeroDyn_Driver.f90 b/modules/aerodyn/src/AeroDyn_Driver.f90 index 076f0a4bcc..63b9eaef79 100644 --- a/modules/aerodyn/src/AeroDyn_Driver.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver.f90 @@ -26,8 +26,8 @@ program AeroDyn_Driver ! Program variables REAL(ReKi) :: PrevClockTime ! Clock time at start of simulation in seconds [(s)] REAL(ReKi) :: UsrTime1 ! User CPU time for simulation initialization [(s)] - REAL(ReKi) :: UsrTime2 ! User CPU time for simulation (without intialization) [(s)] - INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime ! Start time of simulation (including intialization) [-] + REAL(ReKi) :: UsrTime2 ! User CPU time for simulation (without initialization) [(s)] + INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime ! Start time of simulation (including initialization) [-] INTEGER(IntKi) , DIMENSION(1:8) :: SimStrtTime ! Start time of simulation (after initialization) [-] REAL(DbKi) :: t_global ! global-loop time marker REAL(DbKi) :: t_final ! global-loop time marker diff --git a/modules/aerodyn/src/AeroDyn_Inflow.f90 b/modules/aerodyn/src/AeroDyn_Inflow.f90 index dc230ffe53..62ff05d01d 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow.f90 @@ -393,6 +393,11 @@ subroutine ADI_InitInflowWind(Root, i_IW, u_AD, o_AD, IW, dt, InitOutData, errSt ! is used until after AD_Init below). InitInData%BoxExceedAllow = .true. InitInData%OutputAccel = i_IW%OutputAccel + + !bjj: what about these initialization inputs? + ! InitInData%HubPosition + ! InitInData%RadAvg + CALL InflowWind_Init( InitInData, IW%u, IW%p, & IW%x, IW%xd, IW%z, IW%OtherSt, & IW%y, IW%m, dt, InitOutData, errStat2, errMsg2 ) diff --git a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 index b3f9cd25ff..2fc61e558c 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 @@ -2115,7 +2115,7 @@ end subroutine ADI_C_GetDiskAvgVel !=================================================================================================================================== !> This routine is operating on module level data. Error handling here in case checks added -!! NOTE: the OriginInit is not included in the data passed in and must be added to the the position info here +!! NOTE: the OriginInit is not included in the data passed in and must be added to the position info here subroutine Set_MotionMesh(iWT, ErrStat3, ErrMsg3) integer(IntKi), intent(in ) :: iWT !< current rotor/turbine integer(IntKi), intent( out) :: ErrStat3 @@ -2143,7 +2143,7 @@ end subroutine Set_MotionMesh !> Map the motion of the intermediate input mesh over to the input meshes !! This routine is operating on module level data, hence few inputs -!! NOTE: the OriginInit is not included in the data passed in and must be added to the the position info here +!! NOTE: the OriginInit is not included in the data passed in and must be added to the position info here subroutine AD_SetInputMotion( iWT, u_local, & HubPos_C, HubOri_C, HubVel_C, HubAcc_C, & NacPos_C, NacOri_C, NacVel_C, NacAcc_C, & diff --git a/modules/aerodyn/src/AirfoilInfo.f90 b/modules/aerodyn/src/AirfoilInfo.f90 index 55f0d5d2a4..b00886b7da 100644 --- a/modules/aerodyn/src/AirfoilInfo.f90 +++ b/modules/aerodyn/src/AirfoilInfo.f90 @@ -1391,8 +1391,8 @@ SUBROUTINE ComputeUA360_AttachedFlow(p, ColUAf, cn_cl, iLower, iUpper) !------------------------------------------------ call Compute_iLoweriUpper(p, iLower, iUpper) - p%UA_BL%alphaLower = p%alpha(iLower) ! note we are overwritting values here to make them consistent in the linear equation - p%UA_BL%alphaUpper = p%alpha(iUpper) ! note we are overwritting values here to make them consistent in the linear equation + p%UA_BL%alphaLower = p%alpha(iLower) ! note we are overwriting values here to make them consistent in the linear equation + p%UA_BL%alphaUpper = p%alpha(iUpper) ! note we are overwriting values here to make them consistent in the linear equation p%UA_BL%c_alphaLower = cn_cl(iLower) ! for vortex calculations (x5, HGMV model) p%UA_BL%c_alphaUpper = cn_cl(iUpper) ! for vortex calculations (x5, HGMV model) diff --git a/modules/aerodyn/src/DBEMT.f90 b/modules/aerodyn/src/DBEMT.f90 index 4f5a2d6bd8..add09cedc5 100644 --- a/modules/aerodyn/src/DBEMT.f90 +++ b/modules/aerodyn/src/DBEMT.f90 @@ -844,7 +844,7 @@ SUBROUTINE DBEMT_ABM4( i, j, t, n, u, utimes, p, x, OtherState, m, ErrStat, ErrM x_in = x%element(i,j) - ! predict: (note that we are overwritting x%element(i,j)%vind and x%element(i,j)%vind_1 here): + ! predict: (note that we are overwriting x%element(i,j)%vind and x%element(i,j)%vind_1 here): CALL DBEMT_AB4( i, j, t, n, u, utimes, p, x, OtherState, m, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) RETURN diff --git a/modules/aerodyn/src/FVW.f90 b/modules/aerodyn/src/FVW.f90 index 2c55f4dc27..5b519f14c8 100644 --- a/modules/aerodyn/src/FVW.f90 +++ b/modules/aerodyn/src/FVW.f90 @@ -480,7 +480,7 @@ subroutine FVW_FinalWrite(u, p, x, z, m, ErrStat, ErrMsg) ErrMsg = "" ! Place any last minute operations or calculations here: if (p%WrVTK>0 .and. m%VTKstep= AbortErrLev ) RETURN diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index aba69d29c6..f8b4b5d791 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -909,9 +909,7 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO IfW_InitInp%RootName = TRIM(p%OutFileRoot)//'.IfW' IfW_InitInp%FilePassingMethod = 0_IntKi ! Read IfW input file from disk IfW_InitInp%InputFileName = InitInp%InputFileData%InflowFile - IfW_InitInp%lidar%Tmax = 0.0_ReKi - IfW_InitInp%lidar%HubPosition = 0.0_ReKi - IfW_InitInp%lidar%SensorType = SensorType_None + IfW_InitInp%HubPosition = 0.0_ReKi IfW_InitInp%Use4Dext = .false. IfW_InitInp%MHK = MHK_None IfW_InitInp%WtrDpth = 0.0_ReKi diff --git a/modules/beamdyn/src/BeamDyn.f90 b/modules/beamdyn/src/BeamDyn.f90 index 6568785970..ab3564d5fb 100644 --- a/modules/beamdyn/src/BeamDyn.f90 +++ b/modules/beamdyn/src/BeamDyn.f90 @@ -1746,6 +1746,27 @@ subroutine Init_MiscVars( p, u, y, m, ErrStat, ErrMsg ) CALL BD_CopyInput(u, m%u2, MESH_NEWCOPY, ErrStat2, ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! compute mapping of applied distributed loads to the root location + ! NOTE: PtLoads are not handled at present. See comments in BeamDyn_IO.f90 for changes required. + if (p%CompAppliedLdAtRoot .and. p%BldMotionNodeLoc == BD_MESH_QP) then + ! create point mesh at root (cousin of rootmotion) + CALL MeshCopy( SrcMesh = u%RootMotion & + , DestMesh = m%LoadsAtRoot & + , CtrlCode = MESH_COUSIN & + , IOS = COMPONENT_OUTPUT & + , Force = .TRUE. & + , Moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat>=AbortErrLev) RETURN + + ! mapping of distributed loads to LoadsAtRoot + CALL MeshMapCreate( u%DistrLoad, m%LoadsAtRoot, m%Map_u_DistrLoad_to_R, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + m%LoadsAtRoot%remapFlag = .false. + + endif end subroutine Init_MiscVars !----------------------------------------------------------------------------------------------------------------------------------- @@ -2282,7 +2303,7 @@ SUBROUTINE BD_QuadraturePointDataAt0( p ) DO nelem = 1,p%elem_total DO idx_qp = 1,p%nqp - !> ### Calculate the the initial displacement fields in an element + !> ### Calculate the initial displacement fields in an element !! Initial displacement field \n !! \f$ \underline{u_0}\left( \xi \right) = !! \sum_{k=1}^{p+1} h^k\left( \xi \right) \underline{\hat{u}_0}^k @@ -2370,7 +2391,7 @@ SUBROUTINE BD_DisplacementQP( nelem, p, x, m ) INTEGER(IntKi) :: idx_qp !< index to the current quadrature point INTEGER(IntKi) :: elem_start !< Node point of first node in current element - !> ### Calculate the the displacement fields in an element + !> ### Calculate the displacement fields in an element !! Using equations (27) and (28) \n !! \f$ \underline{u}\left( \xi \right) = !! \sum_{i=1}^{p+1} h^i\left( \xi \right) \underline{\hat{u}}^i diff --git a/modules/beamdyn/src/BeamDyn_IO.f90 b/modules/beamdyn/src/BeamDyn_IO.f90 index ee278ca399..5840b4b160 100644 --- a/modules/beamdyn/src/BeamDyn_IO.f90 +++ b/modules/beamdyn/src/BeamDyn_IO.f90 @@ -41,7 +41,7 @@ MODULE BeamDyn_IO ! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these ! lines should be modified in the Matlab script and/or Excel worksheet as necessary. ! =================================================================================================== -! This code was generated by Write_ChckOutLst.m at 29-Sep-2015 10:23:41. +! This code was generated by Write_ChckOutLst.m at 08-May-2025 15:51:30. ! Indices for computing output channels: @@ -51,387 +51,403 @@ MODULE BeamDyn_IO ! Time: - INTEGER(IntKi), PARAMETER :: Time = 0 + INTEGER(IntKi), PARAMETER :: Time = 0 ! Reaction Loads: - INTEGER(IntKi), PARAMETER :: RootFxr = 1 - INTEGER(IntKi), PARAMETER :: RootFyr = 2 - INTEGER(IntKi), PARAMETER :: RootFzr = 3 - INTEGER(IntKi), PARAMETER :: RootMxr = 4 - INTEGER(IntKi), PARAMETER :: RootMyr = 5 - INTEGER(IntKi), PARAMETER :: RootMzr = 6 + INTEGER(IntKi), PARAMETER :: RootFxr = 1 + INTEGER(IntKi), PARAMETER :: RootFyr = 2 + INTEGER(IntKi), PARAMETER :: RootFzr = 3 + INTEGER(IntKi), PARAMETER :: RootMxr = 4 + INTEGER(IntKi), PARAMETER :: RootMyr = 5 + INTEGER(IntKi), PARAMETER :: RootMzr = 6 ! Tip Motions: - INTEGER(IntKi), PARAMETER :: TipTDxr = 7 - INTEGER(IntKi), PARAMETER :: TipTDyr = 8 - INTEGER(IntKi), PARAMETER :: TipTDzr = 9 - INTEGER(IntKi), PARAMETER :: TipRDxr = 10 - INTEGER(IntKi), PARAMETER :: TipRDyr = 11 - INTEGER(IntKi), PARAMETER :: TipRDzr = 12 - INTEGER(IntKi), PARAMETER :: TipTVXg = 13 - INTEGER(IntKi), PARAMETER :: TipTVYg = 14 - INTEGER(IntKi), PARAMETER :: TipTVZg = 15 - INTEGER(IntKi), PARAMETER :: TipRVXg = 16 - INTEGER(IntKi), PARAMETER :: TipRVYg = 17 - INTEGER(IntKi), PARAMETER :: TipRVZg = 18 - INTEGER(IntKi), PARAMETER :: TipTAXl = 19 - INTEGER(IntKi), PARAMETER :: TipTAYl = 20 - INTEGER(IntKi), PARAMETER :: TipTAZl = 21 - INTEGER(IntKi), PARAMETER :: TipRAXl = 22 - INTEGER(IntKi), PARAMETER :: TipRAYl = 23 - INTEGER(IntKi), PARAMETER :: TipRAZl = 24 + INTEGER(IntKi), PARAMETER :: TipTDxr = 7 + INTEGER(IntKi), PARAMETER :: TipTDyr = 8 + INTEGER(IntKi), PARAMETER :: TipTDzr = 9 + INTEGER(IntKi), PARAMETER :: TipRDxr = 10 + INTEGER(IntKi), PARAMETER :: TipRDyr = 11 + INTEGER(IntKi), PARAMETER :: TipRDzr = 12 + INTEGER(IntKi), PARAMETER :: TipTVXg = 13 + INTEGER(IntKi), PARAMETER :: TipTVYg = 14 + INTEGER(IntKi), PARAMETER :: TipTVZg = 15 + INTEGER(IntKi), PARAMETER :: TipRVXg = 16 + INTEGER(IntKi), PARAMETER :: TipRVYg = 17 + INTEGER(IntKi), PARAMETER :: TipRVZg = 18 + INTEGER(IntKi), PARAMETER :: TipTAXl = 19 + INTEGER(IntKi), PARAMETER :: TipTAYl = 20 + INTEGER(IntKi), PARAMETER :: TipTAZl = 21 + INTEGER(IntKi), PARAMETER :: TipRAXl = 22 + INTEGER(IntKi), PARAMETER :: TipRAYl = 23 + INTEGER(IntKi), PARAMETER :: TipRAZl = 24 ! Sectional Loads: - INTEGER(IntKi), PARAMETER :: N1Fxl = 25 - INTEGER(IntKi), PARAMETER :: N1Fyl = 26 - INTEGER(IntKi), PARAMETER :: N1Fzl = 27 - INTEGER(IntKi), PARAMETER :: N2Fxl = 28 - INTEGER(IntKi), PARAMETER :: N2Fyl = 29 - INTEGER(IntKi), PARAMETER :: N2Fzl = 30 - INTEGER(IntKi), PARAMETER :: N3Fxl = 31 - INTEGER(IntKi), PARAMETER :: N3Fyl = 32 - INTEGER(IntKi), PARAMETER :: N3Fzl = 33 - INTEGER(IntKi), PARAMETER :: N4Fxl = 34 - INTEGER(IntKi), PARAMETER :: N4Fyl = 35 - INTEGER(IntKi), PARAMETER :: N4Fzl = 36 - INTEGER(IntKi), PARAMETER :: N5Fxl = 37 - INTEGER(IntKi), PARAMETER :: N5Fyl = 38 - INTEGER(IntKi), PARAMETER :: N5Fzl = 39 - INTEGER(IntKi), PARAMETER :: N6Fxl = 40 - INTEGER(IntKi), PARAMETER :: N6Fyl = 41 - INTEGER(IntKi), PARAMETER :: N6Fzl = 42 - INTEGER(IntKi), PARAMETER :: N7Fxl = 43 - INTEGER(IntKi), PARAMETER :: N7Fyl = 44 - INTEGER(IntKi), PARAMETER :: N7Fzl = 45 - INTEGER(IntKi), PARAMETER :: N8Fxl = 46 - INTEGER(IntKi), PARAMETER :: N8Fyl = 47 - INTEGER(IntKi), PARAMETER :: N8Fzl = 48 - INTEGER(IntKi), PARAMETER :: N9Fxl = 49 - INTEGER(IntKi), PARAMETER :: N9Fyl = 50 - INTEGER(IntKi), PARAMETER :: N9Fzl = 51 - INTEGER(IntKi), PARAMETER :: N1Mxl = 52 - INTEGER(IntKi), PARAMETER :: N1Myl = 53 - INTEGER(IntKi), PARAMETER :: N1Mzl = 54 - INTEGER(IntKi), PARAMETER :: N2Mxl = 55 - INTEGER(IntKi), PARAMETER :: N2Myl = 56 - INTEGER(IntKi), PARAMETER :: N2Mzl = 57 - INTEGER(IntKi), PARAMETER :: N3Mxl = 58 - INTEGER(IntKi), PARAMETER :: N3Myl = 59 - INTEGER(IntKi), PARAMETER :: N3Mzl = 60 - INTEGER(IntKi), PARAMETER :: N4Mxl = 61 - INTEGER(IntKi), PARAMETER :: N4Myl = 62 - INTEGER(IntKi), PARAMETER :: N4Mzl = 63 - INTEGER(IntKi), PARAMETER :: N5Mxl = 64 - INTEGER(IntKi), PARAMETER :: N5Myl = 65 - INTEGER(IntKi), PARAMETER :: N5Mzl = 66 - INTEGER(IntKi), PARAMETER :: N6Mxl = 67 - INTEGER(IntKi), PARAMETER :: N6Myl = 68 - INTEGER(IntKi), PARAMETER :: N6Mzl = 69 - INTEGER(IntKi), PARAMETER :: N7Mxl = 70 - INTEGER(IntKi), PARAMETER :: N7Myl = 71 - INTEGER(IntKi), PARAMETER :: N7Mzl = 72 - INTEGER(IntKi), PARAMETER :: N8Mxl = 73 - INTEGER(IntKi), PARAMETER :: N8Myl = 74 - INTEGER(IntKi), PARAMETER :: N8Mzl = 75 - INTEGER(IntKi), PARAMETER :: N9Mxl = 76 - INTEGER(IntKi), PARAMETER :: N9Myl = 77 - INTEGER(IntKi), PARAMETER :: N9Mzl = 78 + INTEGER(IntKi), PARAMETER :: N1Fxl = 25 + INTEGER(IntKi), PARAMETER :: N1Fyl = 26 + INTEGER(IntKi), PARAMETER :: N1Fzl = 27 + INTEGER(IntKi), PARAMETER :: N2Fxl = 28 + INTEGER(IntKi), PARAMETER :: N2Fyl = 29 + INTEGER(IntKi), PARAMETER :: N2Fzl = 30 + INTEGER(IntKi), PARAMETER :: N3Fxl = 31 + INTEGER(IntKi), PARAMETER :: N3Fyl = 32 + INTEGER(IntKi), PARAMETER :: N3Fzl = 33 + INTEGER(IntKi), PARAMETER :: N4Fxl = 34 + INTEGER(IntKi), PARAMETER :: N4Fyl = 35 + INTEGER(IntKi), PARAMETER :: N4Fzl = 36 + INTEGER(IntKi), PARAMETER :: N5Fxl = 37 + INTEGER(IntKi), PARAMETER :: N5Fyl = 38 + INTEGER(IntKi), PARAMETER :: N5Fzl = 39 + INTEGER(IntKi), PARAMETER :: N6Fxl = 40 + INTEGER(IntKi), PARAMETER :: N6Fyl = 41 + INTEGER(IntKi), PARAMETER :: N6Fzl = 42 + INTEGER(IntKi), PARAMETER :: N7Fxl = 43 + INTEGER(IntKi), PARAMETER :: N7Fyl = 44 + INTEGER(IntKi), PARAMETER :: N7Fzl = 45 + INTEGER(IntKi), PARAMETER :: N8Fxl = 46 + INTEGER(IntKi), PARAMETER :: N8Fyl = 47 + INTEGER(IntKi), PARAMETER :: N8Fzl = 48 + INTEGER(IntKi), PARAMETER :: N9Fxl = 49 + INTEGER(IntKi), PARAMETER :: N9Fyl = 50 + INTEGER(IntKi), PARAMETER :: N9Fzl = 51 + INTEGER(IntKi), PARAMETER :: N1Mxl = 52 + INTEGER(IntKi), PARAMETER :: N1Myl = 53 + INTEGER(IntKi), PARAMETER :: N1Mzl = 54 + INTEGER(IntKi), PARAMETER :: N2Mxl = 55 + INTEGER(IntKi), PARAMETER :: N2Myl = 56 + INTEGER(IntKi), PARAMETER :: N2Mzl = 57 + INTEGER(IntKi), PARAMETER :: N3Mxl = 58 + INTEGER(IntKi), PARAMETER :: N3Myl = 59 + INTEGER(IntKi), PARAMETER :: N3Mzl = 60 + INTEGER(IntKi), PARAMETER :: N4Mxl = 61 + INTEGER(IntKi), PARAMETER :: N4Myl = 62 + INTEGER(IntKi), PARAMETER :: N4Mzl = 63 + INTEGER(IntKi), PARAMETER :: N5Mxl = 64 + INTEGER(IntKi), PARAMETER :: N5Myl = 65 + INTEGER(IntKi), PARAMETER :: N5Mzl = 66 + INTEGER(IntKi), PARAMETER :: N6Mxl = 67 + INTEGER(IntKi), PARAMETER :: N6Myl = 68 + INTEGER(IntKi), PARAMETER :: N6Mzl = 69 + INTEGER(IntKi), PARAMETER :: N7Mxl = 70 + INTEGER(IntKi), PARAMETER :: N7Myl = 71 + INTEGER(IntKi), PARAMETER :: N7Mzl = 72 + INTEGER(IntKi), PARAMETER :: N8Mxl = 73 + INTEGER(IntKi), PARAMETER :: N8Myl = 74 + INTEGER(IntKi), PARAMETER :: N8Mzl = 75 + INTEGER(IntKi), PARAMETER :: N9Mxl = 76 + INTEGER(IntKi), PARAMETER :: N9Myl = 77 + INTEGER(IntKi), PARAMETER :: N9Mzl = 78 ! Sectional Motions: - INTEGER(IntKi), PARAMETER :: N1TDxr = 79 - INTEGER(IntKi), PARAMETER :: N1TDyr = 80 - INTEGER(IntKi), PARAMETER :: N1TDzr = 81 - INTEGER(IntKi), PARAMETER :: N2TDxr = 82 - INTEGER(IntKi), PARAMETER :: N2TDyr = 83 - INTEGER(IntKi), PARAMETER :: N2TDzr = 84 - INTEGER(IntKi), PARAMETER :: N3TDxr = 85 - INTEGER(IntKi), PARAMETER :: N3TDyr = 86 - INTEGER(IntKi), PARAMETER :: N3TDzr = 87 - INTEGER(IntKi), PARAMETER :: N4TDxr = 88 - INTEGER(IntKi), PARAMETER :: N4TDyr = 89 - INTEGER(IntKi), PARAMETER :: N4TDzr = 90 - INTEGER(IntKi), PARAMETER :: N5TDxr = 91 - INTEGER(IntKi), PARAMETER :: N5TDyr = 92 - INTEGER(IntKi), PARAMETER :: N5TDzr = 93 - INTEGER(IntKi), PARAMETER :: N6TDxr = 94 - INTEGER(IntKi), PARAMETER :: N6TDyr = 95 - INTEGER(IntKi), PARAMETER :: N6TDzr = 96 - INTEGER(IntKi), PARAMETER :: N7TDxr = 97 - INTEGER(IntKi), PARAMETER :: N7TDyr = 98 - INTEGER(IntKi), PARAMETER :: N7TDzr = 99 - INTEGER(IntKi), PARAMETER :: N8TDxr = 100 - INTEGER(IntKi), PARAMETER :: N8TDyr = 101 - INTEGER(IntKi), PARAMETER :: N8TDzr = 102 - INTEGER(IntKi), PARAMETER :: N9TDxr = 103 - INTEGER(IntKi), PARAMETER :: N9TDyr = 104 - INTEGER(IntKi), PARAMETER :: N9TDzr = 105 - INTEGER(IntKi), PARAMETER :: N1RDxr = 106 - INTEGER(IntKi), PARAMETER :: N1RDyr = 107 - INTEGER(IntKi), PARAMETER :: N1RDzr = 108 - INTEGER(IntKi), PARAMETER :: N2RDxr = 109 - INTEGER(IntKi), PARAMETER :: N2RDyr = 110 - INTEGER(IntKi), PARAMETER :: N2RDzr = 111 - INTEGER(IntKi), PARAMETER :: N3RDxr = 112 - INTEGER(IntKi), PARAMETER :: N3RDyr = 113 - INTEGER(IntKi), PARAMETER :: N3RDzr = 114 - INTEGER(IntKi), PARAMETER :: N4RDxr = 115 - INTEGER(IntKi), PARAMETER :: N4RDyr = 116 - INTEGER(IntKi), PARAMETER :: N4RDzr = 117 - INTEGER(IntKi), PARAMETER :: N5RDxr = 118 - INTEGER(IntKi), PARAMETER :: N5RDyr = 119 - INTEGER(IntKi), PARAMETER :: N5RDzr = 120 - INTEGER(IntKi), PARAMETER :: N6RDxr = 121 - INTEGER(IntKi), PARAMETER :: N6RDyr = 122 - INTEGER(IntKi), PARAMETER :: N6RDzr = 123 - INTEGER(IntKi), PARAMETER :: N7RDxr = 124 - INTEGER(IntKi), PARAMETER :: N7RDyr = 125 - INTEGER(IntKi), PARAMETER :: N7RDzr = 126 - INTEGER(IntKi), PARAMETER :: N8RDxr = 127 - INTEGER(IntKi), PARAMETER :: N8RDyr = 128 - INTEGER(IntKi), PARAMETER :: N8RDzr = 129 - INTEGER(IntKi), PARAMETER :: N9RDxr = 130 - INTEGER(IntKi), PARAMETER :: N9RDyr = 131 - INTEGER(IntKi), PARAMETER :: N9RDzr = 132 - INTEGER(IntKi), PARAMETER :: N1TVXg = 133 - INTEGER(IntKi), PARAMETER :: N1TVYg = 134 - INTEGER(IntKi), PARAMETER :: N1TVZg = 135 - INTEGER(IntKi), PARAMETER :: N2TVXg = 136 - INTEGER(IntKi), PARAMETER :: N2TVYg = 137 - INTEGER(IntKi), PARAMETER :: N2TVZg = 138 - INTEGER(IntKi), PARAMETER :: N3TVXg = 139 - INTEGER(IntKi), PARAMETER :: N3TVYg = 140 - INTEGER(IntKi), PARAMETER :: N3TVZg = 141 - INTEGER(IntKi), PARAMETER :: N4TVXg = 142 - INTEGER(IntKi), PARAMETER :: N4TVYg = 143 - INTEGER(IntKi), PARAMETER :: N4TVZg = 144 - INTEGER(IntKi), PARAMETER :: N5TVXg = 145 - INTEGER(IntKi), PARAMETER :: N5TVYg = 146 - INTEGER(IntKi), PARAMETER :: N5TVZg = 147 - INTEGER(IntKi), PARAMETER :: N6TVXg = 148 - INTEGER(IntKi), PARAMETER :: N6TVYg = 149 - INTEGER(IntKi), PARAMETER :: N6TVZg = 150 - INTEGER(IntKi), PARAMETER :: N7TVXg = 151 - INTEGER(IntKi), PARAMETER :: N7TVYg = 152 - INTEGER(IntKi), PARAMETER :: N7TVZg = 153 - INTEGER(IntKi), PARAMETER :: N8TVXg = 154 - INTEGER(IntKi), PARAMETER :: N8TVYg = 155 - INTEGER(IntKi), PARAMETER :: N8TVZg = 156 - INTEGER(IntKi), PARAMETER :: N9TVXg = 157 - INTEGER(IntKi), PARAMETER :: N9TVYg = 158 - INTEGER(IntKi), PARAMETER :: N9TVZg = 159 - INTEGER(IntKi), PARAMETER :: N1RVXg = 160 - INTEGER(IntKi), PARAMETER :: N1RVYg = 161 - INTEGER(IntKi), PARAMETER :: N1RVZg = 162 - INTEGER(IntKi), PARAMETER :: N2RVXg = 163 - INTEGER(IntKi), PARAMETER :: N2RVYg = 164 - INTEGER(IntKi), PARAMETER :: N2RVZg = 165 - INTEGER(IntKi), PARAMETER :: N3RVXg = 166 - INTEGER(IntKi), PARAMETER :: N3RVYg = 167 - INTEGER(IntKi), PARAMETER :: N3RVZg = 168 - INTEGER(IntKi), PARAMETER :: N4RVXg = 169 - INTEGER(IntKi), PARAMETER :: N4RVYg = 170 - INTEGER(IntKi), PARAMETER :: N4RVZg = 171 - INTEGER(IntKi), PARAMETER :: N5RVXg = 172 - INTEGER(IntKi), PARAMETER :: N5RVYg = 173 - INTEGER(IntKi), PARAMETER :: N5RVZg = 174 - INTEGER(IntKi), PARAMETER :: N6RVXg = 175 - INTEGER(IntKi), PARAMETER :: N6RVYg = 176 - INTEGER(IntKi), PARAMETER :: N6RVZg = 177 - INTEGER(IntKi), PARAMETER :: N7RVXg = 178 - INTEGER(IntKi), PARAMETER :: N7RVYg = 179 - INTEGER(IntKi), PARAMETER :: N7RVZg = 180 - INTEGER(IntKi), PARAMETER :: N8RVXg = 181 - INTEGER(IntKi), PARAMETER :: N8RVYg = 182 - INTEGER(IntKi), PARAMETER :: N8RVZg = 183 - INTEGER(IntKi), PARAMETER :: N9RVXg = 184 - INTEGER(IntKi), PARAMETER :: N9RVYg = 185 - INTEGER(IntKi), PARAMETER :: N9RVZg = 186 - INTEGER(IntKi), PARAMETER :: N1TAXl = 187 - INTEGER(IntKi), PARAMETER :: N1TAYl = 188 - INTEGER(IntKi), PARAMETER :: N1TAZl = 189 - INTEGER(IntKi), PARAMETER :: N2TAXl = 190 - INTEGER(IntKi), PARAMETER :: N2TAYl = 191 - INTEGER(IntKi), PARAMETER :: N2TAZl = 192 - INTEGER(IntKi), PARAMETER :: N3TAXl = 193 - INTEGER(IntKi), PARAMETER :: N3TAYl = 194 - INTEGER(IntKi), PARAMETER :: N3TAZl = 195 - INTEGER(IntKi), PARAMETER :: N4TAXl = 196 - INTEGER(IntKi), PARAMETER :: N4TAYl = 197 - INTEGER(IntKi), PARAMETER :: N4TAZl = 198 - INTEGER(IntKi), PARAMETER :: N5TAXl = 199 - INTEGER(IntKi), PARAMETER :: N5TAYl = 200 - INTEGER(IntKi), PARAMETER :: N5TAZl = 201 - INTEGER(IntKi), PARAMETER :: N6TAXl = 202 - INTEGER(IntKi), PARAMETER :: N6TAYl = 203 - INTEGER(IntKi), PARAMETER :: N6TAZl = 204 - INTEGER(IntKi), PARAMETER :: N7TAXl = 205 - INTEGER(IntKi), PARAMETER :: N7TAYl = 206 - INTEGER(IntKi), PARAMETER :: N7TAZl = 207 - INTEGER(IntKi), PARAMETER :: N8TAXl = 208 - INTEGER(IntKi), PARAMETER :: N8TAYl = 209 - INTEGER(IntKi), PARAMETER :: N8TAZl = 210 - INTEGER(IntKi), PARAMETER :: N9TAXl = 211 - INTEGER(IntKi), PARAMETER :: N9TAYl = 212 - INTEGER(IntKi), PARAMETER :: N9TAZl = 213 - INTEGER(IntKi), PARAMETER :: N1RAXl = 214 - INTEGER(IntKi), PARAMETER :: N1RAYl = 215 - INTEGER(IntKi), PARAMETER :: N1RAZl = 216 - INTEGER(IntKi), PARAMETER :: N2RAXl = 217 - INTEGER(IntKi), PARAMETER :: N2RAYl = 218 - INTEGER(IntKi), PARAMETER :: N2RAZl = 219 - INTEGER(IntKi), PARAMETER :: N3RAXl = 220 - INTEGER(IntKi), PARAMETER :: N3RAYl = 221 - INTEGER(IntKi), PARAMETER :: N3RAZl = 222 - INTEGER(IntKi), PARAMETER :: N4RAXl = 223 - INTEGER(IntKi), PARAMETER :: N4RAYl = 224 - INTEGER(IntKi), PARAMETER :: N4RAZl = 225 - INTEGER(IntKi), PARAMETER :: N5RAXl = 226 - INTEGER(IntKi), PARAMETER :: N5RAYl = 227 - INTEGER(IntKi), PARAMETER :: N5RAZl = 228 - INTEGER(IntKi), PARAMETER :: N6RAXl = 229 - INTEGER(IntKi), PARAMETER :: N6RAYl = 230 - INTEGER(IntKi), PARAMETER :: N6RAZl = 231 - INTEGER(IntKi), PARAMETER :: N7RAXl = 232 - INTEGER(IntKi), PARAMETER :: N7RAYl = 233 - INTEGER(IntKi), PARAMETER :: N7RAZl = 234 - INTEGER(IntKi), PARAMETER :: N8RAXl = 235 - INTEGER(IntKi), PARAMETER :: N8RAYl = 236 - INTEGER(IntKi), PARAMETER :: N8RAZl = 237 - INTEGER(IntKi), PARAMETER :: N9RAXl = 238 - INTEGER(IntKi), PARAMETER :: N9RAYl = 239 - INTEGER(IntKi), PARAMETER :: N9RAZl = 240 + INTEGER(IntKi), PARAMETER :: N1TDxr = 79 + INTEGER(IntKi), PARAMETER :: N1TDyr = 80 + INTEGER(IntKi), PARAMETER :: N1TDzr = 81 + INTEGER(IntKi), PARAMETER :: N2TDxr = 82 + INTEGER(IntKi), PARAMETER :: N2TDyr = 83 + INTEGER(IntKi), PARAMETER :: N2TDzr = 84 + INTEGER(IntKi), PARAMETER :: N3TDxr = 85 + INTEGER(IntKi), PARAMETER :: N3TDyr = 86 + INTEGER(IntKi), PARAMETER :: N3TDzr = 87 + INTEGER(IntKi), PARAMETER :: N4TDxr = 88 + INTEGER(IntKi), PARAMETER :: N4TDyr = 89 + INTEGER(IntKi), PARAMETER :: N4TDzr = 90 + INTEGER(IntKi), PARAMETER :: N5TDxr = 91 + INTEGER(IntKi), PARAMETER :: N5TDyr = 92 + INTEGER(IntKi), PARAMETER :: N5TDzr = 93 + INTEGER(IntKi), PARAMETER :: N6TDxr = 94 + INTEGER(IntKi), PARAMETER :: N6TDyr = 95 + INTEGER(IntKi), PARAMETER :: N6TDzr = 96 + INTEGER(IntKi), PARAMETER :: N7TDxr = 97 + INTEGER(IntKi), PARAMETER :: N7TDyr = 98 + INTEGER(IntKi), PARAMETER :: N7TDzr = 99 + INTEGER(IntKi), PARAMETER :: N8TDxr = 100 + INTEGER(IntKi), PARAMETER :: N8TDyr = 101 + INTEGER(IntKi), PARAMETER :: N8TDzr = 102 + INTEGER(IntKi), PARAMETER :: N9TDxr = 103 + INTEGER(IntKi), PARAMETER :: N9TDyr = 104 + INTEGER(IntKi), PARAMETER :: N9TDzr = 105 + INTEGER(IntKi), PARAMETER :: N1RDxr = 106 + INTEGER(IntKi), PARAMETER :: N1RDyr = 107 + INTEGER(IntKi), PARAMETER :: N1RDzr = 108 + INTEGER(IntKi), PARAMETER :: N2RDxr = 109 + INTEGER(IntKi), PARAMETER :: N2RDyr = 110 + INTEGER(IntKi), PARAMETER :: N2RDzr = 111 + INTEGER(IntKi), PARAMETER :: N3RDxr = 112 + INTEGER(IntKi), PARAMETER :: N3RDyr = 113 + INTEGER(IntKi), PARAMETER :: N3RDzr = 114 + INTEGER(IntKi), PARAMETER :: N4RDxr = 115 + INTEGER(IntKi), PARAMETER :: N4RDyr = 116 + INTEGER(IntKi), PARAMETER :: N4RDzr = 117 + INTEGER(IntKi), PARAMETER :: N5RDxr = 118 + INTEGER(IntKi), PARAMETER :: N5RDyr = 119 + INTEGER(IntKi), PARAMETER :: N5RDzr = 120 + INTEGER(IntKi), PARAMETER :: N6RDxr = 121 + INTEGER(IntKi), PARAMETER :: N6RDyr = 122 + INTEGER(IntKi), PARAMETER :: N6RDzr = 123 + INTEGER(IntKi), PARAMETER :: N7RDxr = 124 + INTEGER(IntKi), PARAMETER :: N7RDyr = 125 + INTEGER(IntKi), PARAMETER :: N7RDzr = 126 + INTEGER(IntKi), PARAMETER :: N8RDxr = 127 + INTEGER(IntKi), PARAMETER :: N8RDyr = 128 + INTEGER(IntKi), PARAMETER :: N8RDzr = 129 + INTEGER(IntKi), PARAMETER :: N9RDxr = 130 + INTEGER(IntKi), PARAMETER :: N9RDyr = 131 + INTEGER(IntKi), PARAMETER :: N9RDzr = 132 + INTEGER(IntKi), PARAMETER :: N1TVXg = 133 + INTEGER(IntKi), PARAMETER :: N1TVYg = 134 + INTEGER(IntKi), PARAMETER :: N1TVZg = 135 + INTEGER(IntKi), PARAMETER :: N2TVXg = 136 + INTEGER(IntKi), PARAMETER :: N2TVYg = 137 + INTEGER(IntKi), PARAMETER :: N2TVZg = 138 + INTEGER(IntKi), PARAMETER :: N3TVXg = 139 + INTEGER(IntKi), PARAMETER :: N3TVYg = 140 + INTEGER(IntKi), PARAMETER :: N3TVZg = 141 + INTEGER(IntKi), PARAMETER :: N4TVXg = 142 + INTEGER(IntKi), PARAMETER :: N4TVYg = 143 + INTEGER(IntKi), PARAMETER :: N4TVZg = 144 + INTEGER(IntKi), PARAMETER :: N5TVXg = 145 + INTEGER(IntKi), PARAMETER :: N5TVYg = 146 + INTEGER(IntKi), PARAMETER :: N5TVZg = 147 + INTEGER(IntKi), PARAMETER :: N6TVXg = 148 + INTEGER(IntKi), PARAMETER :: N6TVYg = 149 + INTEGER(IntKi), PARAMETER :: N6TVZg = 150 + INTEGER(IntKi), PARAMETER :: N7TVXg = 151 + INTEGER(IntKi), PARAMETER :: N7TVYg = 152 + INTEGER(IntKi), PARAMETER :: N7TVZg = 153 + INTEGER(IntKi), PARAMETER :: N8TVXg = 154 + INTEGER(IntKi), PARAMETER :: N8TVYg = 155 + INTEGER(IntKi), PARAMETER :: N8TVZg = 156 + INTEGER(IntKi), PARAMETER :: N9TVXg = 157 + INTEGER(IntKi), PARAMETER :: N9TVYg = 158 + INTEGER(IntKi), PARAMETER :: N9TVZg = 159 + INTEGER(IntKi), PARAMETER :: N1RVXg = 160 + INTEGER(IntKi), PARAMETER :: N1RVYg = 161 + INTEGER(IntKi), PARAMETER :: N1RVZg = 162 + INTEGER(IntKi), PARAMETER :: N2RVXg = 163 + INTEGER(IntKi), PARAMETER :: N2RVYg = 164 + INTEGER(IntKi), PARAMETER :: N2RVZg = 165 + INTEGER(IntKi), PARAMETER :: N3RVXg = 166 + INTEGER(IntKi), PARAMETER :: N3RVYg = 167 + INTEGER(IntKi), PARAMETER :: N3RVZg = 168 + INTEGER(IntKi), PARAMETER :: N4RVXg = 169 + INTEGER(IntKi), PARAMETER :: N4RVYg = 170 + INTEGER(IntKi), PARAMETER :: N4RVZg = 171 + INTEGER(IntKi), PARAMETER :: N5RVXg = 172 + INTEGER(IntKi), PARAMETER :: N5RVYg = 173 + INTEGER(IntKi), PARAMETER :: N5RVZg = 174 + INTEGER(IntKi), PARAMETER :: N6RVXg = 175 + INTEGER(IntKi), PARAMETER :: N6RVYg = 176 + INTEGER(IntKi), PARAMETER :: N6RVZg = 177 + INTEGER(IntKi), PARAMETER :: N7RVXg = 178 + INTEGER(IntKi), PARAMETER :: N7RVYg = 179 + INTEGER(IntKi), PARAMETER :: N7RVZg = 180 + INTEGER(IntKi), PARAMETER :: N8RVXg = 181 + INTEGER(IntKi), PARAMETER :: N8RVYg = 182 + INTEGER(IntKi), PARAMETER :: N8RVZg = 183 + INTEGER(IntKi), PARAMETER :: N9RVXg = 184 + INTEGER(IntKi), PARAMETER :: N9RVYg = 185 + INTEGER(IntKi), PARAMETER :: N9RVZg = 186 + INTEGER(IntKi), PARAMETER :: N1TAXl = 187 + INTEGER(IntKi), PARAMETER :: N1TAYl = 188 + INTEGER(IntKi), PARAMETER :: N1TAZl = 189 + INTEGER(IntKi), PARAMETER :: N2TAXl = 190 + INTEGER(IntKi), PARAMETER :: N2TAYl = 191 + INTEGER(IntKi), PARAMETER :: N2TAZl = 192 + INTEGER(IntKi), PARAMETER :: N3TAXl = 193 + INTEGER(IntKi), PARAMETER :: N3TAYl = 194 + INTEGER(IntKi), PARAMETER :: N3TAZl = 195 + INTEGER(IntKi), PARAMETER :: N4TAXl = 196 + INTEGER(IntKi), PARAMETER :: N4TAYl = 197 + INTEGER(IntKi), PARAMETER :: N4TAZl = 198 + INTEGER(IntKi), PARAMETER :: N5TAXl = 199 + INTEGER(IntKi), PARAMETER :: N5TAYl = 200 + INTEGER(IntKi), PARAMETER :: N5TAZl = 201 + INTEGER(IntKi), PARAMETER :: N6TAXl = 202 + INTEGER(IntKi), PARAMETER :: N6TAYl = 203 + INTEGER(IntKi), PARAMETER :: N6TAZl = 204 + INTEGER(IntKi), PARAMETER :: N7TAXl = 205 + INTEGER(IntKi), PARAMETER :: N7TAYl = 206 + INTEGER(IntKi), PARAMETER :: N7TAZl = 207 + INTEGER(IntKi), PARAMETER :: N8TAXl = 208 + INTEGER(IntKi), PARAMETER :: N8TAYl = 209 + INTEGER(IntKi), PARAMETER :: N8TAZl = 210 + INTEGER(IntKi), PARAMETER :: N9TAXl = 211 + INTEGER(IntKi), PARAMETER :: N9TAYl = 212 + INTEGER(IntKi), PARAMETER :: N9TAZl = 213 + INTEGER(IntKi), PARAMETER :: N1RAXl = 214 + INTEGER(IntKi), PARAMETER :: N1RAYl = 215 + INTEGER(IntKi), PARAMETER :: N1RAZl = 216 + INTEGER(IntKi), PARAMETER :: N2RAXl = 217 + INTEGER(IntKi), PARAMETER :: N2RAYl = 218 + INTEGER(IntKi), PARAMETER :: N2RAZl = 219 + INTEGER(IntKi), PARAMETER :: N3RAXl = 220 + INTEGER(IntKi), PARAMETER :: N3RAYl = 221 + INTEGER(IntKi), PARAMETER :: N3RAZl = 222 + INTEGER(IntKi), PARAMETER :: N4RAXl = 223 + INTEGER(IntKi), PARAMETER :: N4RAYl = 224 + INTEGER(IntKi), PARAMETER :: N4RAZl = 225 + INTEGER(IntKi), PARAMETER :: N5RAXl = 226 + INTEGER(IntKi), PARAMETER :: N5RAYl = 227 + INTEGER(IntKi), PARAMETER :: N5RAZl = 228 + INTEGER(IntKi), PARAMETER :: N6RAXl = 229 + INTEGER(IntKi), PARAMETER :: N6RAYl = 230 + INTEGER(IntKi), PARAMETER :: N6RAZl = 231 + INTEGER(IntKi), PARAMETER :: N7RAXl = 232 + INTEGER(IntKi), PARAMETER :: N7RAYl = 233 + INTEGER(IntKi), PARAMETER :: N7RAZl = 234 + INTEGER(IntKi), PARAMETER :: N8RAXl = 235 + INTEGER(IntKi), PARAMETER :: N8RAYl = 236 + INTEGER(IntKi), PARAMETER :: N8RAZl = 237 + INTEGER(IntKi), PARAMETER :: N9RAXl = 238 + INTEGER(IntKi), PARAMETER :: N9RAYl = 239 + INTEGER(IntKi), PARAMETER :: N9RAZl = 240 ! Applied Loads: - INTEGER(IntKi), PARAMETER :: N1PFxl = 241 - INTEGER(IntKi), PARAMETER :: N1PFyl = 242 - INTEGER(IntKi), PARAMETER :: N1PFzl = 243 - INTEGER(IntKi), PARAMETER :: N2PFxl = 244 - INTEGER(IntKi), PARAMETER :: N2PFyl = 245 - INTEGER(IntKi), PARAMETER :: N2PFzl = 246 - INTEGER(IntKi), PARAMETER :: N3PFxl = 247 - INTEGER(IntKi), PARAMETER :: N3PFyl = 248 - INTEGER(IntKi), PARAMETER :: N3PFzl = 249 - INTEGER(IntKi), PARAMETER :: N4PFxl = 250 - INTEGER(IntKi), PARAMETER :: N4PFyl = 251 - INTEGER(IntKi), PARAMETER :: N4PFzl = 252 - INTEGER(IntKi), PARAMETER :: N5PFxl = 253 - INTEGER(IntKi), PARAMETER :: N5PFyl = 254 - INTEGER(IntKi), PARAMETER :: N5PFzl = 255 - INTEGER(IntKi), PARAMETER :: N6PFxl = 256 - INTEGER(IntKi), PARAMETER :: N6PFyl = 257 - INTEGER(IntKi), PARAMETER :: N6PFzl = 258 - INTEGER(IntKi), PARAMETER :: N7PFxl = 259 - INTEGER(IntKi), PARAMETER :: N7PFyl = 260 - INTEGER(IntKi), PARAMETER :: N7PFzl = 261 - INTEGER(IntKi), PARAMETER :: N8PFxl = 262 - INTEGER(IntKi), PARAMETER :: N8PFyl = 263 - INTEGER(IntKi), PARAMETER :: N8PFzl = 264 - INTEGER(IntKi), PARAMETER :: N9PFxl = 265 - INTEGER(IntKi), PARAMETER :: N9PFyl = 266 - INTEGER(IntKi), PARAMETER :: N9PFzl = 267 - INTEGER(IntKi), PARAMETER :: N1PMxl = 268 - INTEGER(IntKi), PARAMETER :: N1PMyl = 269 - INTEGER(IntKi), PARAMETER :: N1PMzl = 270 - INTEGER(IntKi), PARAMETER :: N2PMxl = 271 - INTEGER(IntKi), PARAMETER :: N2PMyl = 272 - INTEGER(IntKi), PARAMETER :: N2PMzl = 273 - INTEGER(IntKi), PARAMETER :: N3PMxl = 274 - INTEGER(IntKi), PARAMETER :: N3PMyl = 275 - INTEGER(IntKi), PARAMETER :: N3PMzl = 276 - INTEGER(IntKi), PARAMETER :: N4PMxl = 277 - INTEGER(IntKi), PARAMETER :: N4PMyl = 278 - INTEGER(IntKi), PARAMETER :: N4PMzl = 279 - INTEGER(IntKi), PARAMETER :: N5PMxl = 280 - INTEGER(IntKi), PARAMETER :: N5PMyl = 281 - INTEGER(IntKi), PARAMETER :: N5PMzl = 282 - INTEGER(IntKi), PARAMETER :: N6PMxl = 283 - INTEGER(IntKi), PARAMETER :: N6PMyl = 284 - INTEGER(IntKi), PARAMETER :: N6PMzl = 285 - INTEGER(IntKi), PARAMETER :: N7PMxl = 286 - INTEGER(IntKi), PARAMETER :: N7PMyl = 287 - INTEGER(IntKi), PARAMETER :: N7PMzl = 288 - INTEGER(IntKi), PARAMETER :: N8PMxl = 289 - INTEGER(IntKi), PARAMETER :: N8PMyl = 290 - INTEGER(IntKi), PARAMETER :: N8PMzl = 291 - INTEGER(IntKi), PARAMETER :: N9PMxl = 292 - INTEGER(IntKi), PARAMETER :: N9PMyl = 293 - INTEGER(IntKi), PARAMETER :: N9PMzl = 294 - INTEGER(IntKi), PARAMETER :: N1DFxl = 295 - INTEGER(IntKi), PARAMETER :: N1DFyl = 296 - INTEGER(IntKi), PARAMETER :: N1DFzl = 297 - INTEGER(IntKi), PARAMETER :: N2DFxl = 298 - INTEGER(IntKi), PARAMETER :: N2DFyl = 299 - INTEGER(IntKi), PARAMETER :: N2DFzl = 300 - INTEGER(IntKi), PARAMETER :: N3DFxl = 301 - INTEGER(IntKi), PARAMETER :: N3DFyl = 302 - INTEGER(IntKi), PARAMETER :: N3DFzl = 303 - INTEGER(IntKi), PARAMETER :: N4DFxl = 304 - INTEGER(IntKi), PARAMETER :: N4DFyl = 305 - INTEGER(IntKi), PARAMETER :: N4DFzl = 306 - INTEGER(IntKi), PARAMETER :: N5DFxl = 307 - INTEGER(IntKi), PARAMETER :: N5DFyl = 308 - INTEGER(IntKi), PARAMETER :: N5DFzl = 309 - INTEGER(IntKi), PARAMETER :: N6DFxl = 310 - INTEGER(IntKi), PARAMETER :: N6DFyl = 311 - INTEGER(IntKi), PARAMETER :: N6DFzl = 312 - INTEGER(IntKi), PARAMETER :: N7DFxl = 313 - INTEGER(IntKi), PARAMETER :: N7DFyl = 314 - INTEGER(IntKi), PARAMETER :: N7DFzl = 315 - INTEGER(IntKi), PARAMETER :: N8DFxl = 316 - INTEGER(IntKi), PARAMETER :: N8DFyl = 317 - INTEGER(IntKi), PARAMETER :: N8DFzl = 318 - INTEGER(IntKi), PARAMETER :: N9DFxl = 319 - INTEGER(IntKi), PARAMETER :: N9DFyl = 320 - INTEGER(IntKi), PARAMETER :: N9DFzl = 321 - INTEGER(IntKi), PARAMETER :: N1DMxl = 322 - INTEGER(IntKi), PARAMETER :: N1DMyl = 323 - INTEGER(IntKi), PARAMETER :: N1DMzl = 324 - INTEGER(IntKi), PARAMETER :: N2DMxl = 325 - INTEGER(IntKi), PARAMETER :: N2DMyl = 326 - INTEGER(IntKi), PARAMETER :: N2DMzl = 327 - INTEGER(IntKi), PARAMETER :: N3DMxl = 328 - INTEGER(IntKi), PARAMETER :: N3DMyl = 329 - INTEGER(IntKi), PARAMETER :: N3DMzl = 330 - INTEGER(IntKi), PARAMETER :: N4DMxl = 331 - INTEGER(IntKi), PARAMETER :: N4DMyl = 332 - INTEGER(IntKi), PARAMETER :: N4DMzl = 333 - INTEGER(IntKi), PARAMETER :: N5DMxl = 334 - INTEGER(IntKi), PARAMETER :: N5DMyl = 335 - INTEGER(IntKi), PARAMETER :: N5DMzl = 336 - INTEGER(IntKi), PARAMETER :: N6DMxl = 337 - INTEGER(IntKi), PARAMETER :: N6DMyl = 338 - INTEGER(IntKi), PARAMETER :: N6DMzl = 339 - INTEGER(IntKi), PARAMETER :: N7DMxl = 340 - INTEGER(IntKi), PARAMETER :: N7DMyl = 341 - INTEGER(IntKi), PARAMETER :: N7DMzl = 342 - INTEGER(IntKi), PARAMETER :: N8DMxl = 343 - INTEGER(IntKi), PARAMETER :: N8DMyl = 344 - INTEGER(IntKi), PARAMETER :: N8DMzl = 345 - INTEGER(IntKi), PARAMETER :: N9DMxl = 346 - INTEGER(IntKi), PARAMETER :: N9DMyl = 347 - INTEGER(IntKi), PARAMETER :: N9DMzl = 348 + INTEGER(IntKi), PARAMETER :: N1PFxl = 241 + INTEGER(IntKi), PARAMETER :: N1PFyl = 242 + INTEGER(IntKi), PARAMETER :: N1PFzl = 243 + INTEGER(IntKi), PARAMETER :: N2PFxl = 244 + INTEGER(IntKi), PARAMETER :: N2PFyl = 245 + INTEGER(IntKi), PARAMETER :: N2PFzl = 246 + INTEGER(IntKi), PARAMETER :: N3PFxl = 247 + INTEGER(IntKi), PARAMETER :: N3PFyl = 248 + INTEGER(IntKi), PARAMETER :: N3PFzl = 249 + INTEGER(IntKi), PARAMETER :: N4PFxl = 250 + INTEGER(IntKi), PARAMETER :: N4PFyl = 251 + INTEGER(IntKi), PARAMETER :: N4PFzl = 252 + INTEGER(IntKi), PARAMETER :: N5PFxl = 253 + INTEGER(IntKi), PARAMETER :: N5PFyl = 254 + INTEGER(IntKi), PARAMETER :: N5PFzl = 255 + INTEGER(IntKi), PARAMETER :: N6PFxl = 256 + INTEGER(IntKi), PARAMETER :: N6PFyl = 257 + INTEGER(IntKi), PARAMETER :: N6PFzl = 258 + INTEGER(IntKi), PARAMETER :: N7PFxl = 259 + INTEGER(IntKi), PARAMETER :: N7PFyl = 260 + INTEGER(IntKi), PARAMETER :: N7PFzl = 261 + INTEGER(IntKi), PARAMETER :: N8PFxl = 262 + INTEGER(IntKi), PARAMETER :: N8PFyl = 263 + INTEGER(IntKi), PARAMETER :: N8PFzl = 264 + INTEGER(IntKi), PARAMETER :: N9PFxl = 265 + INTEGER(IntKi), PARAMETER :: N9PFyl = 266 + INTEGER(IntKi), PARAMETER :: N9PFzl = 267 + INTEGER(IntKi), PARAMETER :: N1PMxl = 268 + INTEGER(IntKi), PARAMETER :: N1PMyl = 269 + INTEGER(IntKi), PARAMETER :: N1PMzl = 270 + INTEGER(IntKi), PARAMETER :: N2PMxl = 271 + INTEGER(IntKi), PARAMETER :: N2PMyl = 272 + INTEGER(IntKi), PARAMETER :: N2PMzl = 273 + INTEGER(IntKi), PARAMETER :: N3PMxl = 274 + INTEGER(IntKi), PARAMETER :: N3PMyl = 275 + INTEGER(IntKi), PARAMETER :: N3PMzl = 276 + INTEGER(IntKi), PARAMETER :: N4PMxl = 277 + INTEGER(IntKi), PARAMETER :: N4PMyl = 278 + INTEGER(IntKi), PARAMETER :: N4PMzl = 279 + INTEGER(IntKi), PARAMETER :: N5PMxl = 280 + INTEGER(IntKi), PARAMETER :: N5PMyl = 281 + INTEGER(IntKi), PARAMETER :: N5PMzl = 282 + INTEGER(IntKi), PARAMETER :: N6PMxl = 283 + INTEGER(IntKi), PARAMETER :: N6PMyl = 284 + INTEGER(IntKi), PARAMETER :: N6PMzl = 285 + INTEGER(IntKi), PARAMETER :: N7PMxl = 286 + INTEGER(IntKi), PARAMETER :: N7PMyl = 287 + INTEGER(IntKi), PARAMETER :: N7PMzl = 288 + INTEGER(IntKi), PARAMETER :: N8PMxl = 289 + INTEGER(IntKi), PARAMETER :: N8PMyl = 290 + INTEGER(IntKi), PARAMETER :: N8PMzl = 291 + INTEGER(IntKi), PARAMETER :: N9PMxl = 292 + INTEGER(IntKi), PARAMETER :: N9PMyl = 293 + INTEGER(IntKi), PARAMETER :: N9PMzl = 294 + INTEGER(IntKi), PARAMETER :: N1DFxl = 295 + INTEGER(IntKi), PARAMETER :: N1DFyl = 296 + INTEGER(IntKi), PARAMETER :: N1DFzl = 297 + INTEGER(IntKi), PARAMETER :: N2DFxl = 298 + INTEGER(IntKi), PARAMETER :: N2DFyl = 299 + INTEGER(IntKi), PARAMETER :: N2DFzl = 300 + INTEGER(IntKi), PARAMETER :: N3DFxl = 301 + INTEGER(IntKi), PARAMETER :: N3DFyl = 302 + INTEGER(IntKi), PARAMETER :: N3DFzl = 303 + INTEGER(IntKi), PARAMETER :: N4DFxl = 304 + INTEGER(IntKi), PARAMETER :: N4DFyl = 305 + INTEGER(IntKi), PARAMETER :: N4DFzl = 306 + INTEGER(IntKi), PARAMETER :: N5DFxl = 307 + INTEGER(IntKi), PARAMETER :: N5DFyl = 308 + INTEGER(IntKi), PARAMETER :: N5DFzl = 309 + INTEGER(IntKi), PARAMETER :: N6DFxl = 310 + INTEGER(IntKi), PARAMETER :: N6DFyl = 311 + INTEGER(IntKi), PARAMETER :: N6DFzl = 312 + INTEGER(IntKi), PARAMETER :: N7DFxl = 313 + INTEGER(IntKi), PARAMETER :: N7DFyl = 314 + INTEGER(IntKi), PARAMETER :: N7DFzl = 315 + INTEGER(IntKi), PARAMETER :: N8DFxl = 316 + INTEGER(IntKi), PARAMETER :: N8DFyl = 317 + INTEGER(IntKi), PARAMETER :: N8DFzl = 318 + INTEGER(IntKi), PARAMETER :: N9DFxl = 319 + INTEGER(IntKi), PARAMETER :: N9DFyl = 320 + INTEGER(IntKi), PARAMETER :: N9DFzl = 321 + INTEGER(IntKi), PARAMETER :: N1DMxl = 322 + INTEGER(IntKi), PARAMETER :: N1DMyl = 323 + INTEGER(IntKi), PARAMETER :: N1DMzl = 324 + INTEGER(IntKi), PARAMETER :: N2DMxl = 325 + INTEGER(IntKi), PARAMETER :: N2DMyl = 326 + INTEGER(IntKi), PARAMETER :: N2DMzl = 327 + INTEGER(IntKi), PARAMETER :: N3DMxl = 328 + INTEGER(IntKi), PARAMETER :: N3DMyl = 329 + INTEGER(IntKi), PARAMETER :: N3DMzl = 330 + INTEGER(IntKi), PARAMETER :: N4DMxl = 331 + INTEGER(IntKi), PARAMETER :: N4DMyl = 332 + INTEGER(IntKi), PARAMETER :: N4DMzl = 333 + INTEGER(IntKi), PARAMETER :: N5DMxl = 334 + INTEGER(IntKi), PARAMETER :: N5DMyl = 335 + INTEGER(IntKi), PARAMETER :: N5DMzl = 336 + INTEGER(IntKi), PARAMETER :: N6DMxl = 337 + INTEGER(IntKi), PARAMETER :: N6DMyl = 338 + INTEGER(IntKi), PARAMETER :: N6DMzl = 339 + INTEGER(IntKi), PARAMETER :: N7DMxl = 340 + INTEGER(IntKi), PARAMETER :: N7DMyl = 341 + INTEGER(IntKi), PARAMETER :: N7DMzl = 342 + INTEGER(IntKi), PARAMETER :: N8DMxl = 343 + INTEGER(IntKi), PARAMETER :: N8DMyl = 344 + INTEGER(IntKi), PARAMETER :: N8DMzl = 345 + INTEGER(IntKi), PARAMETER :: N9DMxl = 346 + INTEGER(IntKi), PARAMETER :: N9DMyl = 347 + INTEGER(IntKi), PARAMETER :: N9DMzl = 348 + + + ! Applied loads mapped to root (includes distributed and point): + + INTEGER(IntKi), PARAMETER :: RootAppliedFxr = 349 + INTEGER(IntKi), PARAMETER :: RootAppliedFyr = 350 + INTEGER(IntKi), PARAMETER :: RootAppliedFzr = 351 + INTEGER(IntKi), PARAMETER :: RootAppliedMxr = 352 + INTEGER(IntKi), PARAMETER :: RootAppliedMyr = 353 + INTEGER(IntKi), PARAMETER :: RootAppliedMzr = 354 + INTEGER(IntKi), PARAMETER :: RootAppliedFxg = 355 + INTEGER(IntKi), PARAMETER :: RootAppliedFyg = 356 + INTEGER(IntKi), PARAMETER :: RootAppliedFzg = 357 + INTEGER(IntKi), PARAMETER :: RootAppliedMxg = 358 + INTEGER(IntKi), PARAMETER :: RootAppliedMyg = 359 + INTEGER(IntKi), PARAMETER :: RootAppliedMzg = 360 ! Pitch Actuator: - INTEGER(IntKi), PARAMETER :: PAngInp = 349 - INTEGER(IntKi), PARAMETER :: PAngAct = 350 - INTEGER(IntKi), PARAMETER :: PRatAct = 351 - INTEGER(IntKi), PARAMETER :: PAccAct = 352 + INTEGER(IntKi), PARAMETER :: PAngInp = 361 + INTEGER(IntKi), PARAMETER :: PAngAct = 362 + INTEGER(IntKi), PARAMETER :: PRatAct = 363 + INTEGER(IntKi), PARAMETER :: PAccAct = 364 ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi), PARAMETER :: MaxOutPts = 352 + INTEGER(IntKi), PARAMETER :: MaxOutPts = 364 !End of code generated by Matlab script ! =================================================================================================== @@ -1159,15 +1175,16 @@ END SUBROUTINE BD_ReadBladeFile !---------------------------------------------------------------------------------------------------------------------------------- !********************************************************************************************************************************** ! NOTE: The following lines of code were generated by a Matlab script called "Write_ChckOutLst.m" -! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these -! lines should be modified in the Matlab script and/or Excel worksheet as necessary. -! This code was generated by Write_ChckOutLst.m at 29-Sep-2015 10:23:41. +! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these +! lines should be modified in the Matlab script and/or Excel worksheet as necessary. !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine checks to see if any requested output channel names (stored in the OutList(:)) are invalid. It returns a +!> This routine checks to see if any requested output channel names (stored in the OutList(:)) are invalid. It returns a !! warning if any of the channels are not available outputs from the module. !! It assigns the settings for OutParam(:) (i.e, the index, name, and units of the output channels, WriteOutput(:)). !! the sign is set to 0 if the channel is invalid. !! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. +!! +!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 08-May-2025 15:51:30. SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) IMPLICIT NONE @@ -1191,162 +1208,232 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(352) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "N1DFXL ","N1DFYL ","N1DFZL ","N1DMXL ","N1DMYL ","N1DMZL ","N1FXL ", & - "N1FYL ","N1FZL ","N1MXL ","N1MYL ","N1MZL ","N1PFXL ","N1PFYL ", & - "N1PFZL ","N1PMXL ","N1PMYL ","N1PMZL ","N1RAXL ","N1RAYL ","N1RAZL ", & - "N1RDXR ","N1RDYR ","N1RDZR ","N1RVXG ","N1RVYG ","N1RVZG ","N1TAXL ", & - "N1TAYL ","N1TAZL ","N1TDXR ","N1TDYR ","N1TDZR ","N1TVXG ","N1TVYG ", & - "N1TVZG ","N2DFXL ","N2DFYL ","N2DFZL ","N2DMXL ","N2DMYL ","N2DMZL ", & - "N2FXL ","N2FYL ","N2FZL ","N2MXL ","N2MYL ","N2MZL ","N2PFXL ", & - "N2PFYL ","N2PFZL ","N2PMXL ","N2PMYL ","N2PMZL ","N2RAXL ","N2RAYL ", & - "N2RAZL ","N2RDXR ","N2RDYR ","N2RDZR ","N2RVXG ","N2RVYG ","N2RVZG ", & - "N2TAXL ","N2TAYL ","N2TAZL ","N2TDXR ","N2TDYR ","N2TDZR ","N2TVXG ", & - "N2TVYG ","N2TVZG ","N3DFXL ","N3DFYL ","N3DFZL ","N3DMXL ","N3DMYL ", & - "N3DMZL ","N3FXL ","N3FYL ","N3FZL ","N3MXL ","N3MYL ","N3MZL ", & - "N3PFXL ","N3PFYL ","N3PFZL ","N3PMXL ","N3PMYL ","N3PMZL ","N3RAXL ", & - "N3RAYL ","N3RAZL ","N3RDXR ","N3RDYR ","N3RDZR ","N3RVXG ","N3RVYG ", & - "N3RVZG ","N3TAXL ","N3TAYL ","N3TAZL ","N3TDXR ","N3TDYR ","N3TDZR ", & - "N3TVXG ","N3TVYG ","N3TVZG ","N4DFXL ","N4DFYL ","N4DFZL ","N4DMXL ", & - "N4DMYL ","N4DMZL ","N4FXL ","N4FYL ","N4FZL ","N4MXL ","N4MYL ", & - "N4MZL ","N4PFXL ","N4PFYL ","N4PFZL ","N4PMXL ","N4PMYL ","N4PMZL ", & - "N4RAXL ","N4RAYL ","N4RAZL ","N4RDXR ","N4RDYR ","N4RDZR ","N4RVXG ", & - "N4RVYG ","N4RVZG ","N4TAXL ","N4TAYL ","N4TAZL ","N4TDXR ","N4TDYR ", & - "N4TDZR ","N4TVXG ","N4TVYG ","N4TVZG ","N5DFXL ","N5DFYL ","N5DFZL ", & - "N5DMXL ","N5DMYL ","N5DMZL ","N5FXL ","N5FYL ","N5FZL ","N5MXL ", & - "N5MYL ","N5MZL ","N5PFXL ","N5PFYL ","N5PFZL ","N5PMXL ","N5PMYL ", & - "N5PMZL ","N5RAXL ","N5RAYL ","N5RAZL ","N5RDXR ","N5RDYR ","N5RDZR ", & - "N5RVXG ","N5RVYG ","N5RVZG ","N5TAXL ","N5TAYL ","N5TAZL ","N5TDXR ", & - "N5TDYR ","N5TDZR ","N5TVXG ","N5TVYG ","N5TVZG ","N6DFXL ","N6DFYL ", & - "N6DFZL ","N6DMXL ","N6DMYL ","N6DMZL ","N6FXL ","N6FYL ","N6FZL ", & - "N6MXL ","N6MYL ","N6MZL ","N6PFXL ","N6PFYL ","N6PFZL ","N6PMXL ", & - "N6PMYL ","N6PMZL ","N6RAXL ","N6RAYL ","N6RAZL ","N6RDXR ","N6RDYR ", & - "N6RDZR ","N6RVXG ","N6RVYG ","N6RVZG ","N6TAXL ","N6TAYL ","N6TAZL ", & - "N6TDXR ","N6TDYR ","N6TDZR ","N6TVXG ","N6TVYG ","N6TVZG ","N7DFXL ", & - "N7DFYL ","N7DFZL ","N7DMXL ","N7DMYL ","N7DMZL ","N7FXL ","N7FYL ", & - "N7FZL ","N7MXL ","N7MYL ","N7MZL ","N7PFXL ","N7PFYL ","N7PFZL ", & - "N7PMXL ","N7PMYL ","N7PMZL ","N7RAXL ","N7RAYL ","N7RAZL ","N7RDXR ", & - "N7RDYR ","N7RDZR ","N7RVXG ","N7RVYG ","N7RVZG ","N7TAXL ","N7TAYL ", & - "N7TAZL ","N7TDXR ","N7TDYR ","N7TDZR ","N7TVXG ","N7TVYG ","N7TVZG ", & - "N8DFXL ","N8DFYL ","N8DFZL ","N8DMXL ","N8DMYL ","N8DMZL ","N8FXL ", & - "N8FYL ","N8FZL ","N8MXL ","N8MYL ","N8MZL ","N8PFXL ","N8PFYL ", & - "N8PFZL ","N8PMXL ","N8PMYL ","N8PMZL ","N8RAXL ","N8RAYL ","N8RAZL ", & - "N8RDXR ","N8RDYR ","N8RDZR ","N8RVXG ","N8RVYG ","N8RVZG ","N8TAXL ", & - "N8TAYL ","N8TAZL ","N8TDXR ","N8TDYR ","N8TDZR ","N8TVXG ","N8TVYG ", & - "N8TVZG ","N9DFXL ","N9DFYL ","N9DFZL ","N9DMXL ","N9DMYL ","N9DMZL ", & - "N9FXL ","N9FYL ","N9FZL ","N9MXL ","N9MYL ","N9MZL ","N9PFXL ", & - "N9PFYL ","N9PFZL ","N9PMXL ","N9PMYL ","N9PMZL ","N9RAXL ","N9RAYL ", & - "N9RAZL ","N9RDXR ","N9RDYR ","N9RDZR ","N9RVXG ","N9RVYG ","N9RVZG ", & - "N9TAXL ","N9TAYL ","N9TAZL ","N9TDXR ","N9TDYR ","N9TDZR ","N9TVXG ", & - "N9TVYG ","N9TVZG ","PACCACT ","PANGACT ","PANGINP ","PRATACT ","ROOTFXR ", & - "ROOTFYR ","ROOTFZR ","ROOTMXR ","ROOTMYR ","ROOTMZR ","TIPRAXL ","TIPRAYL ", & - "TIPRAZL ","TIPRDXR ","TIPRDYR ","TIPRDZR ","TIPRVXG ","TIPRVYG ","TIPRVZG ", & - "TIPTAXL ","TIPTAYL ","TIPTAZL ","TIPTDXR ","TIPTDYR ","TIPTDZR ","TIPTVXG ", & - "TIPTVYG ","TIPTVZG "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(352) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - N1DFxl , N1DFyl , N1DFzl , N1DMxl , N1DMyl , N1DMzl , N1Fxl , & - N1Fyl , N1Fzl , N1Mxl , N1Myl , N1Mzl , N1PFxl , N1PFyl , & - N1PFzl , N1PMxl , N1PMyl , N1PMzl , N1RAXl , N1RAYl , N1RAZl , & - N1RDxr , N1RDyr , N1RDzr , N1RVXg , N1RVYg , N1RVZg , N1TAXl , & - N1TAYl , N1TAZl , N1TDxr , N1TDyr , N1TDzr , N1TVXg , N1TVYg , & - N1TVZg , N2DFxl , N2DFyl , N2DFzl , N2DMxl , N2DMyl , N2DMzl , & - N2Fxl , N2Fyl , N2Fzl , N2Mxl , N2Myl , N2Mzl , N2PFxl , & - N2PFyl , N2PFzl , N2PMxl , N2PMyl , N2PMzl , N2RAXl , N2RAYl , & - N2RAZl , N2RDxr , N2RDyr , N2RDzr , N2RVXg , N2RVYg , N2RVZg , & - N2TAXl , N2TAYl , N2TAZl , N2TDxr , N2TDyr , N2TDzr , N2TVXg , & - N2TVYg , N2TVZg , N3DFxl , N3DFyl , N3DFzl , N3DMxl , N3DMyl , & - N3DMzl , N3Fxl , N3Fyl , N3Fzl , N3Mxl , N3Myl , N3Mzl , & - N3PFxl , N3PFyl , N3PFzl , N3PMxl , N3PMyl , N3PMzl , N3RAXl , & - N3RAYl , N3RAZl , N3RDxr , N3RDyr , N3RDzr , N3RVXg , N3RVYg , & - N3RVZg , N3TAXl , N3TAYl , N3TAZl , N3TDxr , N3TDyr , N3TDzr , & - N3TVXg , N3TVYg , N3TVZg , N4DFxl , N4DFyl , N4DFzl , N4DMxl , & - N4DMyl , N4DMzl , N4Fxl , N4Fyl , N4Fzl , N4Mxl , N4Myl , & - N4Mzl , N4PFxl , N4PFyl , N4PFzl , N4PMxl , N4PMyl , N4PMzl , & - N4RAXl , N4RAYl , N4RAZl , N4RDxr , N4RDyr , N4RDzr , N4RVXg , & - N4RVYg , N4RVZg , N4TAXl , N4TAYl , N4TAZl , N4TDxr , N4TDyr , & - N4TDzr , N4TVXg , N4TVYg , N4TVZg , N5DFxl , N5DFyl , N5DFzl , & - N5DMxl , N5DMyl , N5DMzl , N5Fxl , N5Fyl , N5Fzl , N5Mxl , & - N5Myl , N5Mzl , N5PFxl , N5PFyl , N5PFzl , N5PMxl , N5PMyl , & - N5PMzl , N5RAXl , N5RAYl , N5RAZl , N5RDxr , N5RDyr , N5RDzr , & - N5RVXg , N5RVYg , N5RVZg , N5TAXl , N5TAYl , N5TAZl , N5TDxr , & - N5TDyr , N5TDzr , N5TVXg , N5TVYg , N5TVZg , N6DFxl , N6DFyl , & - N6DFzl , N6DMxl , N6DMyl , N6DMzl , N6Fxl , N6Fyl , N6Fzl , & - N6Mxl , N6Myl , N6Mzl , N6PFxl , N6PFyl , N6PFzl , N6PMxl , & - N6PMyl , N6PMzl , N6RAXl , N6RAYl , N6RAZl , N6RDxr , N6RDyr , & - N6RDzr , N6RVXg , N6RVYg , N6RVZg , N6TAXl , N6TAYl , N6TAZl , & - N6TDxr , N6TDyr , N6TDzr , N6TVXg , N6TVYg , N6TVZg , N7DFxl , & - N7DFyl , N7DFzl , N7DMxl , N7DMyl , N7DMzl , N7Fxl , N7Fyl , & - N7Fzl , N7Mxl , N7Myl , N7Mzl , N7PFxl , N7PFyl , N7PFzl , & - N7PMxl , N7PMyl , N7PMzl , N7RAXl , N7RAYl , N7RAZl , N7RDxr , & - N7RDyr , N7RDzr , N7RVXg , N7RVYg , N7RVZg , N7TAXl , N7TAYl , & - N7TAZl , N7TDxr , N7TDyr , N7TDzr , N7TVXg , N7TVYg , N7TVZg , & - N8DFxl , N8DFyl , N8DFzl , N8DMxl , N8DMyl , N8DMzl , N8Fxl , & - N8Fyl , N8Fzl , N8Mxl , N8Myl , N8Mzl , N8PFxl , N8PFyl , & - N8PFzl , N8PMxl , N8PMyl , N8PMzl , N8RAXl , N8RAYl , N8RAZl , & - N8RDxr , N8RDyr , N8RDzr , N8RVXg , N8RVYg , N8RVZg , N8TAXl , & - N8TAYl , N8TAZl , N8TDxr , N8TDyr , N8TDzr , N8TVXg , N8TVYg , & - N8TVZg , N9DFxl , N9DFyl , N9DFzl , N9DMxl , N9DMyl , N9DMzl , & - N9Fxl , N9Fyl , N9Fzl , N9Mxl , N9Myl , N9Mzl , N9PFxl , & - N9PFyl , N9PFzl , N9PMxl , N9PMyl , N9PMzl , N9RAXl , N9RAYl , & - N9RAZl , N9RDxr , N9RDyr , N9RDzr , N9RVXg , N9RVYg , N9RVZg , & - N9TAXl , N9TAYl , N9TAZl , N9TDxr , N9TDyr , N9TDzr , N9TVXg , & - N9TVYg , N9TVZg , PAccAct , PAngAct , PAngInp , PRatAct , RootFxr , & - RootFyr , RootFzr , RootMxr , RootMyr , RootMzr , TipRAXl , TipRAYl , & - TipRAZl , TipRDxr , TipRDyr , TipRDzr , TipRVXg , TipRVYg , TipRVZg , & - TipTAXl , TipTAYl , TipTAZl , TipTDxr , TipTDyr , TipTDzr , TipTVXg , & - TipTVYg , TipTVZg /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(352) = (/ & ! This lists the units corresponding to the allowed parameters - "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ", & - "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ", & - "(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2) ","(deg/s^2) ","(deg/s^2) ", & - "(-) ","(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ","(m/s) ", & - "(m/s) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ", & - "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2) ","(deg/s^2) ", & - "(deg/s^2) ","(-) ","(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ", & - "(m/s) ","(m/s) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & - "(N-m/m) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2) ", & - "(deg/s^2) ","(deg/s^2) ","(-) ","(-) ","(-) ","(deg/s) ","(deg/s) ", & - "(deg/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(m/s) ","(m/s) ","(m/s) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & - "(N-m/m) ","(N-m/m) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & - "(N-m) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(deg/s^2) ","(deg/s^2) ","(deg/s^2) ","(-) ","(-) ","(-) ","(deg/s) ", & - "(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(m/s) ","(m/s) ","(m/s) ","(N/m) ","(N/m) ","(N/m) ", & - "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ","(N) ","(N) ","(N-m) ", & - "(N-m) ","(N-m) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & - "(N-m) ","(deg/s^2) ","(deg/s^2) ","(deg/s^2) ","(-) ","(-) ","(-) ", & - "(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(m/s) ","(m/s) ","(m/s) ","(N/m) ","(N/m) ", & - "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ","(N) ","(N) ", & - "(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ","(N) ","(N-m) ", & - "(N-m) ","(N-m) ","(deg/s^2) ","(deg/s^2) ","(deg/s^2) ","(-) ","(-) ", & - "(-) ","(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(m/s) ","(m/s) ","(m/s) ","(N/m) ", & - "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ","(N) ", & - "(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ","(N) ", & - "(N-m) ","(N-m) ","(N-m) ","(deg/s^2) ","(deg/s^2) ","(deg/s^2) ","(-) ", & - "(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ","(m/s) ","(m/s) ", & - "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ", & - "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ", & - "(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2) ","(deg/s^2) ","(deg/s^2) ", & - "(-) ","(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ","(m/s) ", & - "(m/s) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ", & - "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2) ","(deg/s^2) ", & - "(deg/s^2) ","(-) ","(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg/s^2) ","(deg) ","(deg) ","(deg/s) ","(N) ", & - "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2) ","(deg/s^2) ", & - "(deg/s^2) ","(-) ","(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ", & - "(m/s) ","(m/s) "/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(364) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "N1DFXL ","N1DFYL ","N1DFZL ","N1DMXL ","N1DMYL ", & + "N1DMZL ","N1FXL ","N1FYL ","N1FZL ","N1MXL ", & + "N1MYL ","N1MZL ","N1PFXL ","N1PFYL ","N1PFZL ", & + "N1PMXL ","N1PMYL ","N1PMZL ","N1RAXL ","N1RAYL ", & + "N1RAZL ","N1RDXR ","N1RDYR ","N1RDZR ","N1RVXG ", & + "N1RVYG ","N1RVZG ","N1TAXL ","N1TAYL ","N1TAZL ", & + "N1TDXR ","N1TDYR ","N1TDZR ","N1TVXG ","N1TVYG ", & + "N1TVZG ","N2DFXL ","N2DFYL ","N2DFZL ","N2DMXL ", & + "N2DMYL ","N2DMZL ","N2FXL ","N2FYL ","N2FZL ", & + "N2MXL ","N2MYL ","N2MZL ","N2PFXL ","N2PFYL ", & + "N2PFZL ","N2PMXL ","N2PMYL ","N2PMZL ","N2RAXL ", & + "N2RAYL ","N2RAZL ","N2RDXR ","N2RDYR ","N2RDZR ", & + "N2RVXG ","N2RVYG ","N2RVZG ","N2TAXL ","N2TAYL ", & + "N2TAZL ","N2TDXR ","N2TDYR ","N2TDZR ","N2TVXG ", & + "N2TVYG ","N2TVZG ","N3DFXL ","N3DFYL ","N3DFZL ", & + "N3DMXL ","N3DMYL ","N3DMZL ","N3FXL ","N3FYL ", & + "N3FZL ","N3MXL ","N3MYL ","N3MZL ","N3PFXL ", & + "N3PFYL ","N3PFZL ","N3PMXL ","N3PMYL ","N3PMZL ", & + "N3RAXL ","N3RAYL ","N3RAZL ","N3RDXR ","N3RDYR ", & + "N3RDZR ","N3RVXG ","N3RVYG ","N3RVZG ","N3TAXL ", & + "N3TAYL ","N3TAZL ","N3TDXR ","N3TDYR ","N3TDZR ", & + "N3TVXG ","N3TVYG ","N3TVZG ","N4DFXL ","N4DFYL ", & + "N4DFZL ","N4DMXL ","N4DMYL ","N4DMZL ","N4FXL ", & + "N4FYL ","N4FZL ","N4MXL ","N4MYL ","N4MZL ", & + "N4PFXL ","N4PFYL ","N4PFZL ","N4PMXL ","N4PMYL ", & + "N4PMZL ","N4RAXL ","N4RAYL ","N4RAZL ","N4RDXR ", & + "N4RDYR ","N4RDZR ","N4RVXG ","N4RVYG ","N4RVZG ", & + "N4TAXL ","N4TAYL ","N4TAZL ","N4TDXR ","N4TDYR ", & + "N4TDZR ","N4TVXG ","N4TVYG ","N4TVZG ","N5DFXL ", & + "N5DFYL ","N5DFZL ","N5DMXL ","N5DMYL ","N5DMZL ", & + "N5FXL ","N5FYL ","N5FZL ","N5MXL ","N5MYL ", & + "N5MZL ","N5PFXL ","N5PFYL ","N5PFZL ","N5PMXL ", & + "N5PMYL ","N5PMZL ","N5RAXL ","N5RAYL ","N5RAZL ", & + "N5RDXR ","N5RDYR ","N5RDZR ","N5RVXG ","N5RVYG ", & + "N5RVZG ","N5TAXL ","N5TAYL ","N5TAZL ","N5TDXR ", & + "N5TDYR ","N5TDZR ","N5TVXG ","N5TVYG ","N5TVZG ", & + "N6DFXL ","N6DFYL ","N6DFZL ","N6DMXL ","N6DMYL ", & + "N6DMZL ","N6FXL ","N6FYL ","N6FZL ","N6MXL ", & + "N6MYL ","N6MZL ","N6PFXL ","N6PFYL ","N6PFZL ", & + "N6PMXL ","N6PMYL ","N6PMZL ","N6RAXL ","N6RAYL ", & + "N6RAZL ","N6RDXR ","N6RDYR ","N6RDZR ","N6RVXG ", & + "N6RVYG ","N6RVZG ","N6TAXL ","N6TAYL ","N6TAZL ", & + "N6TDXR ","N6TDYR ","N6TDZR ","N6TVXG ","N6TVYG ", & + "N6TVZG ","N7DFXL ","N7DFYL ","N7DFZL ","N7DMXL ", & + "N7DMYL ","N7DMZL ","N7FXL ","N7FYL ","N7FZL ", & + "N7MXL ","N7MYL ","N7MZL ","N7PFXL ","N7PFYL ", & + "N7PFZL ","N7PMXL ","N7PMYL ","N7PMZL ","N7RAXL ", & + "N7RAYL ","N7RAZL ","N7RDXR ","N7RDYR ","N7RDZR ", & + "N7RVXG ","N7RVYG ","N7RVZG ","N7TAXL ","N7TAYL ", & + "N7TAZL ","N7TDXR ","N7TDYR ","N7TDZR ","N7TVXG ", & + "N7TVYG ","N7TVZG ","N8DFXL ","N8DFYL ","N8DFZL ", & + "N8DMXL ","N8DMYL ","N8DMZL ","N8FXL ","N8FYL ", & + "N8FZL ","N8MXL ","N8MYL ","N8MZL ","N8PFXL ", & + "N8PFYL ","N8PFZL ","N8PMXL ","N8PMYL ","N8PMZL ", & + "N8RAXL ","N8RAYL ","N8RAZL ","N8RDXR ","N8RDYR ", & + "N8RDZR ","N8RVXG ","N8RVYG ","N8RVZG ","N8TAXL ", & + "N8TAYL ","N8TAZL ","N8TDXR ","N8TDYR ","N8TDZR ", & + "N8TVXG ","N8TVYG ","N8TVZG ","N9DFXL ","N9DFYL ", & + "N9DFZL ","N9DMXL ","N9DMYL ","N9DMZL ","N9FXL ", & + "N9FYL ","N9FZL ","N9MXL ","N9MYL ","N9MZL ", & + "N9PFXL ","N9PFYL ","N9PFZL ","N9PMXL ","N9PMYL ", & + "N9PMZL ","N9RAXL ","N9RAYL ","N9RAZL ","N9RDXR ", & + "N9RDYR ","N9RDZR ","N9RVXG ","N9RVYG ","N9RVZG ", & + "N9TAXL ","N9TAYL ","N9TAZL ","N9TDXR ","N9TDYR ", & + "N9TDZR ","N9TVXG ","N9TVYG ","N9TVZG ","PACCACT ", & + "PANGACT ","PANGINP ","PRATACT ","ROOTAPPLIEDFXG","ROOTAPPLIEDFXR", & + "ROOTAPPLIEDFYG","ROOTAPPLIEDFYR","ROOTAPPLIEDFZG","ROOTAPPLIEDFZR","ROOTAPPLIEDMXG", & + "ROOTAPPLIEDMXR","ROOTAPPLIEDMYG","ROOTAPPLIEDMYR","ROOTAPPLIEDMZG","ROOTAPPLIEDMZR", & + "ROOTFXR ","ROOTFYR ","ROOTFZR ","ROOTMXR ","ROOTMYR ", & + "ROOTMZR ","TIPRAXL ","TIPRAYL ","TIPRAZL ","TIPRDXR ", & + "TIPRDYR ","TIPRDZR ","TIPRVXG ","TIPRVYG ","TIPRVZG ", & + "TIPTAXL ","TIPTAYL ","TIPTAZL ","TIPTDXR ","TIPTDYR ", & + "TIPTDZR ","TIPTVXG ","TIPTVYG ","TIPTVZG "/) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(364) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + N1DFxl , N1DFyl , N1DFzl , N1DMxl , N1DMyl , & + N1DMzl , N1Fxl , N1Fyl , N1Fzl , N1Mxl , & + N1Myl , N1Mzl , N1PFxl , N1PFyl , N1PFzl , & + N1PMxl , N1PMyl , N1PMzl , N1RAXl , N1RAYl , & + N1RAZl , N1RDxr , N1RDyr , N1RDzr , N1RVXg , & + N1RVYg , N1RVZg , N1TAXl , N1TAYl , N1TAZl , & + N1TDxr , N1TDyr , N1TDzr , N1TVXg , N1TVYg , & + N1TVZg , N2DFxl , N2DFyl , N2DFzl , N2DMxl , & + N2DMyl , N2DMzl , N2Fxl , N2Fyl , N2Fzl , & + N2Mxl , N2Myl , N2Mzl , N2PFxl , N2PFyl , & + N2PFzl , N2PMxl , N2PMyl , N2PMzl , N2RAXl , & + N2RAYl , N2RAZl , N2RDxr , N2RDyr , N2RDzr , & + N2RVXg , N2RVYg , N2RVZg , N2TAXl , N2TAYl , & + N2TAZl , N2TDxr , N2TDyr , N2TDzr , N2TVXg , & + N2TVYg , N2TVZg , N3DFxl , N3DFyl , N3DFzl , & + N3DMxl , N3DMyl , N3DMzl , N3Fxl , N3Fyl , & + N3Fzl , N3Mxl , N3Myl , N3Mzl , N3PFxl , & + N3PFyl , N3PFzl , N3PMxl , N3PMyl , N3PMzl , & + N3RAXl , N3RAYl , N3RAZl , N3RDxr , N3RDyr , & + N3RDzr , N3RVXg , N3RVYg , N3RVZg , N3TAXl , & + N3TAYl , N3TAZl , N3TDxr , N3TDyr , N3TDzr , & + N3TVXg , N3TVYg , N3TVZg , N4DFxl , N4DFyl , & + N4DFzl , N4DMxl , N4DMyl , N4DMzl , N4Fxl , & + N4Fyl , N4Fzl , N4Mxl , N4Myl , N4Mzl , & + N4PFxl , N4PFyl , N4PFzl , N4PMxl , N4PMyl , & + N4PMzl , N4RAXl , N4RAYl , N4RAZl , N4RDxr , & + N4RDyr , N4RDzr , N4RVXg , N4RVYg , N4RVZg , & + N4TAXl , N4TAYl , N4TAZl , N4TDxr , N4TDyr , & + N4TDzr , N4TVXg , N4TVYg , N4TVZg , N5DFxl , & + N5DFyl , N5DFzl , N5DMxl , N5DMyl , N5DMzl , & + N5Fxl , N5Fyl , N5Fzl , N5Mxl , N5Myl , & + N5Mzl , N5PFxl , N5PFyl , N5PFzl , N5PMxl , & + N5PMyl , N5PMzl , N5RAXl , N5RAYl , N5RAZl , & + N5RDxr , N5RDyr , N5RDzr , N5RVXg , N5RVYg , & + N5RVZg , N5TAXl , N5TAYl , N5TAZl , N5TDxr , & + N5TDyr , N5TDzr , N5TVXg , N5TVYg , N5TVZg , & + N6DFxl , N6DFyl , N6DFzl , N6DMxl , N6DMyl , & + N6DMzl , N6Fxl , N6Fyl , N6Fzl , N6Mxl , & + N6Myl , N6Mzl , N6PFxl , N6PFyl , N6PFzl , & + N6PMxl , N6PMyl , N6PMzl , N6RAXl , N6RAYl , & + N6RAZl , N6RDxr , N6RDyr , N6RDzr , N6RVXg , & + N6RVYg , N6RVZg , N6TAXl , N6TAYl , N6TAZl , & + N6TDxr , N6TDyr , N6TDzr , N6TVXg , N6TVYg , & + N6TVZg , N7DFxl , N7DFyl , N7DFzl , N7DMxl , & + N7DMyl , N7DMzl , N7Fxl , N7Fyl , N7Fzl , & + N7Mxl , N7Myl , N7Mzl , N7PFxl , N7PFyl , & + N7PFzl , N7PMxl , N7PMyl , N7PMzl , N7RAXl , & + N7RAYl , N7RAZl , N7RDxr , N7RDyr , N7RDzr , & + N7RVXg , N7RVYg , N7RVZg , N7TAXl , N7TAYl , & + N7TAZl , N7TDxr , N7TDyr , N7TDzr , N7TVXg , & + N7TVYg , N7TVZg , N8DFxl , N8DFyl , N8DFzl , & + N8DMxl , N8DMyl , N8DMzl , N8Fxl , N8Fyl , & + N8Fzl , N8Mxl , N8Myl , N8Mzl , N8PFxl , & + N8PFyl , N8PFzl , N8PMxl , N8PMyl , N8PMzl , & + N8RAXl , N8RAYl , N8RAZl , N8RDxr , N8RDyr , & + N8RDzr , N8RVXg , N8RVYg , N8RVZg , N8TAXl , & + N8TAYl , N8TAZl , N8TDxr , N8TDyr , N8TDzr , & + N8TVXg , N8TVYg , N8TVZg , N9DFxl , N9DFyl , & + N9DFzl , N9DMxl , N9DMyl , N9DMzl , N9Fxl , & + N9Fyl , N9Fzl , N9Mxl , N9Myl , N9Mzl , & + N9PFxl , N9PFyl , N9PFzl , N9PMxl , N9PMyl , & + N9PMzl , N9RAXl , N9RAYl , N9RAZl , N9RDxr , & + N9RDyr , N9RDzr , N9RVXg , N9RVYg , N9RVZg , & + N9TAXl , N9TAYl , N9TAZl , N9TDxr , N9TDyr , & + N9TDzr , N9TVXg , N9TVYg , N9TVZg , PAccAct , & + PAngAct , PAngInp , PRatAct , RootAppliedFxg , RootAppliedFxr , & + RootAppliedFyg , RootAppliedFyr , RootAppliedFzg , RootAppliedFzr , RootAppliedMxg , & + RootAppliedMxr , RootAppliedMyg , RootAppliedMyr , RootAppliedMzg , RootAppliedMzr , & + RootFxr , RootFyr , RootFzr , RootMxr , RootMyr , & + RootMzr , TipRAXl , TipRAYl , TipRAZl , TipRDxr , & + TipRDyr , TipRDzr , TipRVXg , TipRVYg , TipRVZg , & + TipTAXl , TipTAYl , TipTAZl , TipTDxr , TipTDyr , & + TipTDzr , TipTVXg , TipTVYg , TipTVZg /) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(364) = (/ & ! This lists the units corresponding to the allowed parameters + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(deg/s^2)","(deg/s^2)", & + "(deg/s^2)","(-) ","(-) ","(-) ","(deg/s) ", & + "(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(m/s) ","(m/s) ", & + "(m/s) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2)", & + "(deg/s^2)","(deg/s^2)","(-) ","(-) ","(-) ", & + "(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ", & + "(m/s) ","(m/s) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(deg/s^2)","(deg/s^2)","(deg/s^2)","(-) ","(-) ", & + "(-) ","(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(m/s) ","(m/s) ","(m/s) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(deg/s^2)","(deg/s^2)","(deg/s^2)","(-) ", & + "(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(m/s) ","(m/s) ","(m/s) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(deg/s^2)","(deg/s^2)","(deg/s^2)", & + "(-) ","(-) ","(-) ","(deg/s) ","(deg/s) ", & + "(deg/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(m/s) ","(m/s) ","(m/s) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(deg/s^2)","(deg/s^2)", & + "(deg/s^2)","(-) ","(-) ","(-) ","(deg/s) ", & + "(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(m/s) ","(m/s) ", & + "(m/s) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(deg/s^2)", & + "(deg/s^2)","(deg/s^2)","(-) ","(-) ","(-) ", & + "(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(m/s) ", & + "(m/s) ","(m/s) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(deg/s^2)","(deg/s^2)","(deg/s^2)","(-) ","(-) ", & + "(-) ","(deg/s) ","(deg/s) ","(deg/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(m/s) ","(m/s) ","(m/s) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(deg/s^2)","(deg/s^2)","(deg/s^2)","(-) ", & + "(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(m/s) ","(m/s) ","(m/s) ","(deg/s^2)", & + "(deg) ","(deg) ","(deg/s) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(deg/s^2)","(deg/s^2)","(deg/s^2)","(-) ", & + "(-) ","(-) ","(deg/s) ","(deg/s) ","(deg/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(m/s) ","(m/s) ","(m/s) "/) + + INTEGER, PARAMETER :: RootAppliedLd(12) = (/ & ! all applied load mapped to root outputs. For convenience in setting calculation flag + RootAppliedFxr, RootAppliedFyr, RootAppliedFzr, RootAppliedMxr, RootAppliedMyr, RootAppliedMzr, & + RootAppliedFxg, RootAppliedFyg, RootAppliedFzg, RootAppliedMxg, RootAppliedMyg, RootAppliedMzg /) ! Initialize values @@ -1357,7 +1444,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) ! ..... Developer must add checking for invalid inputs here: ..... DO I = p%NNodeOuts+1,9 ! Invalid nodes - + InvalidOutput( NFl( i,:) ) = .true. InvalidOutput( NMl( i,:) ) = .true. InvalidOutput( NTDr(i,:) ) = .true. @@ -1458,6 +1545,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) p%OutParam(I)%Units = ParamUnitsAry(Indx) ! it's a valid output if ( p%OutParam(I)%Indx >= N1DFxl .and. p%OutParam(I)%Indx <= N9DMzl ) p%OutInputs = .true. + if ( any(RootAppliedLd==p%OutParam(I)%Indx) ) p%CompAppliedLdAtRoot = .true. ! need to setup meshes END IF ELSE ! this channel isn't valid p%OutParam(I)%Indx = Time ! pick any valid channel (I just picked "Time" here because it's universal) @@ -1911,11 +1999,46 @@ SUBROUTINE Calc_WriteOutput( p, AllOuts, y, m, ErrStat, ErrMsg, CalcWriteOutput end do ! nodes end if - - end if - + ! compute mapping of applied distributed loads to the root location + ! FIXME: currently not mapping the PointLoads over since there is no motion mesh associated with the PointLoad + ! To get the PointLoads mapped, the following is necessary + ! 1. create a y%BldMotionFE mesh at the finite element points (this would be very useful someday) + ! - take position info directly from uuu and state information etc. + ! - Add output channels for this for comparison + ! 2. make u%PointLoad a sibling of y%BldMotionFE + ! 3. Setup m%Map_u_PtLoad_to_R + ! 4. map loads and do summation here (remember Transfer zero's out forces/moments, so add temp arrays to hold those) + if (p%CompAppliedLdAtRoot .and. p%BldMotionNodeLoc == BD_MESH_QP) then + + ! shorthand to simplify life + associate(RF => m%LoadsAtRoot%Force, RM => m%LoadsAtRoot%Moment) + + ! mapping of distributed loads to LoadsAtRoot + call Transfer_Line2_to_Point( m%u2%DistrLoad, m%LoadsAtRoot, m%Map_u_DistrLoad_to_R, ErrStat2, ErrMsg2, y%BldMotion, m%u2%RootMotion ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Global coords + AllOuts( RootAppliedFxg ) = RF(1,1) + AllOuts( RootAppliedFyg ) = RF(2,1) + AllOuts( RootAppliedFzg ) = RF(3,1) + AllOuts( RootAppliedMxg ) = RM(1,1) + AllOuts( RootAppliedMyg ) = RM(2,1) + AllOuts( RootAppliedMzg ) = RM(3,1) + + ! Root coords + temp_vec = MATMUL(m%u2%RootMotion%Orientation(:,:,1),RF(:,1)) + AllOuts( RootAppliedFxr ) = temp_vec(1) + AllOuts( RootAppliedFyr ) = temp_vec(2) + AllOuts( RootAppliedFzr ) = temp_vec(3) + temp_vec = MATMUL(m%u2%RootMotion%Orientation(:,:,1),RM(:,1)) + AllOuts( RootAppliedMxr ) = temp_vec(1) + AllOuts( RootAppliedMyr ) = temp_vec(2) + AllOuts( RootAppliedMzr ) = temp_vec(3) + + end associate + endif END SUBROUTINE Calc_WriteOutput diff --git a/modules/beamdyn/src/BeamDyn_Subs.f90 b/modules/beamdyn/src/BeamDyn_Subs.f90 index c1b9796a07..823fa9d0e2 100644 --- a/modules/beamdyn/src/BeamDyn_Subs.f90 +++ b/modules/beamdyn/src/BeamDyn_Subs.f90 @@ -146,7 +146,7 @@ SUBROUTINE BD_CrvMatrixR(cc,Rr) c2 = cc(2)/4.0_BDKi c3 = cc(3)/4.0_BDKi ! \f$ c_0 \f$ is equivalent to \f$ 0.5 - (||\vec{c}||)^2 / 32 \f$ - c0 = 0.5_BDKi * (1.0_BDKi-c1*c1-c2*c2-c3*c3) ! 1/4 the value of the the AIAA paper (after plugging in c1, c2, c3 conversions) + c0 = 0.5_BDKi * (1.0_BDKi-c1*c1-c2*c2-c3*c3) ! 1/4 the value of the AIAA paper (after plugging in c1, c2, c3 conversions) tr0 = 1.0_BDKi - c0 ! This is 1/4 the value of the AIAA paper, after converting c0. @@ -316,7 +316,7 @@ END SUBROUTINE BD_CrvCompose SUBROUTINE BD_CrvExtractCrv(R, cc, ErrStat, ErrMsg) REAL(BDKi), INTENT(IN ) :: R(3,3) !< Rotation Matrix - REAL(BDKi), INTENT( OUT) :: cc(3) !< Crv paramters + REAL(BDKi), INTENT( OUT) :: cc(3) !< Crv parameters INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -525,13 +525,13 @@ SUBROUTINE BD_GaussPointWeight(n, x, w, ErrStat, ErrMsg) ! loop through each of the "half" n points do i = 1, n_half - ! Intial guess for ith root; based on ith root of Chebyshev polynomial + ! Initial guess for ith root; based on ith root of Chebyshev polynomial x(i) = - cos( REAL( 2*i - 1, BDKi) * pi_D / (2.0_BDKi * n_real) ) ! initialize newton iteration counter newton = 0 - p3 = 1. ! some intial big number; logic will always take at least one newton iteration + p3 = 1. ! some initial big number; logic will always take at least one newton iteration do while (abs(p3) .gt. eps .and. newton .le. newton_max) newton = newton + 1 ! keep track of number of newton iterations diff --git a/modules/beamdyn/src/BeamDyn_Types.f90 b/modules/beamdyn/src/BeamDyn_Types.f90 index 81632c30ff..81b34982b8 100644 --- a/modules/beamdyn/src/BeamDyn_Types.f90 +++ b/modules/beamdyn/src/BeamDyn_Types.f90 @@ -237,6 +237,7 @@ MODULE BeamDyn_Types LOGICAL :: RotStates = .false. !< Orient states in rotating frame during linearization? (flag) [-] LOGICAL :: RelStates = .false. !< Define states relative to root motion during linearization? (flag) [-] LOGICAL :: CompAeroMaps = .FALSE. !< flag to determine if BeamDyn is computing aero maps (true) or running a normal simulation (false) [-] + LOGICAL :: CompAppliedLdAtRoot = .FALSE. !< flag to determine if BeamDyn should compute the applied loads at root [-] END TYPE BD_ParameterType ! ======================= ! ========= BD_InputType ======= @@ -295,8 +296,10 @@ MODULE BeamDyn_Types TYPE, PUBLIC :: BD_MiscVarType TYPE(MeshType) :: u_DistrLoad_at_y !< input loads at output node locations [-] TYPE(MeshType) :: y_BldMotion_at_u !< output motions at input node locations (displacements necessary for mapping loads) [-] + TYPE(MeshType) :: LoadsAtRoot !< Applied loads mapped to root [-] TYPE(MeshMapType) :: Map_u_DistrLoad_to_y !< mapping of input loads to output node locations [-] TYPE(MeshMapType) :: Map_y_BldMotion_to_u !< mapping of output motions to input node locations (for load transfer) [-] + TYPE(MeshMapType) :: Map_u_DistrLoad_to_R !< mapping of input loads to root location [-] INTEGER(IntKi) :: Un_Sum = 0_IntKi !< unit number of summary file [-] TYPE(EqMotionQP) :: qp !< Quadrature point calculation info [-] REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: lin_A !< A (dXdx) matrix used in linearization (before RotState is applied) [-] @@ -1685,6 +1688,7 @@ subroutine BD_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg) DstParamData%RotStates = SrcParamData%RotStates DstParamData%RelStates = SrcParamData%RelStates DstParamData%CompAeroMaps = SrcParamData%CompAeroMaps + DstParamData%CompAppliedLdAtRoot = SrcParamData%CompAppliedLdAtRoot end subroutine subroutine BD_DestroyParam(ParamData, ErrStat, ErrMsg) @@ -1899,6 +1903,7 @@ subroutine BD_PackParam(RF, Indata) call RegPack(RF, InData%RotStates) call RegPack(RF, InData%RelStates) call RegPack(RF, InData%CompAeroMaps) + call RegPack(RF, InData%CompAppliedLdAtRoot) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -2013,6 +2018,7 @@ subroutine BD_UnPackParam(RF, OutData) call RegUnpack(RF, OutData%RotStates); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%RelStates); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%CompAeroMaps); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%CompAppliedLdAtRoot); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine BD_CopyInput(SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg) @@ -2747,12 +2753,18 @@ subroutine BD_CopyMisc(SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg) call MeshCopy(SrcMiscData%y_BldMotion_at_u, DstMiscData%y_BldMotion_at_u, CtrlCode, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return + call MeshCopy(SrcMiscData%LoadsAtRoot, DstMiscData%LoadsAtRoot, CtrlCode, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return call NWTC_Library_CopyMeshMapType(SrcMiscData%Map_u_DistrLoad_to_y, DstMiscData%Map_u_DistrLoad_to_y, CtrlCode, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return call NWTC_Library_CopyMeshMapType(SrcMiscData%Map_y_BldMotion_to_u, DstMiscData%Map_y_BldMotion_to_u, CtrlCode, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return + call NWTC_Library_CopyMeshMapType(SrcMiscData%Map_u_DistrLoad_to_R, DstMiscData%Map_u_DistrLoad_to_R, CtrlCode, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return DstMiscData%Un_Sum = SrcMiscData%Un_Sum call BD_CopyEqMotionQP(SrcMiscData%qp, DstMiscData%qp, CtrlCode, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3138,10 +3150,14 @@ subroutine BD_DestroyMisc(MiscData, ErrStat, ErrMsg) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call MeshDestroy( MiscData%y_BldMotion_at_u, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call MeshDestroy( MiscData%LoadsAtRoot, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call NWTC_Library_DestroyMeshMapType(MiscData%Map_u_DistrLoad_to_y, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call NWTC_Library_DestroyMeshMapType(MiscData%Map_y_BldMotion_to_u, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call NWTC_Library_DestroyMeshMapType(MiscData%Map_u_DistrLoad_to_R, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call BD_DestroyEqMotionQP(MiscData%qp, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (allocated(MiscData%lin_A)) then @@ -3247,8 +3263,10 @@ subroutine BD_PackMisc(RF, Indata) if (RF%ErrStat >= AbortErrLev) return call MeshPack(RF, InData%u_DistrLoad_at_y) call MeshPack(RF, InData%y_BldMotion_at_u) + call MeshPack(RF, InData%LoadsAtRoot) call NWTC_Library_PackMeshMapType(RF, InData%Map_u_DistrLoad_to_y) call NWTC_Library_PackMeshMapType(RF, InData%Map_y_BldMotion_to_u) + call NWTC_Library_PackMeshMapType(RF, InData%Map_u_DistrLoad_to_R) call RegPack(RF, InData%Un_Sum) call BD_PackEqMotionQP(RF, InData%qp) call RegPackAlloc(RF, InData%lin_A) @@ -3296,8 +3314,10 @@ subroutine BD_UnPackMisc(RF, OutData) if (RF%ErrStat /= ErrID_None) return call MeshUnpack(RF, OutData%u_DistrLoad_at_y) ! u_DistrLoad_at_y call MeshUnpack(RF, OutData%y_BldMotion_at_u) ! y_BldMotion_at_u + call MeshUnpack(RF, OutData%LoadsAtRoot) ! LoadsAtRoot call NWTC_Library_UnpackMeshMapType(RF, OutData%Map_u_DistrLoad_to_y) ! Map_u_DistrLoad_to_y call NWTC_Library_UnpackMeshMapType(RF, OutData%Map_y_BldMotion_to_u) ! Map_y_BldMotion_to_u + call NWTC_Library_UnpackMeshMapType(RF, OutData%Map_u_DistrLoad_to_R) ! Map_u_DistrLoad_to_R call RegUnpack(RF, OutData%Un_Sum); if (RegCheckErr(RF, RoutineName)) return call BD_UnpackEqMotionQP(RF, OutData%qp) ! qp call RegUnpackAlloc(RF, OutData%lin_A); if (RegCheckErr(RF, RoutineName)) return diff --git a/modules/beamdyn/src/Driver_Beam.f90 b/modules/beamdyn/src/Driver_Beam.f90 index 8b1d51d194..0141190d7e 100644 --- a/modules/beamdyn/src/Driver_Beam.f90 +++ b/modules/beamdyn/src/Driver_Beam.f90 @@ -63,8 +63,8 @@ PROGRAM BeamDyn_Driver_Program REAL(DbKi) :: TiLstPrn ! The simulation time of the last print (to file) [(s)] REAL(ReKi) :: PrevClockTime ! Clock time at start of simulation in seconds [(s)] REAL(ReKi) :: UsrTime1 ! User CPU time for simulation initialization [(s)] - REAL(ReKi) :: UsrTime2 ! User CPU time for simulation (without intialization) [(s)] - INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime ! Start time of simulation (including intialization) [-] + REAL(ReKi) :: UsrTime2 ! User CPU time for simulation (without initialization) [(s)] + INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime ! Start time of simulation (including initialization) [-] INTEGER(IntKi) , DIMENSION(1:8) :: SimStrtTime ! Start time of simulation (after initialization) [-] CHARACTER(200) :: git_commit ! String containing the current git commit hash diff --git a/modules/beamdyn/src/Registry_BeamDyn.txt b/modules/beamdyn/src/Registry_BeamDyn.txt index 448cd81abe..1500bd2a20 100644 --- a/modules/beamdyn/src/Registry_BeamDyn.txt +++ b/modules/beamdyn/src/Registry_BeamDyn.txt @@ -250,6 +250,7 @@ typedef ^ ParameterType Integer Jac_nx - typedef ^ ParameterType logical RotStates - - - "Orient states in rotating frame during linearization? (flag)" - typedef ^ ParameterType Logical RelStates - - - "Define states relative to root motion during linearization? (flag)" - typedef ^ ParameterType LOGICAL CompAeroMaps - .FALSE. - "flag to determine if BeamDyn is computing aero maps (true) or running a normal simulation (false)" - +typedef ^ ParameterType LOGICAL CompAppliedLdAtRoot - .FALSE. - "flag to determine if BeamDyn should compute the applied loads at root" - # ..... Inputs @@ -330,8 +331,10 @@ typedef ^ EqMotionQP ^ Yd :::: - - "Dissipative # e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. typedef ^ MiscVarType MeshType u_DistrLoad_at_y - - - "input loads at output node locations" - typedef ^ MiscVarType MeshType y_BldMotion_at_u - - - "output motions at input node locations (displacements necessary for mapping loads)" - +typedef ^ MiscVarType MeshType LoadsAtRoot - - - "Applied loads mapped to root" - typedef ^ MiscVarType MeshMapType Map_u_DistrLoad_to_y - - - "mapping of input loads to output node locations" - typedef ^ MiscVarType MeshMapType Map_y_BldMotion_to_u - - - "mapping of output motions to input node locations (for load transfer)" - +typedef ^ MiscVarType MeshMapType Map_u_DistrLoad_to_R - - - "mapping of input loads to root location" - typedef ^ MiscVarType IntKi Un_Sum - - - "unit number of summary file" - typedef ^ MiscVarType EqMotionQP qp - - - "Quadrature point calculation info" - typedef ^ MiscVarType R8Ki lin_A {:}{:} - - "A (dXdx) matrix used in linearization (before RotState is applied)" - diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index 05ad19300c..486dfc3c18 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -5211,7 +5211,7 @@ SUBROUTINE Coeff(p,InputFileData, ErrStat, ErrMsg) END SUBROUTINE Coeff !---------------------------------------------------------------------------------------------------------------------------------- !> This routine calculates the initial blade deflections. -!! Base the intial values of the blade DOFs, INITQF1, INITQF2, and +!! Base the initial values of the blade DOFs, INITQF1, INITQF2, and !! INITQE1, on OoPDefl and IPDefl. !! Write messages to the screen if the specified initial tip displacements !! are incompatible with the enabled DOFs. diff --git a/modules/feamooring/src/FEAM.f90 b/modules/feamooring/src/FEAM.f90 index a97aeee76b..76ac6fccbd 100644 --- a/modules/feamooring/src/FEAM.f90 +++ b/modules/feamooring/src/FEAM.f90 @@ -1444,7 +1444,7 @@ SUBROUTINE FEAM_CalcOutput ( t, u, p, x, xd, z, OtherState, y, misc, ErrStat, CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! Local variables - REAL(ReKi) :: AllOuts(MaxOutPts) ! All the the available output channels + REAL(ReKi) :: AllOuts(MaxOutPts) ! All the available output channels INTEGER(IntKi) :: I,J ! Generic loop index ! INTEGER(IntKi) :: K ! Blade index ! INTEGER(IntKi) :: ErrStat2 @@ -2208,7 +2208,7 @@ SUBROUTINE SetPrimaryParameters( p, InputFileData, ErrStat, ErrMsg ) p%NEQ(:) = (p%NumElems+1)*p%NHBD-1 ! number of equations DO I = 1, p%NumLines - p%GSL (I,:,:) = InputFileData%GSL (I,:,:) !bjj: todo: Inspector flags this as unintialized + p%GSL (I,:,:) = InputFileData%GSL (I,:,:) !bjj: todo: Inspector flags this as uninitialized p%LineCI (I) = InputFileData%LineCI (I) p%LineCD (I) = InputFileData%LineCD (I) p%Elength (I) = InputFileData%LUnstrLen(I)/p%NumElems diff --git a/modules/hydrodyn/src/Conv_Radiation.f90 b/modules/hydrodyn/src/Conv_Radiation.f90 index 59842ddd2c..0584f2a8ef 100644 --- a/modules/hydrodyn/src/Conv_Radiation.f90 +++ b/modules/hydrodyn/src/Conv_Radiation.f90 @@ -178,7 +178,7 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, InitOut, E RETURN END IF - ! Initialize all elements of the xd%XDHistory array with the intial values of u%Velocity + ! Initialize all elements of the xd%XDHistory array with the initial values of u%Velocity DO K = 0,p%NStepRdtn-1 DO J = 1,6*p%NBody ! Loop through all DOFs xd%XDHistory(K,J) = u%Velocity(J) diff --git a/modules/hydrodyn/src/HydroDyn.f90 b/modules/hydrodyn/src/HydroDyn.f90 index eb668763be..25afdd70e9 100644 --- a/modules/hydrodyn/src/HydroDyn.f90 +++ b/modules/hydrodyn/src/HydroDyn.f90 @@ -268,11 +268,10 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I END IF ! Copy Additional preload, stiffness, and damping to the parameters - p%AddF0 = InputFileData%AddF0 - p%AddCLin = InputFileData%AddCLin - p%AddBLin = InputFileData%AddBLin - p%AddBQuad = InputFileData%AddBQuad - + call move_alloc(InputFileData%AddF0, p%AddF0 ) + call move_alloc(InputFileData%AddCLin, p%AddCLin ) + call move_alloc(InputFileData%AddBLin, p%AddBLin ) + call move_alloc(InputFileData%AddBQuad,p%AddBQuad) ! Set summary unit number in Morison initialization input data InputFileData%Morison%UnSum = InputFileData%UnSum diff --git a/modules/hydrodyn/src/HydroDyn_DriverCode.f90 b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 index 4c2ccf61bb..a0cc08d04e 100644 --- a/modules/hydrodyn/src/HydroDyn_DriverCode.f90 +++ b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 @@ -73,11 +73,11 @@ PROGRAM HydroDynDriver TYPE(HD_Drvr_Data) :: drvrData ! Data for the driver program (from an input file) TYPE(HD_Drvr_MappingData) :: mappingData ! data for mesh mappings in the driver - integer :: StrtTime (8) ! Start time of simulation (including intialization) + integer :: StrtTime (8) ! Start time of simulation (including initialization) integer :: SimStrtTime (8) ! Start time of simulation (after initialization) real(ReKi) :: PrevClockTime ! Clock time at start of simulation in seconds real(ReKi) :: UsrTime1 ! User CPU time for simulation initialization - real(ReKi) :: UsrTime2 ! User CPU time for simulation (without intialization) + real(ReKi) :: UsrTime2 ! User CPU time for simulation (without initialization) real(DbKi) :: TiLstPrn ! The simulation time of the last print integer :: n_SttsTime ! Number of time steps between screen status messages (-) diff --git a/modules/hydrodyn/src/Morison.f90 b/modules/hydrodyn/src/Morison.f90 index 32ccbe48ae..2c225611dd 100644 --- a/modules/hydrodyn/src/Morison.f90 +++ b/modules/hydrodyn/src/Morison.f90 @@ -225,7 +225,7 @@ END SUBROUTINE FindInterpFactor FUNCTION InterpWrappedStpInt( XValIn, XAry, YAry, Ind, AryLen ) - ! This funtion returns a y-value that corresponds to an input x-value which is wrapped back + ! This function returns a y-value that corresponds to an input x-value which is wrapped back ! into the range [1-XAry(AryLen). It finds a x-value which corresponds to a value in the XAry where XAry(Ind-1) < MOD(XValIn, XAry(AryLen)) <= XAry(Ind) ! It is assumed that XAry is sorted in ascending order. ! It uses the passed index as the starting point and does a stepwise interpolation from there. This is @@ -306,7 +306,7 @@ END FUNCTION InterpWrappedStpInt ! ( XVal, XAry, YAry, Ind, AryLen ) FUNCTION InterpWrappedStpLogical( XValIn, XAry, YAry, Ind, AryLen ) - ! This funtion returns a y-value that corresponds to an input x-value which is wrapped back + ! This function returns a y-value that corresponds to an input x-value which is wrapped back ! into the range [0-XAry(AryLen) by interpolating into the arrays. ! It is assumed that XAry is sorted in ascending order. ! It uses the passed index as the starting point and does a stepwise interpolation from there. This is @@ -437,7 +437,7 @@ SUBROUTINE CylTaperCalc(R1, R2, H, taperV, h_c) if ( EqualRealNos(R1, R2) ) then ! if just a cylinder taperV = abs(pi*R1*R1*H) h_c = H/2.0 - elseif ( EqualRealNos(R1,0.0_ReKi) ) then ! seperate this case out because it gives a divide by zero in general formula + elseif ( EqualRealNos(R1,0.0_ReKi) ) then ! separate this case out because it gives a divide by zero in general formula taperV = abs(1.0/3.0*pi*R2*R2*H) ! cone volume h_c = 3.0/4.0*H ! from base else @@ -490,7 +490,7 @@ SUBROUTINE CylInertia(R1, R2, H, rho, Il, Ir) if ( EqualRealNos(R1, R2) ) then ! if just a cylinder Ir = abs(1.0/12.0* rho*pi*R1*R1*H *(3.0*R1*R1 + 4.0*H*H)) ! radial inertia about node 1 Il = abs(0.5* rho*pi*R1*R1*H *R1*R1) - ELSEIF ( EqualRealNos(R1,0.0_ReKi) ) then ! seperate this case out because it gives a divide by zero in general formula + ELSEIF ( EqualRealNos(R1,0.0_ReKi) ) then ! separate this case out because it gives a divide by zero in general formula Ir = abs(rho*pi*(1.0/20.0/m + 1.0/5.0/m**3) * R2**5) Il = abs(1.0/10.0*rho*pi/m*R2**5) ELSE @@ -1870,7 +1870,7 @@ subroutine FlipMemberNodeData( member, nodes, doSwap) doSwap = .TRUE. ! Z1 > Z2 END IF - ! If we swap the the nodes, we need know this later when calculating the normal vector to the ends + ! If we swap the nodes, we need know this later when calculating the normal vector to the ends member%Flipped = doSwap IF ( doSwap ) THEN member%NodeIndx(1) = j2 @@ -2225,7 +2225,7 @@ subroutine SetMemberProperties_Cyl( gravity, member, MCoefMod, MmbrCoefIDIndx, M member%Vballast = member%Vballast + Vballast_l + Vballast_u else if ((member%memfloodstatus > 0) .and. (member%FillFSLoc > Za) .AND. (member%FillFSLoc < Zb)) then ! Partially flooded element - + member%floodstatus(i) = 2 member%elem_fill = i member%h_fill = member%l_fill - (i-1)*dl diff --git a/modules/hydrodyn/src/Morison_Output.f90 b/modules/hydrodyn/src/Morison_Output.f90 index 16ccff3178..4aa0d64dd6 100644 --- a/modules/hydrodyn/src/Morison_Output.f90 +++ b/modules/hydrodyn/src/Morison_Output.f90 @@ -7980,7 +7980,7 @@ SUBROUTINE MrsnOut_Init( InitInp, y, p, InitOut, ErrStat, ErrMsg ) TYPE(Morison_InitInputType ), INTENT( IN ) :: InitInp ! data needed to initialize the output module TYPE(Morison_OutputType), INTENT( INOUT ) :: y ! Morison module's output data - TYPE(Morison_ParameterType), INTENT( INOUT ) :: p ! Morison module paramters + TYPE(Morison_ParameterType), INTENT( INOUT ) :: p ! Morison module parameters TYPE(Morison_InitOutputType ), INTENT( INOUT ) :: InitOut ! Morison module initialization output data INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None diff --git a/modules/hydrodyn/src/WAMIT.f90 b/modules/hydrodyn/src/WAMIT.f90 index d04c5a823b..bf1260f4ca 100644 --- a/modules/hydrodyn/src/WAMIT.f90 +++ b/modules/hydrodyn/src/WAMIT.f90 @@ -126,12 +126,12 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ErrS ! These are dummy variables to satisfy the framework, but are not used - TYPE(Conv_Rdtn_InitInputType) :: Conv_Rdtn_InitInp ! Local version of the intialization data for the radiation module + TYPE(Conv_Rdtn_InitInputType) :: Conv_Rdtn_InitInp ! Local version of the initialization data for the radiation module TYPE(Conv_Rdtn_InitOutputType) :: Conv_Rdtn_InitOut ! Initialization Outputs from the Conv_Rdtn module initialization !TYPE(Conv_Rdtn_InitOutputType) :: Conv_RdtnInitOutData - TYPE(SS_Rad_InitInputType) :: SS_Rdtn_InitInp ! Local version of the intialization data for the radiation module + TYPE(SS_Rad_InitInputType) :: SS_Rdtn_InitInp ! Local version of the initialization data for the radiation module TYPE(SS_Rad_InitOutputType) :: SS_Rdtn_InitOut ! Initialization Outputs from the SS_Rdtn module initialization - TYPE(SS_Exc_InitInputType) :: SS_Exctn_InitInp ! Local version of the intialization data for the SS wave excitation module + TYPE(SS_Exc_InitInputType) :: SS_Exctn_InitInp ! Local version of the initialization data for the SS wave excitation module TYPE(SS_Exc_InitOutputType) :: SS_Exctn_InitOut ! Initialization Outputs from the SS wave excitation module initialization @@ -1163,7 +1163,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ErrS DO iHdg = 1,p%NExctnHdg+1 DO J = 1,6*p%NBody ! Loop through all wave excitation forces and moments CALL ApplyFFT_cx ( p%WaveExctnGrid(0:p%WaveField%NStepWave-1,1_IntKi,1_IntKi,iHdg,J), WaveExctnC(:,iHdg,J), FFT_Data, ErrStat2 ) - CALL SetErrStat( ErrStat2, ' An error occured while applying an FFT to WaveExctnC.', ErrStat, ErrMsg, RoutineName) + CALL SetErrStat( ErrStat2, ' An error occurred while applying an FFT to WaveExctnC.', ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN @@ -1249,7 +1249,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ErrS iY = (iGrid-1) / p%ExctnGridParams%n(2) + 1 DO J = 1,6*p%NBody ! Loop through all wave excitation forces and moments CALL ApplyFFT_cx ( p%WaveExctnGrid(0:p%WaveField%NStepWave-1,iX,iY,iHdg,J), WaveExctnCGrid(:,iGrid,iHdg,J), FFT_Data, ErrStat2 ) - CALL SetErrStat( ErrStat2, ' An error occured while applying an FFT to WaveExctnC.', ErrStat, ErrMsg, RoutineName) + CALL SetErrStat( ErrStat2, ' An error occurred while applying an FFT to WaveExctnC.', ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN @@ -1332,7 +1332,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ErrS ! representations of the wave kinematics without stretching: CALL InitFFT ( p%WaveField%NStepWave, FFT_Data, .TRUE., ErrStat2 ) - CALL SetErrStat(ErrStat2,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStat2,'Error occurred while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -1341,7 +1341,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ErrS ! We'll need the following for wave stretching once we implement it. ! NOTE THIS IS OVERWRITING THE WAVEFIELD WaveElev0 PARAMETER DATA CALL ApplyFFT_cx ( SS_Exctn_InitInp%WaveField%WaveElev0(0:p%WaveField%NStepWave-1), tmpComplexArr(: ), FFT_Data, ErrStat2 ) - CALL SetErrStat(ErrStat2,'Error occured while applying the FFT to WaveElev0.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStat2,'Error occurred while applying the FFT to WaveElev0.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN diff --git a/modules/hydrodyn/src/WAMIT2.f90 b/modules/hydrodyn/src/WAMIT2.f90 index f62043b92f..3c38462510 100644 --- a/modules/hydrodyn/src/WAMIT2.f90 +++ b/modules/hydrodyn/src/WAMIT2.f90 @@ -1339,7 +1339,7 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg ! Initialize the FFT library CALL InitCFFT ( InitInp%WaveField%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) ! Complex result FFT initialize - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) @@ -1620,7 +1620,7 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg ! Done with the FFT library routines, so end them. CALL ExitCFFT(FFT_Data, ErrStatTmp) - CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) @@ -1803,7 +1803,7 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Initialize the FFT library. Do not apply normalization. CALL InitFFT ( InitInp%WaveField%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN call cleanup() RETURN @@ -1990,7 +1990,7 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Now we apply the FFT to the result of the sum CALL ApplyFFT_cx( TmpDiffQTFForce(:), TmpComplexArr(:,ThisDim), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to the second term of the difference QTF.', & + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT to the second term of the difference QTF.', & ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN call cleanup() @@ -2015,7 +2015,7 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Done with the FFT library routines, so end them. CALL ExitFFT(FFT_Data, ErrStatTmp) - CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN call cleanup() RETURN @@ -2234,7 +2234,7 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat ! Initialize the FFT library. Normalization not required in this formulation. CALL InitFFT ( InitInp%WaveField%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) ! FIXME: - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) IF (ALLOCATED(SumQTFForce)) DEALLOCATE(SumQTFForce,STAT=ErrStatTmp) @@ -2516,7 +2516,7 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat ! Now we apply the FFT to the result of the sum. CALL ApplyFFT_cx( Term1Array(:), Term1ArrayC(:,ThisDim), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to the first term of the Sum QTF.', & + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT to the first term of the Sum QTF.', & ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) @@ -2525,7 +2525,7 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat ! Now we apply the FFT to the result of the sum. CALL ApplyFFT_cx( Term2Array(:), Term2ArrayC(:,ThisDim), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to the second term of the Sum QTF.', & + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT to the second term of the Sum QTF.', & ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) @@ -2548,7 +2548,7 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat ! Done with the FFT library routines, so end them. CALL ExitFFT(FFT_Data, ErrStatTmp) - CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) RETURN diff --git a/modules/icedyn/src/IceDyn.f90 b/modules/icedyn/src/IceDyn.f90 index 9abd548d9f..87440da45c 100644 --- a/modules/icedyn/src/IceDyn.f90 +++ b/modules/icedyn/src/IceDyn.f90 @@ -2516,7 +2516,7 @@ END FUNCTION SolveLambda FUNCTION BrkLdPar (alpha, lambda, mu) Result (A) - !BRKLDPAR Calculates Ralston's horizontal force paramters A1, A2, A3, A4 and B1, B2. + !BRKLDPAR Calculates Ralston's horizontal force parameters A1, A2, A3, A4 and B1, B2. ! Detailed explanation in Ralston's paper: Ice Force Desgin Consideration ! for Conical Offshore Structure and Ice Module Manual diff --git a/modules/icefloe/src/icefloe/IceFlexIEC.f90 b/modules/icefloe/src/icefloe/IceFlexIEC.f90 index 6245d38b57..8e49a28ada 100644 --- a/modules/icefloe/src/icefloe/IceFlexIEC.f90 +++ b/modules/icefloe/src/icefloe/IceFlexIEC.f90 @@ -46,7 +46,7 @@ subroutine initFlexIEC (iceInput, myIceParams, iceLog) real(ReKi) :: freq ! frequency of sinusoidal load integer(IntKi) :: nL !err, -! initialize the common parmeters for flexural ice failure +! initialize the common parameters for flexural ice failure call initIceFlex(iceInput, inParams, myIceParams, iceLog) call logMessage(iceLog, newLine//' Setting up flexural failure by Ralston method ') diff --git a/modules/icefloe/src/icefloe/IceFlexISO.f90 b/modules/icefloe/src/icefloe/IceFlexISO.f90 index aeb4e9f25d..4e292c8bc5 100644 --- a/modules/icefloe/src/icefloe/IceFlexISO.f90 +++ b/modules/icefloe/src/icefloe/IceFlexISO.f90 @@ -126,9 +126,9 @@ subroutine initFlexISO (iceInput, myIceParams, iceLog) call getIceInput(iceInput, 'includeLc', inParams%includeLc, iceLog) if (inParams%includeLc) then - call logMessage(iceLog, ' Including crack lenght modification term, Lc') + call logMessage(iceLog, ' Including crack length modification term, Lc') else - call logMessage(iceLog, ' NOT including crack lenght modification term, Lc') + call logMessage(iceLog, ' NOT including crack length modification term, Lc') endif ! The Croasdale method precalculates a time series of loads based @@ -275,7 +275,7 @@ subroutine randomFlexLoadTimeSeries (myIceParams, iceLog, maxLoad) ! Loop on all legs do nL = 1, myIceParams%numLegs - ! Number of whole periods required not known (since period lenght is random) + ! Number of whole periods required not known (since period length is random) ! So iterate until we have enough points in the time series n = 1 seriesLoop: do while (n < nSteps+1) diff --git a/modules/icefloe/src/icefloe/intermittentCrushing.F90 b/modules/icefloe/src/icefloe/intermittentCrushing.F90 index e88caf4172..feb3601701 100644 --- a/modules/icefloe/src/icefloe/intermittentCrushing.F90 +++ b/modules/icefloe/src/icefloe/intermittentCrushing.F90 @@ -80,7 +80,7 @@ subroutine initInterCrushing (iceInput, myIceParams, iceLog) end subroutine initInterCrushing !**************************************************************************** -! Continuous crushing uses the standard inerpolation routine +! Continuous crushing uses the standard interpolation routine ! of the precalculated time series function outputInterCrushLoad (myIceParams, iceLog, time) result(iceLoads) type(iceFloe_ParameterType), intent(in) :: myIceParams @@ -91,4 +91,4 @@ function outputInterCrushLoad (myIceParams, iceLog, time) result(iceLoads) iceLoads = outputCrushLoadISO (myIceParams, iceLog, time) end function outputInterCrushLoad -end module iceIntermittentCrushing \ No newline at end of file +end module iceIntermittentCrushing diff --git a/modules/icefloe/src/icefloe/lockInISO.F90 b/modules/icefloe/src/icefloe/lockInISO.F90 index ebb1e04ec3..9ba0f61b7c 100644 --- a/modules/icefloe/src/icefloe/lockInISO.F90 +++ b/modules/icefloe/src/icefloe/lockInISO.F90 @@ -41,10 +41,10 @@ subroutine initLockInCrushingISO (iceInput, myIceParams, iceLog) real(ReKi) :: fallTime, maxLoad integer(IntKi) :: nL ! err, -! initialize the common parmeters +! initialize the common parameters call initIceCrushISO(iceInput, inParams, myIceParams, iceLog) - call logMessage(iceLog, newLine//' Setting ice crushing loads with frequency lock-in parameteres per ISO') + call logMessage(iceLog, newLine//' Setting ice crushing loads with frequency lock-in parameters per ISO') call getIceInput(iceInput, 'towerFrequency', inParams%twr%freq, iceLog, 0.01_ReKi, 10.0_ReKi) call logMessage(iceLog, ' Tower fundamental frequency = '//TRIM(Num2LStr(inParams%twr%freq))//' Hz') diff --git a/modules/icefloe/src/icefloe/randomCrushing.F90 b/modules/icefloe/src/icefloe/randomCrushing.F90 index 9996a40321..c55af26098 100644 --- a/modules/icefloe/src/icefloe/randomCrushing.F90 +++ b/modules/icefloe/src/icefloe/randomCrushing.F90 @@ -163,7 +163,7 @@ end subroutine randomCrushLoadTimeSeries end subroutine initRandomCrushing ! containing subroutine !**************************************************************************** -! Continuous crushing uses the standard inerpolation routine +! Continuous crushing uses the standard interpolation routine ! of the precalculated time series function outputRandomCrushLoad (myIceParams, iceLog, time) result(iceLoads) type(iceFloe_ParameterType), intent(in) :: myIceParams @@ -174,4 +174,4 @@ function outputRandomCrushLoad (myIceParams, iceLog, time) result(iceLoads) iceLoads = outputCrushLoadISO (myIceParams, iceLog, time) end function outputRandomCrushLoad -end module randomCrushing \ No newline at end of file +end module randomCrushing diff --git a/modules/icefloe/src/interfaces/FAST/IceFloe.f90 b/modules/icefloe/src/interfaces/FAST/IceFloe.f90 index f257ddeb6e..90b2b4490e 100644 --- a/modules/icefloe/src/interfaces/FAST/IceFloe.f90 +++ b/modules/icefloe/src/interfaces/FAST/IceFloe.f90 @@ -190,7 +190,7 @@ SUBROUTINE IceFloe_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, In endif ! get the simulation length from FAST - ! if the the length from FAST is zero read from iceFloe input file + ! if the length from FAST is zero read from iceFloe input file if (InitInp%simLength <= 0) then duration = InitInp%simLength else diff --git a/modules/icefloe/test/GLA_proto_flex_ISO.log b/modules/icefloe/test/GLA_proto_flex_ISO.log index 88efb643e8..d46f6f5115 100644 --- a/modules/icefloe/test/GLA_proto_flex_ISO.log +++ b/modules/icefloe/test/GLA_proto_flex_ISO.log @@ -44,7 +44,7 @@ Including pile up term, Hp Including rubble lifting term, Hl Including block rotation term, Ht - Including crack lenght modification term, Lc + Including crack length modification term, Lc ** Pile up term, Hp = 2242 Newtons ** Rubble lifting term, Hl = 2.09678E+05 Newtons ** Block rotation term, Ht = 42609 Newtons diff --git a/modules/inflowwind/src/IfW_C_Binding.f90 b/modules/inflowwind/src/IfW_C_Binding.f90 index 66e174b34e..b3bc732f67 100644 --- a/modules/inflowwind/src/IfW_C_Binding.f90 +++ b/modules/inflowwind/src/IfW_C_Binding.f90 @@ -101,7 +101,7 @@ SUBROUTINE IfW_C_Init(IfWinputFilePassed, IfWinputFileString_C, IfWinputFileStri #endif integer(c_int), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR - integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string + integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< length of the input file string character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other integer(c_int), intent(in ) :: NumWindPts_C real(c_double), intent(in ) :: DT_C diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index de2d713a3b..22796ed0dc 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -186,23 +186,8 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, Cons endif ! initialize sensor data: - p%lidar%SensorType = InputFileData%SensorType - IF (InputFileData%SensorType /= SensorType_None) THEN - p%lidar%NumBeam = InputFileData%NumBeam - p%lidar%RotorApexOffsetPos = InputFileData%RotorApexOffsetPos - p%lidar%LidRadialVel = InputFileData%LidRadialVel - p%lidar%NumPulseGate = InputFileData%NumPulseGate - p%lidar%FocalDistanceX = InputFileData%FocalDistanceX ! these are allocatable. Should allocate then copy - p%lidar%FocalDistanceY = InputFileData%FocalDistanceY - p%lidar%FocalDistanceZ = InputFileData%FocalDistanceZ - p%lidar%MeasurementInterval= InputFileData%MeasurementInterval - p%lidar%PulseSpacing = InputFileData%PulseSpacing - p%lidar%URefLid = InputFileData%URefLid - p%lidar%ConsiderHubMotion = InputFileData%ConsiderHubMotion - - CALL Lidar_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & - y, m, TimeInterval, InitOutData, TmpErrStat, TmpErrMsg ); if (Failed()) return - endif + CALL Lidar_Init( InitInp, InputFileData, InputGuess, p, y, m, TimeInterval, TmpErrStat, TmpErrMsg ) + if (Failed()) return ! If a summary file was requested, open it. IF ( InputFileData%SumPrint ) THEN @@ -216,7 +201,7 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, Cons ! Allocate the array for passing points CALL AllocAry( InputGuess%PositionXYZ, 3, InitInp%NumWindPoints, "Array of positions at which to find wind velocities", TmpErrStat, TmpErrMsg ); if (Failed()) return InputGuess%PositionXYZ = 0.0_ReKi - InputGuess%HubPosition = 0.0_ReKi + InputGuess%HubPosition = InitInp%HubPosition CALL Eye(InputGuess%HubOrientation,TmpErrStat,TmpErrMsg); if (Failed()) return ! Allocate the array for passing velocities out @@ -550,7 +535,7 @@ END SUBROUTINE InflowWind_Init !! these PositionXYZPrime coordinates. !! !! After the calculation by the submodule, the PositionXYZPrime coordinate array is deallocated. The returned VelocityUVW -!! array is then rotated by p%PropagationDir so that it now corresponds the the global coordinate UVW values for wind +!! array is then rotated by p%PropagationDir so that it now corresponds to the global coordinate UVW values for wind !! with that direction. !---------------------------------------------------------------------------------------------------- SUBROUTINE InflowWind_CalcOutput( Time, InputData, p, & @@ -619,12 +604,10 @@ SUBROUTINE InflowWind_CalcOutput( Time, InputData, p, & ! return sensor values IF (p%lidar%SensorType /= SensorType_None) THEN - CALL Lidar_CalcOutput(Time, InputData, p, & - ContStates, DiscStates, ConstrStates, OtherStates, & - OutputData, m, TmpErrStat, TmpErrMsg ) + CALL Lidar_CalcOutput(Time, InputData, p, OutputData, m, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - END IF + END IF !----------------------------- diff --git a/modules/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt index 924573b8f5..0d8e864446 100644 --- a/modules/inflowwind/src/InflowWind.txt +++ b/modules/inflowwind/src/InflowWind.txt @@ -76,7 +76,7 @@ typedef ^ ^ ReKi PulseSpacin typedef ^ ^ ReKi MeasurementInterval - - - "Time between each measurement" s typedef ^ ^ ReKi URefLid - - - "Reference average wind speed for the lidar" m/s typedef ^ ^ LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - -typedef ^ ^ IntKi ConsiderHubMotion - - - "Flag whether or not the hub motion's impact on the Lidar measurement will be considered [0 for no, 1 for yes]" - +typedef ^ ^ IntKi ConsiderHubMotion - - - "whether or not the hub motion's impact on the Lidar measurement will be considered" - typedef ^ ^ Grid3D_InitInputType FF - - - "scaling data" - @@ -92,7 +92,6 @@ typedef ^ ^ IntKi FilePassing typedef ^ ^ FileInfoType PassedFileInfo - - - "If we don't use the input file, pass everything through this [FilePassingMethod = 1]" - typedef ^ ^ InflowWind_InputFile PassedFileData - - - "If we don't use the input file, pass everything through this [FilePassingMethod = 2]" - typedef ^ ^ LOGICAL OutputAccel - .FALSE. - "Flag to output wind acceleration" - -typedef ^ ^ Lidar_InitInputType lidar - - - "InitInput for lidar data" - typedef ^ ^ Grid4D_InitInputType FDext - - - "InitInput for 4D external wind data" - typedef ^ ^ ReKi RadAvg - - - "Radius (from hub) used for averaging wind speed" - typedef ^ ^ IntKi MHK - - - "MHK turbine type switch" - @@ -100,6 +99,7 @@ typedef ^ ^ ReKi WtrDpth typedef ^ ^ ReKi MSL2SWL - - - "Mean sea level to still water level" m typedef ^ ^ LOGICAL BoxExceedAllow - .FALSE. - "Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim)" - typedef ^ ^ LOGICAL LidarEnabled - .false. - "Enable LiDAR for this instance of InflowWind? (FAST.Farm, ADI, and InflowWind driver/library are not compatible)" - +typedef ^ ^ ReKi HubPosition {3} - - "initial position of the hub (lidar mounted on hub) [0,0,HubHeight]" "m" # Init Output diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index 42b29d1d11..f1d7dcfb12 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -733,7 +733,7 @@ PROGRAM InflowWind_Driver InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & InflowWind_y1, InflowWind_MiscVars, ErrStat, ErrMsg) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -860,7 +860,7 @@ PROGRAM InflowWind_Driver InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & InflowWind_y1, InflowWind_MiscVars, ErrStat, ErrMsg ) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -879,7 +879,7 @@ PROGRAM InflowWind_Driver InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & InflowWind_y2, InflowWind_MiscVars, ErrStat, ErrMsg ) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -898,7 +898,7 @@ PROGRAM InflowWind_Driver InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & InflowWind_y3, InflowWind_MiscVars, ErrStat, ErrMsg ) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index 3041c710a2..232c89ca97 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -462,7 +462,7 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In ! if (Failed()) return !---------------------------------------------------------------------------------------------- - !> Read the _Mean wind profile paramters (added to HAWC-format files) [used only for WindType = 5]_ subsection + !> Read the _Mean wind profile parameters (added to HAWC-format files) [used only for WindType = 5]_ subsection !---------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break @@ -504,18 +504,14 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In CALL ParseVar( InFileInfo, CurLine, "NumBeam", InputFileData%NumBeam, TmpErrStat, TmpErrMsg, UnEc ) if (Failed()) return - ! Before proceeding, make sure that NumBeam makes sense - IF ((InputFileData%SensorType == 1) .and. (InputFileData%NumBeam < 1 .OR. InputFileData%NumBeam > 5)) THEN - CALL SetErrStat( ErrID_Fatal, 'NumBeam must be greater than or equal to one and less than 6.', & - ErrStat, ErrMsg, RoutineName ) - RETURN - ELSE - ! Allocate space for the output location arrays: - CALL AllocAry( InputFileData%FocalDistanceX, InputFileData%NumBeam, 'FocalDistanceX', TmpErrStat, TmpErrMsg ); CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - CALL AllocAry( InputFileData%FocalDistanceY, InputFileData%NumBeam, 'FocalDistanceY', TmpErrStat, TmpErrMsg ); CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - CALL AllocAry( InputFileData%FocalDistanceZ, InputFileData%NumBeam, 'FocalDistanceZ', TmpErrStat, TmpErrMsg ); CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - if (Failed()) return - ENDIF + ! Before proceeding, make sure that NumBeam makes sense for array allocation + InputFileData%NumBeam = MAX(InputFileData%NumBeam, 1) + + ! Allocate space for the output location arrays: + CALL AllocAry( InputFileData%FocalDistanceX, InputFileData%NumBeam, 'FocalDistanceX', TmpErrStat, TmpErrMsg ); CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( InputFileData%FocalDistanceY, InputFileData%NumBeam, 'FocalDistanceY', TmpErrStat, TmpErrMsg ); CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( InputFileData%FocalDistanceZ, InputFileData%NumBeam, 'FocalDistanceZ', TmpErrStat, TmpErrMsg ); CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return ! Focal Distance X CALL ParseAry( InFileInfo, CurLine, 'FocalDistanceX', InputFileData%FocalDistanceX, InputFileData%NumBeam, TmpErrStat, TmpErrMsg, UnEc ) @@ -647,7 +643,7 @@ SUBROUTINE InflowWind_ValidateInput( InitInp, InputFileData, ErrStat, ErrMsg ) return end if - if (InitInp%lidar%SensorType /= SensorType_None) then + if (InputFileData%SensorType /= SensorType_None) then call SetErrStat(ErrID_Fatal, 'InflowWind can not perform linearization with the lidar module enabled.', ErrStat, ErrMsg, RoutineName) return end if @@ -1177,7 +1173,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) ! Passed variables CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list of user-requested outputs - TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< The module parameters + TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< The module parameters INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred @@ -1288,17 +1284,9 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) InvalidOutput(WindAccZ) = .TRUE. end if - if (p%lidar%SensorType /= SensorType_None) then - IF (p%lidar%SensorType == SensorType_SinglePoint) THEN - DO I=p%lidar%NumBeam+1,5 - InvalidOutput( WindMeas(I) ) = .TRUE. - END DO - ELSE - DO I=p%lidar%NumPulseGate+1,5 - InvalidOutput( WindMeas(I) ) = .TRUE. - END DO - END IF - endif + do I=p%lidar%NumMeasurements+1,SIZE(WindMeas) + InvalidOutput( WindMeas(I) ) = .TRUE. + end do ! ................. End of validity checking ................. @@ -1521,16 +1509,10 @@ SUBROUTINE SetAllOuts( p, y, m, ErrStat, ErrMsg ) !FIXME: Add in Wind1Dir etc. -- although those can be derived outside of FAST. - if (p%lidar%SensorType /= SensorType_None) then - IF ( p%lidar%SensorType == SensorType_SinglePoint) THEN - DO I = 1,MIN(5, p%lidar%NumBeam ) - m%AllOuts( WindMeas(I) ) = y%lidar%LidSpeed(I) - END DO - ELSE - DO I = 1,MIN(5, p%lidar%NumPulseGate ) - m%AllOuts( WindMeas(I) ) = y%lidar%LidSpeed(I) - END DO - END IF + if (ALLOCATED(y%lidar%LidSpeed)) then + DO I = 1,MIN(SIZE(WindMeas), SIZE(y%lidar%LidSpeed) ) + m%AllOuts( WindMeas(I) ) = y%lidar%LidSpeed(I) + END DO endif END SUBROUTINE SetAllOuts diff --git a/modules/inflowwind/src/InflowWind_Types.f90 b/modules/inflowwind/src/InflowWind_Types.f90 index 646d366064..f820e6e9bf 100644 --- a/modules/inflowwind/src/InflowWind_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Types.f90 @@ -94,7 +94,7 @@ MODULE InflowWind_Types REAL(ReKi) :: MeasurementInterval = 0.0_ReKi !< Time between each measurement [s] REAL(ReKi) :: URefLid = 0.0_ReKi !< Reference average wind speed for the lidar [m/s] LOGICAL :: LidRadialVel = .false. !< TRUE => return radial component, FALSE => return 'x' direction estimate [-] - INTEGER(IntKi) :: ConsiderHubMotion = 0_IntKi !< Flag whether or not the hub motion's impact on the Lidar measurement will be considered [0 for no, 1 for yes] [-] + INTEGER(IntKi) :: ConsiderHubMotion = 0_IntKi !< whether or not the hub motion's impact on the Lidar measurement will be considered [-] TYPE(Grid3D_InitInputType) :: FF !< scaling data [-] END TYPE InflowWind_InputFile ! ======================= @@ -111,7 +111,6 @@ MODULE InflowWind_Types TYPE(FileInfoType) :: PassedFileInfo !< If we don't use the input file, pass everything through this [FilePassingMethod = 1] [-] TYPE(InflowWind_InputFile) :: PassedFileData !< If we don't use the input file, pass everything through this [FilePassingMethod = 2] [-] LOGICAL :: OutputAccel = .FALSE. !< Flag to output wind acceleration [-] - TYPE(Lidar_InitInputType) :: lidar !< InitInput for lidar data [-] TYPE(Grid4D_InitInputType) :: FDext !< InitInput for 4D external wind data [-] REAL(ReKi) :: RadAvg = 0.0_ReKi !< Radius (from hub) used for averaging wind speed [-] INTEGER(IntKi) :: MHK = 0_IntKi !< MHK turbine type switch [-] @@ -119,6 +118,7 @@ MODULE InflowWind_Types REAL(ReKi) :: MSL2SWL = 0.0_ReKi !< Mean sea level to still water level [m] LOGICAL :: BoxExceedAllow = .FALSE. !< Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim) [-] LOGICAL :: LidarEnabled = .false. !< Enable LiDAR for this instance of InflowWind? (FAST.Farm, ADI, and InflowWind driver/library are not compatible) [-] + REAL(ReKi) , DIMENSION(1:3) :: HubPosition = 0.0_ReKi !< initial position of the hub (lidar mounted on hub) [0,0,HubHeight] [m] END TYPE InflowWind_InitInputType ! ======================= ! ========= InflowWind_InitOutputType ======= @@ -511,9 +511,6 @@ subroutine InflowWind_CopyInitInput(SrcInitInputData, DstInitInputData, CtrlCode call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return DstInitInputData%OutputAccel = SrcInitInputData%OutputAccel - call Lidar_CopyInitInput(SrcInitInputData%lidar, DstInitInputData%lidar, CtrlCode, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return call InflowWind_IO_CopyGrid4D_InitInputType(SrcInitInputData%FDext, DstInitInputData%FDext, CtrlCode, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -523,6 +520,7 @@ subroutine InflowWind_CopyInitInput(SrcInitInputData, DstInitInputData, CtrlCode DstInitInputData%MSL2SWL = SrcInitInputData%MSL2SWL DstInitInputData%BoxExceedAllow = SrcInitInputData%BoxExceedAllow DstInitInputData%LidarEnabled = SrcInitInputData%LidarEnabled + DstInitInputData%HubPosition = SrcInitInputData%HubPosition end subroutine subroutine InflowWind_DestroyInitInput(InitInputData, ErrStat, ErrMsg) @@ -538,8 +536,6 @@ subroutine InflowWind_DestroyInitInput(InitInputData, ErrStat, ErrMsg) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call InflowWind_DestroyInputFile(InitInputData%PassedFileData, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - call Lidar_DestroyInitInput(InitInputData%lidar, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call InflowWind_IO_DestroyGrid4D_InitInputType(InitInputData%FDext, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) end subroutine @@ -560,7 +556,6 @@ subroutine InflowWind_PackInitInput(RF, Indata) call NWTC_Library_PackFileInfoType(RF, InData%PassedFileInfo) call InflowWind_PackInputFile(RF, InData%PassedFileData) call RegPack(RF, InData%OutputAccel) - call Lidar_PackInitInput(RF, InData%lidar) call InflowWind_IO_PackGrid4D_InitInputType(RF, InData%FDext) call RegPack(RF, InData%RadAvg) call RegPack(RF, InData%MHK) @@ -568,6 +563,7 @@ subroutine InflowWind_PackInitInput(RF, Indata) call RegPack(RF, InData%MSL2SWL) call RegPack(RF, InData%BoxExceedAllow) call RegPack(RF, InData%LidarEnabled) + call RegPack(RF, InData%HubPosition) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -587,7 +583,6 @@ subroutine InflowWind_UnPackInitInput(RF, OutData) call NWTC_Library_UnpackFileInfoType(RF, OutData%PassedFileInfo) ! PassedFileInfo call InflowWind_UnpackInputFile(RF, OutData%PassedFileData) ! PassedFileData call RegUnpack(RF, OutData%OutputAccel); if (RegCheckErr(RF, RoutineName)) return - call Lidar_UnpackInitInput(RF, OutData%lidar) ! lidar call InflowWind_IO_UnpackGrid4D_InitInputType(RF, OutData%FDext) ! FDext call RegUnpack(RF, OutData%RadAvg); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%MHK); if (RegCheckErr(RF, RoutineName)) return @@ -595,6 +590,7 @@ subroutine InflowWind_UnPackInitInput(RF, OutData) call RegUnpack(RF, OutData%MSL2SWL); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%BoxExceedAllow); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%LidarEnabled); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%HubPosition); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine InflowWind_CopyInitOutput(SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg) diff --git a/modules/inflowwind/src/Lidar.f90 b/modules/inflowwind/src/Lidar.f90 index ddb5861b0e..f0dd9a1e71 100644 --- a/modules/inflowwind/src/Lidar.f90 +++ b/modules/inflowwind/src/Lidar.f90 @@ -62,15 +62,12 @@ MODULE Lidar !! The parameters are set here and not changed during the simulation. !! The initial states and initial guess for the input are defined. !! note that we're calling this with the InflowWind data types, so that data is INOUT instead of OUT -SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut, ErrStat, ErrMsg ) +SUBROUTINE Lidar_Init( InitInp, InputFileData, u, p, y, m, Interval, ErrStat, ErrMsg ) TYPE(InflowWind_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine + TYPE(InflowWind_InputFile), INTENT(INOUT) :: InputFileData !< Data from input file TYPE(InflowWind_InputType), INTENT(INOUT) :: u !< An initial guess for the input; input mesh must be defined TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(InflowWind_ContinuousStateType), INTENT(INOUT) :: x !< Initial continuous states - TYPE(InflowWind_DiscreteStateType), INTENT(INOUT) :: xd !< Initial discrete states - TYPE(InflowWind_ConstraintStateType), INTENT(INOUT) :: z !< Initial guess of the constraint states - TYPE(InflowWind_OtherStateType), INTENT(INOUT) :: OtherState !< Initial other states TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Initial system outputs (outputs are not calculated; !! only the output mesh is initialized) @@ -80,16 +77,15 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init !! Input is the suggested time from the glue code; !! Output is the actual coupling interval that will be used !! by the glue code. - TYPE(InflowWind_InitOutputType), INTENT(INOUT) :: InitOut !< Output for initialization routine INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat !< temporary error message - CHARACTER(ErrMsgLen) :: TmpErrMsg + INTEGER(IntKi) :: TmpErrStat !< temporary error message + CHARACTER(ErrMsgLen) :: TmpErrMsg ! local variables - INTEGER(IntKi) :: IBeam + INTEGER(IntKi) :: IBeam INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None @@ -102,148 +98,111 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ErrStat = ErrID_None ErrMsg = "" - ! Check for errors in the InflowWind Input File - - ! Make sure that NumPulseGate makes sense - IF ( (p%lidar%SensorType == 3) .and. (p%lidar%NumPulseGate < 0 .OR. p%lidar%NumPulseGate > 5) ) THEN - CALL SetErrStat( ErrID_Fatal, 'NumPulseGate must be greater than or equal to zero and less than 5.', & - ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ! Make sure that multiple beams are only used when using single point beams - IF ( p%lidar%NumBeam > 1 .AND. p%lidar%SensorType > 1) THEN - CALL SetErrStat( ErrID_Fatal, 'Multiple beams can only be used with single point lidar', & - ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - CALL AllocAry(p%lidar%MsrPosition , 3, max(1,p%lidar%NumBeam), 'Array for measurement coordinates', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat>= AbortErrLev ) RETURN - - - IF (p%lidar%SensorType == SensorType_None) THEN + p%lidar%SensorType = InputFileData%SensorType + if (p%lidar%SensorType == SensorType_None) then p%lidar%NumPulseGate = 0 - ELSEIF (p%lidar%SensorType == SensorType_SinglePoint) THEN - p%lidar%NumPulseGate = 1 - ELSE - - ! variables for both pulsed and continuous-wave lidars - + p%lidar%NumBeam = 0 + return + else + p%lidar%NumBeam = InputFileData%NumBeam + p%lidar%RotorApexOffsetPos = InputFileData%RotorApexOffsetPos + p%lidar%LidRadialVel = InputFileData%LidRadialVel + p%lidar%NumPulseGate = InputFileData%NumPulseGate + call move_alloc(InputFileData%FocalDistanceX, p%lidar%FocalDistanceX) + call move_alloc(InputFileData%FocalDistanceY, p%lidar%FocalDistanceY) + call move_alloc(InputFileData%FocalDistanceZ, p%lidar%FocalDistanceZ) + p%lidar%MeasurementInterval= InputFileData%MeasurementInterval + p%lidar%PulseSpacing = InputFileData%PulseSpacing + p%lidar%URefLid = InputFileData%URefLid + p%lidar%ConsiderHubMotion = InputFileData%ConsiderHubMotion + + if (p%lidar%SensorType == SensorType_SinglePoint) then + p%lidar%NumPulseGate = 1 + if ( (p%lidar%NumBeam < 1 .OR. p%lidar%NumBeam > 5) ) then + call SetErrStat( ErrID_Fatal, 'NumBeam must be greater than zero and less than 6.', ErrStat, ErrMsg, RoutineName ) + return + endif - - p%lidar%SpatialRes = 0.5_ReKi*p%lidar%URefLid*Interval - p%lidar%RayRangeSq = (Pi*(BeamRad**2)/LsrWavLen)**2 - + else - - - IF (p%lidar%SensorType == SensorType_ContinuousLidar) THEN + ! Make sure that multiple beams are only used when using single-point beams + if ( p%lidar%NumBeam > 1 ) then + call SetErrStat( ErrID_Fatal, 'Multiple beams can only be used with single point lidar', ErrStat, ErrMsg, RoutineName ) + return + endif + p%lidar%NumBeam = 1 + + ! variables for both pulsed and continuous-wave lidars + p%lidar%SpatialRes = 0.5_ReKi*p%lidar%URefLid*Interval + p%lidar%RayRangeSq = (Pi*(BeamRad**2)/LsrWavLen)**2 - p%lidar%WtFnTrunc = 0.02_ReKi - p%lidar%NumPulseGate = 1 - - ELSEIF (p%lidar%SensorType == SensorType_PulsedLidar) THEN + if (p%lidar%SensorType == SensorType_ContinuousLidar) then + p%lidar%NumPulseGate = 1 + p%lidar%WtFnTrunc = 0.02_ReKi + elseif (p%lidar%SensorType == SensorType_PulsedLidar) then - p%lidar%WtFnTrunc = 0.01_ReKi + ! Make sure that NumPulseGate makes sense + if ( (p%lidar%NumPulseGate < 1 .OR. p%lidar%NumPulseGate > 5) ) then + call SetErrStat( ErrID_Fatal, 'NumPulseGate must be greater than zero and less than 6.', ErrStat, ErrMsg, RoutineName ) + return + endif + p%lidar%WtFnTrunc = 0.01_ReKi + ! values for the WindCube + p%lidar%DeltaR = 30.0_ReKi + ! p%lidar%PulseRangeOne = 50.0 ReKi ! Replaced by the focal distance; bjj: it's used in an IF statement, so initializing below: + p%lidar%PulseRangeOne = 0.0_ReKi - ! values for the WindCube - ! p%lidar%DeltaP = 30.0_ReKi !Replaced by pulse spacing - p%lidar%DeltaR = 30.0_ReKi - ! p%lidar%PulseRangeOne = 50.0 ReKi ! Replaced by the focal distance - - p%lidar%r_p = p%lidar%DeltaR/(2.0_ReKi*SQRT(LOG(2.0_ReKi))) + p%lidar%r_p = p%lidar%DeltaR/(2.0_ReKi*SQRT(LOG(2.0_ReKi))) - ELSE - - CALL SetErrStat(ErrID_Fatal, "Invalid sensor type.", ErrStat, ErrMsg, RoutineName) - RETURN - - END IF - - END IF - - - !............................................................................................ - ! Define initial system states here: - !............................................................................................ + else + call SetErrStat(ErrID_Fatal, "Invalid sensor type.", ErrStat, ErrMsg, RoutineName) + return + end if + end if + end if ! no lidar - !x%lidar%DummyContState = 0.0_ReKi - !xdlidar%%DummyDiscState = 0.0_ReKi - !z%lidar%DummyConstrState = 0.0_ReKi - !OtherState%lidar%DummyOtherState = 0.0_ReKi - ! - !............................................................................................ - ! Define initial guess for the system inputs here: - !............................................................................................ + p%lidar%LidPosition = InitInp%HubPosition + p%lidar%NumMeasurements = MAX(p%lidar%NumBeam,p%lidar%NumPulseGate) !note, this is at least 1 for every case (except SensorType_None, which cannot get to this place) + + CALL AllocAry(p%lidar%MsrPosition , 3, p%lidar%NumBeam, 'Array for measurement coordinates (per beam)', TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + IF ( ErrStat>= AbortErrLev ) RETURN - p%lidar%LidPosition = InitInp%lidar%HubPosition DO IBeam = 1,p%lidar%NumBeam - p%lidar%MsrPosition(:,IBeam) = (/ p%lidar%FocalDistanceX(IBeam), p%lidar%FocalDistanceY(IBeam), p%lidar%FocalDistanceZ(IBeam) /) !bjj: todo FIXME with initial guess of lidar focus. + p%lidar%MsrPosition(:,IBeam) = (/ p%lidar%FocalDistanceX(IBeam), p%lidar%FocalDistanceY(IBeam), p%lidar%FocalDistanceZ(IBeam) /) ! bjj: todo FIXME with initial guess of lidar focus. END DO + + !............................................................................................ + ! Define initial guess for the system inputs here: + !............................................................................................ u%lidar%PulseLidEl = 0.0_ReKi u%lidar%PulseLidAz = 0.0_ReKi - !............................................................................................ - ! Define system output initializations (set up mesh) here: + ! Define system output initializations here: !............................................................................................ - !CALL AllocAry( y%WriteOutput, p%NumOuts, 'WriteOutput', ErrStat2, ErrMsg2 ) - ! CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - ! IF (ErrStat >= AbortErrLev) RETURN - !y%WriteOutput = 0 - - IF (p%lidar%SensorType == SensorType_SinglePoint) THEN - CALL AllocAry( y%lidar%LidSpeed, p%lidar%NumBeam, 'y%lidar%LidSpeed', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + CALL AllocAry( y%lidar%LidSpeed, p%lidar%NumMeasurements, 'y%lidar%LidSpeed', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - !CALL AllocAry( y%LidErr, p%NumPulseGate, 'y%LidErr', ErrStat2, ErrMsg2 ) - ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - - CALL AllocAry( y%lidar%WtTrunc, p%lidar%NumBeam, 'y%lidar%WtTrunc', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - - CALL AllocAry( y%lidar%MsrPositionsX, p%lidar%NumBeam, 'y%lidar%MsrPositionsX', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - - CALL AllocAry( y%lidar%MsrPositionsY, p%lidar%NumBeam, 'y%lidar%MsrPositionsY', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + CALL AllocAry( y%lidar%WtTrunc, p%lidar%NumMeasurements, 'y%lidar%WtTrunc', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - CALL AllocAry( y%lidar%MsrPositionsZ, p%lidar%NumBeam, 'y%lidar%MsrPositionsZ', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - ELSEIF (p%lidar%NumPulseGate > 0) then ! the Cray Fortran compiler doesn't like allocating size zero - CALL AllocAry( y%lidar%LidSpeed, p%lidar%NumPulseGate, 'y%lidar%LidSpeed', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - - !CALL AllocAry( y%LidErr, p%NumPulseGate, 'y%LidErr', ErrStat2, ErrMsg2 ) - !CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - - CALL AllocAry( y%lidar%WtTrunc, p%lidar%NumPulseGate, 'y%lidar%WtTrunc', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + CALL AllocAry( y%lidar%MsrPositionsX, p%lidar%NumMeasurements, 'y%lidar%MsrPositionsX', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - CALL AllocAry( y%lidar%MsrPositionsX, p%lidar%NumPulseGate, 'y%lidar%MsrPositionsX', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + CALL AllocAry( y%lidar%MsrPositionsY, p%lidar%NumMeasurements, 'y%lidar%MsrPositionsY', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - CALL AllocAry( y%lidar%MsrPositionsY, p%lidar%NumPulseGate, 'y%lidar%MsrPositionsY', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - - CALL AllocAry( y%lidar%MsrPositionsZ, p%lidar%NumPulseGate, 'y%lidar%MsrPositionsZ', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - ENDIF - + CALL AllocAry( y%lidar%MsrPositionsZ, p%lidar%NumMeasurements, 'y%lidar%MsrPositionsZ', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); IF (ErrStat >= AbortErrLev) RETURN - if (allocated(y%lidar%LidSpeed)) y%lidar%LidSpeed = 0.0 - if (allocated(y%lidar%WtTrunc )) y%lidar%WtTrunc = 0.0 - - !............................................................................................ - ! Define initialization-routine output here: - !............................................................................................ + y%lidar%LidSpeed = 0.0 + y%lidar%WtTrunc = 0.0 RETURN @@ -304,16 +263,12 @@ END SUBROUTINE Lidar_End !> Routine for computing outputs, used in both loose and tight coupling. !! @note this breaks the framework because we're passing the IfW types instead of the Lidar types... this is necessary to get !! appropriate wind speeds for the lidar measurements. -SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) +SUBROUTINE Lidar_CalcOutput( t, u, p, y, m, ErrStat, ErrMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds TYPE(InflowWind_InputType), INTENT(IN ) :: u !< Inputs at t TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t - TYPE(InflowWind_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t - TYPE(InflowWind_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t - TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherState !< Other/optimization states TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Outputs computed at t (Input only so that mesh con- !! nectivity information does not have to be recalculated) TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) @@ -357,37 +312,37 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs ErrStat = ErrID_None ErrMsg = "" - + + IF (p%lidar%SensorType == SensorType_None) RETURN + MeasurementCurrentStep = INT(t / p%lidar%MeasurementInterval) IF ( (p%lidar%MeasurementInterval * MeasurementCurrentStep) /= t ) THEN - VelocityUVW(:,1) = 0 + !bjj: note: no error set; no output set. RETURN ENDIF - + LidPosition = p%lidar%LidPosition + p%lidar%RotorApexOffsetPos ! lidar offset-from-rotor-apex position - IF (p%lidar%ConsiderHubMotion == 1) THEN + IF (p%lidar%ConsiderHubMotion /= 0) THEN LidPosition = LidPosition + (/ u%lidar%HubDisplacementX, u%lidar%HubDisplacementY, u%lidar%HubDisplacementZ /) ! rotor apex position (absolute) END IF - IF (p%lidar%SensorType == SensorType_None) RETURN - !............................................................................................................................... ! Compute the outputs !............................................................................................................................... - ! Initialize position to zero in case no all values are set + ! Initialize position to zero in case not all values are set PositionXYZ = 0.0_ReKi + IBeam = 1 IF (p%lidar%SensorType == SensorType_SinglePoint) THEN DO IBeam = 1,p%lidar%NumBeam !get lidar speed at the focal point to see if it is out of bounds - PositionXYZ(:,1) = LidPosition + p%lidar%MsrPosition(:,IBeam) + PositionXYZ(:,1) = LidPosition + p%lidar%MsrPosition(:,IBeam) - call IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, & - AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) + call IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) y%lidar%LidSpeed(IBeam) = SQRT( DOT_PRODUCT(VelocityUVW(:,1), VelocityUVW(:,1)) ) @@ -395,15 +350,16 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs y%lidar%MsrPositionsX(IBeam) = PositionXYZ(1,1) y%lidar%MsrPositionsY(IBeam) = PositionXYZ(2,1) - y%lidar%MsrPositionsZ(IBeam) = PositionXYZ(3,1) + y%lidar%MsrPositionsZ(IBeam) = PositionXYZ(3,1) END DO ELSEIF (p%lidar%SensorType == SensorType_ContinuousLidar) THEN !calculate the focal distance of the lidar as well as the modified focal distance so that the peak of the weighting func !is at the intended focal distance - - Distance = p%lidar%MsrPosition(:,1) - LidPosition + IBeam = 1 + + Distance = p%lidar%MsrPosition(:,IBeam) - LidPosition FocDist = SQRT( DOT_PRODUCT( Distance, Distance ) ) !TwoNorm IF(EqualRealNos(FocDist,0.0_ReKi)) THEN ! Avoid division-by-zero @@ -429,19 +385,17 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs LidWtRatio = 1.0_ReKi !LidWt/LidWtMax !get lidar speed at the focal point to see if it is out of bounds - PositionXYZ(:,1) = LidPosition + p%lidar%MsrPosition(:,1) + PositionXYZ(:,1) = LidPosition + p%lidar%MsrPosition(:,IBeam) - y%lidar%MsrPositionsX(1) = LidPosition(1) + p%lidar%MsrPosition(1,1) - y%lidar%MsrPositionsY(1) = LidPosition(2) + p%lidar%MsrPosition(2,1) - y%lidar%MsrPositionsZ(1) = LidPosition(3) + p%lidar%MsrPosition(3,1) + y%lidar%MsrPositionsX(IBeam) = PositionXYZ(1,1) + y%lidar%MsrPositionsY(IBeam) = PositionXYZ(2,1) + y%lidar%MsrPositionsZ(IBeam) = PositionXYZ(3,1) - CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, & - AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ(:,1:1), VelocityUVW(:,1:1), AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) !if out of bounds IF (ErrStat >= AbortErrLev) THEN - !y%lidar%LidErr = 1 y%lidar%LidSpeed = -99.0 RETURN !escape function ENDIF @@ -474,7 +428,6 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs IF (LidRange > FocDist) THEN IF (NWTC_VerboseLevel == NWTC_Verbose) & CALL SetErrStat( ErrID_Info, "Lidar truncation point is behind the lidar. Truncation ratio is "//trim(num2lstr(LidWtRatio))//'.', ErrStat, ErrMsg, RoutineName) ! set informational message about point being behind lidar - !y%LidErr = 3 y%lidar%WtTrunc = LidWtRatio EXIT ENDIF @@ -490,17 +443,15 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs PositionXYZ(1,2) = LidPosition(1) - COS(LidTheta)*COS(LidPhi)*(FocDist - LidRange) PositionXYZ(2,2) = LidPosition(2) + SIN(LidTheta)*COS(LidPhi)*(FocDist - LidRange) - CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, & - AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) IF (ErrStat2 >= AbortErrLev) THEN !out of bounds IF (NWTC_VerboseLevel == NWTC_Verbose) & CALL SetErrStat( ErrID_Warn, "Lidar speed truncated. Truncation ratio is "//trim(num2lstr(LidWtRatio))//".", ErrStat, ErrMsg, RoutineName ) - !y%LidErr = 2 y%lidar%WtTrunc = LidWtRatio EXIT ENDIF - y%lidar%LidSpeed = y%lidar%LidSpeed + LidWt*DOT_PRODUCT(-1*LidDirUnVec, VelocityUVW(:,1) + VelocityUVW(:,2)) + y%lidar%LidSpeed = y%lidar%LidSpeed + LidWt*DOT_PRODUCT(-1*LidDirUnVec, VelocityUVW(:,1) + VelocityUVW(:,2)) WtFuncSum = WtFuncSum + 2*LidWt END DO @@ -516,40 +467,38 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs ENDIF ELSE !p%SensorType == SensorType_PulsedLidar + IBeam = 1 - - + !bjj: note that u%lidar%PulseLidEl and u%lidar%PulseLidAz are not set in the calling code, so they are always 0 LidDirUnVec(1) = -1*COS(u%lidar%PulseLidEl) LidDirUnVec(2) = SIN(u%lidar%PulseLidEl)*SIN(u%lidar%PulseLidAz) LidDirUnVec(3) = SIN(u%lidar%PulseLidEl)*COS(u%lidar%PulseLidAz) - DO IRangeGt = 1,p%lidar%NumPulseGate - !y%lidar%LidErr(IRangeGt) = 0 - - LidPosition(2) = LidPosition(2) + p%lidar%MsrPosition(2,1) - LidPosition(3) = LidPosition(3) + p%lidar%MsrPosition(3,1) + !bjj: do the y- and z- components of PositionXYZ make sense here? It looks like they assume p%lidar%MsrPosition(2:3,IBeam) are zero + + LidPosition(2) = LidPosition(2) + p%lidar%MsrPosition(2,IBeam) + LidPosition(3) = LidPosition(3) + p%lidar%MsrPosition(3,IBeam) - !get lidar speed at the focal point to see if it is out of bounds - PositionXYZ(:,1) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing) + !get lidar speed at the focal point to see if it is out of bounds; bjj: this equation looks strange to me. Note how the X component is used to modify Y and Z. + PositionXYZ(:,1) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,IBeam) - (IRangeGt-1)*p%lidar%PulseSpacing) - y%lidar%MsrPositionsX(IRangeGt) = LidPosition(1) + LidDirUnVec(1)*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing) - y%lidar%MsrPositionsY(IRangeGt) = LidPosition(2) + p%lidar%MsrPosition(2,1) - y%lidar%MsrPositionsZ(IRangeGt) = LidPosition(3) + p%lidar%MsrPosition(3,1) + !bjj: I don't think this makes any sense in the Y and Z components. Will modify MsrPositionsY and MsrPositionsZ + y%lidar%MsrPositionsX(IRangeGt) = PositionXYZ(1,1) + y%lidar%MsrPositionsY(IRangeGt) = PositionXYZ(2,1) ! was LidPosition(2) + p%lidar%MsrPosition(2,IBeam), adding p%lidar%MsrPosition(2,IBeam) to the position AGAIN + y%lidar%MsrPositionsZ(IRangeGt) = PositionXYZ(3,1) ! was LidPosition(3) + p%lidar%MsrPosition(3,IBeam) - CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, & - AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ(:,1:1), VelocityUVW(:,1:1), AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - LidWt = NWTC_ERF((p%lidar%PulseSpacing/2)/p%lidar%r_p)/p%lidar%PulseSpacing + LidWt = NWTC_ERF((p%lidar%PulseSpacing/2)/p%lidar%r_p)/p%lidar%PulseSpacing LidWtMax = LidWt LidWtRatio = 1.0_ReKi !LidWt/LidWtMax !if out of bounds IF (ErrStat2 >= AbortErrLev) THEN - !y%LidErr(IRangeGt) = 1 y%lidar%LidSpeed(IRangeGt) = -99 RETURN !escape function ENDIF @@ -580,26 +529,23 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs IF (NWTC_VerboseLevel == NWTC_Verbose) & CALL SetErrStat( ErrID_Info, "Lidar truncation point at gate "//trim(num2lstr(IRangeGt))//" is behind the lidar. Truncation ratio is "& //trim(num2lstr(LidWtRatio))//'.', ErrStat, ErrMsg, RoutineName) ! set informational message about point being behind lidar - !y%LidErr(IRangeGt) = 3 y%lidar%WtTrunc(IRangeGt) = LidWtRatio EXIT ENDIF !calculate points to scan for current beam point - PositionXYZ(:,1) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing + LidRange) - PositionXYZ(:,2) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing - LidRange) - CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, & - AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) + PositionXYZ(:,1) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,IBeam) - (IRangeGt-1)*p%lidar%PulseSpacing + LidRange) + PositionXYZ(:,2) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,IBeam) - (IRangeGt-1)*p%lidar%PulseSpacing - LidRange) + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, t, PositionXYZ, VelocityUVW, AccelUVW, ErrStat2, ErrMsg2, BoxExceedAllow=.true.) IF (ErrStat2 >= AbortErrLev) THEN !out of bounds IF (NWTC_VerboseLevel == NWTC_Verbose) & CALL SetErrStat( ErrID_Warn, "Lidar speed at gate "//trim(num2lstr(IRangeGt))//" truncated. Truncation ratio is "//trim(num2lstr(LidWtRatio))//".", ErrStat, ErrMsg, RoutineName ) - !y%LidErr(IRangeGt) = 2 y%lidar%WtTrunc(IRangeGt) = LidWtRatio EXIT ENDIF - y%lidar%LidSpeed(IRangeGt) = y%lidar%LidSpeed(IRangeGt) + LidWt*DOT_PRODUCT(-1*LidDirUnVec,VelocityUVW(:,1) + VelocityUVW(:,2)) + y%lidar%LidSpeed(IRangeGt) = y%lidar%LidSpeed(IRangeGt) + LidWt*DOT_PRODUCT(-1*LidDirUnVec,VelocityUVW(:,1) + VelocityUVW(:,2)) WtFuncSum = WtFuncSum + 2*LidWt END DO @@ -613,9 +559,9 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs y%lidar%LidSpeed(IRangeGt) = -1*y%lidar%LidSpeed(IRangeGt)/(LidDirUnVec(1)*WtFuncSum) ENDIF - END DO + END DO - END IF + END IF END SUBROUTINE Lidar_CalcOutput !---------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules/inflowwind/src/Lidar.txt b/modules/inflowwind/src/Lidar.txt index 8f2defd9dd..7bdc3d63c0 100644 --- a/modules/inflowwind/src/Lidar.txt +++ b/modules/inflowwind/src/Lidar.txt @@ -14,16 +14,6 @@ param Lidar - IntKi SensorType_SinglePoint - 1 - - param ^ - IntKi SensorType_ContinuousLidar - 2 - - param ^ - IntKi SensorType_PulsedLidar - 3 - - -# ..... LIDAR_InitInputType data ....................................................................................................... -typedef ^ Lidar_InitInputType IntKi SensorType - SensorType_None - "SensorType_* parameter" - -typedef ^ Lidar_InitInputType DbKi Tmax - - - "the length of the simulation" "s" -typedef ^ Lidar_InitInputType ReKi RotorApexOffsetPos {3} - - "position of the lidar unit relative to the rotor apex of rotation" "m" -typedef ^ Lidar_InitInputType ReKi HubPosition {3} - - "initial position of the hub (lidar mounted on hub) [0,0,HubHeight]" "m" -typedef ^ Lidar_InitInputType IntKi NumPulseGate - - - "the number of range gates to return wind speeds at" - -typedef ^ Lidar_InitInputType LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - - -# ..... LIDAR_InitInputType data ....................................................................................................... -typedef ^ Lidar_InitOutputType ReKi DummyInitOut - # ..... LIDAR_ParameterType data ....................................................................................................... typedef ^ Lidar_ParameterType IntKi NumPulseGate - - - "the number of range gates to return wind speeds at; pulsed lidar only" - @@ -33,7 +23,6 @@ typedef ^ Lidar_ParameterType ReKi SpatialRes - - - "spatial samp typedef ^ Lidar_ParameterType IntKi SensorType - - - "SensorType_* parameter" - typedef ^ Lidar_ParameterType ReKi WtFnTrunc - - - "Percentage of the peak value at which to truncate weighting function" typedef ^ Lidar_ParameterType ReKi PulseRangeOne - - - "the range to the closest range gate" "m" -typedef ^ Lidar_ParameterType ReKi DeltaP - - - "the distance between range gates" "m" typedef ^ Lidar_ParameterType ReKi DeltaR - - - "the FWHM width of the pulse" typedef ^ Lidar_ParameterType ReKi r_p - - - typedef ^ Lidar_ParameterType LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - @@ -44,28 +33,15 @@ typedef ^ Lidar_ParameterType IntKi NumBeam - - - "Numb typedef ^ Lidar_ParameterType ReKi FocalDistanceX : - - "LIDAR LOS focal distance co-ordinates in the x direction" "m" typedef ^ Lidar_ParameterType ReKi FocalDistanceY : - - "LIDAR LOS focal distance co-ordinates in the y direction" "m" typedef ^ Lidar_ParameterType ReKi FocalDistanceZ : - - "LIDAR LOS focal distance co-ordinates in the z direction" "m" -typedef ^ Lidar_ParameterType ReKi MsrPosition {:}{:} - - "Position of the desired wind measurement (was XMsrPt, YMsrPt, ZMsrPt)" "m" +typedef ^ Lidar_ParameterType ReKi MsrPosition {:}{:} - - "Position of the desired wind measurement, per beam (was XMsrPt, YMsrPt, ZMsrPt)" "m" typedef ^ Lidar_ParameterType ReKi PulseSpacing - - - "Distance between range gates" "m" typedef ^ Lidar_ParameterType ReKi URefLid - - - "Reference average wind speed for the lidar" "m/s" -typedef ^ Lidar_ParameterType IntKi ConsiderHubMotion - - - "Flag whether to consider the hub motion's impact on the Lidar measurement" - +typedef ^ Lidar_ParameterType IntKi ConsiderHubMotion - - - "Whether to consider the hub motion's impact on the Lidar measurement" - typedef ^ Lidar_ParameterType ReKi MeasurementInterval - - - "Time steps between lidar measurements" "s" typedef ^ Lidar_ParameterType ReKi LidPosition {3} - - "Position of the Lidar unit (was XLidPt, YLidPt, ZLidPt)" "m" +typedef ^ Lidar_ParameterType IntKi NumMeasurements - 0 - "Number of measurements output" - -# ..... States .................................................................................................................... -# Define continuous (differentiable) states here: -typedef ^ ContinuousStateType ReKi DummyContState - - - "Remove this variable if you have continuous states" - -# Define discrete (nondifferentiable) states here: -typedef ^ DiscreteStateType ReKi DummyDiscState - - - "Remove this variable if you have discrete states" - -# Define constraint states here: -typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" - -# Define "other" states (any data that are not considered actual states) here: -typedef ^ OtherStateType ReKi DummyOtherState - - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType ReKi DummyMiscVar - - - "Remove this variable if you have misc variables" - # ..... LIDAR_InputType data ....................................................................................................... @@ -81,4 +57,3 @@ typedef ^ Lidar_OutputType ReKi WtTrunc {:} - - "Contains the frac typedef ^ Lidar_OutputType ReKi MsrPositionsX {:} - - "Lidar X direction measurement points" "m" typedef ^ Lidar_OutputType ReKi MsrPositionsY {:} - - "Lidar Y direction measurement points" "m" typedef ^ Lidar_OutputType ReKi MsrPositionsZ {:} - - "Lidar Z direction measurement points" "m" -#typedef ^ Lidar_OutputType IntKi LidErr {:} - - "Error code; THIS NEEDS TO GET FIXED (no integer outputs)" diff --git a/modules/inflowwind/src/Lidar_Types.f90 b/modules/inflowwind/src/Lidar_Types.f90 index 8277eb6a54..490316f137 100644 --- a/modules/inflowwind/src/Lidar_Types.f90 +++ b/modules/inflowwind/src/Lidar_Types.f90 @@ -37,21 +37,6 @@ MODULE Lidar_Types INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_SinglePoint = 1 INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_ContinuousLidar = 2 INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_PulsedLidar = 3 -! ========= Lidar_InitInputType ======= - TYPE, PUBLIC :: Lidar_InitInputType - INTEGER(IntKi) :: SensorType = SensorType_None !< SensorType_* parameter [-] - REAL(DbKi) :: Tmax = 0.0_R8Ki !< the length of the simulation [s] - REAL(ReKi) , DIMENSION(1:3) :: RotorApexOffsetPos = 0.0_ReKi !< position of the lidar unit relative to the rotor apex of rotation [m] - REAL(ReKi) , DIMENSION(1:3) :: HubPosition = 0.0_ReKi !< initial position of the hub (lidar mounted on hub) [0,0,HubHeight] [m] - INTEGER(IntKi) :: NumPulseGate = 0_IntKi !< the number of range gates to return wind speeds at [-] - LOGICAL :: LidRadialVel = .false. !< TRUE => return radial component, FALSE => return 'x' direction estimate [-] - END TYPE Lidar_InitInputType -! ======================= -! ========= Lidar_InitOutputType ======= - TYPE, PUBLIC :: Lidar_InitOutputType - REAL(ReKi) :: DummyInitOut = 0.0_ReKi - END TYPE Lidar_InitOutputType -! ======================= ! ========= Lidar_ParameterType ======= TYPE, PUBLIC :: Lidar_ParameterType INTEGER(IntKi) :: NumPulseGate = 0_IntKi !< the number of range gates to return wind speeds at; pulsed lidar only [-] @@ -61,7 +46,6 @@ MODULE Lidar_Types INTEGER(IntKi) :: SensorType = 0_IntKi !< SensorType_* parameter [-] REAL(ReKi) :: WtFnTrunc = 0.0_ReKi !< Percentage of the peak value at which to truncate weighting function [-] REAL(ReKi) :: PulseRangeOne = 0.0_ReKi !< the range to the closest range gate [m] - REAL(ReKi) :: DeltaP = 0.0_ReKi !< the distance between range gates [m] REAL(ReKi) :: DeltaR = 0.0_ReKi !< the FWHM width of the pulse [-] REAL(ReKi) :: r_p = 0.0_ReKi LOGICAL :: LidRadialVel = .false. !< TRUE => return radial component, FALSE => return 'x' direction estimate [-] @@ -72,39 +56,15 @@ MODULE Lidar_Types REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceX !< LIDAR LOS focal distance co-ordinates in the x direction [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceY !< LIDAR LOS focal distance co-ordinates in the y direction [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceZ !< LIDAR LOS focal distance co-ordinates in the z direction [m] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MsrPosition !< Position of the desired wind measurement (was XMsrPt, YMsrPt, ZMsrPt) [m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MsrPosition !< Position of the desired wind measurement, per beam (was XMsrPt, YMsrPt, ZMsrPt) [m] REAL(ReKi) :: PulseSpacing = 0.0_ReKi !< Distance between range gates [m] REAL(ReKi) :: URefLid = 0.0_ReKi !< Reference average wind speed for the lidar [m/s] - INTEGER(IntKi) :: ConsiderHubMotion = 0_IntKi !< Flag whether to consider the hub motion's impact on the Lidar measurement [-] + INTEGER(IntKi) :: ConsiderHubMotion = 0_IntKi !< Whether to consider the hub motion's impact on the Lidar measurement [-] REAL(ReKi) :: MeasurementInterval = 0.0_ReKi !< Time steps between lidar measurements [s] REAL(ReKi) , DIMENSION(1:3) :: LidPosition = 0.0_ReKi !< Position of the Lidar unit (was XLidPt, YLidPt, ZLidPt) [m] + INTEGER(IntKi) :: NumMeasurements = 0 !< Number of measurements output [-] END TYPE Lidar_ParameterType ! ======================= -! ========= Lidar_ContinuousStateType ======= - TYPE, PUBLIC :: Lidar_ContinuousStateType - REAL(ReKi) :: DummyContState = 0.0_ReKi !< Remove this variable if you have continuous states [-] - END TYPE Lidar_ContinuousStateType -! ======================= -! ========= Lidar_DiscreteStateType ======= - TYPE, PUBLIC :: Lidar_DiscreteStateType - REAL(ReKi) :: DummyDiscState = 0.0_ReKi !< Remove this variable if you have discrete states [-] - END TYPE Lidar_DiscreteStateType -! ======================= -! ========= Lidar_ConstraintStateType ======= - TYPE, PUBLIC :: Lidar_ConstraintStateType - REAL(ReKi) :: DummyConstrState = 0.0_ReKi !< Remove this variable if you have constraint states [-] - END TYPE Lidar_ConstraintStateType -! ======================= -! ========= Lidar_OtherStateType ======= - TYPE, PUBLIC :: Lidar_OtherStateType - REAL(ReKi) :: DummyOtherState = 0.0_ReKi - END TYPE Lidar_OtherStateType -! ======================= -! ========= Lidar_MiscVarType ======= - TYPE, PUBLIC :: Lidar_MiscVarType - REAL(ReKi) :: DummyMiscVar = 0.0_ReKi !< Remove this variable if you have misc variables [-] - END TYPE Lidar_MiscVarType -! ======================= ! ========= Lidar_InputType ======= TYPE, PUBLIC :: Lidar_InputType REAL(ReKi) :: PulseLidEl = 0.0_ReKi !< the angle off of the x axis that the lidar is aimed (0 would be staring directly upwind, pi/2 would be staring perpendicular to the x axis) [-] @@ -125,97 +85,6 @@ MODULE Lidar_Types ! ======================= CONTAINS -subroutine Lidar_CopyInitInput(SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg) - type(Lidar_InitInputType), intent(in) :: SrcInitInputData - type(Lidar_InitInputType), intent(inout) :: DstInitInputData - integer(IntKi), intent(in ) :: CtrlCode - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_CopyInitInput' - ErrStat = ErrID_None - ErrMsg = '' - DstInitInputData%SensorType = SrcInitInputData%SensorType - DstInitInputData%Tmax = SrcInitInputData%Tmax - DstInitInputData%RotorApexOffsetPos = SrcInitInputData%RotorApexOffsetPos - DstInitInputData%HubPosition = SrcInitInputData%HubPosition - DstInitInputData%NumPulseGate = SrcInitInputData%NumPulseGate - DstInitInputData%LidRadialVel = SrcInitInputData%LidRadialVel -end subroutine - -subroutine Lidar_DestroyInitInput(InitInputData, ErrStat, ErrMsg) - type(Lidar_InitInputType), intent(inout) :: InitInputData - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_DestroyInitInput' - ErrStat = ErrID_None - ErrMsg = '' -end subroutine - -subroutine Lidar_PackInitInput(RF, Indata) - type(RegFile), intent(inout) :: RF - type(Lidar_InitInputType), intent(in) :: InData - character(*), parameter :: RoutineName = 'Lidar_PackInitInput' - if (RF%ErrStat >= AbortErrLev) return - call RegPack(RF, InData%SensorType) - call RegPack(RF, InData%Tmax) - call RegPack(RF, InData%RotorApexOffsetPos) - call RegPack(RF, InData%HubPosition) - call RegPack(RF, InData%NumPulseGate) - call RegPack(RF, InData%LidRadialVel) - if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_UnPackInitInput(RF, OutData) - type(RegFile), intent(inout) :: RF - type(Lidar_InitInputType), intent(inout) :: OutData - character(*), parameter :: RoutineName = 'Lidar_UnPackInitInput' - if (RF%ErrStat /= ErrID_None) return - call RegUnpack(RF, OutData%SensorType); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%Tmax); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%RotorApexOffsetPos); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%HubPosition); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%NumPulseGate); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%LidRadialVel); if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_CopyInitOutput(SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg) - type(Lidar_InitOutputType), intent(in) :: SrcInitOutputData - type(Lidar_InitOutputType), intent(inout) :: DstInitOutputData - integer(IntKi), intent(in ) :: CtrlCode - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_CopyInitOutput' - ErrStat = ErrID_None - ErrMsg = '' - DstInitOutputData%DummyInitOut = SrcInitOutputData%DummyInitOut -end subroutine - -subroutine Lidar_DestroyInitOutput(InitOutputData, ErrStat, ErrMsg) - type(Lidar_InitOutputType), intent(inout) :: InitOutputData - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_DestroyInitOutput' - ErrStat = ErrID_None - ErrMsg = '' -end subroutine - -subroutine Lidar_PackInitOutput(RF, Indata) - type(RegFile), intent(inout) :: RF - type(Lidar_InitOutputType), intent(in) :: InData - character(*), parameter :: RoutineName = 'Lidar_PackInitOutput' - if (RF%ErrStat >= AbortErrLev) return - call RegPack(RF, InData%DummyInitOut) - if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_UnPackInitOutput(RF, OutData) - type(RegFile), intent(inout) :: RF - type(Lidar_InitOutputType), intent(inout) :: OutData - character(*), parameter :: RoutineName = 'Lidar_UnPackInitOutput' - if (RF%ErrStat /= ErrID_None) return - call RegUnpack(RF, OutData%DummyInitOut); if (RegCheckErr(RF, RoutineName)) return -end subroutine - subroutine Lidar_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg) type(Lidar_ParameterType), intent(in) :: SrcParamData type(Lidar_ParameterType), intent(inout) :: DstParamData @@ -234,7 +103,6 @@ subroutine Lidar_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%SensorType = SrcParamData%SensorType DstParamData%WtFnTrunc = SrcParamData%WtFnTrunc DstParamData%PulseRangeOne = SrcParamData%PulseRangeOne - DstParamData%DeltaP = SrcParamData%DeltaP DstParamData%DeltaR = SrcParamData%DeltaR DstParamData%r_p = SrcParamData%r_p DstParamData%LidRadialVel = SrcParamData%LidRadialVel @@ -295,6 +163,7 @@ subroutine Lidar_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%ConsiderHubMotion = SrcParamData%ConsiderHubMotion DstParamData%MeasurementInterval = SrcParamData%MeasurementInterval DstParamData%LidPosition = SrcParamData%LidPosition + DstParamData%NumMeasurements = SrcParamData%NumMeasurements end subroutine subroutine Lidar_DestroyParam(ParamData, ErrStat, ErrMsg) @@ -330,7 +199,6 @@ subroutine Lidar_PackParam(RF, Indata) call RegPack(RF, InData%SensorType) call RegPack(RF, InData%WtFnTrunc) call RegPack(RF, InData%PulseRangeOne) - call RegPack(RF, InData%DeltaP) call RegPack(RF, InData%DeltaR) call RegPack(RF, InData%r_p) call RegPack(RF, InData%LidRadialVel) @@ -347,6 +215,7 @@ subroutine Lidar_PackParam(RF, Indata) call RegPack(RF, InData%ConsiderHubMotion) call RegPack(RF, InData%MeasurementInterval) call RegPack(RF, InData%LidPosition) + call RegPack(RF, InData%NumMeasurements) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -365,7 +234,6 @@ subroutine Lidar_UnPackParam(RF, OutData) call RegUnpack(RF, OutData%SensorType); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%WtFnTrunc); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%PulseRangeOne); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%DeltaP); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%DeltaR); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%r_p); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%LidRadialVel); if (RegCheckErr(RF, RoutineName)) return @@ -382,196 +250,7 @@ subroutine Lidar_UnPackParam(RF, OutData) call RegUnpack(RF, OutData%ConsiderHubMotion); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%MeasurementInterval); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%LidPosition); if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_CopyContState(SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg) - type(Lidar_ContinuousStateType), intent(in) :: SrcContStateData - type(Lidar_ContinuousStateType), intent(inout) :: DstContStateData - integer(IntKi), intent(in ) :: CtrlCode - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_CopyContState' - ErrStat = ErrID_None - ErrMsg = '' - DstContStateData%DummyContState = SrcContStateData%DummyContState -end subroutine - -subroutine Lidar_DestroyContState(ContStateData, ErrStat, ErrMsg) - type(Lidar_ContinuousStateType), intent(inout) :: ContStateData - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_DestroyContState' - ErrStat = ErrID_None - ErrMsg = '' -end subroutine - -subroutine Lidar_PackContState(RF, Indata) - type(RegFile), intent(inout) :: RF - type(Lidar_ContinuousStateType), intent(in) :: InData - character(*), parameter :: RoutineName = 'Lidar_PackContState' - if (RF%ErrStat >= AbortErrLev) return - call RegPack(RF, InData%DummyContState) - if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_UnPackContState(RF, OutData) - type(RegFile), intent(inout) :: RF - type(Lidar_ContinuousStateType), intent(inout) :: OutData - character(*), parameter :: RoutineName = 'Lidar_UnPackContState' - if (RF%ErrStat /= ErrID_None) return - call RegUnpack(RF, OutData%DummyContState); if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_CopyDiscState(SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg) - type(Lidar_DiscreteStateType), intent(in) :: SrcDiscStateData - type(Lidar_DiscreteStateType), intent(inout) :: DstDiscStateData - integer(IntKi), intent(in ) :: CtrlCode - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_CopyDiscState' - ErrStat = ErrID_None - ErrMsg = '' - DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState -end subroutine - -subroutine Lidar_DestroyDiscState(DiscStateData, ErrStat, ErrMsg) - type(Lidar_DiscreteStateType), intent(inout) :: DiscStateData - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_DestroyDiscState' - ErrStat = ErrID_None - ErrMsg = '' -end subroutine - -subroutine Lidar_PackDiscState(RF, Indata) - type(RegFile), intent(inout) :: RF - type(Lidar_DiscreteStateType), intent(in) :: InData - character(*), parameter :: RoutineName = 'Lidar_PackDiscState' - if (RF%ErrStat >= AbortErrLev) return - call RegPack(RF, InData%DummyDiscState) - if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_UnPackDiscState(RF, OutData) - type(RegFile), intent(inout) :: RF - type(Lidar_DiscreteStateType), intent(inout) :: OutData - character(*), parameter :: RoutineName = 'Lidar_UnPackDiscState' - if (RF%ErrStat /= ErrID_None) return - call RegUnpack(RF, OutData%DummyDiscState); if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_CopyConstrState(SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg) - type(Lidar_ConstraintStateType), intent(in) :: SrcConstrStateData - type(Lidar_ConstraintStateType), intent(inout) :: DstConstrStateData - integer(IntKi), intent(in ) :: CtrlCode - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_CopyConstrState' - ErrStat = ErrID_None - ErrMsg = '' - DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState -end subroutine - -subroutine Lidar_DestroyConstrState(ConstrStateData, ErrStat, ErrMsg) - type(Lidar_ConstraintStateType), intent(inout) :: ConstrStateData - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_DestroyConstrState' - ErrStat = ErrID_None - ErrMsg = '' -end subroutine - -subroutine Lidar_PackConstrState(RF, Indata) - type(RegFile), intent(inout) :: RF - type(Lidar_ConstraintStateType), intent(in) :: InData - character(*), parameter :: RoutineName = 'Lidar_PackConstrState' - if (RF%ErrStat >= AbortErrLev) return - call RegPack(RF, InData%DummyConstrState) - if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_UnPackConstrState(RF, OutData) - type(RegFile), intent(inout) :: RF - type(Lidar_ConstraintStateType), intent(inout) :: OutData - character(*), parameter :: RoutineName = 'Lidar_UnPackConstrState' - if (RF%ErrStat /= ErrID_None) return - call RegUnpack(RF, OutData%DummyConstrState); if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_CopyOtherState(SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg) - type(Lidar_OtherStateType), intent(in) :: SrcOtherStateData - type(Lidar_OtherStateType), intent(inout) :: DstOtherStateData - integer(IntKi), intent(in ) :: CtrlCode - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_CopyOtherState' - ErrStat = ErrID_None - ErrMsg = '' - DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState -end subroutine - -subroutine Lidar_DestroyOtherState(OtherStateData, ErrStat, ErrMsg) - type(Lidar_OtherStateType), intent(inout) :: OtherStateData - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_DestroyOtherState' - ErrStat = ErrID_None - ErrMsg = '' -end subroutine - -subroutine Lidar_PackOtherState(RF, Indata) - type(RegFile), intent(inout) :: RF - type(Lidar_OtherStateType), intent(in) :: InData - character(*), parameter :: RoutineName = 'Lidar_PackOtherState' - if (RF%ErrStat >= AbortErrLev) return - call RegPack(RF, InData%DummyOtherState) - if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_UnPackOtherState(RF, OutData) - type(RegFile), intent(inout) :: RF - type(Lidar_OtherStateType), intent(inout) :: OutData - character(*), parameter :: RoutineName = 'Lidar_UnPackOtherState' - if (RF%ErrStat /= ErrID_None) return - call RegUnpack(RF, OutData%DummyOtherState); if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_CopyMisc(SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg) - type(Lidar_MiscVarType), intent(in) :: SrcMiscData - type(Lidar_MiscVarType), intent(inout) :: DstMiscData - integer(IntKi), intent(in ) :: CtrlCode - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_CopyMisc' - ErrStat = ErrID_None - ErrMsg = '' - DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar -end subroutine - -subroutine Lidar_DestroyMisc(MiscData, ErrStat, ErrMsg) - type(Lidar_MiscVarType), intent(inout) :: MiscData - integer(IntKi), intent( out) :: ErrStat - character(*), intent( out) :: ErrMsg - character(*), parameter :: RoutineName = 'Lidar_DestroyMisc' - ErrStat = ErrID_None - ErrMsg = '' -end subroutine - -subroutine Lidar_PackMisc(RF, Indata) - type(RegFile), intent(inout) :: RF - type(Lidar_MiscVarType), intent(in) :: InData - character(*), parameter :: RoutineName = 'Lidar_PackMisc' - if (RF%ErrStat >= AbortErrLev) return - call RegPack(RF, InData%DummyMiscVar) - if (RegCheckErr(RF, RoutineName)) return -end subroutine - -subroutine Lidar_UnPackMisc(RF, OutData) - type(RegFile), intent(inout) :: RF - type(Lidar_MiscVarType), intent(inout) :: OutData - character(*), parameter :: RoutineName = 'Lidar_UnPackMisc' - if (RF%ErrStat /= ErrID_None) return - call RegUnpack(RF, OutData%DummyMiscVar); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%NumMeasurements); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine Lidar_CopyInput(SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg) diff --git a/modules/lindyn/src/LinDyn.f90 b/modules/lindyn/src/LinDyn.f90 index 3bb9f0f292..799c0d2fd3 100644 --- a/modules/lindyn/src/LinDyn.f90 +++ b/modules/lindyn/src/LinDyn.f90 @@ -179,10 +179,10 @@ subroutine LD_SetInitialConditions(x, x0, xd0, p, OtherState, m, errStat, errMsg nx = int(size(x%q)/2) errStat = ErrID_Fatal if (size(x0)/=size(xd0)) then - errMsg ='Shape of x0 and xd0 should match when setting intial conditions'; return + errMsg ='Shape of x0 and xd0 should match when setting initial conditions'; return endif if (size(x0)/=nx) then - errMsg ='Shape of x0 should match nx when setting intial conditions'; return + errMsg ='Shape of x0 should match nx when setting initial conditions'; return endif errMsg = '' errStat = ErrID_None diff --git a/modules/map/src/bstring/bstrlib.h b/modules/map/src/bstring/bstrlib.h index 1292a38cb9..0887977a90 100644 --- a/modules/map/src/bstring/bstrlib.h +++ b/modules/map/src/bstring/bstrlib.h @@ -1506,7 +1506,7 @@ bseof(const struct bStream *s); /* Static constant block parameter pair */ /** - * The bsStaticBlkParms macro emits a pair of comma seperated parameters + * The bsStaticBlkParms macro emits a pair of comma separated parameters * corresponding to the block parameters for the block functions in Bstrlib * (i.e., blk2bstr, bcatblk, blk2tbstr, bisstemeqblk, bisstemeqcaselessblk). * @@ -1521,7 +1521,7 @@ bseof(const struct bStream *s); * * These are faster than using bfromcstr() and bcatcstr() respectively * because the length of the inline string is known as a compile time - * constant. Also note that seperate struct tagbstring declarations for + * constant. Also note that separate struct tagbstring declarations for */ #define bsStaticBlkParms(q) \ ((void *)("" q "")), ((int)sizeof(q) -1) diff --git a/modules/map/src/freedata.c b/modules/map/src/freedata.c index f875db98d0..062564d132 100644 --- a/modules/map/src/freedata.c +++ b/modules/map/src/freedata.c @@ -56,8 +56,8 @@ MAP_ERROR_CODE free_outlist(Domain* domain, char* map_msg, MAP_ERROR_CODE* ierr) list_iterator_stop(&domain->y_list->out_list_ptr); // @rm y_list->out_list no longer exists/is useful ? - list_destroy(&domain->y_list->out_list); /* destroy output lists for writting information to output file */ - list_destroy(&domain->y_list->out_list_ptr); /* destroy output lists for writting information to output file */ + list_destroy(&domain->y_list->out_list); /* destroy output lists for writing information to output file */ + list_destroy(&domain->y_list->out_list_ptr); /* destroy output lists for writing information to output file */ }; MAPFREE(domain->y_list); return MAP_SAFE; diff --git a/modules/map/src/lineroutines.c b/modules/map/src/lineroutines.c index ba89c7b5bd..de5f61939f 100644 --- a/modules/map/src/lineroutines.c +++ b/modules/map/src/lineroutines.c @@ -350,7 +350,7 @@ MAP_ERROR_CODE line_solve_sequence(Domain* domain, MAP_ParameterType_t* p_type, success = set_line_variables_pre_solve(domain, map_msg, ierr); success = reset_node_force_to_zero(domain, map_msg, ierr); success = solve_line(domain, t, map_msg, ierr); CHECKERRQ(MAP_FATAL_88); - // /* prematurely terminating the the line solve routine to return back to the + // /* prematurely terminating the line solve routine to return back to the // caller function. Do a back tracking on the solution and attempt recovery */ // if (success==MAP_FATAL) { // return MAP_FATAL_59; diff --git a/modules/map/src/mapapi.c b/modules/map/src/mapapi.c index ec86d8402a..69d47714b1 100644 --- a/modules/map/src/mapapi.c +++ b/modules/map/src/mapapi.c @@ -151,7 +151,7 @@ MAP_EXTERNCALL void map_init(MAP_InitInputType_t* init_type, MAP_END_ERROR_LOG; - /* the next functions are called in a seperate do-loop to log information to the + /* the next functions are called in a separate do-loop to log information to the * summary file even if a fatal error is encountered. This guarantees the summary * file is written even if garbage is recorded. */ @@ -159,7 +159,7 @@ MAP_EXTERNCALL void map_init(MAP_InitInputType_t* init_type, free_init_data(init_data, map_msg, ierr); MAP_InitInput_Delete(init_data); - if (*ierr!=MAP_SAFE) printf("Intialization: %s\n", map_msg); + if (*ierr!=MAP_SAFE) printf("Initialization: %s\n", map_msg); // checkpoint(); // printf("In initialization: %p\n",z_type); diff --git a/modules/map/src/mapapi.h b/modules/map/src/mapapi.h index 5d7134b1bf..4111f818e1 100644 --- a/modules/map/src/mapapi.h +++ b/modules/map/src/mapapi.h @@ -98,7 +98,7 @@ MAP_EXTERNCALL int free_init_data (MAP_InitializationData_t init, char* map_msg, /** * @brief Set the water depth. Should be called before {@link map_init()} - * @param p_type paramter type, native C struct {@link MAP_ParameterType_t} + * @param p_type parameter type, native C struct {@link MAP_ParameterType_t} * @param depth water depth [m] * * Example Fortran usage: @@ -123,7 +123,7 @@ MAP_EXTERNCALL void map_set_sea_depth(MAP_Parameter_t p_type, const double depth /** * @brief Set the water density. Should be called before {@link map_init()} - * @param p_type paramter type, native C struct {@link MAP_ParameterType_t} + * @param p_type parameter type, native C struct {@link MAP_ParameterType_t} * @param rho water density [kg/m^3] * * Example Fortran usage: @@ -148,7 +148,7 @@ MAP_EXTERNCALL void map_set_sea_density(MAP_Parameter_t p_type, const double rho /** * @brief Set the gravitational constant. Should be called before {@link map_init()} - * @param p_type paramter type, native C struct {@link MAP_ParameterType_t} + * @param p_type parameter type, native C struct {@link MAP_ParameterType_t} * @param grtavity gravitational acceleration [m/s^2] * * Example Fortran usage: diff --git a/modules/map/src/mapinit.h b/modules/map/src/mapinit.h index 2693c26171..bd3063827d 100644 --- a/modules/map/src/mapinit.h +++ b/modules/map/src/mapinit.h @@ -210,7 +210,7 @@ MAP_ERROR_CODE check_help_flag(bstring list); * inner_ftol * * @param list, a character array structure - * @param ftol, pointer to the FTOL paramter for minpack + * @param ftol, pointer to the FTOL parameter for minpack * @see set_model_options_list(), map_init() * @return MAP error code */ @@ -230,7 +230,7 @@ MAP_ERROR_CODE check_inner_f_tol_flag(struct bstrList* list, double* ftol); * inner_gtol * * @param list, a character array structure - * @param gtol, pointer to the GTOL paramter for minpack + * @param gtol, pointer to the GTOL parameter for minpack * @see set_model_options_list(), map_init() * @return MAP error code */ @@ -249,7 +249,7 @@ MAP_ERROR_CODE check_inner_g_tol_flag(struct bstrList* list, double* gtol); * inner_xtol * * @param list, a character array structure - * @param xtol, pointer to the XTOL paramter for minpack + * @param xtol, pointer to the XTOL parameter for minpack * @see set_model_options_list(), map_init() * @return MAP error code */ @@ -302,7 +302,7 @@ MAP_ERROR_CODE check_outer_max_its_flag(struct bstrList* list, int* max_its); * outer_tol * * @param list, a character array structure - * @param outer_tol, pointer to the tolerance paramter + * @param outer_tol, pointer to the tolerance parameter * @see set_model_options_list(), map_init() * @return MAP error code */ diff --git a/modules/map/src/simclist/simclist.h b/modules/map/src/simclist/simclist.h index c6463a8719..32b2a13d99 100644 --- a/modules/map/src/simclist/simclist.h +++ b/modules/map/src/simclist/simclist.h @@ -97,7 +97,7 @@ typedef int (*element_comparator)(const void *a, const void *b); typedef int (*element_seeker)(const void *el, const void *indicator); /** - * an element lenght meter. + * an element length meter. * * An element meter is a function that: * -# receives the reference to an element el diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 12f381927e..ebee550a70 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -2418,7 +2418,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! rRef and OrMatRef or the position and orientation matrix of the ! coupled object relative to the platform, based on the input file. ! They are used to set the "reference" pose of each coupled mesh - ! entry before the intial offsets from PtfmInit are applied. + ! entry before the initial offsets from PtfmInit are applied. J = 0 ! this is the counter through the mesh points for each turbine @@ -2525,7 +2525,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er end do ! iTurb - ! >>>>>> ensure the output mesh includes all elements from u%(Farm)CoupledKinematics, OR make a seperate array of output meshes for each turbine <<<<<<<<< + ! >>>>>> ensure the output mesh includes all elements from u%(Farm)CoupledKinematics, OR make a separate array of output meshes for each turbine <<<<<<<<< CALL CheckError( ErrStat2, ErrMsg2 ) @@ -2694,7 +2694,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! if log file, compute and write some object properties ! ------------------------------------------------------------------- if (p%writeLog > 1) then - write(p%UnLog, '(A)' ) "Values after intialization before dynamic relaxation" + write(p%UnLog, '(A)' ) "Values after initialization before dynamic relaxation" write(p%UnLog, '(A)' ) " Bodies:" DO l = 1,p%nBodies write(p%UnLog, '(A)' ) " Body"//trim(num2lstr(l))//":" @@ -3988,7 +3988,7 @@ END SUBROUTINE MD_Step !-------------------------------------------------------------- SUBROUTINE MD_RK2 ( t, dtM, u_interp, u, t_array, p, x, xd, z, other, m, ErrStat, ErrMsg ) - REAL(DbKi) , INTENT(INOUT) :: t ! intial time (s) for this integration step + REAL(DbKi) , INTENT(INOUT) :: t ! initial time (s) for this integration step REAL(DbKi) , INTENT(IN ) :: dtM ! single time step size (s) for this integration step TYPE( MD_InputType ) , INTENT(INOUT) :: u_interp ! interpolated instantaneous input values to be calculated for each mooring time step TYPE( MD_InputType ) , INTENT(INOUT) :: u(:) ! INTENT(IN ) @@ -4353,7 +4353,7 @@ SUBROUTINE MD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM ! get central difference: ! we may have had an error allocating memory, so we'll check if(Failed()) return - ! get central difference (state entries are mapped the the dXdu column in routine): + ! get central difference (state entries are mapped to the dXdu column in routine): call MD_Compute_dX( p, x_p, x_m, delta_p, dXdu(:,i) ) end do END IF ! dXdu diff --git a/modules/moordyn/src/MoorDyn_C_Binding.f90 b/modules/moordyn/src/MoorDyn_C_Binding.f90 index b2d136c46f..8380665966 100644 --- a/modules/moordyn/src/MoorDyn_C_Binding.f90 +++ b/modules/moordyn/src/MoorDyn_C_Binding.f90 @@ -150,7 +150,7 @@ SUBROUTINE MD_C_Init( & REAL(C_FLOAT) , INTENT(IN ) :: PtfmInit_C(6) ! TODO: make this more flexible, can we not have 6 DOF only coupling? INTEGER(C_INT) , INTENT(IN ) :: InterpOrder_C INTEGER(C_INT) , INTENT( OUT) :: NumChannels_C - CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: OutputChannelNames_C(100000) + CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: OutputChannelNames_C(100000) ! The size of these arrays was chosen as a "big number", it isn't set by MoorDyn. Watch out, it might be bigger than this! CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: OutputChannelUnits_C(100000) INTEGER(C_INT) , INTENT( OUT) :: ErrStat_C CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) @@ -585,7 +585,6 @@ END SUBROUTINE MD_C_End !----------------------------------------------- MD SetWaveFieldData ------------------------------------------- !=============================================================================================================== !> Set the wave field data pointer from an external source such as SeaState -!! Assumes that MD_C_Init has been run since it uses those values to check that there's a valid pointer SUBROUTINE MD_C_SetWaveFieldData(WaveFieldData_C) BIND (C, NAME='MD_C_SetWaveFieldData') #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: MD_C_SetWaveFieldData diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 6e2d4326c5..3ed23fc7c2 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -124,8 +124,8 @@ PROGRAM MoorDyn_Driver REAL(ReKi) :: PrevClockTime !< Previous clock time in seconds past midnight INTEGER :: SimStrtTime (8) !< An array containing the elements of the start time (after initialization). INTEGER :: ProgStrtTime (8) !< An array containing the elements of the program start time (before initialization). - REAL(ReKi) :: SimStrtCPU !< User CPU time for simulation (without intialization) - REAL(ReKi) :: ProgStrtCPU !< User CPU time for program (with intialization) + REAL(ReKi) :: SimStrtCPU !< User CPU time for simulation (without initialization) + REAL(ReKi) :: ProgStrtCPU !< User CPU time for program (with initialization) CHARACTER(20) :: FlagArg ! flag argument from command line diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index a533d083d4..4466718db2 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -191,7 +191,7 @@ SUBROUTINE TransformKinematics(rRelBody, r_in, TransMat, rd_in, r_out, rd_out) ! rd_in should be in global orientation frame ! note: it's okay if r_out and rd_out are 6-size. Only the first 3 will be written, and 4-6 will - ! already be correct or can be assigned seperately from r_in and rd_in (assuming orientation frames are identical) + ! already be correct or can be assigned separately from r_in and rd_in (assuming orientation frames are identical) ! locations (unrotated reference frame) about platform reference point (2021-01-05: just transposed TransMat, it was incorrect before) @@ -248,7 +248,7 @@ SUBROUTINE TransformKinematicsA(rRelBody, r_in, TransMat, v_in, a_in, r_out, v_o ! rd_in should be in global orientation frame ! note: it's okay if r_out and rd_out are 6-size. Only the first 3 will be written, and 4-6 will - ! already be correct or can be assigned seperately from r_in and rd_in (assuming orientation frames are identical) + ! already be correct or can be assigned separately from r_in and rd_in (assuming orientation frames are identical) ! locations about ref point in *unrotated* reference frame @@ -1067,7 +1067,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) INTEGER(IntKi) :: NStepWave ! INTEGER(IntKi) :: NStepWave2 ! - REAL(SiKi) :: WaveTMax ! max wave elevation time series duration after optimizing lenght for FFT + REAL(SiKi) :: WaveTMax ! max wave elevation time series duration after optimizing length for FFT REAL(SiKi) :: WaveDOmega ! frequency step REAL(SiKi), ALLOCATABLE :: SinWaveDir(:) ! SIN( WaveDirArr(I) ) -- Each wave frequency has a unique wave direction. REAL(SiKi), ALLOCATABLE :: CosWaveDir(:) ! COS( WaveDirArr(I) ) -- Each wave frequency has a unique wave direction. @@ -1189,8 +1189,8 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) FileName = trim(WaterKinString) END IF - - + + UnEcho=-1 CALL GetNewUnit( UnIn ) CALL OpenFInpFile( UnIn, FileName, ErrStat2, ErrMsg2); IF(Failed()) RETURN @@ -1617,10 +1617,10 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) ENDDO ! Initialize the FFT - CALL InitFFT ( NStepWave, FFT_Data, .FALSE., ErrStat2 ); ErrMsg2 = 'Error occured while initializing the FFT.'; IF(Failed()) RETURN + CALL InitFFT ( NStepWave, FFT_Data, .FALSE., ErrStat2 ); ErrMsg2 = 'Error occurred while initializing the FFT.'; IF(Failed()) RETURN ! Apply the forward FFT on the wave elevation timeseries to get the real and imaginary parts of the frequency information. - CALL ApplyFFT_f ( TmpFFTWaveElev(:), FFT_Data, ErrStat2 ); ErrMsg2 = 'Error occured while applying the forwards FFT to TmpFFTWaveElev array.'; IF(Failed()) RETURN ! Note that the TmpFFTWaveElev now contains the real and imaginary bits. + CALL ApplyFFT_f ( TmpFFTWaveElev(:), FFT_Data, ErrStat2 ); ErrMsg2 = 'Error occurred while applying the forwards FFT to TmpFFTWaveElev array.'; IF(Failed()) RETURN ! Note that the TmpFFTWaveElev now contains the real and imaginary bits. ! Copy the resulting TmpFFTWaveElev(:) data over to the WaveElevC0 array DO I=1,NStepWave2-1 @@ -1629,7 +1629,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) ENDDO WaveElevC0(:,NStepWave2) = 0.0_SiKi - CALL ExitFFT(FFT_Data, ErrStat2); ErrMsg2 = 'Error occured while cleaning up after the FFTs.'; IF(Failed()) RETURN + CALL ExitFFT(FFT_Data, ErrStat2); ErrMsg2 = 'Error occurred while cleaning up after the FFTs.'; IF(Failed()) RETURN IF (ALLOCATED( WaveElev0 )) DEALLOCATE( WaveElev0 , STAT=ErrStat2); ErrMsg2 = 'Cannot deallocate WaveElev0.' ; IF (Failed0()) RETURN IF (ALLOCATED( TmpFFTWaveElev )) DEALLOCATE( TmpFFTWaveElev, STAT=ErrStat2); ErrMsg2 = 'Cannot deallocate TmpFFTWaveElev.'; IF (Failed0()) RETURN @@ -1674,7 +1674,7 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) END DO ! set up FFTer for doing IFFTs - CALL InitFFT ( NStepWave, FFT_Data, .TRUE., ErrStat2 ); ErrMsg2 = 'Error occured while initializing the FFT.'; IF(Failed()) RETURN + CALL InitFFT ( NStepWave, FFT_Data, .TRUE., ErrStat2 ); ErrMsg2 = 'Error occurred while initializing the FFT.'; IF(Failed()) RETURN ! Loop through all points where the incident wave kinematics will be computed DO ix = 1,p%nxWave @@ -1715,8 +1715,8 @@ SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) ! could also reproduce the wave elevation at 0,0,0 on a separate channel for verIFication... - CALL ExitFFT(FFT_Data, ErrStat2); ErrMsg2 = 'Error occured while cleaning up after the IFFTs.'; IF(Failed()) RETURN - + CALL ExitFFT(FFT_Data, ErrStat2); ErrMsg2 = 'Error occurred while cleaning up after the IFFTs.'; IF(Failed()) RETURN + END IF ! p%WaveKin > 0 diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 48b39a8c41..ec5177d6de 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -98,7 +98,7 @@ typedef ^ ^ IntKi nAttachedP - typedef ^ ^ IntKi nAttachedR - - - "number of attached rods" typedef ^ ^ DbKi rPointRel {3}{30} - - "relative position of point on body" typedef ^ ^ DbKi r6RodRel {6}{30} - - "relative position and orientation of rod on body" -typedef ^ ^ DbKi bodyM - - - "body mass (seperate from attached objects)" "[kg]" +typedef ^ ^ DbKi bodyM - - - "body mass (separate from attached objects)" "[kg]" typedef ^ ^ DbKi bodyV - - - "body volume (for buoyancy calculation)" "[m^3]" typedef ^ ^ DbKi bodyI {3} - - "body 3x3 inertia matrix diagonals" "[kg-m^2]" typedef ^ ^ DbKi bodyCdA {6} - - "product of drag force and frontal area of body" "[m^2]" diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 8278b06d80..2175d3bc12 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -118,7 +118,7 @@ MODULE MoorDyn_Types INTEGER(IntKi) :: nAttachedR = 0_IntKi !< number of attached rods [-] REAL(DbKi) , DIMENSION(1:3,1:30) :: rPointRel = 0.0_R8Ki !< relative position of point on body [-] REAL(DbKi) , DIMENSION(1:6,1:30) :: r6RodRel = 0.0_R8Ki !< relative position and orientation of rod on body [-] - REAL(DbKi) :: bodyM = 0.0_R8Ki !< body mass (seperate from attached objects) [[kg]] + REAL(DbKi) :: bodyM = 0.0_R8Ki !< body mass (separate from attached objects) [[kg]] REAL(DbKi) :: bodyV = 0.0_R8Ki !< body volume (for buoyancy calculation) [[m^3]] REAL(DbKi) , DIMENSION(1:3) :: bodyI = 0.0_R8Ki !< body 3x3 inertia matrix diagonals [[kg-m^2]] REAL(DbKi) , DIMENSION(1:6) :: bodyCdA = 0.0_R8Ki !< product of drag force and frontal area of body [[m^2]] diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index 241a7bc672..204db312bf 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -7456,7 +7456,7 @@ SUBROUTINE WrMatrix2R8( A, Un, ReFmt, MatName ) END SUBROUTINE WrMatrix2R8 !======================================================================= !> Based on nwtc_io::wrmatrix, this routine writes a matrix to an already-open text file. It allows -!! the user to omit rows and columns of A in the the file. +!! the user to omit rows and columns of A in the file. !! Use WrPartialMatrix (nwtc_io::wrpartialmatrix) instead of directly calling a specific routine in the generic interface. SUBROUTINE WrPartialMatrix1R8( A, Un, ReFmt, MatName, UseCol, UseAllCols, ExtCol ) diff --git a/modules/nwtc-library/src/NWTC_Num.f90 b/modules/nwtc-library/src/NWTC_Num.f90 index 97284cde29..928321affb 100644 --- a/modules/nwtc-library/src/NWTC_Num.f90 +++ b/modules/nwtc-library/src/NWTC_Num.f90 @@ -1490,7 +1490,7 @@ END SUBROUTINE DCM_logMapR !! Use DCM_SetLogMapForInterp (nwtc_num::dcm_setlogmapforinterp) instead of directly calling a specific routine in the generic interface. SUBROUTINE DCM_SetLogMapForInterpD( tensor ) - REAL(DbKi), INTENT(INOUT) :: tensor(:,:) !< a 3xn matrix, whose columns represent individual skew-symmmetric matrices. On exit, + REAL(DbKi), INTENT(INOUT) :: tensor(:,:) !< a 3xn matrix, whose columns represent individual skew-symmetric matrices. On exit, !! each column will be within \f$2\pi\f$ of the previous column, allowing for interpolation !! of the quantities. @@ -2814,7 +2814,7 @@ FUNCTION GetSmllRotAngsR ( DCMat, ErrStat, ErrMsg ) END FUNCTION GetSmllRotAngsR !======================================================================= -!> This funtion returns the non-dimensional (-1:+1) location of the given Gauss-Legendre Quadrature point and its weight. +!> This function returns the non-dimensional (-1:+1) location of the given Gauss-Legendre Quadrature point and its weight. !! It works for NPts \f$\in \left[{1,6\right]\f$. !! The values came from Carnahan, Brice; Luther, H.A.; Wilkes, James O. (1969) "Applied Numerical Methods." SUBROUTINE GL_Pts ( IPt, NPts, Loc, Wt, ErrStat, ErrMsg ) @@ -2937,7 +2937,7 @@ SUBROUTINE GL_Pts ( IPt, NPts, Loc, Wt, ErrStat, ErrMsg ) RETURN END SUBROUTINE GL_Pts ! ( IPt, NPts, Loc, Wt [, ErrStat] ) !======================================================================= -!> This funtion returns an integer index such that CAry(IndexCharAry) = CVal. If +!> This function returns an integer index such that CAry(IndexCharAry) = CVal. If !! no element in the array matches CVal, the value -1 is returned. The routine !! performs a binary search on the input array to determine if CVal is an !! element of the array; thus, CAry must be sorted and stored in increasing @@ -3002,7 +3002,7 @@ FUNCTION IndexCharAry( CVal, CAry ) END FUNCTION IndexCharAry !======================================================================= -!> This funtion returns a y-value that corresponds to an input x-value by interpolating into the arrays. +!> This function returns a y-value that corresponds to an input x-value by interpolating into the arrays. !! It uses a binary interpolation scheme that takes about log(AryLen) / log(2) steps to converge. !! It returns the first or last YAry() value if XVal is outside the limits of XAry(). !! @@ -3131,7 +3131,7 @@ FUNCTION InterpBinReal( XVal, XAry, YAry, ILo, AryLen ) RETURN END FUNCTION InterpBinReal ! ( XVal, XAry, YAry, ILo, AryLen ) !======================================================================= -!> This funtion returns a y-value that corresponds to an input x-value by interpolating into the arrays. +!> This function returns a y-value that corresponds to an input x-value by interpolating into the arrays. !! It uses the passed index as the starting point and does a stepwise interpolation from there. This is !! especially useful when the calling routines save the value from the last time this routine was called !! for a given case where XVal does not change much from call to call. When there is no correlation @@ -3505,7 +3505,7 @@ FUNCTION InterpStpReal8( XVal, XAry, YAry, Ind, AryLen ) END FUNCTION InterpStpReal8 !======================================================================= -!> This funtion returns a y-value array that corresponds to an input x-value by interpolating into the arrays. +!> This function returns a y-value array that corresponds to an input x-value by interpolating into the arrays. !! It uses the passed index as the starting point and does a stepwise interpolation from there. This is !! especially useful when the calling routines save the value from the last time this routine was called !! for a given case where XVal does not change much from call to call. @@ -3568,7 +3568,7 @@ SUBROUTINE InterpStpMat4( XVal, XAry, Y, Ind, AryLen, yInterp ) RETURN END SUBROUTINE InterpStpMat4 !======================================================================= -!> This funtion returns a y-value array that corresponds to an input x-value by interpolating into the arrays. +!> This function returns a y-value array that corresponds to an input x-value by interpolating into the arrays. !! It uses the passed index as the starting point and does a stepwise interpolation from there. This is !! especially useful when the calling routines save the value from the last time this routine was called !! for a given case where XVal does not change much from call to call. @@ -3869,7 +3869,7 @@ SUBROUTINE InterpStpReal3D( InCoord, Dataset, x, y, z, LastIndex, InterpData ) END SUBROUTINE InterpStpReal3D !======================================================================= -!> This funtion returns a y-value that corresponds to an input x-value which is wrapped back +!> This function returns a y-value that corresponds to an input x-value which is wrapped back !! into the range [0-XAry(AryLen)] by interpolating into the arrays. !! It is assumed that XAry is sorted in ascending order. !! It uses the passed index as the starting point and does a stepwise interpolation from there. This is @@ -4674,7 +4674,7 @@ FUNCTION PSF ( Npsf, NumPrimes, subtract ) ELSE - NPr = NPrime(IPR) ! The small prime number we will try to find the the factorization of NTR + NPr = NPrime(IPR) ! The small prime number we will try to find the factorization of NTR DO NT = NTR/NPr ! Doing some modular arithmetic to see if @@ -5420,7 +5420,7 @@ SUBROUTINE RunTimes( StrtTime, UsrTime1, SimStrtTime, UsrTime2, ZTime, UnSum, Us INTEGER , INTENT(IN) :: StrtTime (8) !< Start time of simulation (including initialization) INTEGER , INTENT(IN) :: SimStrtTime (8) !< Start time of simulation (after initialization) REAL(ReKi), INTENT(IN) :: UsrTime1 !< User CPU time for simulation initialization. - REAL(ReKi), INTENT(IN) :: UsrTime2 !< User CPU time for simulation (without intialization) + REAL(ReKi), INTENT(IN) :: UsrTime2 !< User CPU time for simulation (without initialization) REAL(DbKi), INTENT(IN) :: ZTime !< The final simulation time (not necessarially TMax) INTEGER(IntKi), INTENT(IN), OPTIONAL:: UnSum !< optional unit number of file. If present and > 0, REAL(ReKi), INTENT(OUT),OPTIONAL:: UsrTime_out !< User CPU time for entire run - optional value returned to calling routine @@ -5634,7 +5634,7 @@ SUBROUTINE SimStatus_FirstTime( PrevSimTime, PrevClockTime, SimStrtTime, UsrTime REAL(DbKi), INTENT( OUT) :: PrevSimTime !< Previous time message was written to screen (s > 0) REAL(ReKi), INTENT( OUT) :: PrevClockTime !< Previous clock time in seconds past midnight INTEGER, INTENT( OUT) :: SimStrtTime (8) !< An array containing the elements of the start time. - REAL(ReKi), INTENT( OUT) :: UsrTimeSim !< User CPU time for simulation (without intialization) + REAL(ReKi), INTENT( OUT) :: UsrTimeSim !< User CPU time for simulation (without initialization) CHARACTER(*), INTENT(IN), OPTIONAL :: DescStrIn !< optional additional string to print for SimStatus diff --git a/modules/nwtc-library/src/NetLib/scalapack/dlasrt2.f b/modules/nwtc-library/src/NetLib/scalapack/dlasrt2.f index b134da5c36..c063a923b7 100644 --- a/modules/nwtc-library/src/NetLib/scalapack/dlasrt2.f +++ b/modules/nwtc-library/src/NetLib/scalapack/dlasrt2.f @@ -75,7 +75,7 @@ SUBROUTINE DLASRT2( ID, N, D, KEY, INFO ) * .. * .. Executable Statements .. * -* Test the input paramters. +* Test the input parameters. * * INFO = 0 diff --git a/modules/nwtc-library/src/NetLib/scalapack/slasrt2.f b/modules/nwtc-library/src/NetLib/scalapack/slasrt2.f index 7c4b9ce2d2..fa725eb506 100644 --- a/modules/nwtc-library/src/NetLib/scalapack/slasrt2.f +++ b/modules/nwtc-library/src/NetLib/scalapack/slasrt2.f @@ -75,7 +75,7 @@ SUBROUTINE SLASRT2( ID, N, D, KEY, INFO ) * .. * .. Executable Statements .. * -* Test the input paramters. +* Test the input parameters. * * INFO = 0 diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index 685a2adc03..e3ff240d7f 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -400,10 +400,6 @@ subroutine FAST_SetExternalInputs(iTurb, NumInputs_c, InputAry, m_FAST) m_FAST%ExternInput%CableDeltaL = InputAry(12:31) m_FAST%ExternInput%CableDeltaLdot = InputAry(32:51) - IF ( NumInputs_c > NumFixedInputs ) THEN ! NumFixedInputs is the fixed number of inputs - IF ( NumInputs_c == NumFixedInputs + 3 ) & - m_FAST%ExternInput%LidarFocus = InputAry(52:54) - END IF end subroutine FAST_SetExternalInputs !================================================================================================================================== diff --git a/modules/openfast-library/src/FAST_Library.h b/modules/openfast-library/src/FAST_Library.h index 318d08e49e..5296d3e229 100644 --- a/modules/openfast-library/src/FAST_Library.h +++ b/modules/openfast-library/src/FAST_Library.h @@ -15,7 +15,7 @@ EXTERNAL_ROUTINE void FAST_AllocateTurbines(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_DeallocateTurbines(int *ErrStat, char *ErrMsg); -EXTERNAL_ROUTINE void FAST_ExtInfw_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * InflowType, +EXTERNAL_ROUTINE void FAST_ExtInfw_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * NumBlElem, int * NumTwrElem, int * n_t_global, ExtInfw_InputType_t* ExtInfw_Input, ExtInfw_OutputType_t* ExtInfw_Output, int *ErrStat, char *ErrMsg); diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index 7d1caaafc1..4c1915047b 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -714,7 +714,7 @@ typedef ^ FAST_ModuleMapType MeshMapType TStC_P_2_ED_P_T {:} - - "Map ServoDyn/T typedef ^ FAST_ModuleMapType MeshMapType ED_L_2_BStC_P_B {:}{:} - - "Map ElastoDyn blade line2 mesh to ServoDyn/BStC point mesh" typedef ^ FAST_ModuleMapType MeshMapType BStC_P_2_ED_P_B {:}{:} - - "Map ServoDyn/BStC point mesh to ElastoDyn point load mesh on the blade" typedef ^ FAST_ModuleMapType MeshMapType BD_L_2_BStC_P_B {:}{:} - - "Map BeamDyn blade line2 mesh to ServoDyn/BStC point mesh" -typedef ^ FAST_ModuleMapType MeshMapType BStC_P_2_BD_P_B {:}{:} - - "Map ServoDyn/BStC point mesh to BeamDyn point load mesh on the blade" +typedef ^ FAST_ModuleMapType MeshMapType BStC_P_2_BD_P_B {:}{:} - - "Map ServoDyn/BStC point mesh to BeamDyn distributed load mesh on the blade" # ED/SD <-> SrvD/StC -- Platform TMD typedef ^ FAST_ModuleMapType MeshMapType SStC_P_P_2_SubStructure {:} - - "Map ServoDyn/SStC platform point mesh load to SubDyn/ElastoDyn point load mesh" typedef ^ FAST_ModuleMapType MeshMapType SubStructure_2_SStC_P_P {:} - - "Map SubDyn y3mesh or ED platform mesh motion to ServoDyn/SStC point mesh" @@ -801,7 +801,6 @@ typedef ^ FAST_ExternInputType ReKi YawRateCom - - - "yaw rate command from Simu typedef ^ FAST_ExternInputType ReKi BlPitchCom 3 - 2pi "blade pitch commands from Simulink/Labview" "rad" typedef ^ FAST_ExternInputType ReKi BlAirfoilCom 3 - - "blade airfoil commands from Simulink/Labview" "-" typedef ^ FAST_ExternInputType ReKi HSSBrFrac - - - "Fraction of full braking torque: 0 (off) <= HSSBrFrac <= 1 (full) from Simulink or LabVIEW" -typedef ^ FAST_ExternInputType ReKi LidarFocus 3 - - "lidar focus (relative to lidar location)" m typedef ^ FAST_ExternInputType ReKi CableDeltaL {20} - - "Cable control DeltaL" m typedef ^ FAST_ExternInputType ReKi CableDeltaLdot {20} - - "Cable control DeltaLdot" m/s @@ -811,8 +810,8 @@ typedef ^ FAST_MiscVarType DbKi t_global - - - "Current simulation time (for glo typedef ^ FAST_MiscVarType DbKi NextJacCalcTime - - - "Time between calculating Jacobians in the HD-ED and SD-ED simulations" (s) typedef ^ FAST_MiscVarType ReKi PrevClockTime - - - "Clock time at start of simulation in seconds" (s) typedef ^ FAST_MiscVarType ReKi UsrTime1 - - - "User CPU time for simulation initialization" (s) -typedef ^ FAST_MiscVarType ReKi UsrTime2 - - - "User CPU time for simulation (without intialization)" (s) -typedef ^ FAST_MiscVarType INTEGER StrtTime {8} - - "Start time of simulation (including intialization)" +typedef ^ FAST_MiscVarType ReKi UsrTime2 - - - "User CPU time for simulation (without initialization)" (s) +typedef ^ FAST_MiscVarType INTEGER StrtTime {8} - - "Start time of simulation (including initialization)" typedef ^ FAST_MiscVarType INTEGER SimStrtTime {8} - - "Start time of simulation (after initialization)" #typedef ^ FAST_MiscVarType IntKi n_t_global - - - "simulation time step, loop counter for global (FAST) simulation" (s) typedef ^ FAST_MiscVarType Logical calcJacobian - - - "Should we calculate Jacobians in Option 1?" (flag) diff --git a/modules/openfast-library/src/FAST_SS_Solver.f90 b/modules/openfast-library/src/FAST_SS_Solver.f90 index f4ea398e61..ffd64c979a 100644 --- a/modules/openfast-library/src/FAST_SS_Solver.f90 +++ b/modules/openfast-library/src/FAST_SS_Solver.f90 @@ -586,8 +586,11 @@ SUBROUTINE SteadyStateSolve_Residual(caseData, p_FAST, y_FAST, m_FAST, ED, BD, A INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*) , INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(R8Ki) :: Orientation(3,3) + INTEGER(IntKi) :: k, node INTEGER(IntKi) :: ErrStat2 INTEGER(IntKi) :: Indx_u_start + INTEGER(IntKi) :: Indx_u_angle_start(p_FAST%NumBl_Lin) CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'SteadyStateSolve_Residual' @@ -608,12 +611,23 @@ SUBROUTINE SteadyStateSolve_Residual(caseData, p_FAST, y_FAST, m_FAST, ED, BD, A !.................. ! Pack the output "residual vector" with these state derivatives and new inputs: !.................. - CALL Create_SS_Vector( p_FAST, y_FAST, U_Resid, AD, ED, BD, InputIndex, STATE_PRED ) + CALL Create_SS_Vector( p_FAST, y_FAST, U_Resid, AD, ED, BD, InputIndex, STATE_PRED, Indx_u_angle_start ) ! Make the inputs a residual (subtract from previous inputs) Indx_u_start = y_FAST%Lin%Glue%SizeLin(LIN_ContSTATE_COL) + 1 U_Resid(Indx_u_start : ) = u_in(Indx_u_start : ) - U_Resid(Indx_u_start : ) + ! we need to make a special case for the orientation matrices + do k=1,p_FAST%NumBl_Lin + Indx_u_start = Indx_u_angle_start(k) + do node=1, AD%Input(InputIndex)%rotors(1)%BladeMotion(k)%NNodes + Orientation = EulerConstruct( u_in( Indx_u_start:Indx_u_start+2 ) ) + Orientation = MATMUL(TRANSPOSE( AD%Input(InputIndex)%rotors(1)%BladeMotion(k)%Orientation(:,:,node)), Orientation) + U_Resid(Indx_u_start:Indx_u_start+2) = EulerExtract(Orientation) + Indx_u_start = Indx_u_start + 3 + end do + end do + END SUBROUTINE SteadyStateSolve_Residual !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine saves the current states so they can be used to compute the residual. @@ -794,7 +808,7 @@ END SUBROUTINE Precondition_Jmat !---------------------------------------------------------------------------------------------------------------------------------- !> This routine basically packs the relevant parts of the modules' inputs and states for use in the steady-state solver. -SUBROUTINE Create_SS_Vector( p_FAST, y_FAST, u, AD, ED, BD, InputIndex, StateIndex ) +SUBROUTINE Create_SS_Vector( p_FAST, y_FAST, u, AD, ED, BD, InputIndex, StateIndex, IndxOrientStart ) !.................................................................................................................................. TYPE(FAST_ParameterType) , INTENT(IN ) :: p_FAST !< Glue-code simulation parameters TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< Output variables for the glue code @@ -804,6 +818,7 @@ SUBROUTINE Create_SS_Vector( p_FAST, y_FAST, u, AD, ED, BD, InputIndex, StateInd TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data INTEGER(IntKi), INTENT(IN ) :: InputIndex INTEGER(IntKi), INTENT(IN ) :: StateIndex + INTEGER(IntKi), optional, INTENT( OUT) :: IndxOrientStart(p_FAST%NumBl_Lin) ! local variables: INTEGER :: n @@ -904,8 +919,9 @@ SUBROUTINE Create_SS_Vector( p_FAST, y_FAST, u, AD, ED, BD, InputIndex, StateInd end do end do + if (PRESENT(IndxOrientStart)) IndxOrientStart(k) = n ! keep track of index for AD orientation do node = 1, AD%Input(InputIndex)%rotors(1)%BladeMotion(k)%NNodes - CALL DCM_LogMap( AD%Input(InputIndex)%rotors(1)%BladeMotion(k)%Orientation(:,:,node), u(n:n+2), ErrStat2, ErrMsg2 ) + u(n:n+2) = EulerExtract( AD%Input(InputIndex)%rotors(1)%BladeMotion(k)%Orientation(:,:,node) ) n = n+3 end do diff --git a/modules/openfast-library/src/FAST_Solver.f90 b/modules/openfast-library/src/FAST_Solver.f90 index 618d53ee01..4d0ee9910f 100644 --- a/modules/openfast-library/src/FAST_Solver.f90 +++ b/modules/openfast-library/src/FAST_Solver.f90 @@ -4602,7 +4602,7 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, SED, BD, AD, ADsk, ExtLd, HD, SD, ExtP RETURN END IF - ! Create the the mesh mapping for mapping between ED and ExtLoad blade root meshes + ! Create the mesh mapping for mapping between ED and ExtLoad blade root meshes DO K=1,NumBl CALL MeshMapCreate( ED%y%BladeRootMotion(K), ExtLd%u%BladeRootMotion(K), MeshMapData%ED_P_2_ExtLd_P_R(K), ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_ExtLd_P_R('//TRIM(Num2LStr(K))//')' ) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index d5cdfc82a5..fadce6fc23 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -196,7 +196,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, SED, BD, S END IF ! ... Open and read input files ... - ! also, set applicable farm paramters and turbine reference position also for graphics output + ! also, set applicable farm parameters and turbine reference position also for graphics output if (PRESENT(ExternInitData)) then p_FAST%FarmIntegration = ExternInitData%FarmIntegration p_FAST%TurbinePos = ExternInitData%TurbinePos @@ -493,15 +493,14 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, SED, BD, S ! lidar Init%InData_IfW%LidarEnabled = .true. ! allowed with OF, but not FF - Init%InData_IfW%lidar%Tmax = p_FAST%TMax if (p_FAST%CompElast == Module_SED) then - Init%InData_IfW%lidar%HubPosition = SED%y%HubPtMotion%Position(:,1) + Init%InData_IfW%HubPosition = SED%y%HubPtMotion%Position(:,1) Init%InData_IfW%RadAvg = Init%OutData_SED%BladeLength elseif ( p_FAST%CompElast == Module_ED ) then - Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) + Init%InData_IfW%HubPosition = ED%y%HubPtMotion%Position(:,1) Init%InData_IfW%RadAvg = Init%OutData_ED%BladeLength elseif ( p_FAST%CompElast == Module_BD ) then - Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) + Init%InData_IfW%HubPosition = ED%y%HubPtMotion%Position(:,1) Init%InData_IfW%RadAvg = TwoNorm(BD%y(1)%BldMotion%Position(:,1) - BD%y(1)%BldMotion%Position(:,BD%y(1)%BldMotion%Nnodes)) end if @@ -1510,31 +1509,14 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, SED, BD, S - IF ( p_FAST%CompInflow == Module_IfW ) THEN !assign the number of gates to ServD - if (allocated(IfW%y%lidar%LidSpeed)) then ! make sure we have the array allocated before setting it - CALL AllocAry(Init%InData_SrvD%LidSpeed, size(IfW%y%lidar%LidSpeed), 'Init%InData_SrvD%LidSpeed', errStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - Init%InData_SrvD%LidSpeed = IfW%y%lidar%LidSpeed - endif - if (allocated(IfW%y%lidar%MsrPositionsX)) then ! make sure we have the array allocated before setting it - CALL AllocAry(Init%InData_SrvD%MsrPositionsX, size(IfW%y%lidar%MsrPositionsX), 'Init%InData_SrvD%MsrPositionsX', errStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - Init%InData_SrvD%MsrPositionsX = IfW%y%lidar%MsrPositionsX - endif - if (allocated(IfW%y%lidar%MsrPositionsY)) then ! make sure we have the array allocated before setting it - CALL AllocAry(Init%InData_SrvD%MsrPositionsY, size(IfW%y%lidar%MsrPositionsY), 'Init%InData_SrvD%MsrPositionsY', errStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - Init%InData_SrvD%MsrPositionsY = IfW%y%lidar%MsrPositionsY - endif - if (allocated(IfW%y%lidar%MsrPositionsZ)) then ! make sure we have the array allocated before setting it - CALL AllocAry(Init%InData_SrvD%MsrPositionsZ, size(IfW%y%lidar%MsrPositionsZ), 'Init%InData_SrvD%MsrPositionsZ', errStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - Init%InData_SrvD%MsrPositionsZ = IfW%y%lidar%MsrPositionsZ - endif + IF ( p_FAST%CompInflow == Module_IfW ) THEN ! assign the number of gates to ServD Init%InData_SrvD%SensorType = IfW%p%lidar%SensorType Init%InData_SrvD%NumBeam = IfW%p%lidar%NumBeam Init%InData_SrvD%NumPulseGate = IfW%p%lidar%NumPulseGate - Init%InData_SrvD%PulseSpacing = IfW%p%lidar%PulseSpacing + else + Init%InData_SrvD%SensorType = 0 + Init%InData_SrvD%NumBeam = 0 + Init%InData_SrvD%NumPulseGate = 0 END IF @@ -2425,7 +2407,7 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) !...................................................... ! Set the number of output columns from each module !...................................................... - y_FAST%numOuts = 0 ! Inintialize entire array + y_FAST%numOuts = 0 ! Initialize entire array IF ( ALLOCATED( Init%OutData_IfW%WriteOutputHdr ) ) y_FAST%numOuts(Module_IfW) = SIZE(Init%OutData_IfW%WriteOutputHdr) IF ( ALLOCATED( Init%OutData_ExtInfw%WriteOutputHdr ) ) y_FAST%numOuts(Module_ExtInfw) = SIZE(Init%OutData_ExtInfw%WriteOutputHdr) @@ -3663,7 +3645,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS IF (p%WrVTK == VTK_ModeShapes) THEN p%n_VTKTime = 1 ELSE IF (TmpTime > p%TMax) THEN - p%n_VTKTime = HUGE(p%n_VTKTime) + p%n_VTKTime = NINT( p%TMax / p%DT ) ! write at init and last step only ELSE p%n_VTKTime = NINT( TmpTime / p%DT ) ! I'll warn if p%n_VTKTime*p%DT is not TmpTime diff --git a/modules/openfast-library/src/FAST_Types.f90 b/modules/openfast-library/src/FAST_Types.f90 index 5de2f68fc6..64b9ac18be 100644 --- a/modules/openfast-library/src/FAST_Types.f90 +++ b/modules/openfast-library/src/FAST_Types.f90 @@ -735,7 +735,7 @@ MODULE FAST_Types TYPE(MeshMapType) , DIMENSION(:,:), ALLOCATABLE :: ED_L_2_BStC_P_B !< Map ElastoDyn blade line2 mesh to ServoDyn/BStC point mesh [-] TYPE(MeshMapType) , DIMENSION(:,:), ALLOCATABLE :: BStC_P_2_ED_P_B !< Map ServoDyn/BStC point mesh to ElastoDyn point load mesh on the blade [-] TYPE(MeshMapType) , DIMENSION(:,:), ALLOCATABLE :: BD_L_2_BStC_P_B !< Map BeamDyn blade line2 mesh to ServoDyn/BStC point mesh [-] - TYPE(MeshMapType) , DIMENSION(:,:), ALLOCATABLE :: BStC_P_2_BD_P_B !< Map ServoDyn/BStC point mesh to BeamDyn point load mesh on the blade [-] + TYPE(MeshMapType) , DIMENSION(:,:), ALLOCATABLE :: BStC_P_2_BD_P_B !< Map ServoDyn/BStC point mesh to BeamDyn distributed load mesh on the blade [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: SStC_P_P_2_SubStructure !< Map ServoDyn/SStC platform point mesh load to SubDyn/ElastoDyn point load mesh [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: SubStructure_2_SStC_P_P !< Map SubDyn y3mesh or ED platform mesh motion to ServoDyn/SStC point mesh [-] TYPE(MeshMapType) :: ED_P_2_SrvD_P_P !< Map ElastoDyn/Simplified-ElastoDyn platform point mesh motion to ServoDyn point mesh -- for passing to controller [-] @@ -807,7 +807,6 @@ MODULE FAST_Types REAL(ReKi) , DIMENSION(1:3) :: BlPitchCom = 0.0_ReKi !< blade pitch commands from Simulink/Labview [rad] REAL(ReKi) , DIMENSION(1:3) :: BlAirfoilCom = 0.0_ReKi !< blade airfoil commands from Simulink/Labview [-] REAL(ReKi) :: HSSBrFrac = 0.0_ReKi !< Fraction of full braking torque: 0 (off) <= HSSBrFrac <= 1 (full) from Simulink or LabVIEW [-] - REAL(ReKi) , DIMENSION(1:3) :: LidarFocus = 0.0_ReKi !< lidar focus (relative to lidar location) [m] REAL(ReKi) , DIMENSION(1:20) :: CableDeltaL = 0.0_ReKi !< Cable control DeltaL [m] REAL(ReKi) , DIMENSION(1:20) :: CableDeltaLdot = 0.0_ReKi !< Cable control DeltaLdot [m/s] END TYPE FAST_ExternInputType @@ -819,8 +818,8 @@ MODULE FAST_Types REAL(DbKi) :: NextJacCalcTime = 0.0_R8Ki !< Time between calculating Jacobians in the HD-ED and SD-ED simulations [(s)] REAL(ReKi) :: PrevClockTime = 0.0_ReKi !< Clock time at start of simulation in seconds [(s)] REAL(ReKi) :: UsrTime1 = 0.0_ReKi !< User CPU time for simulation initialization [(s)] - REAL(ReKi) :: UsrTime2 = 0.0_ReKi !< User CPU time for simulation (without intialization) [(s)] - INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime = 0_IntKi !< Start time of simulation (including intialization) [-] + REAL(ReKi) :: UsrTime2 = 0.0_ReKi !< User CPU time for simulation (without initialization) [(s)] + INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime = 0_IntKi !< Start time of simulation (including initialization) [-] INTEGER(IntKi) , DIMENSION(1:8) :: SimStrtTime = 0_IntKi !< Start time of simulation (after initialization) [-] LOGICAL :: calcJacobian = .false. !< Should we calculate Jacobians in Option 1? [(flag)] TYPE(FAST_ExternInputType) :: ExternInput !< external input values [-] @@ -14636,7 +14635,6 @@ subroutine FAST_CopyExternInputType(SrcExternInputTypeData, DstExternInputTypeDa DstExternInputTypeData%BlPitchCom = SrcExternInputTypeData%BlPitchCom DstExternInputTypeData%BlAirfoilCom = SrcExternInputTypeData%BlAirfoilCom DstExternInputTypeData%HSSBrFrac = SrcExternInputTypeData%HSSBrFrac - DstExternInputTypeData%LidarFocus = SrcExternInputTypeData%LidarFocus DstExternInputTypeData%CableDeltaL = SrcExternInputTypeData%CableDeltaL DstExternInputTypeData%CableDeltaLdot = SrcExternInputTypeData%CableDeltaLdot end subroutine @@ -14662,7 +14660,6 @@ subroutine FAST_PackExternInputType(RF, Indata) call RegPack(RF, InData%BlPitchCom) call RegPack(RF, InData%BlAirfoilCom) call RegPack(RF, InData%HSSBrFrac) - call RegPack(RF, InData%LidarFocus) call RegPack(RF, InData%CableDeltaL) call RegPack(RF, InData%CableDeltaLdot) if (RegCheckErr(RF, RoutineName)) return @@ -14680,7 +14677,6 @@ subroutine FAST_UnPackExternInputType(RF, OutData) call RegUnpack(RF, OutData%BlPitchCom); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%BlAirfoilCom); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%HSSBrFrac); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%LidarFocus); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%CableDeltaL); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%CableDeltaLdot); if (RegCheckErr(RF, RoutineName)) return end subroutine diff --git a/modules/orcaflex-interface/src/OrcaDriver.f90 b/modules/orcaflex-interface/src/OrcaDriver.f90 index 667e588cd4..5addc01640 100644 --- a/modules/orcaflex-interface/src/OrcaDriver.f90 +++ b/modules/orcaflex-interface/src/OrcaDriver.f90 @@ -355,7 +355,7 @@ PROGRAM OrcaDriver Orca_y, Orca_m, Settings%DT, Orca_InitOut, ErrStat, ErrMsg ) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -447,7 +447,7 @@ PROGRAM OrcaDriver - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -505,7 +505,7 @@ PROGRAM OrcaDriver Orca_y, Orca_m, ErrStat, ErrMsg) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -535,7 +535,7 @@ PROGRAM OrcaDriver TimeNow, Orca_InitOut, Orca_p, Orca_u, Orca_y, ErrStat, ErrMsg ) CLOSE(TmpUnit) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -583,7 +583,7 @@ PROGRAM OrcaDriver IF ( SettingsFlags%AddedMassFile ) THEN CALL AddedMass_OutputWrite( Settings, SettingsFlags%AddedMassOutputInit, & Orca_m%PtfmAM, ErrStat, ErrMsg ) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) @@ -611,7 +611,7 @@ PROGRAM OrcaDriver Orca_x, Orca_xd, Orca_z, Orca_OtherState, & Orca_y, Orca_m, ErrStat, ErrMsg ) - ! Make sure no errors occured that give us reason to terminate now. + ! Make sure no errors occurred that give us reason to terminate now. IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) diff --git a/modules/seastate/src/SeaState_DriverCode.f90 b/modules/seastate/src/SeaState_DriverCode.f90 index 885a1f50e7..53e33165f3 100644 --- a/modules/seastate/src/SeaState_DriverCode.f90 +++ b/modules/seastate/src/SeaState_DriverCode.f90 @@ -89,11 +89,11 @@ program SeaStateDriver character(1024) :: drvrFilename ! Filename and path for the driver input file. This is passed in as a command line argument when running the Driver exe. type(SeaSt_Drvr_InitInput) :: drvrInitInp ! Initialization data for the driver program - integer :: StrtTime (8) ! Start time of simulation (including intialization) + integer :: StrtTime (8) ! Start time of simulation (including initialization) integer :: SimStrtTime (8) ! Start time of simulation (after initialization) real(ReKi) :: PrevClockTime ! Clock time at start of simulation in seconds real(ReKi) :: UsrTime1 ! User CPU time for simulation initialization - real(ReKi) :: UsrTime2 ! User CPU time for simulation (without intialization) + real(ReKi) :: UsrTime2 ! User CPU time for simulation (without initialization) real(DbKi) :: TiLstPrn ! The simulation time of the last print real(DbKi) :: t_global ! Current simulation time (for global/FAST simulation) real(DbKi) :: SttsTime ! Amount of time between screen status messages (sec) diff --git a/modules/seastate/src/UserWaves.f90 b/modules/seastate/src/UserWaves.f90 index 1ff95fef81..454ad5ca7c 100644 --- a/modules/seastate/src/UserWaves.f90 +++ b/modules/seastate/src/UserWaves.f90 @@ -367,7 +367,7 @@ SUBROUTINE UserWaveElevations_Init ( InitInp, InitOut, WaveField, ErrStat, ErrMs ! Initialize the FFT CALL InitFFT ( WaveField%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -375,7 +375,7 @@ SUBROUTINE UserWaveElevations_Init ( InitInp, InitOut, WaveField, ErrStat, ErrMs ! Apply the forward FFT to get the real and imaginary parts of the frequency information. CALL ApplyFFT_f ( TmpFFTWaveElev(:), FFT_Data, ErrStatTmp ) ! Note that the TmpFFTWaveElev now contains the real and imaginary bits. - CALL SetErrStat(ErrStatTmp,'Error occured while applying the forwards FFT to TmpFFTWaveElev array.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the forwards FFT to TmpFFTWaveElev array.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -389,7 +389,7 @@ SUBROUTINE UserWaveElevations_Init ( InitInp, InitOut, WaveField, ErrStat, ErrMs WaveField%WaveElevC0(:,WaveField%NStepWave2) = 0.0_SiKi CALL ExitFFT(FFT_Data, ErrStatTmp) - CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN diff --git a/modules/seastate/src/Waves.f90 b/modules/seastate/src/Waves.f90 index 405b35e2ab..f4580fa0f7 100644 --- a/modules/seastate/src/Waves.f90 +++ b/modules/seastate/src/Waves.f90 @@ -900,7 +900,7 @@ SUBROUTINE VariousWaves_Init ( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) ! make sure this is called before calling ConstrainedNewWaves CALL InitFFT ( WaveField%NStepWave, FFT_Data, .TRUE., ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -1106,7 +1106,7 @@ SUBROUTINE VariousWaves_Init ( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) END IF CALL ExitFFT(FFT_Data, ErrStatTmp) - CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -1319,7 +1319,7 @@ logical function Failed0(TmpName) end function logical function FailedFFT(TmpName) character(*), intent(in) :: TmpName - CALL SetErrStat( ErrStatTmp, 'Error occured while applying the FFT to '//trim(TmpName), ErrStat, ErrMsg, RoutineName ) + CALL SetErrStat( ErrStatTmp, 'Error occurred while applying the FFT to '//trim(TmpName), ErrStat, ErrMsg, RoutineName ) FailedFFT = ErrStat >= AbortErrLev if (FailedFFT) CALL Cleanup() end function @@ -1355,7 +1355,7 @@ SUBROUTINE WaveElevTimeSeriesAtXY(Xcoord,Ycoord, WaveElevAtXY, WaveElevCAtXY, tm ENDDO CALL ApplyFFT_cx ( WaveElevAtXY(0:WaveField%NStepWave-1), tmpComplexArr, FFT_Data, ErrStatLcl2 ) - CALL SetErrStat(ErrStatLcl2,'Error occured while applying the FFT.',ErrStatLcl,ErrMsgLcl,'WaveElevTimeSeriesAtXY') + CALL SetErrStat(ErrStatLcl2,'Error occurred while applying the FFT.',ErrStatLcl,ErrMsgLcl,'WaveElevTimeSeriesAtXY') WaveElevCAtXY( 1,: ) = REAL(tmpComplexArr(:)) WaveElevCAtXY( 2,: ) = AIMAG(tmpComplexArr(:)) @@ -2239,7 +2239,7 @@ SUBROUTINE ConstrainedNewWaves(InitInp, InitOut, WaveField, OmegaArr, WaveS1SddA tmpComplexArr = CMPLX( WaveField%WaveElevC0(1,:) + Crest * tmpArr, & WaveField%WaveElevC0(2,:)) CALL ApplyFFT_cx ( WaveField%WaveElev0 (0:WaveField%NStepWave-1), tmpComplexArr (: ), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to WaveElev0.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT to WaveElev0.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) RETURN ! Find the preceding or following trough, whichever is lower @@ -2254,7 +2254,7 @@ SUBROUTINE ConstrainedNewWaves(InitInp, InitOut, WaveField, OmegaArr, WaveS1SddA tmpComplexArr = CMPLX( WaveField%WaveElevC0(1,:) + (Crest+CrestHeightTol) * tmpArr, & WaveField%WaveElevC0(2,:)) CALL ApplyFFT_cx ( WaveField%WaveElev0 (0:WaveField%NStepWave-1), tmpComplexArr (: ), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to WaveElev0.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT to WaveElev0.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) RETURN diff --git a/modules/seastate/src/Waves2.f90 b/modules/seastate/src/Waves2.f90 index f7edb77883..b8c985dafb 100644 --- a/modules/seastate/src/Waves2.f90 +++ b/modules/seastate/src/Waves2.f90 @@ -395,7 +395,7 @@ SUBROUTINE Waves2_Init( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) !-------------------------------------------------------------------------------- CALL InitFFT ( WaveField%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -495,7 +495,7 @@ SUBROUTINE Waves2_Init( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) i = mod(k-1, InitInp%NGrid(1)) + 1 j = (k-1) / InitInp%NGrid(1) + 1 CALL WaveElevTimeSeriesAtXY_Diff(InitInp%WaveKinGridxi(k), InitInp%WaveKinGridyi(k), TmpTimeSeries, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to WaveField%WaveElev2.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT to WaveField%WaveElev2.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -639,21 +639,21 @@ SUBROUTINE Waves2_Init( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) !> ### Apply the inverse FFT to each of the components to get the time domain result ### !> * \f$ V(t) = 2 \operatorname{IFFT}\left[H^-\right] \f$ CALL ApplyFFT_cx( WaveVel2xDiff(:), WaveVel2xCDiff(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_x.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_x.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveVel2yDiff(:), WaveVel2yCDiff(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_y.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_y.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveVel2zDiff(:), WaveVel2zCDiff(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_z.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_z.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2xDiff(:), WaveAcc2xCDiff(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_x.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_x.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2yDiff(:), WaveAcc2yCDiff(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_y.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_y.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2zDiff(:), WaveAcc2zCDiff(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_z.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_z.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveDynP2Diff(:), WaveDynP2CDiff(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on DynP2.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on DynP2.',ErrStat,ErrMsg,RoutineName) @@ -858,7 +858,7 @@ SUBROUTINE Waves2_Init( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) i = mod(k-1, InitInp%NGrid(1)) + 1 j = (k-1) / InitInp%NGrid(1) + 1 CALL WaveElevTimeSeriesAtXY_Sum(InitInp%WaveKinGridxi(k), InitInp%WaveKinGridyi(k), TmpTimeSeries, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to WaveField%WaveElev2.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT to WaveField%WaveElev2.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -1124,38 +1124,38 @@ SUBROUTINE Waves2_Init( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) !> * \f$ V^{(2)+}(t) = \operatorname{IFFT}\left[K^+\right] !! + 2\operatorname{IFFT}\left[H^+\right] \f$ CALL ApplyFFT_cx( WaveVel2xSumT1(:), WaveVel2xCSumT1(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_x.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_x.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveVel2ySumT1(:), WaveVel2yCSumT1(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_y.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_y.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveVel2zSumT1(:), WaveVel2zCSumT1(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_z.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_z.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2xSumT1(:), WaveAcc2xCSumT1(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_x.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_x.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2ySumT1(:), WaveAcc2yCSumT1(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_y.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_y.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2zSumT1(:), WaveAcc2zCSumT1(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_z.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_z.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveDynP2SumT1(:), WaveDynP2CSumT1(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on DynP2.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on DynP2.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveVel2xSumT2(:), WaveVel2xCSumT2(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_x.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_x.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveVel2ySumT2(:), WaveVel2yCSumT2(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_y.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_y.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveVel2zSumT2(:), WaveVel2zCSumT2(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on V_z.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on V_z.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2xSumT2(:), WaveAcc2xCSumT2(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_x.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_x.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2ySumT2(:), WaveAcc2yCSumT2(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_y.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_y.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveAcc2zSumT2(:), WaveAcc2zCSumT2(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on Acc_z.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on Acc_z.',ErrStat,ErrMsg,RoutineName) CALL ApplyFFT_cx( WaveDynP2SumT2(:), WaveDynP2CSumT2(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT on DynP2.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while applying the FFT on DynP2.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() @@ -1236,7 +1236,7 @@ SUBROUTINE Waves2_Init( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) CALL ExitFFT(FFT_Data, ErrStatTmp) - CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) + CALL SetErrStat(ErrStatTmp,'Error occurred while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN @@ -1376,7 +1376,7 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Diff(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrSta !> ### Apply the inverse FFT to each of the components to get the time domain result ### !> * \f$ \eta(t) = \operatorname{IFFT}\left[2 H^-\right] \f$ CALL ApplyFFT_cx( WaveElevSeriesAtXY(:), TmpFreqSeries(:), FFT_Data, ErrStatLcl2 ) - CALL SetErrStat(ErrStatLcl2,'Error occured while applying the FFT on WaveElevSeriesAtXY.',ErrStatLcl,ErrMsgLcl,'WaveElevSeriesAtXY_Diff') + CALL SetErrStat(ErrStatLcl2,'Error occurred while applying the FFT on WaveElevSeriesAtXY.',ErrStatLcl,ErrMsgLcl,'WaveElevSeriesAtXY_Diff') ! Append first datapoint as the last as aid for repeated wave data WaveElevSeriesAtXY(WaveField%NStepWave) = WaveElevSeriesAtXY(0) @@ -1563,9 +1563,9 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Sum(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrStat !> * \f$ \eta^{(2)+}(t) = \operatorname{IFFT}\left[K^+\right] !! + 2\operatorname{IFFT}\left[H^+\right] \f$ CALL ApplyFFT_cx( WaveElevSeriesAtXY(:), TmpFreqSeries(:), FFT_Data, ErrStatLcl2 ) - CALL SetErrStat(ErrStatLcl2,'Error occured while applying the FFT on WaveElevSeriesAtXY.',ErrStatLcl,ErrMsgLcl,'WaveElevSeriesAtXY_Sum') + CALL SetErrStat(ErrStatLcl2,'Error occurred while applying the FFT on WaveElevSeriesAtXY.',ErrStatLcl,ErrMsgLcl,'WaveElevSeriesAtXY_Sum') CALL ApplyFFT_cx( TmpTimeSeries2(:), TmpFreqSeries2(:), FFT_Data, ErrStatLcl2 ) - CALL SetErrStat(ErrStatLcl2,'Error occured while applying the FFT on WaveElevSeriesAtXY.',ErrStatLcl,ErrMsgLcl,'WaveElevSeriesAtXY_Sum') + CALL SetErrStat(ErrStatLcl2,'Error occurred while applying the FFT on WaveElevSeriesAtXY.',ErrStatLcl,ErrMsgLcl,'WaveElevSeriesAtXY_Sum') ! Add the two terms together DO Ctr=0,WaveField%NStepWave diff --git a/modules/servodyn/src/BladedInterface.f90 b/modules/servodyn/src/BladedInterface.f90 index f58b9106b8..b4bc4d4e1d 100644 --- a/modules/servodyn/src/BladedInterface.f90 +++ b/modules/servodyn/src/BladedInterface.f90 @@ -579,7 +579,6 @@ subroutine WrLegacyChannelInfoToSummaryFile(u,p,dll_data,UnSum,ErrStat,ErrMsg) call WrSumInfoRcvd(120, 'Airfoil command, blade 1') call WrSumInfoRcvd(121, 'Airfoil command, blade 2') call WrSumInfoRcvd(122, 'Airfoil command, blade 3') - call WrSumInfoRcvd(63,'Number logging channels') ! Write to summary file @@ -815,7 +814,10 @@ SUBROUTINE BladedInterface_End(u, p, m, xd, ErrStat, ErrMsg) INTEGER(IntKi) :: ErrStat2 ! The error status code CHARACTER(ErrMsgLen) :: ErrMsg2 ! The error message, if an error occurred - ! call DLL final time, but skip if we've never called it + ErrStat = ErrID_None + ErrMsg = "" + + ! call DLL final time, but skip if we've never called it if (allocated(m%dll_data%avrSWAP)) then IF ( m%dll_data%SimStatus /= GH_DISCON_STATUS_INITIALISING ) THEN m%dll_data%SimStatus = GH_DISCON_STATUS_FINALISING @@ -825,10 +827,7 @@ SUBROUTINE BladedInterface_End(u, p, m, xd, ErrStat, ErrMsg) end if CALL FreeDynamicLib( p%DLL_Trgt, ErrStat2, ErrMsg2 ) ! this doesn't do anything #ifdef STATIC_DLL_LOAD because p%DLL_Trgt is 0 (NULL) - IF (ErrStat2 /= ErrID_None) THEN - ErrStat = MAX(ErrStat, ErrStat2) - ErrMsg = TRIM(ErrMsg)//NewLine//TRIM(ErrMsg2) - END IF + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'BladedInterface_End') END SUBROUTINE BladedInterface_End !================================================================================================================================== diff --git a/modules/servodyn/src/BladedInterface_EX.f90 b/modules/servodyn/src/BladedInterface_EX.f90 index 37e77d0978..b2f08be893 100644 --- a/modules/servodyn/src/BladedInterface_EX.f90 +++ b/modules/servodyn/src/BladedInterface_EX.f90 @@ -374,66 +374,40 @@ end subroutine InitStCCtrl subroutine InitLidarMeas() integer :: I,J - if (p%NumBeam == 0) return ! Nothing to set + integer :: nPts + + nPts = p%NumBeam * p%NumPulseGate + + if (nPts == 0) return ! Nothing to set ! Allocate arrays for inputs -- these may have been set in ServoDyn already - if (allocated(InitInp%LidSpeed)) then ! make sure we have the array allocated before setting it - if (.not. allocated(u%LidSpeed)) then - CALL AllocAry(u%LidSpeed, size(InitInp%LidSpeed), 'u%LidSpeed', errStat2, ErrMsg2) - if (Failed()) return - endif - u%LidSpeed = InitInp%LidSpeed + if (.not. allocated(u%LidSpeed)) then + CALL AllocAry(u%LidSpeed, nPts, 'u%LidSpeed', errStat2, ErrMsg2); if (Failed()) return endif - if (allocated(InitInp%MsrPositionsX)) then ! make sure we have the array allocated before setting it - if (.not. allocated(u%MsrPositionsX)) then - CALL AllocAry(u%MsrPositionsX, size(InitInp%MsrPositionsX), 'u%MsrPositionsX', errStat2, ErrMsg2) - if (Failed()) return - endif - u%MsrPositionsX = InitInp%MsrPositionsX + if (.not. allocated(u%MsrPositionsX)) then + CALL AllocAry(u%MsrPositionsX, nPts, 'u%MsrPositionsX', errStat2, ErrMsg2); if (Failed()) return endif - if (allocated(InitInp%MsrPositionsY)) then ! make sure we have the array allocated before setting it - if (.not. allocated(u%MsrPositionsY)) then - CALL AllocAry(u%MsrPositionsY, size(InitInp%MsrPositionsY), 'u%MsrPositionsY', errStat2, ErrMsg2) - if (Failed()) return - endif - u%MsrPositionsY = InitInp%MsrPositionsY + if (.not. allocated(u%MsrPositionsY)) then + CALL AllocAry(u%MsrPositionsY, nPts, 'u%MsrPositionsY', errStat2, ErrMsg2); if (Failed()) return endif - if (allocated(InitInp%MsrPositionsZ)) then ! make sure we have the array allocated before setting it - if (.not. allocated(u%MsrPositionsZ)) then - CALL AllocAry(u%MsrPositionsZ, size(InitInp%MsrPositionsZ), 'u%MsrPositionsZ', errStat2, ErrMsg2) - if (Failed()) return - endif - u%MsrPositionsZ = InitInp%MsrPositionsZ + if (.not. allocated(u%MsrPositionsZ)) then + CALL AllocAry(u%MsrPositionsZ, nPts, 'u%MsrPositionsZ', errStat2, ErrMsg2) + if (Failed()) return endif ! Write summary info to summary file if (UnSum > 0) then - if (p%SensorType > 0) then ! Set these here rather than overwrite every loop step in SensorType 1 or 3 + if (p%SensorType > 0) then J=LidarMsr_StartIdx call WrSumInfoRcvd( J+0, '','Lidar input: Sensor Type') call WrSumInfoRcvd( J+1, '','Lidar input: Number of Beams') call WrSumInfoRcvd( J+2, '','Lidar input: Number of Pulse Gates') call WrSumInfoRcvd( J+3, '','Lidar input: Reference average wind speed for the lidar') - endif - if (p%SensorType == 1) THEN - do I=1,min(p%NumBeam,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group - J=LidarMsr_StartIdx + 4 + (I-1) - call WrSumInfoRcvd( J+0, '','Lidar input: Measured Wind Speeds ('//trim(Num2LStr(I))//')') - call WrSumInfoRcvd( J+p%NumBeam*1, '','Lidar input: Measurement Points X ('//trim(Num2LStr(I))//')') - call WrSumInfoRcvd( J+p%NumBeam*2, '','Lidar input: Measurement Points Y ('//trim(Num2LStr(I))//')') - call WrSumInfoRcvd( J+p%NumBeam*3, '','Lidar input: Measurement Points Z ('//trim(Num2LStr(I))//')') - enddo - elseif (p%SensorType == 2) THEN - J=LidarMsr_StartIdx - call WrSumInfoRcvd( J+4, '','Lidar input: Measured Wind Speeds') - call WrSumInfoRcvd( J+5, '','Lidar input: Measurement Points X') - call WrSumInfoRcvd( J+6, '','Lidar input: Measurement Points Y') - call WrSumInfoRcvd( J+7, '','Lidar input: Measurement Points Z') - elseif (p%SensorType == 3) THEN - do I=1,min(p%NumPulseGate,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group + + do I=1,min(nPts,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group J=LidarMsr_StartIdx + 4 + (I-1) - call WrSumInfoRcvd( J+0, '','Lidar input: Measured Wind Speeds ('//trim(Num2LStr(I))//')') - call WrSumInfoRcvd( J+p%NumPulseGate*1, '','Lidar input: Measurement Points X ('//trim(Num2LStr(I))//')') - call WrSumInfoRcvd( J+p%NumPulseGate*2, '','Lidar input: Measurement Points Y ('//trim(Num2LStr(I))//')') - call WrSumInfoRcvd( J+p%NumPulseGate*3, '','Lidar input: Measurement Points Z ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+0, '','Lidar input: Measured Wind Speeds ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+nPts*1, '','Lidar input: Measurement Points X ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+nPts*2, '','Lidar input: Measurement Points Y ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+nPts*3, '','Lidar input: Measurement Points Z ('//trim(Num2LStr(I))//')') enddo endif endif @@ -552,36 +526,24 @@ end subroutine SetEXavrSWAP_Sensors !> Set the Lidar related sensor inputs !! avrSWAP(2001:2500) subroutine SetEXavrSWAP_LidarSensors() + integer(IntKi) :: nPts + ! in case something got set wrong, don't try to write beyond array if (size(dll_data%avrswap) < (LidarMsr_StartIdx + LidarMsr_MaxChan - 1) ) return - if (p%NumBeam == 0) return ! Nothing to set - if (p%SensorType > 0) then ! Set these here rather than overwrite every loop step in SensorType 1 or 3 + if (p%SensorType > 0) then dll_data%avrswap(LidarMsr_StartIdx) = real(p%SensorType,SiKi) ! Sensor Type dll_data%avrswap(LidarMsr_StartIdx+1) = real(p%NumBeam,SiKi) ! Number of Beams dll_data%avrswap(LidarMsr_StartIdx+2) = real(p%NumPulseGate,SiKi) ! Number of Pulse Gates - dll_data%avrswap(LidarMsr_StartIdx+3) = p%URefLid ! Reference average wind speed for the lidar - endif - if (p%SensorType == 1) THEN - do I=1,min(p%NumBeam,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group - J=LidarMsr_StartIdx + 4 + (I-1) - dll_data%avrswap(J) = u%LidSpeed(I) ! Lidar Measured Wind Speeds - dll_data%avrswap(J+p%NumBeam) = u%MsrPositionsX(I) ! Lidar Measurement Points X - dll_data%avrswap(J+(p%NumBeam*2)) = u%MsrPositionsY(I) ! Lidar Measurement Points Y - dll_data%avrswap(J+(p%NumBeam*3)) = u%MsrPositionsZ(I) ! Lidar Measurement Points Z - enddo - elseif (p%SensorType == 2) THEN - dll_data%avrswap(LidarMsr_StartIdx+4) = u%LidSpeed(1) ! Lidar Measured Wind Speeds - dll_data%avrswap(LidarMsr_StartIdx+5) = u%MsrPositionsX(1) ! Lidar Measurement Points X - dll_data%avrswap(LidarMsr_StartIdx+6) = u%MsrPositionsY(1) ! Lidar Measurement Points Y - dll_data%avrswap(LidarMsr_StartIdx+7) = u%MsrPositionsZ(1) ! Lidar Measurement Points Z - elseif (p%SensorType == 3) THEN - do I=1,min(p%NumPulseGate,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group + dll_data%avrswap(LidarMsr_StartIdx+3) = 0.0_SiKi ! Reference average wind speed for the lidar (this was never set, plus it doesn't really make sense that the controller would need it) + + nPts = SIZE(u%MsrPositionsX) + do I=1,min(nPts,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group J=LidarMsr_StartIdx + 4 + (I-1) - dll_data%avrswap(J) = u%LidSpeed(I) ! Lidar Measured Wind Speeds - dll_data%avrswap(J+p%NumPulseGate) = u%MsrPositionsX(I) ! Lidar Measurement Points X - dll_data%avrswap(J+(p%NumPulseGate*2)) = u%MsrPositionsY(I) ! Lidar Measurement Points Y - dll_data%avrswap(J+(p%NumPulseGate*3)) = u%MsrPositionsZ(I) ! Lidar Measurement Points Z + dll_data%avrswap(J) = u%LidSpeed(I) ! Lidar Measured Wind Speeds + dll_data%avrswap(J+nPts) = u%MsrPositionsX(I) ! Lidar Measurement Points X + dll_data%avrswap(J+(nPts*2)) = u%MsrPositionsY(I) ! Lidar Measurement Points Y + dll_data%avrswap(J+(nPts*3)) = u%MsrPositionsZ(I) ! Lidar Measurement Points Z enddo endif end subroutine SetEXavrSWAP_LidarSensors @@ -680,10 +642,10 @@ subroutine Retrieve_EXavrSWAP_StControls () ! Retrieve StC control channels here do I=1,p%NumStC_Control J=StCCtrl_StartIdx + ((I-1)*StCCtrl_ChanPerSet-1) ! Index into the full avrSWAP (minus 1 so counting is simpler) - dll_data%StCCmdStiff(1:3,I) = dll_data%avrswap(J+ 7:J+ 9) ! StC commmanded stiffness -- StC_Stiff_X, StC_Stiff_Y, StC_Stiff_Z (N/m) - dll_data%StCCmdDamp( 1:3,I) = dll_data%avrswap(J+10:J+12) ! StC commmanded damping -- StC_Damp_X, StC_Damp_Y, StC_Damp_Z (N/(m/s)) - dll_data%StCCmdBrake(1:3,I) = dll_data%avrswap(J+13:J+15) ! StC commmanded brake -- StC_Brake_X, StC_Brake_Y, StC_Brake_Z (N) - dll_data%StCCmdForce(1:3,I) = dll_data%avrswap(J+16:J+18) ! StC commmanded brake -- StC_Force_X, StC_Force_Y, StC_Force_Z (N) + dll_data%StCCmdStiff(1:3,I) = dll_data%avrswap(J+ 7:J+ 9) ! StC commanded stiffness -- StC_Stiff_X, StC_Stiff_Y, StC_Stiff_Z (N/m) + dll_data%StCCmdDamp( 1:3,I) = dll_data%avrswap(J+10:J+12) ! StC commanded damping -- StC_Damp_X, StC_Damp_Y, StC_Damp_Z (N/(m/s)) + dll_data%StCCmdBrake(1:3,I) = dll_data%avrswap(J+13:J+15) ! StC commanded brake -- StC_Brake_X, StC_Brake_Y, StC_Brake_Z (N) + dll_data%StCCmdForce(1:3,I) = dll_data%avrswap(J+16:J+18) ! StC commanded brake -- StC_Force_X, StC_Force_Y, StC_Force_Z (N) enddo end subroutine Retrieve_EXavrSWAP_StControls diff --git a/modules/servodyn/src/ServoDyn.f90 b/modules/servodyn/src/ServoDyn.f90 index 5b1e74ae94..a48212bad6 100644 --- a/modules/servodyn/src/ServoDyn.f90 +++ b/modules/servodyn/src/ServoDyn.f90 @@ -134,14 +134,13 @@ SUBROUTINE SrvD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO INTEGER(IntKi) :: i ! loop counter INTEGER(IntKi) :: j ! loop counter INTEGER(IntKi) :: K ! loop counter + INTEGER(IntKi) :: nPts ! number of linear wind-speed points INTEGER(IntKi) :: UnSum ! Summary file unit INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None character(*), parameter :: RoutineName = 'SrvD_Init' - - ! Initialize variables ErrStat = ErrID_None @@ -322,6 +321,19 @@ SUBROUTINE SrvD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO if (Failed()) return; + nPts = InitInp%NumBeam * InitInp%NumPulseGate + if (nPts > 0 .and. p%UseBladedInterface) then + CALL AllocAry( u%LidSpeed, nPts, 'u%LidSpeed', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocAry( u%MsrPositionsX, nPts, 'u%MsrPositionsX', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocAry( u%MsrPositionsY, nPts, 'u%MsrPositionsY', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocAry( u%MsrPositionsZ, nPts, 'u%MsrPositionsZ', ErrStat2, ErrMsg2 ); if (Failed()) return; + + u%LidSpeed = 0.0_SiKi + u%MsrPositionsX = 0.0_ReKi + u%MsrPositionsY = 0.0_ReKi + u%MsrPositionsZ = 0.0_ReKi + end if + u%BlPitch = p%BlPitchInit(1:p%NumBl) u%Yaw = p%YawNeut @@ -362,22 +374,7 @@ SUBROUTINE SrvD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO u%RotPwr = 0. u%HorWindV = 0. u%YawAngle = 0. - if (allocated(InitInp%LidSpeed)) then ! Must allocate - allocate(u%LidSpeed(size(InitInp%LidSpeed))) - u%LidSpeed = 0. - endif - if (allocated(InitInp%MsrPositionsX)) then - allocate(u%MsrPositionsX(size(InitInp%MsrPositionsX))) - u%MsrPositionsX = 0. - endif - if (allocated(InitInp%MsrPositionsY)) then - allocate(u%MsrPositionsY(size(InitInp%MsrPositionsY))) - u%MsrPositionsY = 0. - endif - if (allocated(InitInp%MsrPositionsZ)) then - allocate(u%MsrPositionsZ(size(InitInp%MsrPositionsZ))) - u%MsrPositionsZ = 0. - endif + m%dll_data%ElecPwr_prev = 0. m%dll_data%GenTrq_prev = 0. @@ -474,8 +471,6 @@ SUBROUTINE SrvD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO p%SensorType = InitInp%SensorType p%NumBeam = InitInp%NumBeam p%NumPulseGate = InitInp%NumPulseGate - p%PulseSpacing = InitInp%PulseSpacing - p%URefLid = InitInp%URefLid CALL BladedInterface_Init(u, p, m, xd, y, InputFileData, InitInp, StC_CtrlChanInitInfo, UnSum, ErrStat2, ErrMsg2 ) if (Failed()) return; @@ -1634,7 +1629,7 @@ subroutine StC_CtrlChan_Setup(m,p,CtrlChanInitInfo,UnSum,ErrStat,ErrMsg) ErrMsg = "" ! NOTE: For now we only have the option of the StC requesting the bladed interface - ! at the the ServoDyn level. If we later add a Simulink interface, the logic + ! at the ServoDyn level. If we later add a Simulink interface, the logic ! below for checking if the DLL interface was requested will need updating. ! At that point it might be necessary to set an array for the p%StCCMode so ! it is possible to tell which channel is from Simulink and which is from @@ -2153,7 +2148,7 @@ SUBROUTINE SrvD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! Local variables - REAL(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels + REAL(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels INTEGER(IntKi) :: I ! Generic loop index INTEGER(IntKi) :: K ! Blade index INTEGER(IntKi) :: J ! Structural control instance at location @@ -2823,7 +2818,7 @@ subroutine Jac_BStC_dYdu( n, sgn, u_perturb, delta, y_perturb, ErrStat3, ErrMsg3 integer(IntKi) :: i,j,k ! Generic indices type(StC_InputType) :: u_StC ! copy of the StC inputs for StC_CalcOutput call type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_u_indx array. This allows us to simplify the number of calls dramatically k = p%Jac_u_indx(n,4) ! this blade @@ -2867,7 +2862,7 @@ subroutine Jac_NStC_dYdu( n, sgn, u_perturb, delta, y_perturb, ErrStat3, ErrMsg3 integer(IntKi) :: i,j,k ! Generic indices type(StC_InputType) :: u_StC ! copy of the StC inputs for StC_CalcOutput call type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_u_indx array. This allows us to simplify the number of calls dramatically j = p%Jac_u_indx(n,3) ! this instance @@ -2911,7 +2906,7 @@ subroutine Jac_TStC_dYdu( n, sgn, u_perturb, delta, y_perturb, ErrStat3, ErrMsg3 integer(IntKi) :: i,j,k ! Generic indices type(StC_InputType) :: u_StC ! copy of the StC inputs for StC_CalcOutput call type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_u_indx array. This allows us to simplify the number of calls dramatically j = p%Jac_u_indx(n,3) ! this instance @@ -2955,7 +2950,7 @@ subroutine Jac_SStC_dYdu( n, sgn, u_perturb, delta, y_perturb, ErrStat3, ErrMsg3 integer(IntKi) :: i,j,k ! Generic indices type(StC_InputType) :: u_StC ! copy of the StC inputs for StC_CalcOutput call type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_u_indx array. This allows us to simplify the number of calls dramatically j = p%Jac_u_indx(n,3) ! this instance @@ -3737,7 +3732,7 @@ subroutine Jac_BStC_dYdx( n, sgn, x_perturb, delta, y_perturb, ErrStat3, ErrMsg3 character(ErrMsgLen), intent( out) :: ErrMsg3 integer(IntKi) :: i,j,k ! Generic indices type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_x_indx array. This allows us to simplify the number of calls dramatically k = p%Jac_x_indx(n,4) ! this blade @@ -3774,7 +3769,7 @@ subroutine Jac_NStC_dYdx( n, sgn, x_perturb, delta, y_perturb, ErrStat3, ErrMsg3 character(ErrMsgLen), intent( out) :: ErrMsg3 integer(IntKi) :: i,j ! Generic indices type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_x_indx array. This allows us to simplify the number of calls dramatically j = p%Jac_x_indx(n,3) ! this instance @@ -3810,7 +3805,7 @@ subroutine Jac_TStC_dYdx( n, sgn, x_perturb, delta, y_perturb, ErrStat3, ErrMsg3 character(ErrMsgLen), intent( out) :: ErrMsg3 integer(IntKi) :: i,j ! Generic indices type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_x_indx array. This allows us to simplify the number of calls dramatically j = p%Jac_x_indx(n,3) ! this instance @@ -3846,7 +3841,7 @@ subroutine Jac_SStC_dYdx( n, sgn, x_perturb, delta, y_perturb, ErrStat3, ErrMsg3 character(ErrMsgLen), intent( out) :: ErrMsg3 integer(IntKi) :: i,j ! Generic indices type(StC_OutputType) :: y_StC ! copy of the StC outputs for StC_CalcOutput call - real(ReKi) :: AllOuts(0:MaxOutPts) ! All the the available output channels - perturbed (ReKi since WriteOutput is ReKi) + real(ReKi) :: AllOuts(0:MaxOutPts) ! All the available output channels - perturbed (ReKi since WriteOutput is ReKi) ! Since this is acting on only a single blade within a single StC instance, we can look up exactly which one ! from the Jac_x_indx array. This allows us to simplify the number of calls dramatically j = p%Jac_x_indx(n,3) ! this instance diff --git a/modules/servodyn/src/ServoDyn_IO.f90 b/modules/servodyn/src/ServoDyn_IO.f90 index a98b3dc14d..2a618589b4 100644 --- a/modules/servodyn/src/ServoDyn_IO.f90 +++ b/modules/servodyn/src/ServoDyn_IO.f90 @@ -769,7 +769,7 @@ subroutine Set_SrvD_Outs( p, y, m, AllOuts ) type(SrvD_ParameterType), intent(in ) :: p !< Parameters type(SrvD_OutputType), intent(in ) :: y !< Outputs computed at Time type(SrvD_MiscVarType), intent(inout) :: m !< Misc (optimization) variables - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: K !............................................................................................................................... @@ -803,7 +803,7 @@ subroutine Set_NStC_Outs( p_SrvD, x, m, y, AllOuts ) ! Nacelle type(StC_ContinuousStateType), allocatable,intent(in ) :: x(:) !< Continuous states at t type(StC_MiscVarType), allocatable,intent(in ) :: m(:) !< Misc (optimization) variables type(StC_OutputType), allocatable,intent(in ) :: y(:) !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: i if (allocated(x) .and. allocated(m) .and. allocated(y)) then do i=1,min(p_SrvD%NumNStC,MaxStC) ! in case we have more Nacelle StCs than the outputs are set for @@ -817,7 +817,7 @@ subroutine Set_NStC_Outs_Instance( i, x, m, y, AllOuts ) ! Nacelle single St type(StC_ContinuousStateType), intent(in ) :: x !< Continuous states at t type(StC_MiscVarType), intent(in ) :: m !< Misc (optimization) variables type(StC_OutputType), intent(in ) :: y !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: j j=1 if (i < MaxStC) then @@ -847,7 +847,7 @@ subroutine Set_TStC_Outs( p_SrvD, x, m, y, AllOuts ) ! Tower type(StC_ContinuousStateType), allocatable,intent(in ) :: x(:) !< Continuous states at t type(StC_MiscVarType), allocatable,intent(in ) :: m(:) !< Misc (optimization) variables type(StC_OutputType), allocatable,intent(in ) :: y(:) !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: i if (allocated(x) .and. allocated(m) .and. allocated(y)) then do i=1,min(p_SrvD%NumTStC,MaxStC) ! in case we have more Nacelle StCs than the outputs are set for @@ -861,7 +861,7 @@ subroutine Set_TStC_Outs_Instance( i, x, m, y, AllOuts ) ! Tower single StC type(StC_ContinuousStateType), intent(in ) :: x !< Continuous states at t type(StC_MiscVarType), intent(in ) :: m !< Misc (optimization) variables type(StC_OutputType), intent(in ) :: y !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: j j=1 if (i < MaxStC) then @@ -891,7 +891,7 @@ subroutine Set_BStC_Outs( p_SrvD, x, m, y, AllOuts ) ! Blades type(StC_ContinuousStateType), allocatable,intent(in ) :: x(:) !< Continuous states at t type(StC_MiscVarType), allocatable,intent(in ) :: m(:) !< Misc (optimization) variables type(StC_OutputType), allocatable,intent(in ) :: y(:) !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: i if (allocated(x) .and. allocated(m) .and. allocated(y)) then do i=1,min(p_SrvD%NumBStC,MaxStC) ! in case we have more Blade StCs than the outputs are set for @@ -906,7 +906,7 @@ subroutine Set_BStC_Outs_Instance( i, numBl, x, m, y, AllOuts ) ! Single type(StC_ContinuousStateType), intent(in ) :: x !< Continuous states at t type(StC_MiscVarType), intent(in ) :: m !< Misc (optimization) variables type(StC_OutputType), intent(in ) :: y !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: j if (i < MaxStC) then do j=1,min(NumBl,MaxBlOuts) @@ -937,7 +937,7 @@ subroutine Set_SStC_Outs( p_SrvD, x, m, y, AllOuts ) ! Platform type(StC_ContinuousStateType), allocatable,intent(in ) :: x(:) !< Continuous states at t type(StC_MiscVarType), allocatable,intent(in ) :: m(:) !< Misc (optimization) variables type(StC_OutputType), allocatable,intent(in ) :: y(:) !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: i if (allocated(x) .and. allocated(m) .and. allocated(y)) then do i=1,min(p_SrvD%NumSStC,MaxStC) ! in case we have more Nacelle StCs than the outputs are set for @@ -951,7 +951,7 @@ subroutine Set_SStC_Outs_Instance( i, x, m, y, AllOuts ) ! Platform type(StC_ContinuousStateType), intent(in ) :: x !< Continuous states at t type(StC_MiscVarType), intent(in ) :: m !< Misc (optimization) variables type(StC_OutputType), intent(in ) :: y !< Outputs computed at Time - real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the the available output channels + real(ReKi), intent(inout) :: AllOuts(0:MaxOutPts) ! All the available output channels integer :: j j=1 if (i < MaxStC) then diff --git a/modules/servodyn/src/ServoDyn_Registry.txt b/modules/servodyn/src/ServoDyn_Registry.txt index 0a6d8e7efe..8160192355 100644 --- a/modules/servodyn/src/ServoDyn_Registry.txt +++ b/modules/servodyn/src/ServoDyn_Registry.txt @@ -52,15 +52,9 @@ typedef ^ InitInputType CHARACTER(64) CableControlRequestor {:} - - "Array with typedef ^ InitInputType IntKi InterpOrder - - - "Interpolation order from glue code -- required to set m%u_xStC sizes" - #ADD in the TMD submodule input file passing here #initial inputs of lidar parameters -typedef ^ InitInputType ReKi LidSpeed {:} - - "Number of Lidar measurement distances" - -typedef ^ InitInputType ReKi MsrPositionsX {:} - - "Lidar X direction measurement points" m -typedef ^ InitInputType ReKi MsrPositionsY {:} - - "Lidar Y direction measurement points" m -typedef ^ InitInputType ReKi MsrPositionsZ {:} - - "Lidar Z direction measurement points" m typedef ^ InitInputType IntKi SensorType - - - "Lidar sensor type" - typedef ^ InitInputType IntKi NumBeam - - - "Number of beams" - typedef ^ InitInputType IntKi NumPulseGate - - - "Number of pulse gates" - -typedef ^ InitInputType ReKi PulseSpacing - - - "Distance between range gates" - -typedef ^ InitInputType ReKi URefLid - - - "Reference average wind speed for the lidar" m/s # Define outputs from the initialization routine here: typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - @@ -236,8 +230,6 @@ typedef ^ BladedDLLType ReKi MsrPositionsZ {:} - - "Lidar Z direction meas typedef ^ BladedDLLType IntKi SensorType - - - "Lidar sensor type" - typedef ^ BladedDLLType IntKi NumBeam - - - "Number of beams" - typedef ^ BladedDLLType IntKi NumPulseGate - - - "Number of pulse gates" - -typedef ^ BladedDLLType IntKi PulseSpacing - - - "Distance between range gates" - -typedef ^ BladedDLLType IntKi URefLid - - - "Reference average wind speed for the lidar" m/s ## these are PARAMETERS sent to the DLL (THEIR VALUES SHOULD NOT CHANGE DURING SIMULATION): typedef ^ BladedDLLType DbKi DLL_DT - - - "interval for calling DLL (integer multiple number of DT)" s typedef ^ BladedDLLType CHARACTER(1024) DLL_InFile - - - "Name of input file used in DLL" - @@ -485,8 +477,6 @@ typedef ^ ParameterType Integer Jac_Idx_SStC_y {:}{:} - - "the start and typedef ^ ParameterType IntKi SensorType - - - "Lidar sensor type" - typedef ^ ParameterType IntKi NumBeam - - - "Number of beams" - typedef ^ ParameterType IntKi NumPulseGate - - - "Number of pulse gates" - -typedef ^ ParameterType ReKi PulseSpacing - - - "Distance between range gates" m -typedef ^ ParameterType ReKi URefLid - - - "Reference average wind speed for the lidar" m/s diff --git a/modules/servodyn/src/ServoDyn_Types.f90 b/modules/servodyn/src/ServoDyn_Types.f90 index eb53b248ae..da5d45358c 100644 --- a/modules/servodyn/src/ServoDyn_Types.f90 +++ b/modules/servodyn/src/ServoDyn_Types.f90 @@ -69,15 +69,9 @@ MODULE ServoDyn_Types INTEGER(IntKi) :: NumCableControl = 0_IntKi !< Number of cable control channels requested [-] CHARACTER(64) , DIMENSION(:), ALLOCATABLE :: CableControlRequestor !< Array with text info about which module requested the cable control channel (size of NumCableControl). This is just for diagnostics. [-] INTEGER(IntKi) :: InterpOrder = 0_IntKi !< Interpolation order from glue code -- required to set m%u_xStC sizes [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LidSpeed !< Number of Lidar measurement distances [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsX !< Lidar X direction measurement points [m] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsY !< Lidar Y direction measurement points [m] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsZ !< Lidar Z direction measurement points [m] INTEGER(IntKi) :: SensorType = 0_IntKi !< Lidar sensor type [-] INTEGER(IntKi) :: NumBeam = 0_IntKi !< Number of beams [-] INTEGER(IntKi) :: NumPulseGate = 0_IntKi !< Number of pulse gates [-] - REAL(ReKi) :: PulseSpacing = 0.0_ReKi !< Distance between range gates [-] - REAL(ReKi) :: URefLid = 0.0_ReKi !< Reference average wind speed for the lidar [m/s] END TYPE SrvD_InitInputType ! ======================= ! ========= SrvD_InitOutputType ======= @@ -249,8 +243,6 @@ MODULE ServoDyn_Types INTEGER(IntKi) :: SensorType = 0_IntKi !< Lidar sensor type [-] INTEGER(IntKi) :: NumBeam = 0_IntKi !< Number of beams [-] INTEGER(IntKi) :: NumPulseGate = 0_IntKi !< Number of pulse gates [-] - INTEGER(IntKi) :: PulseSpacing = 0_IntKi !< Distance between range gates [-] - INTEGER(IntKi) :: URefLid = 0_IntKi !< Reference average wind speed for the lidar [m/s] REAL(DbKi) :: DLL_DT = 0.0_R8Ki !< interval for calling DLL (integer multiple number of DT) [s] CHARACTER(1024) :: DLL_InFile !< Name of input file used in DLL [-] CHARACTER(1024) :: RootName !< RootName for writing output files [-] @@ -491,8 +483,6 @@ MODULE ServoDyn_Types INTEGER(IntKi) :: SensorType = 0_IntKi !< Lidar sensor type [-] INTEGER(IntKi) :: NumBeam = 0_IntKi !< Number of beams [-] INTEGER(IntKi) :: NumPulseGate = 0_IntKi !< Number of pulse gates [-] - REAL(ReKi) :: PulseSpacing = 0.0_ReKi !< Distance between range gates [m] - REAL(ReKi) :: URefLid = 0.0_ReKi !< Reference average wind speed for the lidar [m/s] END TYPE SrvD_ParameterType ! ======================= ! ========= SrvD_InputType ======= @@ -682,59 +672,9 @@ subroutine SrvD_CopyInitInput(SrcInitInputData, DstInitInputData, CtrlCode, ErrS DstInitInputData%CableControlRequestor = SrcInitInputData%CableControlRequestor end if DstInitInputData%InterpOrder = SrcInitInputData%InterpOrder - if (allocated(SrcInitInputData%LidSpeed)) then - LB(1:1) = lbound(SrcInitInputData%LidSpeed) - UB(1:1) = ubound(SrcInitInputData%LidSpeed) - if (.not. allocated(DstInitInputData%LidSpeed)) then - allocate(DstInitInputData%LidSpeed(LB(1):UB(1)), stat=ErrStat2) - if (ErrStat2 /= 0) then - call SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%LidSpeed.', ErrStat, ErrMsg, RoutineName) - return - end if - end if - DstInitInputData%LidSpeed = SrcInitInputData%LidSpeed - end if - if (allocated(SrcInitInputData%MsrPositionsX)) then - LB(1:1) = lbound(SrcInitInputData%MsrPositionsX) - UB(1:1) = ubound(SrcInitInputData%MsrPositionsX) - if (.not. allocated(DstInitInputData%MsrPositionsX)) then - allocate(DstInitInputData%MsrPositionsX(LB(1):UB(1)), stat=ErrStat2) - if (ErrStat2 /= 0) then - call SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%MsrPositionsX.', ErrStat, ErrMsg, RoutineName) - return - end if - end if - DstInitInputData%MsrPositionsX = SrcInitInputData%MsrPositionsX - end if - if (allocated(SrcInitInputData%MsrPositionsY)) then - LB(1:1) = lbound(SrcInitInputData%MsrPositionsY) - UB(1:1) = ubound(SrcInitInputData%MsrPositionsY) - if (.not. allocated(DstInitInputData%MsrPositionsY)) then - allocate(DstInitInputData%MsrPositionsY(LB(1):UB(1)), stat=ErrStat2) - if (ErrStat2 /= 0) then - call SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%MsrPositionsY.', ErrStat, ErrMsg, RoutineName) - return - end if - end if - DstInitInputData%MsrPositionsY = SrcInitInputData%MsrPositionsY - end if - if (allocated(SrcInitInputData%MsrPositionsZ)) then - LB(1:1) = lbound(SrcInitInputData%MsrPositionsZ) - UB(1:1) = ubound(SrcInitInputData%MsrPositionsZ) - if (.not. allocated(DstInitInputData%MsrPositionsZ)) then - allocate(DstInitInputData%MsrPositionsZ(LB(1):UB(1)), stat=ErrStat2) - if (ErrStat2 /= 0) then - call SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%MsrPositionsZ.', ErrStat, ErrMsg, RoutineName) - return - end if - end if - DstInitInputData%MsrPositionsZ = SrcInitInputData%MsrPositionsZ - end if DstInitInputData%SensorType = SrcInitInputData%SensorType DstInitInputData%NumBeam = SrcInitInputData%NumBeam DstInitInputData%NumPulseGate = SrcInitInputData%NumPulseGate - DstInitInputData%PulseSpacing = SrcInitInputData%PulseSpacing - DstInitInputData%URefLid = SrcInitInputData%URefLid end subroutine subroutine SrvD_DestroyInitInput(InitInputData, ErrStat, ErrMsg) @@ -766,18 +706,6 @@ subroutine SrvD_DestroyInitInput(InitInputData, ErrStat, ErrMsg) if (allocated(InitInputData%CableControlRequestor)) then deallocate(InitInputData%CableControlRequestor) end if - if (allocated(InitInputData%LidSpeed)) then - deallocate(InitInputData%LidSpeed) - end if - if (allocated(InitInputData%MsrPositionsX)) then - deallocate(InitInputData%MsrPositionsX) - end if - if (allocated(InitInputData%MsrPositionsY)) then - deallocate(InitInputData%MsrPositionsY) - end if - if (allocated(InitInputData%MsrPositionsZ)) then - deallocate(InitInputData%MsrPositionsZ) - end if end subroutine subroutine SrvD_PackInitInput(RF, Indata) @@ -818,15 +746,9 @@ subroutine SrvD_PackInitInput(RF, Indata) call RegPack(RF, InData%NumCableControl) call RegPackAlloc(RF, InData%CableControlRequestor) call RegPack(RF, InData%InterpOrder) - call RegPackAlloc(RF, InData%LidSpeed) - call RegPackAlloc(RF, InData%MsrPositionsX) - call RegPackAlloc(RF, InData%MsrPositionsY) - call RegPackAlloc(RF, InData%MsrPositionsZ) call RegPack(RF, InData%SensorType) call RegPack(RF, InData%NumBeam) call RegPack(RF, InData%NumPulseGate) - call RegPack(RF, InData%PulseSpacing) - call RegPack(RF, InData%URefLid) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -871,15 +793,9 @@ subroutine SrvD_UnPackInitInput(RF, OutData) call RegUnpack(RF, OutData%NumCableControl); if (RegCheckErr(RF, RoutineName)) return call RegUnpackAlloc(RF, OutData%CableControlRequestor); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%InterpOrder); if (RegCheckErr(RF, RoutineName)) return - call RegUnpackAlloc(RF, OutData%LidSpeed); if (RegCheckErr(RF, RoutineName)) return - call RegUnpackAlloc(RF, OutData%MsrPositionsX); if (RegCheckErr(RF, RoutineName)) return - call RegUnpackAlloc(RF, OutData%MsrPositionsY); if (RegCheckErr(RF, RoutineName)) return - call RegUnpackAlloc(RF, OutData%MsrPositionsZ); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%SensorType); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%NumBeam); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%NumPulseGate); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%PulseSpacing); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%URefLid); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine SrvD_CopyInitOutput(SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg) @@ -1671,8 +1587,6 @@ subroutine SrvD_CopyBladedDLLType(SrcBladedDLLTypeData, DstBladedDLLTypeData, Ct DstBladedDLLTypeData%SensorType = SrcBladedDLLTypeData%SensorType DstBladedDLLTypeData%NumBeam = SrcBladedDLLTypeData%NumBeam DstBladedDLLTypeData%NumPulseGate = SrcBladedDLLTypeData%NumPulseGate - DstBladedDLLTypeData%PulseSpacing = SrcBladedDLLTypeData%PulseSpacing - DstBladedDLLTypeData%URefLid = SrcBladedDLLTypeData%URefLid DstBladedDLLTypeData%DLL_DT = SrcBladedDLLTypeData%DLL_DT DstBladedDLLTypeData%DLL_InFile = SrcBladedDLLTypeData%DLL_InFile DstBladedDLLTypeData%RootName = SrcBladedDLLTypeData%RootName @@ -2049,8 +1963,6 @@ subroutine SrvD_PackBladedDLLType(RF, Indata) call RegPack(RF, InData%SensorType) call RegPack(RF, InData%NumBeam) call RegPack(RF, InData%NumPulseGate) - call RegPack(RF, InData%PulseSpacing) - call RegPack(RF, InData%URefLid) call RegPack(RF, InData%DLL_DT) call RegPack(RF, InData%DLL_InFile) call RegPack(RF, InData%RootName) @@ -2167,8 +2079,6 @@ subroutine SrvD_UnPackBladedDLLType(RF, OutData) call RegUnpack(RF, OutData%SensorType); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%NumBeam); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%NumPulseGate); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%PulseSpacing); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%URefLid); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%DLL_DT); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%DLL_InFile); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%RootName); if (RegCheckErr(RF, RoutineName)) return @@ -4861,8 +4771,6 @@ subroutine SrvD_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg) DstParamData%SensorType = SrcParamData%SensorType DstParamData%NumBeam = SrcParamData%NumBeam DstParamData%NumPulseGate = SrcParamData%NumPulseGate - DstParamData%PulseSpacing = SrcParamData%PulseSpacing - DstParamData%URefLid = SrcParamData%URefLid end subroutine subroutine SrvD_DestroyParam(ParamData, ErrStat, ErrMsg) @@ -5159,8 +5067,6 @@ subroutine SrvD_PackParam(RF, Indata) call RegPack(RF, InData%SensorType) call RegPack(RF, InData%NumBeam) call RegPack(RF, InData%NumPulseGate) - call RegPack(RF, InData%PulseSpacing) - call RegPack(RF, InData%URefLid) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -5354,8 +5260,6 @@ subroutine SrvD_UnPackParam(RF, OutData) call RegUnpack(RF, OutData%SensorType); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%NumBeam); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%NumPulseGate); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%PulseSpacing); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%URefLid); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine SrvD_CopyInput(SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg) diff --git a/modules/subdyn/src/SD_FEM.f90 b/modules/subdyn/src/SD_FEM.f90 index c72f30e425..abd7aa3a47 100644 --- a/modules/subdyn/src/SD_FEM.f90 +++ b/modules/subdyn/src/SD_FEM.f90 @@ -24,7 +24,6 @@ MODULE SD_FEM INTEGER(IntKi), PARAMETER :: MaxMemJnt = 20 ! Maximum number of members at one joint - INTEGER(IntKi), PARAMETER :: MaxOutChs = 2000 ! Max number of Output Channels to be read in INTEGER(IntKi), PARAMETER :: nDOFL_TP = 6 !TODO rename me ! 6 degrees of freedom (length of u subarray [UTP]) ! values of these parameters are ordered by their place in SubDyn input file: diff --git a/modules/subdyn/src/SubDyn.f90 b/modules/subdyn/src/SubDyn.f90 index db36131b94..f07a614f53 100644 --- a/modules/subdyn/src/SubDyn.f90 +++ b/modules/subdyn/src/SubDyn.f90 @@ -25,6 +25,7 @@ Module SubDyn USE NWTC_Library USE SubDyn_Types + USE SubDyn_Output_Params, only: MaxOutPts USE SubDyn_Output USE SubDyn_Tests USE SD_FEM @@ -1560,7 +1561,7 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) ! OutList - list of requested parameters to output to a file CALL ReadCom( UnIn, SDInputFile, 'SSOutList',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -ALLOCATE(Init%SSOutList(MaxOutChs), STAT=ErrStat2) +ALLOCATE(Init%SSOutList(MaxOutPts + p%OutAllInt*p%OutAllDims), STAT=ErrStat2) If (Check( ErrStat2 /= ErrID_None ,'Error allocating SSOutList arrays')) return CALL ReadOutputList ( UnIn, SDInputFile, Init%SSOutList, p%NumOuts, 'SSOutList', 'List of outputs requested', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL CleanUp() diff --git a/modules/subdyn/src/SubDyn_Output.f90 b/modules/subdyn/src/SubDyn_Output.f90 index 76d470711c..920c84dad9 100644 --- a/modules/subdyn/src/SubDyn_Output.f90 +++ b/modules/subdyn/src/SubDyn_Output.f90 @@ -22,13 +22,10 @@ MODULE SubDyn_Output USE SubDyn_Types USE SD_FEM USE SubDyn_Output_Params, only: MNfmKe, MNfmMe, MNTDss, MNRDe, MNTRAe, IntfSS, IntfTRss, IntfTRAss, ReactSS, OutStrLenM1 - USE SubDyn_Output_Params, only: ParamIndxAry, ParamUnitsAry, ValidParamAry, SSqm01, SSqmd01, SSqmdd01 + USE SubDyn_Output_Params, only: ParamIndxAry, ParamUnitsAry, ValidParamAry, SSqm01, SSqmd01, SSqmdd01, MaxOutPts IMPLICIT NONE - ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi),PUBLIC, PARAMETER :: MaxOutPts = 21705 - PRIVATE ! ..... Public Subroutines ................................................................................................... PUBLIC :: SDOut_CloseSum @@ -54,7 +51,7 @@ MODULE SubDyn_Output SUBROUTINE SDOut_Init( Init, y, p, misc, InitOut, WtrDpth, ErrStat, ErrMsg ) TYPE(SD_InitType), INTENT( INOUT ) :: Init ! data needed to initialize the output module TYPE(SD_OutputType), INTENT( INOUT ) :: y ! SubDyn module's output data - TYPE(SD_ParameterType), target, INTENT( INOUT ) :: p ! SubDyn module paramters + TYPE(SD_ParameterType), target, INTENT( INOUT ) :: p ! SubDyn module parameters TYPE(SD_MiscVarType), INTENT( INOUT ) :: misc ! SubDyn misc/optimization variables TYPE(SD_InitOutputType ), INTENT( INOUT ) :: InitOut ! SubDyn module initialization output data REAL(ReKi), INTENT( IN ) :: WtrDpth ! water depth from initialization routine diff --git a/modules/subdyn/src/SubDyn_Output_Params.f90 b/modules/subdyn/src/SubDyn_Output_Params.f90 index f530c38508..f789c117fc 100644 --- a/modules/subdyn/src/SubDyn_Output_Params.f90 +++ b/modules/subdyn/src/SubDyn_Output_Params.f90 @@ -21757,7 +21757,7 @@ module SubDyn_Output_Params ! The maximum number of output channels which can be output by the code. - !INTEGER(IntKi), PARAMETER :: MaxOutPts = 21705 + INTEGER(IntKi), PARAMETER :: MaxOutPts = 21705 INTEGER(IntKi), PARAMETER ::MNfmKe(6,9,99) = reshape((/ & diff --git a/modules/turbsim/src/TS_FileIO.f90 b/modules/turbsim/src/TS_FileIO.f90 index d4a5814137..c9afe84b09 100644 --- a/modules/turbsim/src/TS_FileIO.f90 +++ b/modules/turbsim/src/TS_FileIO.f90 @@ -4868,7 +4868,9 @@ SUBROUTINE GetDefaultRS( p, OtherSt_RandNum, TmpUstarHub, ErrStat, ErrMsg ) Z(2) = p%grid%HubHt + 0.5*p%grid%RotorDiameter ! top of the grid - Z(1) = Z(2) - p%grid%GridHeight ! bottom of the grid + Z(1) = MAX( Tolerance, Z(2) - p%grid%GridHeight ) ! bottom of the grid + Z(2) = Z(1) + p%grid%GridHeight ! re-calculate just in case Z1 is set to Tolerance + CALL getVelocityProfile(p, p%UHub, p%grid%HubHt, Z, V, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'GetDefaultRS') diff --git a/modules/turbsim/src/TSsubs.f90 b/modules/turbsim/src/TSsubs.f90 index 173fd53f62..f869387b6e 100644 --- a/modules/turbsim/src/TSsubs.f90 +++ b/modules/turbsim/src/TSsubs.f90 @@ -1349,13 +1349,7 @@ SUBROUTINE CreateGrid( p_grid, p_usr, UHub, AddTower, ErrStat, ErrMsg ) p_grid%Zbottom = p_grid%HubHt + 0.5*p_grid%RotorDiameter ! height of the highest grid points p_grid%Zbottom = p_grid%Zbottom - p_grid%GridRes_Z * REAL(p_grid%NumGrid_Z - 1, ReKi) ! height of the lowest grid points - - IF ( p_grid%Zbottom <= 0.0_ReKi ) THEN - CALL SetErrStat(ErrID_Fatal,'The lowest grid point ('//TRIM(Num2LStr(p_grid%Zbottom))// ' m) must be above the ground. '//& - 'Adjust the appropriate values in the input file.',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - + p_grid%Zbottom = MAX( Tolerance, p_grid%Zbottom) ! make sure it's above the ground ! (2) the tower points: IF ( AddTower ) THEN diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index 4c02606695..be6496b858 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -236,7 +236,7 @@ def loop_dict(vartree, search_var, branch): var = var.replace(' ', '') loop_dict(vartree_head, var, []) - def read_outlist_freeForm(self,f,module): + def read_outlist_freeForm(self, f, module): ''' Replacement for set_outlist that doesn't care about whether the channel is in the outlist vartree Easier, but riskier because OpenFAST can crash @@ -244,37 +244,78 @@ def read_outlist_freeForm(self,f,module): Inputs: f - file handle module - of OpenFAST, e.g. SubDyn, SeaState (these modules use this) ''' + all_channels = [] data = f.readline() - while data.split()[0] != 'END': - pattern = r'"?(.*?)"?' # grab only the text between quotes - data = re.findall(pattern, data)[0] - channels = data.split(',') # split on commas - channels = [c.strip() for c in channels] # strip whitespace - for c in channels: - self.fst_vt['outlist'][module][c] = True + + # Handle the case if there are blank lines before actual data + while data.strip() == '': + data = f.readline() + + while not data.strip().startswith('END'): + # Get part before the dash (comment) + line = data.split('-')[0] + + # Replace all delimiters with spaces + for delim in ['"', "'", ',', ';', '\t']: + line = line.replace(delim, ' ') + + # Split into words and add non-empty ones to the channel list + line_channels = [word.strip() for word in line.split() if word.strip()] + if line_channels: + all_channels.extend(line_channels) + + # Read next line data = f.readline() + + # Handle the case if there are blank lines + while data.strip() == '': + data = f.readline() + + # Store all channels in the outlist + for channel in all_channels: + self.fst_vt['outlist'][module][channel] = True - def read_outlist(self,f,module): + def read_outlist(self, f, module): ''' - Read the outlist section of the FAST input file, genralized for most modules + Read the outlist section of the FAST input file, generalized for most modules Inputs: f - file handle module - of OpenFAST, e.g. ElastoDyn, ServoDyn, AeroDyn, AeroDisk, etc. + Returns: List of channel names ''' - data = f.readline().split()[0] # to counter if we dont have any quotes - while data != 'END': - if data.find('"')>=0: - channels = data.split('"') - channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - channel_list = [row_string[0].split('\n')[0]] - else: - channel_list = row_string - self.set_outlist(self.fst_vt['outlist'][module], channel_list) - data = f.readline().split()[0] # to counter if we dont have any quotes + all_channels = [] + data = f.readline() + + # Handle the case if there are blank lines before actual data + while data.strip() == '': + data = f.readline() + + while not data.strip().startswith('END'): + # Get part before the dash (comment) + line = data.split('-')[0] + + # Replace all delimiters with spaces + for delim in ['"', "'", ',', ';', '\t']: + line = line.replace(delim, ' ') + + # Split into words and add non-empty ones to the channel list + line_channels = [word.strip() for word in line.split() if word.strip()] + if line_channels: + all_channels.extend(line_channels) + + # Read next line + data = f.readline() + + # Handle the case if there are blank lines + while data.strip() == '': + data = f.readline() + + # Store all channels in the outlist + if all_channels: + self.set_outlist(self.fst_vt['outlist'][module], all_channels) + + return all_channels def read_MainInput(self): # Main FAST v8.16-v8.17 Input File @@ -557,38 +598,10 @@ def read_ElastoDyn(self, ed_file): self.fst_vt['ElastoDyn']['BldGagNd'] = read_array(f,self.fst_vt['ElastoDyn']['NBlGages'], array_type=int) else: self.fst_vt['ElastoDyn']['BldGagNd'] = 0 - f.readline() - - # Loop through output channel lines + + f.readline() - data = f.readline() - # if data != '': - # while data.split()[0] != 'END': - # channels = data.split('"') - # channel_list = channels[1].split(',') - # self.set_outlist(self.fst_vt['outlist']['ElastoDyn'], channel_list) - - # data = f.readline() - # else: - # # there is a blank line between the outlist and the END of the file - # f.readline() - - # Handle the case if there are blank lines before the END statement, check if blank line - while data.split().__len__() == 0: - data = f.readline() - - while data.split()[0] != 'END': - if data.find('"')>=0: - channels = data.split('"') - channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - channel_list = row_string[0].split('\n')[0] - else: - channel_list = row_string - self.set_outlist(self.fst_vt['outlist']['ElastoDyn'], channel_list) - data = f.readline() + self.read_outlist(f,'ElastoDyn') # ElastoDyn optional outlist try: @@ -597,19 +610,7 @@ def read_ElastoDyn(self, ed_file): self.fst_vt['ElastoDyn']['BldNd_BlOutNd'] = f.readline().split()[0] f.readline() - data = f.readline() - while data.split()[0] != 'END': - if data.find('"')>=0: - channels = data.split('"') - opt_channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - opt_channel_list = row_string[0].split('\n')[0] - else: - opt_channel_list = row_string - self.set_outlist(self.fst_vt['outlist']['ElastoDyn_Nodes'], opt_channel_list) - data = f.readline() + self.read_outlist(f,'ElastoDyn') except: # The optinal outlist does not exist. None @@ -736,7 +737,7 @@ def read_ElastoDynTower(self, tower_file): f.readline() f.readline() - # General Tower Paramters + # General Tower Parameters f.readline() self.fst_vt['ElastoDynTower']['NTwInpSt'] = int(f.readline().split()[0]) self.fst_vt['ElastoDynTower']['TwrFADmp1'] = float_read(f.readline().split()[0]) @@ -856,13 +857,9 @@ def read_BeamDyn(self, bd_file, BladeNumber = 0): self.fst_vt['BeamDyn'][BladeNumber]['OutNd'] = [idx.strip() for idx in f.readline().split('OutNd')[0].split(',')] # BeamDyn Outlist f.readline() - data = f.readline() - while data.split()[0] != 'END': - channels = data.split('"') - channel_list = channels[1].split(',') - self.set_outlist(self.fst_vt['outlist']['BeamDyn'], channel_list) - data = f.readline() - + + self.read_outlist(f,'BeamDyn') + # BeamDyn optional outlist try: f.readline() @@ -870,19 +867,8 @@ def read_BeamDyn(self, bd_file, BladeNumber = 0): self.fst_vt['BeamDyn'][BladeNumber]['BldNd_BlOutNd'] = f.readline().split()[0] f.readline() - data = f.readline() - while data.split()[0] != 'END': - if data.find('"')>=0: - channels = data.split('"') - opt_channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - opt_channel_list = row_string[0].split('\n')[0] - else: - opt_channel_list = row_string - self.set_outlist(self.fst_vt['outlist']['BeamDyn_Nodes'], opt_channel_list) - data = f.readline() + + self.read_outlist(f,'BeamDyn_Nodes') except: # The optinal outlist does not exist. None @@ -1025,19 +1011,7 @@ def read_InflowWind(self): # InflowWind Outlist f.readline() - data = f.readline() - while data.split()[0] != 'END': - if data.find('"')>=0: - channels = data.split('"') - channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - channel_list = row_string[0].split('\n')[0] - else: - channel_list = row_string - self.set_outlist(self.fst_vt['outlist']['InflowWind'], channel_list) - data = f.readline() + self.read_outlist(f,'InflowWind') f.close() @@ -1194,26 +1168,10 @@ def read_AeroDyn(self): # AeroDyn Outlist f.readline() - data = f.readline() - # Handle the case if there are blank lines before the END statement, check if blank line - while data.split().__len__() == 0: - data = f.readline() + self.read_outlist(f,'AeroDyn') - while data.split()[0] != 'END': - if data.find('"')>=0: - channels = data.split('"') - channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - channel_list = row_string[0].split('\n')[0] - else: - channel_list = row_string - self.set_outlist(self.fst_vt['outlist']['AeroDyn'], channel_list) - data = f.readline() - # AeroDyn optional outlist try: f.readline() @@ -1221,19 +1179,7 @@ def read_AeroDyn(self): self.fst_vt['AeroDyn']['BldNd_BlOutNd'] = f.readline().split()[0] f.readline() - data = f.readline() - while data.split()[0] != 'END': - if data.find('"')>=0: - channels = data.split('"') - opt_channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - opt_channel_list = row_string[0].split('\n')[0] - else: - opt_channel_list = row_string - self.set_outlist(self.fst_vt['outlist']['AeroDyn_Nodes'], opt_channel_list) - data = f.readline() + self.read_outlist(f,'AeroDyn_Nodes') except: # The optinal outlist does not exist. None @@ -1702,12 +1648,7 @@ def read_ServoDyn(self): # ServoDyn Outlist f.readline() - data = f.readline() - while data.split()[0] != 'END': - channels = data.split('"') - channel_list = channels[1].split(',') - self.set_outlist(self.fst_vt['outlist']['ServoDyn'], channel_list) - data = f.readline() + self.read_outlist(f,'ServoDyn') f.close() @@ -1717,7 +1658,10 @@ def read_StC(self,filename): ''' StC_vt = {} - with open(os.path.join(self.FAST_directory, filename)) as f: + # Inputs should be relative to ServoDyn, like in OpenFAST + SvD_dir = os.path.dirname(self.fst_vt['Fst']['ServoFile']) + + with open(os.path.join(self.FAST_directory, SvD_dir, filename)) as f: f.readline() f.readline() @@ -2400,19 +2344,7 @@ def read_HydroDyn(self, hd_file): # HydroDyn Outlist f.readline() - data = f.readline() - while data.split()[0] != 'END': - if data.find('"')>=0: - channels = data.split('"') - channel_list = channels[1].split(',') - else: - row_string = data.split(',') - if len(row_string)==1: - channel_list = row_string[0].split('\n')[0] - else: - channel_list = row_string - self.set_outlist(self.fst_vt['outlist']['AeroDyn'], channel_list) - data = f.readline() + self.read_outlist(f, 'HydroDyn') f.close() @@ -3397,7 +3329,8 @@ def read_MoorDyn(self, moordyn_file): if option_name.upper() == 'WATERKIN': self.fst_vt['MoorDyn']['WaterKin'] = option_value.strip('"') WaterKin_file = os.path.normpath(os.path.join(os.path.dirname(moordyn_file), self.fst_vt['MoorDyn']['WaterKin'])) - self.read_WaterKin(WaterKin_file) + if self.fst_vt['MoorDyn']['WaterKin'].upper() not in ['0','UNUSED']: + self.read_WaterKin(WaterKin_file) self.fst_vt['MoorDyn']['option_values'].append(float_read(option_value.strip('"'))) # some options values can be strings or floats self.fst_vt['MoorDyn']['option_names'].append(option_name) @@ -3582,7 +3515,7 @@ def execute(self): bd_file1 = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['BDBldFile(1)'])) bd_file2 = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['BDBldFile(2)'])) bd_file3 = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['BDBldFile(3)'])) - if os.path.exists(bd_file1): + if os.path.isfile(bd_file1): # if the files are the same then we only need to read it once, need to handle the cases where we have a 2 or 1 bladed rotor # Check unique BeamDyn blade files and read only once if identical if bd_file1 == bd_file2 and bd_file1 == bd_file3: diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 30e594181c..088cea824e 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -65,9 +65,9 @@ def int_default_out(val, trim = False): """ if type(val) is float: if trim: - return '{:d}'.format(val) + return '{:d}'.format(int(val)) else: - return '{:<22d}'.format(val) + return '{:<22d}'.format(int(val)) else: if trim: return '{:}'.format(val) @@ -250,10 +250,10 @@ def execute(self): self.write_MAP() elif self.fst_vt['Fst']['CompMooring'] == 3: self.write_MoorDyn() - if 'option_names' in self.fst_vt['MoorDyn'] and 'WATERKIN' in self.fst_vt['MoorDyn']['option_names']: + if self.fst_vt['WaterKin']: # will be empty if not read self.write_WaterKin(os.path.join(self.FAST_runDirectory,self.fst_vt['MoorDyn']['WaterKin_file'])) - # # look at if the the self.fst_vt['BeamDyn'] is an array, if so, loop through the array + # # look at if the self.fst_vt['BeamDyn'] is an array, if so, loop through the array # # if its a dictionary, just write the same BeamDyn file if isinstance(self.fst_vt['BeamDyn'], list): @@ -2634,10 +2634,14 @@ def write_MoorDyn(self): f.write('---------------------- SOLVER OPTIONS ---------------------------------------\n') for i in range(len(self.fst_vt['MoorDyn']['option_values'])): - if 'WATERKIN' in self.fst_vt['MoorDyn']['option_names'][i]: + if self.fst_vt['MoorDyn']['option_names'][i].upper() == 'WATERKIN' and self.fst_vt['WaterKin']: + # WATERKIN needs to be a string, and should have already been read in and part of fst_vt self.fst_vt['MoorDyn']['WaterKin_file'] = self.FAST_namingOut + '_WaterKin.dat' f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['MoorDyn']['WaterKin_file']+'"', self.fst_vt['MoorDyn']['option_names'][i], self.fst_vt['MoorDyn']['option_descriptions'][i]+'\n')) - else: # if not waterkin handle normally + elif self.fst_vt['MoorDyn']['option_names'][i].upper() in ['INERTIALF','WATERKIN']: + # These options need to be an integer + f.write('{:<22} {:<11} {:}'.format(int_default_out(self.fst_vt['MoorDyn']['option_values'][i]), self.fst_vt['MoorDyn']['option_names'][i], self.fst_vt['MoorDyn']['option_descriptions'][i]+'\n')) + else: # if not handle normally f.write('{:<22} {:<11} {:}'.format(float_default_out(self.fst_vt['MoorDyn']['option_values'][i]), self.fst_vt['MoorDyn']['option_names'][i], self.fst_vt['MoorDyn']['option_descriptions'][i]+'\n')) f.write('------------------------ OUTPUTS --------------------------------------------\n') diff --git a/openfast_io/openfast_io/turbsim_file.py b/openfast_io/openfast_io/turbsim_file.py index 02b8887cff..3434ac7e51 100644 --- a/openfast_io/openfast_io/turbsim_file.py +++ b/openfast_io/openfast_io/turbsim_file.py @@ -367,7 +367,7 @@ def normalPlane(ts, t=None, it0=None, removeMean=False): def vertProfile(self, y_span='full'): """ Vertical profile of the box INPUTS: - - y_span: if 'full', average the vertical profile accross all y-values + - y_span: if 'full', average the vertical profile across all y-values if 'mid', average the vertical profile at the middle y value """ if y_span=='full': @@ -1053,7 +1053,7 @@ def fitPowerLaw(ts, z_ref=None, y_span='full', U_guess=10, alpha_guess=0.1): Fit power law to vertical profile INPUTS: - z_ref: reference height used to define the "U_ref" - - y_span: if 'full', average the vertical profile accross all y-values + - y_span: if 'full', average the vertical profile across all y-values if 'mid', average the vertical profile at the middle y value """ if z_ref is None: diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 7595361ef7..cbac8acf4f 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "openfast_io" # dynamic = ["version"] -version = "4.0.3" +version = "4.1.0" description = "Readers and writers for OpenFAST files." license = {file = "../LICENSE"} authors = [ @@ -39,7 +39,6 @@ classifiers = [ # Optional # Specify the Python versions you support here. In particular, ensure # that you indicate you support Python 3. These classifiers are *not* # checked by "pip install". See instead "python_requires" below. - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 99c76c0bc0..cf14d143f2 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -344,9 +344,9 @@ of_regression("5MW_OC4Jckt_ExtPtfm" "openfast;elastodyn;extpt of_regression("HelicalWake_OLAF" "openfast;aerodyn;olaf") of_regression("EllipticalWing_OLAF" "openfast;aerodyn;olaf") of_regression("StC_test_OC4Semi" "openfast;servodyn;hydrodyn;moordyn;offshore;stc") -of_regression("MHK_RM1_Fixed" "openfast;elastodyn;aerodyn;mhk") -of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk") -of_regression("MHK_RM1_Floating_wNacDrag" "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk") +of_regression("MHK_RM1_Fixed" "openfast;elastodyn;aerodyn;mhk;offshore") +of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk;offshore") +of_regression("MHK_RM1_Floating_wNacDrag" "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk;offshore") of_regression("Tailfin_FreeYaw1DOF_PolarBased" "openfast;elastodyn;aerodyn") of_regression("Tailfin_FreeYaw1DOF_Unsteady" "openfast;elastodyn;aerodyn") of_regression("5MW_Land_DLL_WTurb_ADsk" "openfast;elastodyn;aerodisk") diff --git a/reg_tests/executeUnsteadyAeroRegressionCase.py b/reg_tests/executeUnsteadyAeroRegressionCase.py index 2e441c4abc..53c8bf567e 100644 --- a/reg_tests/executeUnsteadyAeroRegressionCase.py +++ b/reg_tests/executeUnsteadyAeroRegressionCase.py @@ -158,7 +158,7 @@ def Error(msg): sys.exit(0) else: print('---------- UNSTEADY AERODYNAMICS DRIVER TEST: {} --------'.format(caseName)) - print('The following errors occured:') + print('The following errors occurred:') for e in errors: print(e) sys.exit(1) diff --git a/reg_tests/lib/rtestlib.py b/reg_tests/lib/rtestlib.py index e90ca95820..ed952f25ec 100644 --- a/reg_tests/lib/rtestlib.py +++ b/reg_tests/lib/rtestlib.py @@ -64,7 +64,7 @@ def validateExeOrExit(path): def copyTree(src, dst, excludeExt=None, renameDict=None, renameExtDict=None, includeExt=None): """ - Copy a directory to another one, overwritting files if necessary. + Copy a directory to another one, overwriting files if necessary. copy_tree from distutils and copytree from shutil fail on Windows (in particular on git files) INPUTS: - src: source directory diff --git a/reg_tests/r-test b/reg_tests/r-test index a18c4d72d6..12d32990a6 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit a18c4d72d643ac8a8aeebba6e02465671c14c5b0 +Subproject commit 12d32990a625b1c27d6c4166e438777fe0023da4 diff --git a/share/discon/DISCON.F90 b/share/discon/DISCON.F90 index c37070c7ea..b2f8c728d9 100644 --- a/share/discon/DISCON.F90 +++ b/share/discon/DISCON.F90 @@ -69,7 +69,7 @@ SUBROUTINE DISCON ( avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG ) BIND (C, N REAL(4), PARAMETER :: OnePlusEps = 1.0 + EPSILON(OnePlusEps) ! The number slighty greater than unity in single precision. REAL(4), PARAMETER :: PC_DT = 0.000125 !JASON:THIS CHANGED FOR ITI BARGE: 0.0001 ! Communication interval for pitch controller, sec. REAL(4), PARAMETER :: PC_KI = 0.008068634 ! Integral gain for pitch controller at rated pitch (zero), (-). -REAL(4), PARAMETER :: PC_KK = 0.1099965 ! Pitch angle where the the derivative of the aerodynamic power w.r.t. pitch has increased by a factor of two relative to the derivative at rated pitch (zero), rad. +REAL(4), PARAMETER :: PC_KK = 0.1099965 ! Pitch angle where the derivative of the aerodynamic power w.r.t. pitch has increased by a factor of two relative to the derivative at rated pitch (zero), rad. REAL(4), PARAMETER :: PC_KP = 0.01882681 ! Proportional gain for pitch controller at rated pitch (zero), sec. REAL(4), PARAMETER :: PC_MaxPit = 1.570796 ! Maximum pitch setting in pitch controller, rad. REAL(4), PARAMETER :: PC_MaxRat = 0.1396263 ! Maximum pitch rate (in absolute value) in pitch controller, rad/s. @@ -316,7 +316,7 @@ SUBROUTINE DISCON ( avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG ) BIND (C, N ! Main control calculations: -IF ( ( iStatus >= 0 ) .AND. ( aviFAIL >= 0 ) ) THEN ! Only compute control calculations if no error has occured and we are not on the last time step +IF ( ( iStatus >= 0 ) .AND. ( aviFAIL >= 0 ) ) THEN ! Only compute control calculations if no error has occurred and we are not on the last time step diff --git a/vs-build/HydroDyn/HydroDynDriver.vfproj b/vs-build/HydroDyn/HydroDynDriver.vfproj index 3b057f9d10..6b4bd4fe78 100644 --- a/vs-build/HydroDyn/HydroDynDriver.vfproj +++ b/vs-build/HydroDyn/HydroDynDriver.vfproj @@ -437,7 +437,8 @@ - + + @@ -454,8 +455,7 @@ - - + @@ -472,7 +472,9 @@ - + + + @@ -488,8 +490,7 @@ - - + @@ -506,8 +507,7 @@ - - + diff --git a/vs-build/HydroDyn_c_binding/HydroDyn_c_binding.vfproj b/vs-build/HydroDyn_c_binding/HydroDyn_c_binding.vfproj index efe02d92b2..34780120da 100644 --- a/vs-build/HydroDyn_c_binding/HydroDyn_c_binding.vfproj +++ b/vs-build/HydroDyn_c_binding/HydroDyn_c_binding.vfproj @@ -214,7 +214,6 @@ - @@ -263,11 +262,12 @@ - - + + + @@ -382,5 +382,6 @@ + diff --git a/vs-build/MoorDyn/MoorDynDriver.vfproj b/vs-build/MoorDyn/MoorDynDriver.vfproj index 7dba18e7fa..9f7ac9fdfc 100644 --- a/vs-build/MoorDyn/MoorDynDriver.vfproj +++ b/vs-build/MoorDyn/MoorDynDriver.vfproj @@ -85,7 +85,6 @@ - @@ -251,5 +250,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vs-build/MoorDyn_c_binding/MoorDyn_c_binding.vfproj b/vs-build/MoorDyn_c_binding/MoorDyn_c_binding.vfproj index b70d760c32..f74ba72b6b 100644 --- a/vs-build/MoorDyn_c_binding/MoorDyn_c_binding.vfproj +++ b/vs-build/MoorDyn_c_binding/MoorDyn_c_binding.vfproj @@ -105,7 +105,6 @@ - @@ -273,5 +272,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vs-build/SeaState/SeaStateDriver.vfproj b/vs-build/SeaState/SeaStateDriver.vfproj index 483c4ab25a..f0f29c7847 100644 --- a/vs-build/SeaState/SeaStateDriver.vfproj +++ b/vs-build/SeaState/SeaStateDriver.vfproj @@ -199,7 +199,8 @@ - + + @@ -212,8 +213,7 @@ - - + @@ -226,7 +226,9 @@ - + + + @@ -239,8 +241,6 @@ - - diff --git a/vs-build/SeaState_c_binding/SeaState_c_binding.sln b/vs-build/SeaState_c_binding/SeaState_c_binding.sln new file mode 100644 index 0000000000..16bae50940 --- /dev/null +++ b/vs-build/SeaState_c_binding/SeaState_c_binding.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.902 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8A7732CE-4ADA-4074-973E-8E797747D444}") = "SeaState_c_binding", "SeaState_c_binding.vfproj", "{84782F71-FD4C-4427-AD62-B33EF3C9FFE2}" + ProjectSection(ProjectDependencies) = postProject + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16} = {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FAST_Registry", "..\Registry\FAST_Registry.vcxproj", "{DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_Double|Win32 = Debug_Double|Win32 + Debug_Double|x64 = Debug_Double|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release_Double|Win32 = Release_Double|Win32 + Release_Double|x64 = Release_Double|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug_Double|Win32.ActiveCfg = Debug_Double|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug_Double|Win32.Build.0 = Debug_Double|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug_Double|x64.ActiveCfg = Debug_Double|x64 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug_Double|x64.Build.0 = Debug_Double|x64 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug|Win32.Build.0 = Debug|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug|x64.ActiveCfg = Debug|x64 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Debug|x64.Build.0 = Debug|x64 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release_Double|Win32.ActiveCfg = Release_Double|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release_Double|Win32.Build.0 = Release_Double|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release_Double|x64.ActiveCfg = Release_Double|x64 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release_Double|x64.Build.0 = Release_Double|x64 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release|Win32.ActiveCfg = Release|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release|Win32.Build.0 = Release|Win32 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release|x64.ActiveCfg = Release|x64 + {84782F71-FD4C-4427-AD62-B33EF3C9FFE2}.Release|x64.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|Win32.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|Win32.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|x64.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug_Double|x64.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|Win32.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|Win32.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|x64.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Debug|x64.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|Win32.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|Win32.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|x64.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release_Double|x64.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release|Win32.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release|Win32.Build.0 = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release|x64.ActiveCfg = Release|x64 + {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {49DA4583-1BAB-4459-8F53-EB898075680D} + EndGlobalSection +EndGlobal diff --git a/vs-build/SeaState_c_binding/SeaState_c_binding.vfproj b/vs-build/SeaState_c_binding/SeaState_c_binding.vfproj new file mode 100644 index 0000000000..7ea7b9851b --- /dev/null +++ b/vs-build/SeaState_c_binding/SeaState_c_binding.vfproj @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +